v0.27.3
This commit is contained in:
1 parent
e84df445c6
commit
e87a382a7e
109 files changed
+1092
-2925
No files matched your search
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate language-pack content and emit the same-shaped bundle used by UI QA.
|
||||
Rust build.rs performs the actual compile-time discovery and embedding.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
def bundle(root=ROOT):
|
||||
languages=[];locales=set()
|
||||
for path in sorted((root/'langs').glob('*.json')):
|
||||
assert re.fullmatch(r'[A-Za-z0-9_-]{1,64}',path.stem),path
|
||||
assert path.stat().st_size<=262144,path
|
||||
pack=json.loads(path.read_text(encoding='utf-8'));assert set(pack)=={'meta','translations'},f'unexpected top-level language-pack keys: {set(pack)-{"meta","translations"}} in {path}';meta=pack['meta'];translations=pack['translations']
|
||||
assert all(isinstance(meta.get(key),str) and 0<len(meta[key].encode())<=128 for key in ['locale','name','native_name','direction']),path
|
||||
assert meta['direction'] in ('ltr','rtl'),path
|
||||
assert re.fullmatch(r'[A-Za-z0-9]{1,8}(?:-[A-Za-z0-9]{1,8})*',meta['locale']),path
|
||||
assert meta['locale'].lower() not in locales, 'duplicate locale'
|
||||
locales.add(meta['locale'].lower())
|
||||
assert isinstance(translations,dict) and len(translations)<=4096,path
|
||||
assert all(isinstance(v,str) and 0<len(k.encode())<=128 and len(v.encode())<=16384 for k,v in translations.items()),path
|
||||
languages.append({'id':path.stem,**pack})
|
||||
assert 1<=len(languages)<=128
|
||||
fallback=next(pack for pack in languages if pack['id']=='en_US')['translations']
|
||||
html=(root/'src/admin/web/index.html').read_text()
|
||||
keys=set(re.findall(r'data-i18n(?:-placeholder|-aria)?="([^"]+)"',html))
|
||||
js='\n'.join(p.read_text() for p in (root/'src/admin/web').glob('**/*.js'))
|
||||
keys.update(re.findall(r'\bt\("([^"\n]+)"\)',js))
|
||||
keys.update(re.findall(r'"(vh[A-Z][A-Za-z]+)"',js))
|
||||
assert keys<=fallback.keys(),f'Missing fallback keys: {keys-fallback.keys()}'
|
||||
for language in languages:
|
||||
translations=language['translations']
|
||||
assert keys<=translations.keys(),f"Missing UI keys in {language['id']}: {keys-translations.keys()}"
|
||||
result={'default':'en_US','languages':languages}
|
||||
assert len(json.dumps(result,ensure_ascii=False).encode())<=8388608
|
||||
return result
|
||||
if __name__=='__main__':
|
||||
parser=argparse.ArgumentParser();parser.add_argument('--output',type=Path);args=parser.parse_args()
|
||||
data=bundle()
|
||||
if args.output:args.output.write_text(json.dumps(data,ensure_ascii=False)+'\n')
|
||||
print(f"PASS: {len(data['languages'])} language packs, metadata, fallback UI keys and bounds.")
|
||||
Reference in new issue
Block a user