run static method

OutputScan run(
  1. DialectProject project, {
  2. List<PlatformConfig>? platforms,
})

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;
}