From 57500e8f0dd7f238f1b06932d9ebac88a370848f Mon Sep 17 00:00:00 2001 From: JGZYES Date: Sat, 5 Sep 2026 20:36:51 +0800 Subject: [PATCH] fix(i18n): fall back to built-in zh table when a pack misses a key A stale .pjson (e.g. downloaded before new keys existed) showed raw 'msg.xxx' because pmm_tr looked only in the loaded pack. Now a missing key falls back to the built-in zh-CN table, so any pack stays readable. Also sync the mirror language packs (zh-CN/en-US) with the new keys (desc.clean, msg.dep-satisfied, msg.err.conflict, msg.cache-cleared, msg.self-up-to-date); users just re-run 'pmm setting lang ' to pick it up. --- src/i18n.c | 16 +++++++++++++--- web/mirror/lang/en-US.pjson | 7 ++++++- web/mirror/lang/zh-CN.pjson | 7 ++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/i18n.c b/src/i18n.c index 5a5da6f..91c3e92 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -8,6 +8,7 @@ #include static JsonValue *g_lang = NULL; +static JsonValue *g_builtin = NULL; static char g_locale[64] = ""; /* Detect locale from LANG / LC_ALL env, else default "zh-CN". */ @@ -80,9 +81,18 @@ int pmm_lang_load_active(void) { } const char *pmm_tr(const char *key) { - if (!g_lang) return key; - const char *t = json_str(g_lang, key); - return t ? t : key; + /* Look up in the loaded pack first, then fall back to the built-in zh-CN + * table so a stale .pjson never shows a raw "msg.xxx" key. */ + if (g_lang) { + const char *t = json_str(g_lang, key); + if (t) return t; + } + if (!g_builtin) g_builtin = json_parse(kBuiltinZh); + if (g_builtin) { + const char *b = json_str(g_builtin, key); + if (b) return b; + } + return key; } const char *pmm_tr_fmt(const char *key, ...) { diff --git a/web/mirror/lang/en-US.pjson b/web/mirror/lang/en-US.pjson index 1944ca4..68ab6b4 100644 --- a/web/mirror/lang/en-US.pjson +++ b/web/mirror/lang/en-US.pjson @@ -123,5 +123,10 @@ "mirror.sources": "mirrors:", "mirror.checking": "checking registry mirrors...", "mirror.result": "result: %d/%d sources reachable", - "lang.packs-in": "language packs in %s:" + "lang.packs-in": "language packs in %s:", + "desc.clean": "clean cache", + "msg.dep-satisfied": "dependency %s%s%s already installed/provided, skipped", + "msg.err.conflict": "cannot install %s: conflicts with installed %s", + "msg.cache-cleared": "cache cleaned: %d files, freed %.1f KB", + "msg.self-up-to-date": "already up to date (v%s, latest v%s), skipping upgrade" } diff --git a/web/mirror/lang/zh-CN.pjson b/web/mirror/lang/zh-CN.pjson index 3282e57..13fe0fc 100644 --- a/web/mirror/lang/zh-CN.pjson +++ b/web/mirror/lang/zh-CN.pjson @@ -123,5 +123,10 @@ "mirror.sources": "镜像源:", "mirror.checking": "正在检查注册表镜像源...", "mirror.result": "结果: %d/%d 个镜像源可达", - "lang.packs-in": "%s 中的语言包:" + "lang.packs-in": "%s 中的语言包:", + "desc.clean": "清理缓存", + "msg.dep-satisfied": "依赖 %s%s%s 已装/被提供,跳过", + "msg.err.conflict": "无法安装 %s:与已装的 %s 冲突", + "msg.cache-cleared": "已清理缓存: %d 个文件,释放 %.1f KB", + "msg.self-up-to-date": "当前 v%s 已是最新(v%s),跳过升级" }