diff --git a/packages/melos/lib/src/common/utils.dart b/packages/melos/lib/src/common/utils.dart index 293281c2d..6b2f92d2e 100644 --- a/packages/melos/lib/src/common/utils.dart +++ b/packages/melos/lib/src/common/utils.dart @@ -354,15 +354,38 @@ String listAsPaddedTable(List> table, {int paddingSize = 1}) { return output.join('\n'); } -/// Merges two YAML maps together, overriding any values in [base] with those +extension YamlUtils on YamlNode { + /// Converts a YAML node to a regular mutable Dart object. + Object? unYaml() { + final node = this; + if (node is YamlScalar) { + return node.value; + } + if (node is YamlMap) { + return { + for (final entry in node.nodes.entries) + (entry.key as YamlNode).unYaml(): entry.value.unYaml(), + }; + } + if (node is YamlList) { + return node.nodes.map((node) => node.unYaml()).toList(); + } + throw FormatException( + 'Unsupported YAML node type encountered: ${node.runtimeType}', + this, + ); + } +} + +/// Merges two maps together, overriding any values in [base] with those /// with the same key in [overlay]. -void mergeYaml(Map base, Map overlay) { +void mergeMap(Map base, Map overlay) { for (final entry in overlay.entries) { final overlayValue = entry.value; final baseValue = base[entry.key]; if (overlayValue is Map) { if (baseValue is Map) { - mergeYaml(baseValue, overlayValue); + mergeMap(baseValue, overlayValue); } else { base[entry.key] = overlayValue; } diff --git a/packages/melos/lib/src/workspace_configs.dart b/packages/melos/lib/src/workspace_configs.dart index b1d469e06..bcc217a44 100644 --- a/packages/melos/lib/src/workspace_configs.dart +++ b/packages/melos/lib/src/workspace_configs.dart @@ -640,7 +640,8 @@ You must have one of the following to be a valid Melos workspace: final melosYamlPath = melosYamlPathForDirectory(melosWorkspaceDirectory.path); - final yamlContents = await loadYamlFile(melosYamlPath); + final yamlContents = + (await loadYamlFile(melosYamlPath))?.unYaml() as Map?; if (yamlContents == null) { throw MelosConfigException('Failed to parse the melos.yaml file'); @@ -648,9 +649,10 @@ You must have one of the following to be a valid Melos workspace: final melosOverridesYamlPath = melosOverridesYamlPathForDirectory(melosWorkspaceDirectory.path); - final overridesYamlContents = await loadYamlFile(melosOverridesYamlPath); + final overridesYamlContents = (await loadYamlFile(melosOverridesYamlPath)) + ?.unYaml() as Map?; if (overridesYamlContents != null) { - mergeYaml(yamlContents, overridesYamlContents); + mergeMap(yamlContents, overridesYamlContents); } return MelosWorkspaceConfig.fromYaml( diff --git a/packages/melos/test/utils_test.dart b/packages/melos/test/utils_test.dart index 6a53289c5..6c6661851 100644 --- a/packages/melos/test/utils_test.dart +++ b/packages/melos/test/utils_test.dart @@ -120,7 +120,7 @@ void main() { 'stu': ['another', 'different', 'type'], 'yza': false, }; - mergeYaml(base, overlay); + mergeMap(base, overlay); expect(base, const { 'abc': 098, 'def': [4, 5, 6, 7],