运行时依赖
安装命令
点击复制技能文档
作为一名Go代码质量工程师,我将linting作为开发工作流程中的第一类部分——而不是事后清理步骤。
模式:
设置模式 —— 配置 .golangci.yml 文件,选择 linter,启用 CI:按照配置和工作流程部分的顺序进行。
编码模式 —— 编写新Go代码:在后台启动一个运行 golangci-lint run --fix 的代理,只对修改的文件进行操作,同时主代理继续实现功能;当完成时显示结果。
解释/修复模式 —— 读取 lint 输出,抑制警告,修复现有代码的问题:从“解释输出”和“抑制 Lint 警告”开始;对于大规模的遗留代码清理,使用并行子代理。
Go Linting 概述
golangci-lint 是标准的 Go linting 工具。它聚合了 100+ 个 linter 到一个二进制文件中,并行运行它们,并提供了统一的配置格式。在开发过程中频繁运行它,并且始终在 CI 中运行它。每个 Go 项目必须有一个 .golangci.yml 文件 —— 它是启用和配置 linter 的真实来源。请参阅推荐的配置,用于生产就绪的设置,启用 33 个 linter。
快速参考
# 运行所有配置的 linter
golangci-lint run ./...
# 自动修复问题
golangci-lint run --fix ./...
# 格式化代码(golangci-lint v2+)
golangci-lint fmt ./...
# 运行单个 linter
golangci-lint run --enable-only govet ./...
# 列出所有可用的 linter
golangci-lint linters
# 显示详细输出和时间信息
golangci-lint run --verbose ./...
配置
推荐的 .golangci.yml 文件提供了生产就绪的设置,启用 33 个 linter。有关配置详细信息、linter 类别和每个 linter 的描述,请参阅 linter 参考 —— 哪些 linter 检查什么(正确性、样式、复杂性、性能、安全性),所有 33+ 个 linter 的描述,以及每个 linter 何时有用。
抑制 Lint 警告
使用 //nolint 指令时要谨慎 —— 先修复根本原因。
// 好:特定 linter + 正当理由
//nolint:errcheck
// fire-and-forget 日志,错误不可操作
_ = logger.Sync()
// 坏:没有理由的空白抑制
//nolint
_ = logger.Sync()
规则:
//nolint 指令必须指定 linter 名称://nolint:errcheck 而不是 //nolint
//nolint 指令必须包含正当理由注释://nolint:errcheck
// reason
nolint linter 强制执行上述两个规则 —— 它标记了裸露的 //nolint 和缺失的理由
永远不要在没有强烈理由的情况下抑制安全 linter(bodyclose、sqlclosecheck)
开发工作流程
linter 应该在每次重要更改后运行:golangci-lint run ./...
自动修复可以修复的问题:golangci-lint run --fix ./...
在提交之前格式化代码:golangci-lint fmt ./...
在遗留代码上逐渐采用:在 .golangci.yml 文件中设置 issues.new-from-rev 以仅对新/更改的代码进行 lint,然后逐渐清理旧代码
Makefile 目标(推荐):
lint:golangci-lint run ./...
lint-fix:golangci-lint run --fix ./...
fmt:golangci-lint fmt ./...
对于 CI 流水线设置(使用 GitHub Actions 和 golangci-lint-action),请参阅 samber/cc-skills-golang@golang-continuous-integration 技能。
解释输出
每个问题都遵循以下格式:path/to/file.go:42:10: message describing the issue (linter-name)
括号中的 linter 名称告诉您哪个 linter 标记了它。使用它来:
查找 linter 参考以了解它检查什么
使用 //nolint:linter-name // reason 抑制假阳性
使用 golangci-lint run --verbose 获取额外的上下文和时间信息
常见问题
问题 | 解决方案
---|---
“deadline exceeded” | 增加 .golangci.yml 文件中的 run.timeout(默认:5m)
遗留代码中有太多问题 | 设置 issues.new-from-rev: HEAD~1 以仅对新代码进行 lint
找不到 linter | 检查 golangci-lint linters —— linter 可能需要更新版本
linter 之间的冲突 | 禁用不太有用的一个,并注释说明为什么
v1 配置错误后升级 | 运行 golangci-lint migrate 以转换配置格式
大型仓库运行缓慢 | 减少 run.concurrency 或在 run.skip-dirs 中排除目录
并行化遗留代码库清理
在采用 linting 时,使用最多 5 个并行子代理(通过 Agent 工具)同时修复独立的 linter 类别:
子代理 1:运行 golangci-lint run --fix ./... 以自动修复问题
子代理 2:修复安全 linter 找到的问题(bodyclose、sqlclosecheck、gosec)
子代理 3:修复错误处理问题(errcheck、nilerr、wrapcheck)
子代理 4:修复样式和格式问题(gofumpt、goimports、revive)
子代理 5:修复代码质量问题(gocritic、unused、ineffassign)
交叉引用
→ 参阅 samber/cc-skills-golang@golang-continuous-integration 技能,用于使用 golangci-lint-action 的 CI 流水线
→ 参阅 samber/cc-skills-golang@golang-code-style 技能,用于代码样式