Skip to content

Commit 38bc45b

Browse files
committed
fix(translations): make --update-floors ratchet up only, and restore the zh floor
write_floors recorded whatever coverage the run measured, although the flag's help says "ratchet up only" and the floors file says never to lower one. So running --update-floors after adding English strings nobody had translated lowered the floor it was meant to protect: zh-rCN went 76.1 -> 76.0 -> 75.6 over earlier commits today, each time as a side effect. It now keeps the higher of the recorded floor and the measured coverage, and keeps floors for locales the run didn't measure (a --locale run used to drop the rest). The eight strings behind the slide (the certificate-trust notice and the Protection Test feed-trust and hot-feed states) are translated, which puts zh-rCN at 1096/1432 (76.5%), and the floor is recorded there. test_check_translations.py gains a test that a lower measurement leaves the floor alone and a higher one raises it; it fails against the old write_floors.
1 parent 22a294a commit 38bc45b

5 files changed

Lines changed: 41 additions & 3 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ The rest of this section takes effect when the report Worker is next deployed.
189189
`scripts/translation_floors.json` and dropping below it fails the build;
190190
zh-rCN starts at 76.1%. A locale with no recorded floor warns instead, so
191191
adding a translation does not break the build before anyone sets one.
192+
- `check_translations.py --update-floors` now only ever raises a floor. Run
193+
after adding English strings that had no translation yet, it wrote down the
194+
lower coverage instead, and the Chinese floor slid from 76.1% to 75.6% that
195+
way. The eight strings behind the slide are translated now, and the floor is
196+
back up at 76.5%.
192197

193198
## v1.7.38 (2026-08-29)
194199

‎app/src/main/res/values-zh-rCN/strings.xml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,9 @@
679679
<string name="protection_test_fix_database">从主页或“更多”页运行号码库同步,以获取本地防护数据。</string>
680680
<string name="protection_test_fix_engine">在设置中检查检测引擎开关并重新运行本项检查。</string>
681681
<string name="protection_test_fix_sync">等待下次刷新,若仍为空则手动同步。</string>
682+
<string name="protection_test_fix_update_app">请安装最新版 CallShield。同步无法解决这个问题。</string>
683+
<string name="protection_test_feed_trust">防护数据服务器</string>
684+
<string name="protection_test_feed_trust_fail">此版本无法验证服务器证书,因此收不到新的防护数据</string>
682685
<string name="protection_test_fix_overlay">若希望在来电时显示浮动来电识别提醒,请允许悬浮窗权限。</string>
683686
<string name="protection_test_fix_notifications">若希望接收提醒与 RCS 过滤,请启用通知或监听器权限。</string>
684687
<string name="protection_test_db_empty">尚未加载垃圾数据</string>
@@ -699,6 +702,8 @@
699702
<string name="protection_test_ml_fp_fail">误判 — 阈值可能过低</string>
700703
<string name="protection_test_hot_pass">热点营销号段已加载</string>
701704
<string name="protection_test_hot_fail">为空 — 将在下次 30 分钟同步时填充</string>
705+
<string name="protection_test_hot_stalled">可以连接,但热点数据源已有 %1$d 天没有重新生成</string>
706+
<string name="protection_test_hot_cleared">可以连接。发布方表示目前没有热点条目</string>
702707
<string name="protection_test_overlay_pass">可显示来电识别悬浮窗</string>
703708
<string name="protection_test_overlay_fail">未授予 — 悬浮窗不会显示</string>
704709
<string name="protection_test_notif_pass">RCS 过滤器可监控消息</string>
@@ -960,6 +965,9 @@
960965
<string name="notif_role_lost_title">来电筛查已关闭</string>
961966
<string name="notif_role_lost_text">Android 不再将来电发送至 CallShield。恢复来电筛查以继续防护。</string>
962967
<string name="notif_role_lost_action">恢复防护</string>
968+
<string name="notif_feed_trust_title">CallShield 无法下载新的防护数据</string>
969+
<string name="notif_feed_trust_text">此版本无法验证数据服务器的证书。请安装最新版本以重新接收更新。</string>
970+
<string name="notif_feed_trust_action">获取最新版本</string>
963971
<string name="notif_sync_title">正在刷新防护</string>
964972
<string name="notif_sync_text">正在更新垃圾号码与检测数据…</string>
965973
<string name="notif_repeated_urgent_title">重复来电已放行</string>

‎scripts/check_translations.py‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,23 @@ def floor_report(
340340

341341

342342
def write_floors(coverage: dict[str, float]) -> None:
343-
"""Record the current coverage as the new floor."""
343+
"""Raise each measured locale's floor to its current coverage.
344+
345+
A floor only goes up here. Running --update-floors after adding English
346+
strings nobody has translated yet used to record the lower coverage, which
347+
quietly loosened the gate it exists to enforce. Floors for locales this
348+
run didn't measure are kept.
349+
"""
350+
floors = load_floors()
351+
for locale, percent in coverage.items():
352+
floors[locale] = max(floors.get(locale, 0.0), round(percent, 1))
344353
payload = {
345354
"description": (
346355
"Minimum translated-string coverage per locale, in percent. check_translations.py "
347356
"fails when a shipped locale drops below its floor. Raise a floor with --update-floors; "
348357
"never lower one by hand."
349358
),
350-
"floors": {locale: round(percent, 1) for locale, percent in sorted(coverage.items())},
359+
"floors": dict(sorted(floors.items())),
351360
}
352361
with FLOORS_FILE.open("w", encoding="utf-8", newline="\n") as handle:
353362
json.dump(payload, handle, indent=2)

‎scripts/test_check_translations.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,22 @@ def test_floors_round_trip_and_a_broken_file_is_not_fatal(self):
105105
finally:
106106
check_translations.FLOORS_FILE = original
107107

108+
def test_update_floors_only_ever_raises_a_floor(self):
109+
# Recording coverage after adding untranslated strings lowered the
110+
# zh-rCN floor from 76.1 to 75.6 in one step before this was fixed.
111+
with tempfile.TemporaryDirectory() as directory:
112+
path = Path(directory) / "translation_floors.json"
113+
original = check_translations.FLOORS_FILE
114+
check_translations.FLOORS_FILE = path
115+
try:
116+
check_translations.write_floors({"values-zh-rCN": 76.1, "values-de": 40.0})
117+
check_translations.write_floors({"values-zh-rCN": 75.6})
118+
self.assertEqual({"values-de": 40.0, "values-zh-rCN": 76.1}, check_translations.load_floors())
119+
check_translations.write_floors({"values-zh-rCN": 76.54})
120+
self.assertEqual({"values-de": 40.0, "values-zh-rCN": 76.5}, check_translations.load_floors())
121+
finally:
122+
check_translations.FLOORS_FILE = original
123+
108124
def test_recorded_floor_matches_the_shipped_locale(self):
109125
# The committed floor must describe reality, or the gate is decorative.
110126
floors = check_translations.load_floors()

‎scripts/translation_floors.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"description": "Minimum translated-string coverage per locale, in percent. check_translations.py fails when a shipped locale drops below its floor. Raise a floor with --update-floors; never lower one by hand.",
33
"floors": {
4-
"values-zh-rCN": 75.8
4+
"values-zh-rCN": 76.5
55
}
66
}

0 commit comments

Comments
 (0)