mergeCommands static method
Merges project and package commands. Precedence: reservedCommands (built-ins),
then project, then packages; a shadowed command is dropped with an onWarning.
Implementation
static List<NyCommand> mergeCommands({
required List<NyCommand> projectCommands,
required List<NyCommand> packageCommands,
Iterable<String> reservedCommands = const [],
void Function(String message)? onWarning,
}) {
final void Function(String message) warn =
onWarning ?? MetroConsole.writeInYellow;
final Set<String> reserved = reservedCommands.toSet();
final Map<String, NyCommand> taken = {};
final List<NyCommand> merged = [];
for (final NyCommand command in projectCommands) {
final String key = command.fullName;
if (reserved.contains(key)) {
warn(
'[Metro] Skipping "$key" from $commandsFolder/commands.json - it is a built-in Metro command',
);
continue;
}
if (taken.containsKey(key)) continue;
taken[key] = command;
merged.add(command);
}
for (final NyCommand command in packageCommands) {
final String key = command.fullName;
if (reserved.contains(key)) {
warn(
'[Metro] Skipping "$key" from package "${command.package}" - it is a built-in Metro command',
);
continue;
}
final NyCommand? existing = taken[key];
if (existing != null) {
final String owner = existing.package == null
? 'your project'
: 'package "${existing.package}"';
warn(
'[Metro] Skipping "$key" from package "${command.package}" - it is already defined by $owner',
);
continue;
}
taken[key] = command;
merged.add(command);
}
return merged;
}