Files
pangolin/ci/check-codegen-drift.sh
T
wangjia 75d23023e3 feat(i18n): ③ 原型接单源 — I18N 块由 strings.json 生成,消除重复翻译
原型 design/prototype/screens/{ui-desktop,ui-mobile}.html 的 I18N 数据块不再手写,
改由 strings.json 生成(marker 包裹、生成器唯一写):
- alias.json:protoKey → flutterKey(产品串取单源 zh/en,单源赢);desktop 130 / mobile 143。
- overlay.json:原型专属(开发挡板 + app 没有的串,zh/en);desktop 98 / mobile 104。
- new-strings.json:4 个新产品串(分流规则/自定义/局域网直连/强制),6 语,已并入
  strings.json + app_text.dart 抽象声明 + 重生成 6 份 strings_*.dart。
- gen_proto_i18n.mjs:strings.json+alias+overlay → 两份 HTML 的 I18N 块;--check 只比对
  marker 块(unrelated HTML 编辑不误报)。
- check-proto-i18n.mjs:两份 HTML 所有 data-i18n key 的 zh/en 必须 resolve。
- ci/check-codegen-drift.sh:加原型 i18n 段(--check 漂移 + resolution 验收)。

同带入之前路由原型 WIP 的 i18n 收口:私有服务内置行→局域网/私网直连行、rr.* 接 data-i18n
(rr.lan→routingLanDirect 等)。路由页其余 UI(段选/添加规则页)仍为独立后续。

验收(自复核全绿):生成器跑通、data-i18n 0 unresolved、两生成器重生成零 diff、
flutter analyze lib/l10n 0 issue、flutter test 244 全绿、new-strings 无红线词。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
2026-07-27 09:59:18 +08:00

61 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# check-codegen-drift.sh — codegen 漂移检查(支柱 2:契约单源 / token 单源)。
#
# design/prototype/tokens.css 是唯一 token 真相源,client/lib/pangolin_tokens.gen.dart
# 由 design/codegen/gen_flutter_tokens.mjs 生成、勿手改(CLAUDE.md 铁律)。本检查重新
# 生成一遍,若生成物与已提交版本不一致 → 漂移:要么改了 CSS 没重生成,要么手改了
# 生成物。两者都会让"单源"失效、契约悄悄分叉。
#
# 依赖: node(零依赖纯脚本) + git。CI 在 node:20 镜像内跑(含 git/bash)。
# 发现漂移 → 非零退出码(CI fail)。
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
# docker 内挂载目录 owner 与进程 uid 不一致时 git 会拒绝;本地是 owner 时此行无副作用。
git config --global --add safe.directory "$REPO_ROOT" 2>/dev/null || true
GEN="client/lib/pangolin_tokens.gen.dart"
echo "→ 重新生成 Flutter token (design/codegen/gen_flutter_tokens.mjs) ..."
node design/codegen/gen_flutter_tokens.mjs
if ! git diff --quiet -- "$GEN"; then
echo "❌ codegen 漂移:$GEN 与 design/prototype/tokens.css 不一致。" >&2
echo " 原因:改了 CSS 真相源却没重生成,或手改了生成物(铁律:勿手改 *.gen.dart)。" >&2
echo " 修复:node design/codegen/gen_flutter_tokens.mjs 后提交生成物。" >&2
echo " ── diff(前 40 行)──" >&2
git --no-pager diff -- "$GEN" | head -40 >&2
exit 1
fi
echo "✅ codegen 无漂移:token 生成物与 CSS 真相源一致。"
# ── l10n 单源:design/i18n/strings.json → client/lib/l10n/strings_*.dart ──
# gen 为纯 node 确定性输出(不跑 dart format),故本段与 token 段一样零 dart 依赖。
L10N_GEN="client/lib/l10n"
echo "→ 重新生成 l10n (design/codegen/gen_l10n_dart.mjs) ..."
node design/codegen/gen_l10n_dart.mjs
if ! git diff --quiet -- "$L10N_GEN"/strings_*.dart; then
echo "❌ l10n 漂移:strings_*.dart 与 design/i18n/strings.json 不一致。" >&2
echo " 原因:改了 strings.json 却没重生成,或手改了生成物(勿手改 strings_*.dart)。" >&2
echo " 修复:node design/codegen/gen_l10n_dart.mjs 后提交生成物。" >&2
echo " ── diff(前 40 行)──" >&2
git --no-pager diff -- "$L10N_GEN"/strings_*.dart | head -40 >&2
exit 1
fi
echo "✅ l10n 无漂移:strings_*.dart 与 strings.json 单源一致。"
# ── 原型 i18n 单源:strings.json + alias + overlay → 两份 HTML 的 I18N 块 ──
# --check 只比对 marker 块(unrelated HTML 编辑不误报);再跑 key resolution 验收。
echo "→ 校验原型 I18N 块 (design/codegen/gen_proto_i18n.mjs --check) ..."
if ! node design/codegen/gen_proto_i18n.mjs --check; then
echo "❌ 原型 I18N 漂移:改了 strings.json/alias/overlay 却没重生成原型块。" >&2
echo " 修复:node design/codegen/gen_proto_i18n.mjs 后提交。" >&2
exit 1
fi
echo "→ 校验原型 data-i18n key 全 resolve (check-proto-i18n.mjs) ..."
node design/prototype/tools/check-proto-i18n.mjs
echo "✅ 原型 i18n 无漂移:I18N 块与单源一致、data-i18n 全 resolve。"