forked from Teskann/QuaX
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathl10n.py
More file actions
executable file
·134 lines (103 loc) · 3.78 KB
/
Copy pathl10n.py
File metadata and controls
executable file
·134 lines (103 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
"""Manage ARB localization files: sort, fix metadata, report missing and unused keys."""
import argparse
import json
import subprocess
import sys
from pathlib import Path
L10N_DIR = Path("lib/l10n")
DART_DIR = Path("lib")
GENERATED_DIR = Path("lib/generated")
REFERENCE = "intl_en.arb"
def run(cmd):
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Error running {' '.join(cmd)}:\n{result.stderr}", file=sys.stderr)
sys.exit(1)
return result
def get_arb_files():
return sorted(L10N_DIR.glob("intl_*.arb"))
def sort_and_fix(files):
for f in files:
print(f" {f.name}")
run(["fvm", "dart", "run", "arb_utils", "sort", str(f)])
run(["fvm", "dart", "run", "arb_utils", "generate-meta", str(f)])
def content_keys(arb_path):
data = json.loads(arb_path.read_text(encoding="utf-8"))
return {k for k in data if not k.startswith("@")}
def find_unused_keys(ref_file):
ref_keys = content_keys(ref_file)
dart_files = [
f for f in DART_DIR.rglob("*.dart")
if not f.is_relative_to(GENERATED_DIR)
]
dart_source = "\n".join(f.read_text(encoding="utf-8") for f in dart_files)
return [k for k in sorted(ref_keys) if f".{k}" not in dart_source]
def report_missing(files):
ref = L10N_DIR / REFERENCE
ref_keys = content_keys(ref)
any_missing = False
for f in files:
if f.name == REFERENCE:
continue
missing = sorted(ref_keys - content_keys(f))
if missing:
any_missing = True
print(f"\n {f.name}: {len(missing)} missing")
for k in missing:
print(f" - {k}")
if not any_missing:
print(" All locales are complete!")
def report_unused(ref_file):
unused = find_unused_keys(ref_file)
if unused:
print(f" {len(unused)} unused keys:")
for k in unused:
print(f" - {k}")
else:
print(" No unused keys found!")
def clean_en(ref_file):
unused = find_unused_keys(ref_file)
if not unused:
print(" Nothing to remove.")
return
data = json.loads(ref_file.read_text(encoding="utf-8"))
for k in unused:
data.pop(k, None)
data.pop(f"@{k}", None)
ref_file.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
print(f" Removed {len(unused)} keys from {ref_file.name}.")
def clean_locales(files, ref_file):
ref_keys = content_keys(ref_file)
for f in files:
if f.name == REFERENCE:
continue
data = json.loads(f.read_text(encoding="utf-8"))
extra = [k for k in data if not k.startswith("@") and k not in ref_keys]
if not extra:
continue
for k in extra:
data.pop(k, None)
data.pop(f"@{k}", None)
f.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
print(f" {f.name}: removed {len(extra)} keys.")
def main():
parser = argparse.ArgumentParser(description="Manage ARB localization files.")
parser.add_argument("--clean", action="store_true", help="Remove unused keys from the reference locale and extra keys from other locales.")
args = parser.parse_args()
files = get_arb_files()
ref = L10N_DIR / REFERENCE
if args.clean:
print("==> Cleaning unused keys from reference...")
clean_en(ref)
print("\n==> Removing extra keys from other locales...")
clean_locales(files, ref)
print()
print("==> Sorting and fixing metadata...")
sort_and_fix(files)
print("\n==> Missing keys report...")
report_missing(files)
print("\n==> Unused keys (not referenced in lib/**/*.dart)...")
report_unused(ref)
if __name__ == "__main__":
main()