run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<int> run() async {
final results = argResults!;
final prefix = results['prefix'] as String;
final dryRun = results['dry-run'] as bool;
final inPlace = results['in-place'] as bool;
final force = results['force'] as bool;
// Verbose flag isn't on `migrate`'s parser; use a non-verbose
// logger purely to access the stderr-routing `error()` helper.
final logger = FLILogger(false);
// Reject stray positional args before doing anything else.
final rejectCode = rejectUnknownArgs(results, logger);
if (rejectCode != null) {
return rejectCode;
}
// 1. Discover legacy files.
final legacy = _discoverLegacyFiles(prefix);
if (legacy.isEmpty) {
stdout.writeln(
'ℹ No legacy flutter_launcher_icons-<flavor>.yaml files found in '
'$prefix. Nothing to migrate.',
);
return 0;
}
// 2. Target existence check (skipped on --dry-run because we're not
// writing anything).
final targetPath = p.join(prefix, constants.consolidatedFlavorsFileName);
if (!dryRun && File(targetPath).existsSync() && !force) {
logger.error(
'$targetPath already exists. Re-run with --force to overwrite, '
'or move/delete the file first.',
);
return 64;
}
// 3. Parse each legacy file.
final flavorBlocks = <String, Map<String, dynamic>>{};
for (final entry in legacy) {
try {
final block = _parseLegacyFile(entry.path);
flavorBlocks[entry.flavor] = block;
} on _MigrateParseException catch (e) {
logger.error('Failed to parse ${entry.path}: ${e.message}');
return 64;
} on Exception catch (e) {
logger.error('Failed to read ${entry.path}: $e');
return 1;
}
}
// 4. Build the output document.
final doc = <String, dynamic>{
'version': 1,
'defaults': <String, dynamic>{},
'flavors': flavorBlocks,
};
final yamlOut = emitYaml(doc);
// 5. Compute promotion candidates (keys with identical values across
// every flavor block).
final candidates = _computePromotionCandidates(flavorBlocks);
// 6. Output / write.
if (dryRun) {
stdout.write(yamlOut);
_printCandidatesReport(candidates);
return 0;
}
// Backup originals before any destructive step.
for (final entry in legacy) {
try {
File(entry.path).copySync('${entry.path}.bak');
} on Exception catch (e) {
logger.error('Failed to back up ${entry.path}: $e');
return 1;
}
}
try {
File(targetPath).writeAsStringSync(yamlOut);
} on Exception catch (e) {
logger.error('Failed to write $targetPath: $e');
return 1;
}
if (inPlace) {
for (final entry in legacy) {
try {
File(entry.path).deleteSync();
} on Exception catch (e) {
logger.warn('Could not delete ${entry.path}: $e');
}
}
}
stdout.writeln('✓ Wrote $targetPath (${flavorBlocks.length} flavors)');
_printCandidatesReport(candidates);
return 0;
}