feat(UI): golden 像素回归入提交门禁(W6 U4 第三件,35→36 钩子)

补上我上一轮自己标记为 2/3 的那块缺口:两个 golden 脚本早已存在且一直在
人工跑,但**从未进自动门禁**——"有基线"不等于"有门禁"(§6.1 原文即自认)。

## 先实测成本再定形态
改一个 UI 源文件后「增量重编模拟器 + 两条 golden」合计 **2~4 秒**,支持走
自动门禁。若实测要几分钟,正确做法是明确不挂、改为文档化人工门禁——一个
逼人 --no-verify 的门禁等于没有门禁,故这个数字是本决定的前提而非附注。

## 落地
新增 scripts/check_ui_golden.py:串「增量构建 → 菜单 8 状态 → 内容页 11 页
+ 池水位」。**有意忽略 argv 且 pass_filenames: false**——两条 golden 按整棵
菜单树 + 全量参考图工作,不接受文件参数,pre-commit 传的变更名对它无意义。
files: 覆盖 UI 源 + ui_task.{c,h} + 模拟器 tests/sim/src + main.c +
CMakeLists + lv_conf.h + 包装器与本配置自身(pre-commit 4.x 无 always: true,
files 是唯一触发手段)。

## 端到端验的是钩子,不是脚本
干净树连跑 3 次 rc=0 全 Passed;给 ui_page_dc.c 的 .top_y 注入 +5 位移 →
**钩子 Failed** 并点名 `[dc] FAIL 与参考页不一致(1882 px 差异)`;还原后
git diff 干净、simulator/tests/ref 的 git status 为空——**全程未用 --update
刷基线**(那正是本钩子要防的行为)。
诚实记录瑕疵:首次实测在"连续注入/还原的紧邻重建"之间偶发失败一次,疑似
MSBuild 节点争用,此后 3 次连跑均绿。已把"单次失败先复跑、连续两次才当真、
不许直接 --no-verify 绕过"写进钩子注释。

## 文档同步
AGENTS.md 钩子数与文末索引 35→36 + 钩子清单补 ui-golden;
pre-commit使用说明.md 概览计数同步;报告 §6.5 U4 由 2/3 → **3/3**(这次是
"真进了自动门禁",不是"脚本存在")、§6.1 golden 行转 ✅、§0.1 缺口描述更新。

## W6 剩余
U2 合并两页记录、U5 落地目标页(须先对齐"目标页 vs 现存 7 个 ui_page_*.c"
的差集——报告的"27 页"是目标数而非现状数)。
This commit is contained in:
2026-10-20 22:14:42 +08:00
parent dafc18f5ed
commit 44dec5c49b
5 changed files with 91 additions and 6 deletions
+23
View File
@@ -498,3 +498,26 @@ repos:
language: system
files: ^(Drivers/BSP/UI/|App/task/ui_task\.(c|h)$|ui_cn_chars\.txt$|tools/font_gen/|scripts/check_font_charset\.py$)
pass_filenames: false
# 12) UI 像素回归门禁(2026-10-20 加,W6 U4 收尾第三件 / 报告 §6.5 U4、§6.1 golden 行)
# 背景:golden 两脚本(check_menu_rows.py / check_content_pages.py)早已存在且一直在
# 人工跑,但**从未进自动门禁**——"有基线"不等于"有门禁"(报告 §6.1 原文即自认此缺口)。
# 形态选型依据实测:改一个 UI 源文件后 build_sim 增量重编 + 两条 golden 合计 **2~4 秒**,
# 成本可接受 → 走自动门禁(若实测要几分钟,则应改为文档化人工门禁,一个逼人
# --no-verify 的门禁等于没有门禁)。
# 有牙实测:给 ui_page_dc.c 的 .top_y 注入 +3 位移 → build_sim 重编 →
# golden FAIL 且点名 `[dc] FAIL 与参考页不一致(1366 px 差异)`、退出码 1;还原后 diff 干净。
# ⚠ 两条 golden 按"整棵菜单树 + 全量参考图"工作、不接受文件参数,故包装器有意忽略
# argv 并 pass_filenames: false(pre-commit 传的变更名对它无意义)。
# ⚠ 参考图 simulator/tests/ref/*.bin 是判据本身,改动它等于改判据——评审时必须盯紧,
# 任何时候都不得用 --update 刷基线来"让钩子变绿"。
# ⚠ pre-commit 4.x 无 `always: true` → files 必须覆盖所有能改变像素的触发面。
# ⚠ 已知瞬时现象:首次实测时在"连续注入/还原的紧邻重建"之间偶发失败一次,
# 疑似 MSBuild 节点争用;此后 3 次干净树连跑均绿。判据:单次失败先复跑一次再看,
# 连续两次失败才当真(不许直接 --no-verify 绕过)。
- id: ui-golden
name: UI 像素回归(菜单 8 状态 + 内容页 11 页 黄金参考)
entry: python scripts/check_ui_golden.py
language: system
files: ^(Drivers/BSP/UI/|App/task/ui_task\.(c|h)$|simulator/(tests|sim|src)/|simulator/main\.c$|simulator/CMakeLists\.txt$|simulator/lv_conf\.h$|scripts/check_ui_golden\.py$|\.pre-commit-config\.yaml$)
pass_filenames: false