forked from 1b-agent/opencadstudio-upstream
39 lines
1.7 KiB
Python
39 lines
1.7 KiB
Python
"""Check literal translation lookups. Fluent syntax and rendering are tested in i18n.rs."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
STRING = r'"(?:[^"\\]|\\.)*"'
|
|
lookup_text = (ROOT / 'src/locale_catalog.rs').read_text()
|
|
lookup = {}
|
|
for match in re.finditer(r'(' + STRING + r')\s*=>\s*Some\(\(\s*"([\w-]+)"\s*,\s*"([\w-]+)"\s*,?\s*\)\)', lookup_text):
|
|
source = json.loads(match[1])
|
|
assert source not in lookup, f'Duplicate source lookup: {source}'
|
|
lookup[source] = (match[2], match[3])
|
|
assert len(lookup) > 3000
|
|
|
|
keys = set()
|
|
group = None
|
|
for line in (ROOT / 'locales/en-US/opencadstudio.ftl').read_text().splitlines():
|
|
if match := re.match(r'^([A-Za-z][\w-]*)\s*=', line):
|
|
group = match[1]
|
|
elif match := re.match(r'^ \.([A-Za-z][\w-]*)\s*=', line):
|
|
keys.add((group, match[1]))
|
|
assert not set(lookup.values()) - keys, f'Missing Fluent targets: {set(lookup.values()) - keys}'
|
|
|
|
missing = []
|
|
for path in sorted((ROOT / 'src').rglob('*.rs')):
|
|
text = path.read_text()
|
|
for match in re.finditer(r'\b(?:t|tf)!\(\s*(' + STRING + ')', text, re.S):
|
|
# Rust permits escaped line continuations and literal newlines.
|
|
literal = re.sub(r'\\\n\s*', '', match[1])
|
|
literal = re.sub(r'\\u\{([0-9a-fA-F_]+)\}', lambda m: json.dumps(chr(int(m[1].replace('_', ''), 16)))[1:-1], literal)
|
|
source = json.loads(literal, strict=False)
|
|
if source not in lookup and re.search(r'[A-Za-z]{2}', source):
|
|
line = text[:match.start()].count('\n') + 1
|
|
missing.append(f'{path.relative_to(ROOT)}:{line}: {source!r}')
|
|
assert not missing, '\n'.join(missing[:30])
|
|
print(f'{len(lookup)} source lookups and literal translation calls passed')
|