run static method
Scan the on-disk outputs of platforms (default: every configured
platform) for orphan keys.
The source-locale output yields the recoverable English value (+ any
@key metadata); a translation output yields the translated value, so
--adopt can put both back rather than silently dropping the
translation on regenerate.
Implementation
static OutputScan run(
DialectProject project, {
List<PlatformConfig>? platforms,
}) {
final targets = platforms ?? project.config.platforms.values.toList();
final sourceKeys = {for (final e in project.source.entries) e.key};
final sourceLocale = project.config.sourceLocale;
final locales = <String>{sourceLocale, ...project.config.targetLocales};
final scan = OutputScan._();
for (final platform in targets) {
final isArb = platform.format == 'arb';
final isJson = JsonAdapter.handles(platform.format);
// Unknown formats emit nothing, so they can't have orphans we'd
// delete. Skip them.
if (!isArb && !isJson) continue;
final outDir = p.join(project.root, platform.output);
for (final locale in locales) {
final filename = isArb
? ArbAdapter.filenameFor(locale)
: JsonAdapter.filenameFor(locale);
final path = p.join(outDir, filename);
final file = File(path);
if (!file.existsSync()) continue;
final Map<String, ArbEntry> onDisk;
try {
onDisk = _readOutputEntries(file.readAsStringSync(), isArb: isArb);
} on FormatException {
// A malformed output isn't a data-loss concern — the next write
// replaces it with canonical bytes. Skip it for scanning.
continue;
}
for (final entry in onDisk.values) {
if (sourceKeys.contains(entry.key)) continue;
scan._files.putIfAbsent(entry.key, () => <String>{}).add(path);
if (locale == sourceLocale) {
scan._sourceEntries.putIfAbsent(entry.key, () => entry);
} else {
scan._translationEntries
.putIfAbsent(locale, () => <String, String>{})
.putIfAbsent(entry.key, () => entry.value);
}
}
}
}
return scan;
}