关于 go-nolint-audit
Go Nolint Audit 是用于审查 Go 代码库中 `//nolint` 指令的技能,供维护者检查过期或理由不足的抑制项。它结合 golangci-lint 验证和多方辩论,输出处理建议与具体修改。
主要功能
- 01扫描 Go 文件中的 nolint
- 02验证指定规则是否仍触发
- 03评估修复可行性与理由质量
- 04辩论并给出处理结论
- 05输出具体差异和汇总
适用场景
- 01清理已不再需要的 lint 抑制
- 02检查缺少充分理由的 nolint
- 03为争议抑制项生成修订建议
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rshade/ agent-skills --skill go-nolint-audit安装后在 Claude Code 中输入/go-nolint-audit确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/fixture/go.modmain.goreferences/go-nolint-patterns.md详细介绍
Go Nolint 审计
审计 Go 代码库中的 //nolint: 指令。查找过时的抑制(代码已变更,不再触发 lint 规则)或理由牵强的抑制(底层代码本可以修复,而不是被抑制)。通过对抗式辩论逐一质疑每条理由,而不是直接相信注释。
前置条件检查
go version 2>/dev/null && golangci-lint --version 2>/dev/null
如果未安装 go,则停止并报告。如果缺少 golangci-lint:
除非两种工具都可用,否则不要继续。
查找 nolint 指令
grep -rn '//nolint' --include='*.go' . | grep -v vendor/
匹配所有形式://nolint(裸指令)、//nolint:rule、//nolint:rule1,rule2。对于每条指令,记录:
- 文件和行号
- 被抑制的规则,或未指定规则时记为“裸指令”
- 理由注释(如果存在,则记录
//nolint:rule //后的文本) - 周边代码上下文(约 5 行)
裸 //nolint(未指定规则)会抑制所有规则——在第 2 阶段自动标记。如果未找到任何指令,则报告代码库干净并停止。
第 1 阶段:机械验证
对于每条指定了规则的指令,测试该抑制是否仍有必要。将 nolintlint 与目标规则一起启用:
# v2 syntax (preferred):
golangci-lint run --enable-only=<rule>,nolintlint \
--allow-parallel-runners <file>
# v1 syntax (if v2 unavailable):
golangci-lint run --disable-all --enable=<rule>,nolintlint \
--allow-parallel-runners <file>
如果 nolintlint 报告该指令未被使用,则它已过时。这种方法无需修改源文件。对于多规则指令(//nolint:rule1,rule2),分别测试每条规则。最多运行 3 条并行 shell 命令。务必使用 --allow-parallel-runners。
如果 golangci-lint 因目标规则之外的原因失败(构建错误、缺少依赖),则跳过该指令,并报告为“无法验证”。
对每条指令进行分类:
- 过时 — 规则不再触发。可以安全移除。
- 仍有效 — 规则仍会触发。进入第 2 阶段。
立即报告过时指令。如果所有指令都已过时,则跳过第 2 阶段。裸 //nolint 指令跳过第 1 阶段——无法针对特定规则进行验证。
第 2 阶段:对抗式辩论
从两个维度(1-5 分)为所有已发现的指令评分(不只是第 1 阶段抽样的指令)。对于大型代码库(50 条以上指令),第 1 阶段按不同规则抽取 5-10 条进行测试,但此处要为完整列表评分,以找出最有问题的指令:
- 可修复性 — 修复代码而不是抑制规则有多容易?
- 5 = 很简单(提取函数、重命名、添加常量)
- 3 = 中等(重构逻辑、拆分函数)
- 1 = 需要架构变更
- 理由质量 — 注释有多充分?
- 5 = 没有注释,或理由含糊(“复杂度不可避免”“有必要”)
- 3 = 解释了情况,但没说明为什么修复反而更糟
- 1 = 理由具体且令人信服
得分 = 可修复性 x 理由质量。评分指南请参阅 references/go-nolint-patterns.md。
按得分对排名前 3 的指令进行辩论:
- 红方(移除):主张移除 nolint 并修复代码。必须提出具体 diff。对理由提出质疑。
- 蓝方(保留):主张 nolint 是合理的。必须补充现有注释之外的理由,并指出所提修复方案的风险。
- 白方(裁决):依据证据进行评估,并作出决定:移除、保留或重写理由。
辩论规则
- 红方和蓝方必须引用具体代码,不得泛泛而谈
- 红方必须提供具体 diff,不能只说“可以更简单”
- 蓝方不能只是重复现有理由
- 白方的决定为最终决定
输出格式
第 1 阶段
Stale (safe to remove):
file.go:42 //nolint:errcheck — rule no longer triggers
file.go:87 //nolint:mnd — rule no longer triggers
Unable to verify:
file.go:99 //nolint:gosec — golangci-lint build error
第 2 阶段
对于每条参与辩论的指令:
#N: file.go:line — //nolint:rule
当前代码(含 nolint): [周边代码 5-10 行]
理由:“原始注释” 移除后的 lint 警告:[golangci-lint 的确切输出]
红方(移除):[论点 + 具体 diff] 蓝方(保留):[包含具体理由的论点] 白方(裁决):移除 | 保留 | 重写理由 [理由]
[如果选择移除:重复 diff,方便应用] [如果选择重写:提供完整的替换行及改进后的理由]
摘要
| # | 文件:行 | 规则 | 判定 | 工作量 |
|---|---|---|---|---|
| 1 | location | rule | verdict | effort |
| 2 | location | rule | verdict | effort |
| 3 | location | rule | verdict | effort |
过时:N(立即移除) | 无法验证:N