diff --git a/merge_i18n.py b/merge_i18n.py index d11841f4..a98af109 100644 --- a/merge_i18n.py +++ b/merge_i18n.py @@ -2,16 +2,16 @@ """ 合并所有Sage模块的i18n内容到 wwwroot/i18n -从 load_path.py 中提取sage引用的所有模块, +模块清单与 build.sh 保持一致(第29行 for m in ...), 读取每个模块的 i18n/{lang}/msg.txt, -合并输出到 wwwroot/i18n/{lang}/i18n.json。 +合并输出到 wwwroot/i18n/{lang}/i18n.json + msg.txt。 -冲突策略:后加载的模块覆盖先加载的,sage自身覆盖所有。 +冲突策略:按 build.sh 中模块顺序,后加载的覆盖先加载的。 + sage 自身排在首位(优先级最低)。 """ -import os -import re import json +import re import sys from pathlib import Path @@ -22,36 +22,27 @@ I18N_OUTPUT_DIR = SAGE_DIR / 'wwwroot' / 'i18n' # 输出目标 LANGS = ['zh', 'en', 'jp', 'ko'] # 支持的语言 -def parse_load_path(load_path_file): - """从 load_path.py 中提取模块名列表 +def parse_build_sh(build_sh_path): + """从 build.sh 中提取模块清单(第29行 for m in ...) - load_path.py 中每行格式: /module_name/rest/of/path ... - 只提取行首的第一个路径段作为模块名。 + build.sh 有两个 for m in 循环: + - 第21行: pip基础库(apppublic, sqlor, ahserver, ...) + - 第29行: Sage业务模块(appbase, rbac, accounting, ...) + 我们取第二个(业务模块),与 sage 的 wwwroot 符号链接配置一致。 """ - modules = set() - # 已知的非模块路径前缀(系统路径、资源目录等) - skip_prefixes = { - 'conf', 'logs', 'files', 'script', 'skills', 'plugins', - 'py3', 'bin', 'initln', 'docs', 'agents', 'hermes_work', - 'bricks', 'imgs', 'i18n', 'public', 'api', 'shell', - } + with open(build_sh_path, 'r', encoding='utf-8') as f: + content = f.read() - with open(load_path_file, 'r', encoding='utf-8') as f: - for line in f: - line = line.strip() - if not line or line.startswith('#'): - continue - # 匹配行首的 /module_name/ - m = re.match(r'^/\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*/', line) - if not m: - continue - mod = m.group(1) - if mod not in skip_prefixes: - modules.add(mod) + # 匹配所有 "for m in ..." 行 —— 只到行尾(不用 \s 防止跨行匹配到 do) + matches = re.findall(r'^for m in ((?:[a-z][\w-]*[ \t]*)+)$', content, re.MULTILINE) + if len(matches) < 2: + sys.exit(f"错误: 在 build.sh 中找到 {len(matches)} 个 for m in 行,期望至少2个") - # sage 自身始终排在前面(优先级最低,因为 load_path 中 sage 是根路径) - modules.discard('sage') - result = ['sage'] + sorted(modules) + # 第二个 for m in 是 Sage 业务模块清单 + modules_str = matches[1] + modules = [m for m in modules_str.strip().split() if '-' not in m] + # sage 自身始终排在首位(优先级最低) + result = ['sage'] + modules return result @@ -141,13 +132,13 @@ def write_output(merged): def main(): - load_path_file = SAGE_DIR / 'load_path.py' - if not load_path_file.is_file(): - print(f"错误: 找不到 {load_path_file}") + build_sh_path = SAGE_DIR / 'build.sh' + if not build_sh_path.is_file(): + print(f"错误: 找不到 {build_sh_path}") sys.exit(1) - print(f"解析 load_path.py: {load_path_file}") - modules = parse_load_path(load_path_file) + print(f"解析 build.sh: {build_sh_path}") + modules = parse_build_sh(build_sh_path) print(f"发现 {len(modules)} 个模块:") for m in modules: has_i18n = (REPOS_DIR / m / 'i18n').is_dir()