9ab550d398
i18n 单源第一步(用户要求:原型与实际程序必须一份数据)。 - 246 getter + 5 带参方法 × 6 语(zh/en/ja/ko/ru/es),抽取校验 0 缺失 - 抓到真漂移:strings_en.dart 原缺 quotaExhaustedNotice/openAlipayFailed 两个 key(双引号+EN漏维护),单源后六语强制对齐 - migrate_l10n_to_json.py 一次性迁移脚本(单/双引号 + getter/带参方法) 下一步:codegen(JSON→app_text.dart+strings_*.dart,替换手写)+ 原型读同源 + CI 漂移闸。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
56 lines
2.3 KiB
Python
56 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
# 从 6 份手写 strings_*.dart 抽取 l10n 到单源 JSON。只读,不改 Dart。
|
|
import re, json, sys, os
|
|
|
|
BASE = "/Users/wangjia/code/pangolin/.claude/worktrees/configurable-proxy/client/lib/l10n"
|
|
LANGS = ["zh", "en", "ja", "ko", "ru", "es"]
|
|
|
|
# Dart 字符串字面量:单引号或双引号(各自允许 \ 转义);getter 与带参方法
|
|
STR = r"""(?:'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")"""
|
|
GET_RE = re.compile(r"String\s+get\s+(\w+)\s*=>\s*" + STR + r"\s*;")
|
|
MET_RE = re.compile(r"String\s+(\w+)\(([^)]*)\)\s*=>\s*" + STR + r"\s*;")
|
|
|
|
def unescape(s):
|
|
return s.replace("\\'", "'").replace('\\"', '"').replace('\\\\', '\\').replace('\\n', '\n').replace('\\$', '$')
|
|
|
|
getters = {} # key -> {lang: val}
|
|
methods = {} # key -> {args, tpl:{lang:val}}
|
|
counts = {}
|
|
|
|
for lang in LANGS:
|
|
path = os.path.join(BASE, f"strings_{lang}.dart")
|
|
src = open(path, encoding="utf-8").read()
|
|
g = 0
|
|
for m in GET_RE.finditer(src):
|
|
k = m.group(1); v = unescape(m.group(2) if m.group(2) is not None else m.group(3))
|
|
getters.setdefault(k, {})[lang] = v
|
|
g += 1
|
|
mm = 0
|
|
for m in MET_RE.finditer(src):
|
|
k = m.group(1); args = m.group(2).strip()
|
|
v = unescape(m.group(3) if m.group(3) is not None else m.group(4))
|
|
methods.setdefault(k, {"args": args, "tpl": {}})
|
|
methods[k]["tpl"][lang] = v
|
|
mm += 1
|
|
counts[lang] = {"getters": g, "methods": mm}
|
|
|
|
# 完整性校验:每个 key 六语齐全
|
|
missing = []
|
|
for k, d in getters.items():
|
|
for l in LANGS:
|
|
if l not in d: missing.append(f"getter {k}:{l}")
|
|
for k, d in methods.items():
|
|
for l in LANGS:
|
|
if l not in d["tpl"]: missing.append(f"method {k}:{l}")
|
|
|
|
out = {"_note": "l10n 单源(唯一真相源)。codegen 生成 client/lib/l10n/strings_*.dart + app_text.dart + 原型读同源。勿手改生成物。",
|
|
"getters": getters, "methods": methods}
|
|
os.makedirs("/Users/wangjia/code/pangolin/.claude/worktrees/configurable-proxy/design/i18n", exist_ok=True)
|
|
outpath = "/Users/wangjia/code/pangolin/.claude/worktrees/configurable-proxy/design/i18n/strings.json"
|
|
json.dump(out, open(outpath, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
|
|
|
|
print("每语言抽取数:", counts)
|
|
print(f"合并后:getters={len(getters)} methods={len(methods)}")
|
|
print(f"缺失(应为0):{len(missing)}", missing[:5])
|
|
print("输出:", outpath)
|