Files
STM32F4-Base/scripts/README.md
T
wandering1 89b6132c1f docs(编号): 瘦身——58 KB/473 行 → 22 KB/222 行,过程记录进归档
用户裁定 A 方案:这份文档的「规范体系」部分已随门禁退役而死,但四件仍活着的东西
只有这里写着——① §1 政策(默认不发号 / 先问三句);② §3.3 语义标识怎么写;
③ §4.1 族总表 + §4.1.1 已停发栏(现行门禁白名单的机器投影源头);
④ §4.4 这些不是编号(防把 YX15 / 元件位号当垃圾清)。再留 §5.5 销项、
§8 门禁现状与 §8.5 退役路线、§10 速查。

其余 16 节逐字搬进 scripts/archive/id_gate/编号治理历史.md(40 KB):
1.2 / 2 八条原则 / 4.2 / 4.5 / 6 模块码表 / 7+7.1~7.3 / 8.1 基线 / 8.3 批次 /
8.4 台账 / 9+9.1~9.3(含「数据可信」任务卡号换算表),以及原变更记录 17 行流水。
归档文件带「这不是现行口径」横幅 + 归档目录,写清哪些节对应哪段历史。

两处刻意的选择:
- 节号沿用旧编号、不重排——外部文档与脚本引的是 §4.1 / §8.5 这些号,重排等于
  制造一批假链接;文首加「本文范围」说明跳号去哪了。
- 文首那段「机器面才是事实源」改写:现行机器面是 check_ids_new.py 的两张
  前缀级白名单(KNOWN_DASH / KNOWN_BARE),旧的 registry / 别名表 / 八项校验脚本
  已随全库审计退役进归档,只在手工复查存量时才用。

引用重修(6 份文档、10 处):AGENTS 的 §9.3 换算表、数据可信 §9.3 ×2、
门禁说明 id-check 与 host-unit-tests、docs/README 的 §4.5、技能手册的 §9、
以及正文里 §4.2 / §4.5 / §8.1 / §8.3 / §8.4 / §1.2 的裸引用。

验证:doc-links --all --sections-strict 通过(195 文档);mojibake / bom-guard /
git diff --check 全 rc=0;新门禁 --worktree 自查通过;钩子数仍 51。
2026-10-28 12:51:17 +08:00

95 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 等价的门禁**(L0 pre-commit + L0b 提交信息 + **L0c 体积门禁** + L0.5 主机侧单测):自动选用装了 pre-commit 的解释器;无 `.map` 时自适应跳过 `mem-numbers` / `mem-budget`(⚠ 那是 SKIP 不是通过,缺口由 L0c 兜住);退出码 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 的 L0c 步;`--ci` 供 runner(同码性 + 按凭证数字复核红线,主干 push 拦红、其余事件 `--warn-only`);`--show` 排障。**口径与边界的唯一正文在本脚本模块 docstring** |
| `size_attestation.json` | (被 `check_size_gate.py` 读写)体积同码凭证:受管源码指纹(`git ls-files` 范围内逐文件 sha256 聚合)+ 测量数字与占比 + `.map` 出处。改固件源码后不重测 → 指纹对不上 → L0c 与 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 等价的门禁(L0 + L0b + L0c + L0.5)
& '.venv\Scripts\python.exe' scripts/ci_local.py
& '.venv\Scripts\python.exe' scripts/ci_local.py --l0-only # 只跑 L0
& '.venv\Scripts\python.exe' scripts/ci_local.py --l05-only # 只跑 L0.5
& '.venv\Scripts\python.exe' scripts/ci_local.py --size-only # 只跑 L0c 体积门禁(强制路径)
& '.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/栈报告口径