842d711ed6
用户裁定「我不想看到编号」。测试验证层级这一族的整族清退分三道并行:本笔是**代码与 CI 道** (CI 步骤与门禁输出面),代码注释面另走、文档面由文档道走。 口径(旧 → 语义名 → ASCII 段名,段名只进日志/旗标/job id/文件名): L0 静态门禁 static | L0a 钩子解释器预检 preflight | L0b 提交信息门禁 commitmsg L0c 体积门禁 size | L0.5 主机侧纯逻辑单测 host-unit | L0.5c 覆盖率 coverage - scripts/ci_local.py 43 站点:段标题与 [SUMMARY] 标签改 ASCII 段名(static: / host-unit:),函数 run_l0/run_l05 → run_static_gates/run_host_unit_tests, 收尾「已跑:」列表用段名。旗标改 --static-only / --host-unit-only,**旧旗标 --l0-only / --l05-only 保留为 argparse 别名**(肌肉记忆与既有脚本片段不断档, 实测 --help 两名列出)。 - .gitea/workflows/ci.yml 42 站点:job id l0-gates → static-gates、 l05-host-unit-tests → host-unit-tests;步骤名与 step-summary 标题改语义名; 日志名 l0-pre-commit.log → static-pre-commit.log、l05-<模块>.log → host-unit-<模块>.log;::error::/::notice:: 文案同步。yaml.safe_load 核过 两个 job id 与步骤名。 host-unit-tests;步骤名与 step-summary 标题改语义名;日志名 l0-pre-commit.log → static-pre-commit.log、l05-<模块>.log → host-unit-<模块>.log;::error::/::notice:: 文案同步。yaml.safe_load 核过两个 job id 与步骤名。 - 门禁脚本 18 站点:check_registration(登记簿理由串 7)、check_test_coverage 5、 README 8、check_generated_fresh 2、ram_baseline 2、check_size_gate 1、 ci_find_python.ps1 2、ci_runner_bootstrap.ps1 2、.pre-commit-config.yaml 2、 requirements.txt 1(保持纯 ASCII)。 - skills 7 站点:task-worktree(含 [SUMMARY] 样例两行)、mem-budget、ui-verify、 task_worktree.py 的实跑标签。 - AGENTS.md 3 站点:CI 段「只跑静态门禁 + 主机侧纯逻辑单测」、自查命令段、 「2026-10-11 静态门禁全灭」事件名。 - 归档:编号治理历史.md 新增 §10 换算表 + **撞族警示**(同形 L0/L1/L2/L3 还属 UI 设计 令牌层 / UI 菜单层级 / 采集链 / 链路时延段 / CubeMX 三层 / 硬件位号与 FTP 应答字面量 等六个族,其中 6 处在字符串字面量里,改了就是改行为——故全程只按行内置换、先判族)。 - docs/产品需求 §7.4 测试分层表:去号 + 顺带修掉上一批**错族替换疤**(该表 L1/L2 行曾被 采集链层名「语义取数与有效性 / 全周傅氏相量」「保护判据」顶替,现按内容改写为板端测试 套件 / 主机侧回归两行)。同文档 §1.5 G5 判据行同步。 门禁:ci_local --help 两面旗标并列;py_compile 7 个 .py 全过;yaml 解析通过; check_ids_new --worktree rc=0;git diff --check 干净;17 个改动文件 FFFD=0、无 CR、 BOM 与原文件一致(含 requirements.txt 纯 ASCII)。本族无机器识别面(单字母+数字是 新增行门禁的自述盲区),口径来自自建逐行扫描器,复扫本族形态归零。 - 交接说明:文档道 teammate 在改 CI 指南时中断,剩余 9 处双写疤与 29 处 CI 标识 (job id / 日志名 / 汇总行字面量)由 Lead 接手改完,逐处仍走断言式行内置换。
95 lines
9.3 KiB
Markdown
95 lines
9.3 KiB
Markdown
# scripts/ — 开发脚本(提交门禁 + 报告生成)
|
||
|
||
> 本目录是 **pre-commit 门禁脚本**与**报告生成脚本**的存放处。
|
||
> 与 `tools/`(面向开发者的功能工具)区别:本目录服务于**质量门禁与工程度量**。
|
||
|
||
## 文件一览
|
||
|
||
### 提交门禁(接入 `.pre-commit-config.yaml`)
|
||
|
||
| 脚本 | 钩子名 | 作用 |
|
||
|---|---|---|
|
||
| `check_coding_standard.py` | `C coding standard` | C 代码规范机械检查(命名前缀/常量右置/头文件保护宏等) |
|
||
| `check_mojibake.py` | `Forbid U+FFFD mojibake` | 扫描 `U+FFFD` 乱码(`EF BF BD` 字节) |
|
||
| `check_doc_links.py` | `doc-links` | **文档链接存在性** + 命名规范 + **`§N.M` 章节引用**(口径见 `docs/文档规范.md` §3.5)。钩子已带 `--sections-strict`(自引用失效也拦);`--section-todo` 列出机器判不了目标的 `§`(带改写建议)。每次跑打印「可判定比例」行,防覆盖率回落 |
|
||
| `section_aliases.json` | (被 `check_doc_links.py` 读) | 文档**昵称别名表**:「内存方案」→ `docs/内存管理/RAM使用分析与优化方案.md`。只登记无歧义昵称;登记一次即把该昵称的引用纳入硬门禁 |
|
||
| `check_ids.py` | ~~`id-check`~(已退役) | **编号门禁(已退役,2026-10-28)**:`docs/编号规范.md` §8 的八项校验(未登记前缀 / 形态 / 悬空 / 重复定义 / 越游标 / 未紧邻文档名 / 孤儿 / 可判定比例)。**已关闸为增量拦截**:钩子带 `--strict`,只拦 `scripts/archive/id_gate/id_known_backlog.json` 台账之外的新错误级问题(存量按指纹豁免、台账只减不增);可判定比例跌破基线任何模式都失败。详表(含限制与盲区)→ `docs/门禁说明/id-check.md` |
|
||
| `id_registry.json` | (被 `check_ids.py` 读) | 前缀族**注册表**:属主登记处 / 形态正则 / 冻结 / 游标,逐项来自 `docs/编号规范.md` §4;`decidable_ratio_baseline` = 校验 8 的基线(只许涨)。与 `section_aliases.json` 同一套"别名表 + 可判定比例"范式 |
|
||
| `id_aliases.json` | (被 `check_ids.py` 读) | 编号**别名/作废表**:旧字面量 → 现行字面量或 `status: void`(如已销项的旧号仍被引用 → `status: void`、模块码 `PHY→NET`) |
|
||
| `check_test_traceability.py` | (原被 `id-check` 顺带调用;后者已退役) | **TC 用例双向追溯**:文档 ↔ 代码两侧的 TC 编号集合比对;2026-10-20 起范围扩到 `test/host/` 与 7 篇「单元测试说明.md」(`--board-only` 回退旧板级口径)。此前该脚本**未挂任何钩子** |
|
||
| `gen_task_table.py` | `task-table` | FreeRTOS 任务表以 `Src/freertos.c` 为**唯一事实源**生成/校验 |
|
||
| `check_mem_numbers.py` | `mem-numbers` | 内存/Flash 数字以 `.map` 为唯一事实源校验(体积档) |
|
||
| `check_test_suite.py` | `test-suite-switch` | 测试套件开关=产品构建(防测试固件静默提交) |
|
||
|
||
### 报告生成(非门禁)
|
||
|
||
| 脚本 | 作用 |
|
||
|---|---|
|
||
| `ram_report.py` | 从 `.map` 生成**静态 RAM/Flash 占用**报告(→ `docs/内存管理/data/`) |
|
||
| `stack_report.py` | 从 Keil 静态调用图 + 串口 `[STACK]` 水位生成**每任务最坏链**报告 |
|
||
|
||
### 引用同步(改名 / 挪目录)
|
||
|
||
| 脚本 | 作用 |
|
||
|---|---|
|
||
| `rename_ids.py` | **编号(字面量)批量改名**:映射表 JSON 驱动,`files` 显式 scope(同一裸形字面量可能属多族,实测 `S3` 三义 → 全局替换必造新撞号);默认干跑,`--apply` 落盘并自动写 `id_aliases.json` 的 scoped 旧号→新号条目;`[示例]`/`[计划]` 行与变更记录表不改写;按原字节读写(保 BOM 与行尾)。用法与批次记录 → `scripts/archive/id_gate/编号治理历史.md` §8.3 |
|
||
| `rename_ref.py` | **改名/挪目录 + 全库引用自动改写**:默认 dry-run 预览,`--apply` 才落盘(`git mv` → 改写引用 → 自动跑 `check_doc_links --all` 复核)。覆盖反引号引用、Markdown 链接、图片 `../` 层级换算、`#include`、`uvprojx`/`CMakeLists.txt` 源列表。固定动作与边界 → `docs/文档规范.md` §3.6 |
|
||
|
||
> `check_doc_links.py` 除链接存在性外,还校验 **`§N.M` 章节引用**是否指向目标文档真实存在的编号标题(口径见 `docs/文档规范.md` §3.5)。
|
||
|
||
### CI 与本地等价(2026-10-01)
|
||
|
||
| 脚本 / 文件 | 作用 |
|
||
|---|---|
|
||
| `ci_local.py` | **本地跑与 CI 等价的门禁**(静态门禁 pre-commit + 提交信息门禁 + **体积门禁** + 主机侧纯逻辑单测):自动选用装了 pre-commit 的解释器;无 `.map` 时自适应跳过 `mem-numbers` / `mem-budget`(⚠ 那是 SKIP 不是通过,缺口由体积门禁兜住);退出码 0/1/2 与 CI 对齐。CI 定义见 `../.gitea/workflows/ci.yml`,覆盖边界见 `docs/测试说明/测试开发标准流程.md` §9 |
|
||
| `check_size_gate.py` | **体积门禁的强制路径**:`.map` 只在本地有,钩子无它时自适应 SKIP,于是"没测=通过"。本脚本用**已提交的同码凭证** `scripts/size_attestation.json` 把这条判据变成无需 Keil 也能跑:`--stamp` 只在"`.map` 存在、比全部受管源码新、且未超 92%"时才盖章(已挂在 `ram_baseline.py --update` 里,无新增人工步骤);`--local` 供 ci_local 的体积门禁步;`--ci` 供 runner(同码性 + 按凭证数字复核红线,主干 push 拦红、其余事件 `--warn-only`);`--show` 排障。**口径与边界的唯一正文在本脚本模块 docstring** |
|
||
| `size_attestation.json` | (被 `check_size_gate.py` 读写)体积同码凭证:受管源码指纹(`git ls-files` 范围内逐文件 sha256 聚合)+ 测量数字与占比 + `.map` 出处。改固件源码后不重测 → 指纹对不上 → 体积门禁与 CI 同时拦红 |
|
||
| `check_test_coverage.py` | 主机单测**覆盖率**(2026-10-23):mscoverage 动态插桩跑 `test/host/**` 全部 16 套,统计自研生产源码行/函数覆盖(并集)+ 与 `test_coverage_baseline.json` 比回退;`--module/--update-baseline/--md/--json/--list`;**不在 pre-commit 里**,入口是 `ci_local.py --coverage`(口径见 `docs/测试说明/主机单测覆盖率口径.md`) |
|
||
| `ci_gitlint_range.ps1` | CI 侧**提交信息门禁**:逐条校验本次 push/PR 引入的提交(`--all-files` 跑不到 `commit-msg` stage,故必须单独守) |
|
||
| `ci_find_python.ps1` | CI 侧 Python 探测(候选顺序须与 `ci_local.py` 同序同步,否则 CI 与本地判定会分叉) |
|
||
| `ci_runner_bootstrap.ps1` | **本机 runner 运维脚本**(体检 `-Status` / 干跑 `-DryRun` / 部署 `-SetEnv -StartNow`):装"等 Gitea 就绪 + 崩溃自拉起"的看门狗 + 开机计划任务 + 机器级 `DTU_*` |
|
||
|
||
> ⚠️ 后三个脚本是**本机 runner 专属运维**(远程 CI 只跑在本机一台机器上),用法、原理与
|
||
> 踩坑全部集中在 `docs/CI/README.md`,本表只登记不展开。
|
||
|
||
## 使用方式
|
||
|
||
```bash
|
||
# 全库跑门禁(用仓库 .venv 的 python,其 pre-commit 随 requirements.txt 安装;
|
||
# 其他装有 pre-commit 的解释器可用 DTU_PRECOMMIT_PYTHON 指定)
|
||
& '.venv\Scripts\python.exe' -m pre_commit run --all-files
|
||
|
||
# 本地跑与 CI 等价的门禁(静态门禁 + 提交信息门禁 + 体积门禁 + 主机侧纯逻辑单测)
|
||
& '.venv\Scripts\python.exe' scripts/ci_local.py
|
||
& '.venv\Scripts\python.exe' scripts/ci_local.py --static-only # 只跑静态门禁
|
||
& '.venv\Scripts\python.exe' scripts/ci_local.py --host-unit-only # 只跑主机侧纯逻辑单测
|
||
& '.venv\Scripts\python.exe' scripts/ci_local.py --size-only # 只跑体积门禁(强制路径)
|
||
& '.venv\Scripts\python.exe' scripts/check_size_gate.py --show # 体积同码凭证现状(0.3 s,无需 Keil)
|
||
& '.venv\Scripts\python.exe' scripts/check_size_gate.py --stamp # 用新鲜 .map 重新盖戳(--update 已自动带做)
|
||
|
||
# 单个脚本
|
||
& '.venv\Scripts\python.exe' scripts/check_doc_links.py --all
|
||
& '.venv\Scripts\python.exe' scripts/rename_ref.py docs/旧/名.md docs/新/名.md # 预览
|
||
& '.venv\Scripts\python.exe' scripts/rename_ref.py docs/旧/名.md docs/新/名.md --apply # 落盘
|
||
& '.venv\Scripts\python.exe' scripts/gen_task_table.py --check # 或 --write / --diff
|
||
& '.venv\Scripts\python.exe' scripts/check_mem_numbers.py --check
|
||
& '.venv\Scripts\python.exe' scripts/check_test_suite.py # 门禁判定
|
||
& '.venv\Scripts\python.exe' scripts/check_test_suite.py --allow-test-build # 放行测试构建
|
||
& '.venv\Scripts\python.exe' scripts/ram_report.py
|
||
& '.venv\Scripts\python.exe' scripts/stack_report.py -s .dsh\skills\serial-assistant\scripts\state\serial.log
|
||
```
|
||
|
||
## ⚠️ 脚本编写约定
|
||
|
||
- **保真回写**:改文件前先探测原换行符(LF/CRLF)与 BOM,按原样回写(本仓库各文件换行混杂)
|
||
- **受管区锚点**:改文档中的数值/表格时用 `<!-- XXX:BEGIN/END -->` 锚点,只替换锚点内内容
|
||
- 脚本**输出文件绝不能落在自身扫描范围内**(否则会"自我污染",见 `docs-tree-reorg` skill)
|
||
- 生成器与校验器**共用同一套正则/口径**,避免两处数字打架
|
||
|
||
## 相关文档
|
||
|
||
- `docs/代码规范/pre-commit使用说明.md` — 门禁完整说明与排除项
|
||
- `docs/代码规范/cppcheck使用说明.md`
|
||
- `docs/文档规范.md` — 文档门禁三档
|
||
- `docs/内存管理/RAM使用分析与优化方案.md` — RAM/栈报告口径
|