Skip to content

Commit

Permalink
fix: Make loaded config YAML maps mutable to allow merging overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
hacker1024 committed Oct 18, 2022
1 parent 54cea04 commit d629e14
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
29 changes: 26 additions & 3 deletions packages/melos/lib/src/common/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,38 @@ String listAsPaddedTable(List<List<String>> 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<Object?, Object?> base, Map<Object?, Object?> overlay) {
void mergeMap(Map<Object?, Object?> base, Map<Object?, Object?> overlay) {
for (final entry in overlay.entries) {
final overlayValue = entry.value;
final baseValue = base[entry.key];
if (overlayValue is Map<Object?, Object?>) {
if (baseValue is Map<Object?, Object?>) {
mergeYaml(baseValue, overlayValue);
mergeMap(baseValue, overlayValue);
} else {
base[entry.key] = overlayValue;
}
Expand Down
8 changes: 5 additions & 3 deletions packages/melos/lib/src/workspace_configs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -640,17 +640,19 @@ 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<Object?, Object?>?;

if (yamlContents == null) {
throw MelosConfigException('Failed to parse the melos.yaml file');
}

final melosOverridesYamlPath =
melosOverridesYamlPathForDirectory(melosWorkspaceDirectory.path);
final overridesYamlContents = await loadYamlFile(melosOverridesYamlPath);
final overridesYamlContents = (await loadYamlFile(melosOverridesYamlPath))
?.unYaml() as Map<Object?, Object?>?;
if (overridesYamlContents != null) {
mergeYaml(yamlContents, overridesYamlContents);
mergeMap(yamlContents, overridesYamlContents);
}

return MelosWorkspaceConfig.fromYaml(
Expand Down
2 changes: 1 addition & 1 deletion packages/melos/test/utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down

0 comments on commit d629e14

Please sign in to comment.