Files
STM32F4-Base/.pre-commit-config.yaml
T

248 lines
12 KiB
YAML
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.
# pre-commit 自动化代码审查配置
# 详见 docs/代码规范/pre-commit使用说明.md
default_install_hook_types: [pre-commit, commit-msg]
exclude: |
(?x)^(
\.opencode/node_modules/|
Lib/lvgl/|
simulator/|
MDK-ARM/RTE/
)
repos:
# 1) 通用钩子(官方)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
# 豁免 **CubeMX / Keil 生成的文件**(锚名 cubemx-generated,end-of-file-fixer 复用):
# 这类文件的内容事实源是 `.ioc` 与工具链,每次重生成都按工具自己的风格写回
# (行尾空白、文件末尾不带换行)。2026-10-09 实测:每次重生成后 `Src/`/`Inc/`
# 下 10+ 个文件各被补 1 行末尾空行,纯属提交抖动。
# ⚠ 只豁免**改写型**钩子(trailing-whitespace / end-of-file-fixer);
# cppcheck / 乱码 / 存活审计 / 任务表 / 内存数字等**只读检查**仍覆盖
# `Src/`、`Inc/`——`cubemx-survival` 必须能看到这些文件。
exclude: &cubemx-generated |
(?x)^(
Src/.*\.(c|h)$|
Inc/.*\.(c|h)$|
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Middlewares/|
MDK-ARM/.*\.(uvprojx|uvoptx|sct|map)$|
\.mxproject$|
.*\.ioc$
)
- id: end-of-file-fixer
exclude: *cubemx-generated
- id: check-added-large-files
- id: check-merge-conflict
- id: check-yaml
# 2) C 代码格式:只检查,绝不改写(编码铁律)
# Route A:暂不启用,待全库格式化基线后再放开
# - repo: https://github.com/pre-commit/mirrors-clang-format
# rev: v19.1.4
# hooks:
# - id: clang-format
# args: [--dry-run, --Werror]
# 3) commit message 格式(宽松规则,兼容中文标题)
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1
hooks:
- id: gitlint
# 4) 本地自定义钩子(仓库级)
- repo: local
hooks:
- id: cppcheck
name: cppcheck
entry: cppcheck
# 注意:YAML 流序列中逗号是元素分隔符,含逗号/空格的参数必须加引号
args: ['--enable=warning,performance,portability,style', '--error-exitcode=1',
'--inline-suppr',
'--std=c99', '--quiet',
'--suppress=missingIncludeSystem', '--suppress=missingInclude',
'--suppress=invalidPrintfArgType_sint', '--suppress=invalidPrintfArgType_uint',
'--suppress=unusedFunction', '--suppress=unusedStructMember',
'--suppress=noExplicitConstructor', '--suppress=useStlAlgorithm',
'--suppress=constParameterPointer', '--suppress=constParameterCallback',
'--suppress=redundantAssignment',
'--suppress=normalCheckLevelMaxBranches',
'-I', 'Inc', '-I', 'App', '-I', 'Drivers/BSP',
'-I', 'Drivers/STM32F4xx_HAL_Driver/Inc', '-I', 'Drivers/CMSIS/Include',
'-I', 'Middlewares/Third_Party/FreeRTOS/Source/include']
language: system
types: [c]
# 仅扫描项目自有代码;排除第三方库与 LVGL 依赖文件
# (UI 生成文件 ui_font_cn_12/ui_menu_tab 由生成器按工程约定产出,纳入受检)
exclude: |
(?x)^(
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Drivers/BSP/NET/lftpd/|
Drivers/BSP/dhara/|
Lib/|
Middlewares/|
MDK-ARM/|
test/
)
# 4b) test/ 代码宽松静态检查(S5,2026-10-03 加)
# 背景:`test/` 此前完全豁免 pre-commit(靠"自律"),而 `test/board/` 下
# 6300+ 行 C 代码**且编入固件**(曾出现 `s_rx_buf` 使用先于声明)。
# 本钩子**只开 warning**(不引入存量 style 噪音),排除模拟器桩
# (`test/host/*/stub/`,第三方/桩头形态不受控)。
# 基线:2026-10-03 全量实测 **0 条 warning**(存量可控,故直接挂钩子)。
# 依据:docs/审查记录/测试与架构改进建议.md §3.4;实机测试实施指南.md §8.1
- id: test-cppcheck
name: cppcheck (test/, warning only)
entry: cppcheck
args: ['--enable=warning', '--error-exitcode=1',
'--inline-suppr', '--std=c99', '--quiet',
'--suppress=missingIncludeSystem', '--suppress=missingInclude',
'--suppress=invalidPrintfArgType_sint', '--suppress=invalidPrintfArgType_uint',
'--suppress=unusedFunction', '--suppress=unusedStructMember',
'--suppress=constParameterPointer', '--suppress=constParameterCallback',
'--suppress=redundantAssignment',
'--suppress=normalCheckLevelMaxBranches',
'-i', 'test/host/watchdog/stub',
'-i', 'test/host/cfg_file/stub',
'-i', 'test/host/sys_clock/stub',
'-I', 'Inc', '-I', 'App', '-I', 'Drivers/BSP',
'-I', 'Drivers/STM32F4xx_HAL_Driver/Inc', '-I', 'Drivers/CMSIS/Include',
'-I', 'Middlewares/Third_Party/FreeRTOS/Source/include',
'test/']
language: system
# 触发条件:test/ 下 C/头文件变动;扫描范围恒为整个 test/(pass_filenames=false)
files: ^test/.*\.(c|h)$
pass_filenames: false
- id: no-mojibake
name: Forbid U+FFFD mojibake
entry: python scripts/check_mojibake.py
language: system
types: [c]
- id: coding-standard
name: C coding standard (规范V1.0)
entry: python scripts/check_coding_standard.py
language: system
types: [c]
# 范围与 cppcheck 钩子一致;另排除 CubeMX 生成文件(Src/、Inc/,重新生成即覆盖)、
# dhara/FatFS 接口适配层(nand_ftl,函数名由外部 API 固定)
exclude: |
(?x)^(
Drivers/CMSIS/|
Drivers/STM32F4xx_HAL_Driver/|
Drivers/BSP/NET/lftpd/|
Drivers/BSP/GD5F2GQ5UE/nand_ftl\.|
Drivers/BSP/dhara/|
Lib/|
Middlewares/|
MDK-ARM/|
test/|
Src/|
Inc/
)
# 5) 文档一致性门禁(D-7)
# 存在性:md 互链 / 反引号路径是否指向真实文件(防迁移/删除后残留死链)
- id: doc-links
name: 文档链接存在性 (D-3/D-7)
entry: python scripts/check_doc_links.py
language: system
files: \.md$
# 外部资料(芯片手册转录)链接形态不受控;第三方目录整体排除
exclude: |
(?x)^(
\.opencode/node_modules/|
Lib/lvgl/|
simulator/|
MDK-ARM/RTE/|
docs/芯片手册/
)
# 数值:README/AGENTS 任务表须与 Src/freertos.c 一致(D-2/D-7)
- id: task-table
name: FreeRTOS 任务表一致性 (D-2/D-7)
entry: python scripts/gen_task_table.py --check
language: system
files: ^(README\.md|AGENTS\.md|Src/freertos\.c)$
pass_filenames: false
# 体积:内存/Flash 数字须与最新 .map 一致(D-7 第三档)
# 只在内存文档或代码变动时触发;.map 未生成时脚本自身给出明确提示
- id: mem-numbers
name: 内存/Flash 数字一致性 (D-7 体积档)
entry: python scripts/check_mem_numbers.py --scan
language: system
files: ^(docs/内存管理/.*\.md|scripts/check_mem_numbers\.py|App/.*\.c|App/.*\.h|Src/.*\.c|Inc/.*\.h)$
pass_filenames: false
# 6) CubeMX 重生成存活审计(2026-09-29 加)
# 背景:.ioc 的 KeepUserCode 只保护 USER CODE 标记区;标记之外的手工改动
# 重生成即被覆盖,且多数不报编译错(崩溃采集被打回空 while(1)、加固宏被删)。
# 本钩子验证"重生成易失清单"各项是否仍在预期位置,并对关键区做哈希漂移检测。
# 范围:仅在这些易失文件变动时触发(改动 .ioc 或生成文件本身就值得复核)。
- id: cubemx-survival
name: CubeMX 重生成存活审计
entry: python scripts/check_cubemx_survival.py --check
language: system
files: ^(STM32F407-Demo\.ioc|Src/.*\.(c|h)|Inc/.*\.h|App/util/task_watchdog\.(c|h)|MDK-ARM/.*\.uvprojx|scripts/check_cubemx_survival\.py)$
pass_filenames: false
# 7) 看门狗判定状态机主机侧单元测试(2026-10-01 加)
# 背景:task_watchdog.c 的判定逻辑(位图取走清零 / 掩码 / miss_streak
# 累计 / 100ms 节流 / tick 回绕)是纯逻辑,板端套件无法穷举边界;本钩子
# 用 MSVC 离线编译真实源文件(#include 纳入)并用可观测桩驱动,秒级、零
# 硬件、不占 MCU RAM。仅在被测文件或其平台层 / 测试变动时触发。
# 详见 docs/测试说明/看门狗单元测试说明.md
- id: watchdog-unit-test
name: 看门狗判定状态机单测(主机侧)
entry: python test/host/watchdog/run_unit_test.py
language: system
files: ^(App/util/task_watchdog\.(c|h)|test/host/watchdog/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7b) 系统时钟时间换算主机侧单元测试(2026-10-02 加)
# 背景:sys_clock.c 的 Unix↔日历换算(闰年 / 月末 / 世纪 / 2038 上限)、
# 星期(Zeller)、"30 天惰性再基准化"(防 49.7 天 tick 回绕)、RTC 故障
# 降级路径均为纯逻辑;本钩子用 MSVC 离线编译真实源文件(#include 纳入)
# 并以可注入桩驱动(可控时钟 + 阴影 RTC)。首次落地即抓出 Zeller 公式
# 缺陷(1970~2099 全部日期星期皆错,详见测试说明文档)。
# files 含 sys_clock.c 依赖的 sd2506.h(时间结构/返回值定义)。
- id: sys-clock-unit-test
name: 系统时钟换算单测(主机侧)
entry: python test/host/sys_clock/run_unit_test.py
language: system
files: ^(App/util/sys_clock\.(c|h)|Drivers/BSP/SD2506/sd2506\.h|test/host/sys_clock/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7c) 配置引擎主机侧单元测试(2026-10-02 加,S1-b)
# 背景:cfg_file.c 的核心是"文本 <-> 结构"纯变换(INI 段/键解析、四种值
# 类型编解码、外科手术式保存、超长守卫、load/save/poll 契约);板端套件只
# 保存到缺失/新文件(走 s_gen_document 路径),**从不触发对已存在文件的外科
# 手术改写**,故掩盖了该路径的缺陷。本钩子用 MSVC 离线编译真实源文件
# (#include 纳入)+ 内存虚拟文件系统后端驱动,首次落地即抓出 P0:
# `s_encode(...) == 0` 恒假(其成功返回文本长度而非 0)使**外科手术保存的
# 受管值改写路径沦为死码**——对已存在 /config.ini 保存时受管键从不改写(静默
# 不落盘,且 net_cfg_save 仍报 OK)。详见测试说明文档。
- id: cfg-file-unit-test
name: 配置引擎单测(主机侧)
entry: python test/host/cfg_file/run_unit_test.py
language: system
files: ^(App/cfg/cfg_file\.(c|h)|App/cfg/cfg_file_store\.h|App/log/sys_log\.h|test/host/cfg_file/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 8) 测试套件开关门禁(2026-10-01 加)
# 背景:test_config.h 的 TEST_SUITE_* 决定固件里编入哪个测试套件,
# 全部注释 = 产品构建。但此前**无任何门禁检查**——实测已提交的 HEAD 里
# TEST_SUITE_CH395F 就是开启状态(.map 含 34 处 test 代码),即仓库里
# 躺着的是测试固件。本钩子抓这个静默漏网:默认要求产品构建,跑套件回归
# 确需提交测试构建时用 `--allow-test-build` / ALLOW_TEST_BUILD=1 显式放行。
# 详见 docs/待处理内容.md T-1
- id: test-suite-switch
name: 测试套件开关=产品构建
entry: python scripts/check_test_suite.py
language: system
files: ^test/board/test_config\.h$
pass_filenames: false