prune function

PruneResult prune(
  1. List<StringLocale>? strings,
  2. String bundleDir, {
  3. List<String>? locales,
  4. bool dryRun = false,
})

Implementation

PruneResult prune(
  List<StringLocale>? strings,
  String bundleDir, {
  List<String>? locales,
  bool dryRun = false,
}) {
  final list = strings ?? getRegistry().values.toList();
  final declaredIds = {for (final s in list) s.id};

  final manifestFile = File('$bundleDir/manifest.json');
  final manifest =
      jsonDecode(manifestFile.readAsStringSync()) as Map<String, dynamic>;
  final files = (manifest['files'] as Map?) ?? {};
  final targets = locales ?? files.keys.cast<String>().toList();

  final result = PruneResult();
  final changed = <String, String>{};

  for (final locale in targets) {
    final entry = files[locale] as Map?;
    if (entry == null) continue;
    final fpath = File('$bundleDir/${entry['path']}');
    final data = jsonDecode(fpath.readAsStringSync()) as Map<String, dynamic>;
    final stringsMap = (data['strings'] as Map?) ?? {};

    final orphans =
        stringsMap.keys.where((sid) => !declaredIds.contains(sid)).toList();
    if (orphans.isEmpty) continue;

    for (final sid in orphans) {
      result.removed.add([locale, sid as String]);
      if (!dryRun) stringsMap.remove(sid);
    }

    if (!dryRun) {
      final payload = '${const JsonEncoder.withIndent('  ').convert(data)}\n';
      fpath.writeAsStringSync(payload);
      changed[locale] = slHash([payload]);
    }
  }

  if (!dryRun && changed.isNotEmpty) {
    changed.forEach((locale, h) {
      (files[locale] as Map)['hash'] = h;
    });
    manifestFile.writeAsStringSync(
        '${const JsonEncoder.withIndent('  ').convert(manifest)}\n');
  }

  return result;
}