SuperAPI AI 工具集

crap-gate

测试与质量

查看项目

更新于 10-31 06:32

技能介绍

用途

crap-gate 用于在代码提交与 CI 环节执行 CRAP 门禁,阻止新增复杂代码债务,并推动被改动的热点函数逐步缩小。CRAP 按函数计算:CC² × (1 − coverage)³ + CC,其中 CC 是圈复杂度。没有测试覆盖的复杂代码得分很高。

报告来源

  • make crap-check(或 bun scripts/crap/check.ts --base <ref>):检查自与 origin/main 的合并基点以来在工作树中改动的文件。退出码 0 通过、1 违规、2 工具错误。
  • 代理钩子:在 git commit 或 git push 的 bash 调用之后,Xum 会把报告追加到工具结果(警告模式);阻断模式下钩子在命令运行前停止它。模式由 scripts/crap/agent-gate.sh 控制。若一次 bash 调用以非零退出,即使其中前面的 git commit 成功,也不会得到报告,此时需手动运行 make crap-check。
  • CI:Quality / CRAP 作业摘要及其注解。当仓库变量 CRAP_MODE 为 block 时,违规会使 Required 失败;否则仅作信息展示。

不带覆盖率时按 CC 计分;使用 --coverage <lcov> 时按 CRAP 计分。

阅读报告

报告条目形如:VIOLATION floor-cc src/x.ts:10-25 route: CC 30 -> 31 (head CRAP 31 above 30: must not grow)。

规则含义:

  • floor-cc:已有函数 CC 增加并超过增长线。
  • floor-crap:两侧都有覆盖率时,已有函数 CRAP 增加并超过 CRAP 30。
  • new-function:新函数(或重命名、移动到其他文件的函数)超过 CRAP 15(CC 8)。
  • crap-tax:警告,表示改动了一个基线分数高于 30 的函数且分数未下降。

增长线为:有覆盖率时 CRAP 30,无覆盖率时 CC 10。已有函数可以增长,只要最终不超过该线;超过后 CC 与 CRAP 不得再增长。任何规模的缩减都通过,因此热点可以一步步缩小。新函数限制为:有覆盖率时 CRAP 15,无覆盖率时 CC 8。crap-tax 始终是警告。

当改动文件的总 CC 下降时,new-function 发现降为警告(净提取缓解):允许拆分热点,即使其中一块仍高于限制。

从函数中移出一步会使总 CC 增加 1。若保留函数减少的 CC 至少等于新函数持有的决策点(每个 CC−1),且新函数不超过 CC 20,则该移动也是警告(移动缓解)。重命名不享受缓解。有覆盖率时,两种缓解都要求新函数 CRAP 不超过 30;超过且未测试的片段仍是违规,需测试或缩小。

函数身份是 path::namespace::name,所以重命名会使函数被视为新函数。

两种修复方式

  1. 缩小函数:把纯逻辑提取为带独立测试的命名函数;在 React 中把状态和副作用移入命名 hook,或把部分树移入子组件,各自带测试。
  2. 补充测试:覆盖率会降低 CRAP,因此只对有覆盖率数据的报告有效(--coverage <lcov>、CI 作业的 new-function 发现)。钩子和普通 make crap-check 只按 CC 计分,测试无法清除其 floor-cc 或 new-function 发现,应改为缩小函数(或保持 CC 10 以下)。测试必须断言如果代码损坏就会失败的行为。

反规避规则

不得为降低分数做以下事情:

  • 用 !、as 强制转换或其他未检查假设替代 ?. 或 ??。Crapper 把 ?. 和 ?? 计为决策点,但移除真实检查是隐藏缺陷而非消除复杂度。
  • 添加无有意义断言的测试(覆盖探针、仅快照或 expect(true) 测试)。
  • 拆成只传递状态的单调用辅助函数——CC 转移了,复杂度还在。
  • 仅为重置历史而移动或重命名函数。

Crap-Debt 例外

当违规无法在本次改动中修复(热修复、生成文件),使用运行检查处的逃生通道:所有违规变为警告,报告会列出每次使用,原因中需写明后续工作。

  • 本地(提交钩子、make crap-check):在提交信息中添加 Crap-Debt: <reason> trailer。
  • CI(Quality / CRAP):给 PR 添加 crap-debt 标签。CI 不读 trailer,标签不影响本地钩子。
  • 代理:先询问维护者,只有对该 PR 明确批准后才添加 trailer 或标签。该标签会跳过所有 CI 阻断,且代理 PR 以维护者账号运行,GitHub 无法显示是谁添加的。

适用场景

适合需要在提交与 CI 阶段控制函数复杂度、防止新债务、并让热点函数逐步收敛的代码库,尤其是有覆盖率数据可用的项目。限制:钩子与普通 crap-check 只按 CC 计分,补充测试无效;分类、阈值与策略分别位于 scripts/crap/policy.ts 与 scripts/crap/thresholds.ts,具体配置细节资料未展开说明。