Golangci-Lint
相关工具推荐
| 工具 | 说明 |
|---|---|
| govet | Go 编译器内置静态分析工具,官方基础检查 |
| Gosec | Go 语言安全静态分析工具,检测潜在安全漏洞 |
| gofmt | Go 官方代码格式化工具,自动格式化 Go 源码 |
1. 简介
Golangci-Lint 是 Go 语言生态中最主流的代码检查聚合器(linter runner),集成了 govet、errcheck、staticcheck、gosec、revive 等 100+ 个 linter,是 Go 代码静态检查的事实标准工具。
- 主要检查语言:Go
- 主要检查能力:检测 Go 代码的质量问题、安全漏洞、代码风格、性能、错误处理、惯用法;涵盖代码质量检查 + 安全类检查 + 风格类检查
- 核心检查原理:聚合多 linter 的调度框架,并行执行各 linter 并统一输出
- 检查规则/选项:集成 100+ 个 linter(如 errcheck、gosimple、govet、staticcheck、revive、gocritic 等),支持按 Default、Fast、Slow、Autofix 等标签筛选,全量 linter 列表
- GitHub 仓库:https://github.com/golangci/golangci-lint(19,070 stars)
- 开源协议:Apache-2.0
- 最新稳定版本:v2.1.0
- 运行环境要求:需 Go 1.21+(v1.54+ 起)
- 误报率:低
2. 官方文档
| 资源 | 链接 | 说明 |
|---|---|---|
| 官方网站 | https://golangci-lint.run/ | 首页与快速入门 |
| 快速入门 | https://golangci-lint.run/docs/welcome/quick-start/ | 安装与首次运行指南 |
| 所有 Linter 列表 | https://golangci-lint.run/docs/linters/ | 全部 100+ 个 linter 及其说明 |
| Linter 配置 | https://golangci-lint.run/docs/linters/configuration/ | 各 linter 的详细配置参数 |
| 配置文件 | https://golangci-lint.run/docs/configuration/file/ | 配置文件格式与选项 |
| CLI 参数 | https://golangci-lint.run/docs/configuration/cli/ | 命令行参数文档 |
| 安装指南 | https://golangci-lint.run/docs/installation/ | 各平台安装方式 |
| 假阳性处理 | https://golangci-lint.run/docs/linters/false-positives/ | nolint 指令、排除规则、预设 |
| 变更日志 | https://golangci-lint.run/docs/product/changelog/ | 版本更新记录 |
| FAQ | https://golangci-lint.run/welcome/faq/ | 常见问题解答 |
| GitHub 仓库 | https://github.com/golangci/golangci-lint | 源代码与 Issue 跟踪 |
| 配置参考文件 | .golangci.reference.yml | 所有配置选项的完整参考 |
3. 社区优秀实践
以下列出多个主流 TOP 开源项目使用 golangci-lint 的实践案例:
3.1 google/go-github
Google 维护的 GitHub v3 API Go 客户端库,展示了自定义 linter 和严格配置的最佳实践。
- 仓库:google/go-github
- 配置文件:.golangci.yml(已确认存在,445 行)
- 实践特点:
- 使用 v2 配置格式(
version: "2"),default: none手动选择所有 linter - 开发了多个自定义 linter(
fmtpercentv、sliceofpointers、structfield、extraneousnew、redundantptr)解决特定业务场景问题 - 启用 30+ 个 linter,覆盖错误处理、安全、风格、性能等多个维度
- 使用
forbidigo禁止fmt.Print*、reflect.DeepEqual等不推荐用法 - 配置
goheader检查文件头版权声明 - 使用
linters.exclusions.rules精细控制测试文件和示例代码的排除规则
- 使用 v2 配置格式(
3.2 Kubernetes
Kubernetes 是最著名的容器编排系统,其主仓库使用 golangci-lint 作为代码质量门禁。
- 仓库:kubernetes/kubernetes
- 实践特点:
- 在 CI 流水线中通过
verify-golangci-lint.sh脚本运行 golangci-lint - 使用严格的 linter 配置,覆盖错误处理、代码风格、安全性等多个维度
- 通过 Makefile target
make verify触发检查 - 生态参考项目:kubernetes/node-problem-detector 在 Makefile 中锁定 golangci-lint 版本并配置了
.golangci.yml
- 在 CI 流水线中通过
3.3 etcd
etcd 是 CNCF 毕业的分布式键值存储系统,被 Kubernetes 等项目广泛用作元数据存储。
- 仓库:etcd-io/etcd
- 实践特点:
- 在仓库根目录维护
.golangci.yml配置文件(已确认存在) - CI 中通过 GitHub Actions 运行 golangci-lint 作为 PR 合并门禁
- 启用 errcheck、govet、staticcheck 等核心 linter,确保代码质量
- 在仓库根目录维护
4. 工具配置说明
4.1 配置文件说明
golangci-lint 在当前工作目录及向上逐级目录中查找以下配置文件,按优先级解析(找到第一个即停止):
| 配置文件 | 格式 | 用途 |
|---|---|---|
.golangci.yml |
YAML | 推荐格式,可读性最佳,社区示例最丰富 |
.golangci.yaml |
YAML | .golangci.yml 的扩展名变体,行为完全一致 |
.golangci.toml |
TOML | 适合需要更严格类型语义的场景 |
.golangci.json |
JSON | 适合由工具或脚本自动生成的场景 |
4.2 .golangci.yml 配置详解
.golangci.yml 是 golangci-lint 的主配置文件,采用 v2 格式(当前最新主版本),控制 Linter 选择、运行行为、问题过滤与输出。
配置项说明:
| 配置项 | 类型 | 说明 |
|---|---|---|
version |
string | 配置格式版本,v2 写为 "2" |
run.timeout |
duration | 分析超时时间,大型项目建议 5m |
run.tests |
bool | 是否包含测试文件 |
run.relative-path-mode |
string | 路径基准:gomod/gitroot/cfg/wd |
linters.default |
string | 默认 linter 集合:standard/all/none/fast |
linters.enable |
string[] | 在默认集合基础上额外启用的 linter |
linters.disable |
string[] | 从默认集合中禁用的 linter |
linters.settings |
map | 各 linter 的专属配置,键为 linter 名 |
linters.exclusions.rules |
list | 排除规则,每项含 path(正则)和 linters(适用 linter 列表) |
linters.exclusions.presets |
string[] | 排除预设,如 std-error-handling、common-false-positives |
issues.max-issues-per-linter |
int | 单个 linter 最大告警数 |
issues.max-same-issues |
int | 同一告警最大重复次数 |
output.formats |
list | 输出格式列表,每项含 format 字段 |
output.sort-results |
bool | 是否对结果排序 |
severity.default-severity |
string | 默认严重性级别 |
severity.rules |
list | 严重性规则,按 linter 指定级别 |
formatters.enable |
string[] | 启用的格式化器(如 gofumpt) |
formatters.settings |
map | 格式化器专属配置 |
推荐配置示例:
以下配置适用于大多数 Go 项目,兼顾代码质量、安全性和实用性。每条规则均附说明。
# .golangci.yml - 推荐配置
# 适用于大多数 Go 项目的通用规则集
version: "2"
# ============================================================
# 运行选项
# ============================================================
run:
timeout: 5m # 分析超时时间,大型项目建议 5m
tests: true # 包含测试文件
relative-path-mode: gomod # 路径基于 go.mod 所在目录
# ============================================================
# Linter 配置
# ============================================================
linters:
# 使用 standard 默认集(包含 govet、errcheck、ineffassign、staticcheck、unused),
# 再额外启用推荐 linter
default: standard
enable:
# ---- 强烈推荐 ----
- gosimple # 简化代码建议(属于 staticcheck 套件)
- ineffassign # 检测无效赋值(赋值后未使用)
- typecheck # 类型检查(编译级别错误检测)
# ---- 代码质量 ----
- revive # golint 的替代品,可配置的代码风格检查
- gocritic # 高级代码质量检查(性能、风格、bug 检测)
- gosec # 安全问题检查(硬编码密码、SQL 注入、弱加密等)
- goconst # 检测重复字符串字面量,建议提取为常量
- gocognit # 认知复杂度检查,避免过于复杂的函数
- cyclop # 圈复杂度检查(函数和包级别)
# ---- 错误处理 ----
- errorlint # 检查错误处理是否符合 Go 1.13+ 的 wrapping 规范
- errname # 检查哨兵错误命名(Err 前缀)和错误类型命名(Error 后缀)
- wrapcheck # 检查外部包返回的 error 是否被 wrap
- nilerr # 检查 err != nil 后返回 nil error 的逻辑错误
- nilnil # 检查同时返回 nil interface 和 nil error 的问题
# ---- 代码风格 ----
- misspell # 拼写错误检查
- godot # 检查注释是否以句号结尾
- goprintffuncname # 检查 printf 风格函数是否以 f 结尾命名
- gofumpt # 更严格的 gofmt(gofmt 的扩展版)
- whitespace # 检查函数/控制结构前后不必要的空行
- tagalign # 检查 struct tag 对齐
- nolintlint # 检查 nolint 指令的规范性
# ---- 性能 ----
- prealloc # 检测可预分配的 slice
- unconvert # 移除不必要的类型转换
- perfsprint # 检查 fmt.Sprintf 是否可替换为更快的替代方案
- bodyclose # 检查 HTTP response body 是否正确关闭
- noctx # 检查 HTTP 请求是否携带 context
# ---- 测试 ----
- thelper # 检查测试辅助函数是否调用 t.Helper()
- tparallel # 检查 t.Parallel() 的正确使用
- testifylint # 检查 testify 库的正确使用
# ---- 现代 Go ----
- modernize # 建议使用现代 Go 语言特性简化代码
- exptostd # 检测可替换为标准库的 golang.org/x/exp 函数
- intrange # 检测可使用整数 range 的 for 循环
# ---- 不推荐启用的 linter(按需选择)----
disable:
- dupl # 代码重复检测(阈值难调,容易误报模板代码)
- lll # 行长度限制(纯风格偏好,不建议强制)
- funlen # 函数长度限制(与 gocognit/cyclop 功能重叠)
- gochecknoinits # 禁止 init 函数(部分场景合理使用 init)
- gochecknoglobals # 禁止全局变量(部分场景合理使用全局变量)
# ============================================================
# Linter 专属设置
# ============================================================
linters:
settings:
# errcheck: 错误检查配置
errcheck:
check-type-assertions: true # 检查类型断言的错误
check-blank: true # 检查赋值给空白标识符的错误
# revive: 代码风格检查配置
revive:
rules:
- name: exported # 导出符号必须有注释
severity: warning
- name: indent-error-flow # 错误处理缩进
severity: warning
- name: error-return # 错误返回规范
severity: warning
- name: var-naming # 变量命名规范
severity: warning
- name: context-as-argument # context 应作为第一个参数
severity: warning
# gocritic: 高级检查配置
gocritic:
enabled-tags:
- diagnostic # 诊断类检查
- performance # 性能类检查
- style # 风格类检查
- opinionated # 规范性检查
# gosec: 安全检查配置
gosec:
excludes:
- G104 # 排除"未检查的 error"(与 errcheck 重复)
# gocognit: 认知复杂度阈值
gocognit:
min-complexity: 15 # 函数认知复杂度不超过 15
# cyclop: 圈复杂度阈值
cyclop:
max-complexity: 15 # 函数圈复杂度不超过 15
package-average: 10 # 包平均圈复杂度不超过 10
# goconst: 重复字符串检测
goconst:
min-len: 3 # 最小字符串长度
min-occurrences: 3 # 最少出现次数
# misspell: 拼写检查
misspell:
locale: US # 使用美式英语
# nolintlint: nolint 指令规范检查
nolintlint:
allow-leading-space: false # 不允许 nolint 前有空格
allow-unused: true # 允许未使用的 nolint(过渡期可设为 false)
require-explanation: true # 要求 nolint 必须附带解释
require-specific: true # 要求 nolint 必须指定具体 linter
# ============================================================
# 排除规则(v2 格式)
# ============================================================
linters:
exclusions:
rules:
# 测试文件放宽部分规则
- path: _test\.go
linters:
- errcheck # 测试中允许忽略 error
- gosec # 测试中不检查安全问题
- gocognit # 测试中允许更高复杂度
- cyclop # 测试中允许更高复杂度
- wrapcheck # 测试中不要求 wrap error
- nilnil # 测试中允许 nil nil
# 生成代码放宽所有规则
- path: ".*(\\.gen\\.go|_string\\.go|\\.pb\\.go)$"
linters:
- all
# 排除预设
presets:
- std-error-handling # 标准库常见误报
- common-false-positives # 通用假阳性
# ============================================================
# 问题过滤
# ============================================================
issues:
max-issues-per-linter: 50
max-same-issues: 5
# ============================================================
# 严重性配置
# ============================================================
severity:
default-severity: warning
rules:
- linters:
- errcheck
- gosec
- nilerr
- nilnil
severity: error
# ============================================================
# Formatter 配置
# ============================================================
formatters:
enable:
- gofumpt # 更严格的 gofmt
settings:
gofumpt:
extra-rules: true # 启用额外格式化规则
4.3 各 Linter 分类说明
| 分类 | Linter | 说明 |
|---|---|---|
| 核心必开(standard 默认集) | govet | Go 官方静态分析,检查 printf 参数、shadow 变量、atomic 操作等 |
| 核心必开(standard 默认集) | errcheck | 检查未处理的 error 返回值,防止静默失败 |
| 核心必开(standard 默认集) | staticcheck | Go 生态最强大的静态分析,涵盖弃用 API、性能、简化建议等 |
| 核心必开(standard 默认集) | unused | 检测未使用的常量、变量、函数、类型和导入 |
| 核心必开(standard 默认集) | ineffassign | 检测赋值后从未使用的变量 |
| 代码质量 | gosimple | 代码简化建议(如 if x { return true } else { return false } 简化为 return x) |
| 代码质量 | revive | golint 替代品,可配置的代码风格检查(命名规范、导出注释等) |
| 代码质量 | gocritic | 高级检查:性能、风格、bug 检测,支持动态规则扩展 |
| 代码质量 | gocognit / cyclop | 复杂度检查,避免函数过于复杂难以维护 |
| 安全 | gosec | 安全漏洞扫描(硬编码密码、SQL 注入、弱加密、弱随机数等) |
| 错误处理 | errorlint | 检查 errors.New/fmt.Errorf 的使用是否符合 Go 1.13+ wrapping 规范 |
| 错误处理 | wrapcheck | 确保外部包返回的 error 被包装(添加上下文信息) |
| 错误处理 | nilerr / nilnil | 检查错误处理逻辑中的 nil 相关 bug |
| 性能 | prealloc | 建议预分配 slice 容量,减少内存分配次数 |
| 性能 | bodyclose | 确保 HTTP response body 被正确关闭,防止连接泄漏 |
| 性能 | noctx | 确保 HTTP 请求携带 context,支持超时和取消 |
| 性能 | perfsprint | 建议用更快的替代方案替换 fmt.Sprintf |
| 风格 | misspell | 检测常见英语拼写错误 |
| 风格 | gofumpt | 更严格的 gofmt(额外的格式化规则) |
| 风格 | tagalign | 检查 struct tag 的对齐格式 |
| 现代 Go | modernize | 建议使用现代 Go 特性(如 strings.Builder、slices 包等) |
| 规范 | nolintlint | 检查 nolint 指令是否规范(是否带解释、是否指定具体 linter) |
5. 主流集成方式
增量检查使用建议:
| 场景 | 推荐方式 |
|---|---|
| 本地开发快速检查 | --new 或 --new-from-rev=HEAD~1 |
| CI/CD PR 检查 | golangci-lint-action + only-new-issues: true |
| 大型项目渐进式引入 | --new-from-merge-base=main |
| 需要完整文件级检查 | --new-from-rev=xxx --whole-files |
注意:增量检查要求工作区干净(无未提交更改),且基准 commit 必须可达。增量检查与
--fast-only不兼容,因为需要完整的类型检查。
5.1 Go toolchain / go install(生态主流)
Go 项目的主流集成方式是通过 go install 安装 golangci-lint,在 Makefile 中定义 lint target,并在 CI 中调用。
# 安装最新版
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
# 安装指定版本
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2
Makefile 集成
# Makefile
GOLANGCI_LINT_VERSION := v2.12.2
.PHONY: lint
lint:
golangci-lint run --timeout=5m
.PHONY: lint-fix
lint-fix:
golangci-lint run --fix --timeout=5m
.PHONY: lint-install
lint-install:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | \
sh -s -- -b $(shell go env GOPATH)/bin $(GOLANGCI_LINT_VERSION)
5.2 pre-commit 集成
golangci-lint 官方仓库自带 .pre-commit-hooks.yaml,可作为 pre-commit hook 使用。适合作为本地开发阶段的补充门禁;Go 项目仍应以 Go toolchain、Makefile 和 CI 中的 golangci-lint run 作为主入口。
依赖说明:使用
language: system,要求本地已安装 golangci-lint 二进制文件。可通过repo: https://github.com/golangci/golangci-lint配合rev锁定版本。
# .pre-commit-config.yaml
repos:
- repo: https://github.com/golangci/golangci-lint
rev: v2.12.2
hooks:
- id: golangci-lint
args:
- --fix
安装 pre-commit hooks:
# 安装 pre-commit(如尚未安装)
pip install pre-commit
# 在项目根目录安装 hooks
pre-commit install
# 手动运行所有 hooks
pre-commit run --all-files
参考:安装指南
增量检查:当通过 pre-commit local hook 集成 golangci-lint 时,pre-commit 框架默认只对暂存区中变更的 .go 文件触发 hook。由于 golangci-lint 的 local hook 使用 pass_filenames: false(golangci-lint 自行管理检查范围),实际增量由 golangci-lint 的 --new-from-rev 参数决定。两种方式配合使用:
# .pre-commit-config.yaml
- repo: local
hooks:
- id: golangci-lint
name: golangci-lint
entry: golangci-lint run --new-from-rev=HEAD
language: system
files: \.go$
pass_filenames: false # 由 --new-from-rev 控制增量
pre-commit 负责"何时触发"(只在有 .go 文件变更时),
--new-from-rev=HEAD负责"检查什么"(只报告自上一个提交以来新增的问题)。CI 中可将entry改为golangci-lint run(全量)或golangci-lint run --new-from-rev=origin/main(PR 级增量),配合pre-commit run --all-files执行。
5.3 IDE 集成
VS Code
在 settings.json 中配置:
{
"go.lintTool": "golangci-lint",
"go.lintFlags": ["--fast-only"],
"go.lintOnSave": "file"
}
注意:VS Code 的 Go 扩展会自动查找项目中的
.golangci.yml配置文件,无需额外指定路径。
GoLand
GoLand 内置了 golangci-lint 集成支持(通过 Go Linter 插件,默认启用):
- 打开 Settings > Tools > Go Linter
- 选择 golangci-lint 可执行文件路径(或使用 Get Latest 自动下载)
- 如项目中有
.golangci.yml,插件会自动检测并使用
Vim/Neovim
使用 ALE 配置:
" ALE 配置
let g:ale_linters = {'go': ['golangci-lint']}
let g:ale_go_golangci_lint_options = '--fast-only'
使用 LSP 配置(通过 null-ls 或 none-ls):
-- null-ls 配置示例
local null_ls = require("null-ls")
null_ls.setup({
sources = {
null_ls.builtins.diagnostics.golangci_lint.with({
extra_args = { "--fast-only" },
}),
},
})
5.4 命令行使用方式
# 基本运行(检查当前目录及子目录)
golangci-lint run
# 检查指定路径
golangci-lint run ./pkg/...
golangci-lint run ./internal/... ./cmd/...
# 检查指定文件
golangci-lint run main.go
# 自动修复可修复的问题
golangci-lint run --fix
# 启用/禁用特定 linter
golangci-lint run --enable gosec,govet
golangci-lint run --disable errcheck
# 仅运行快速 linter(跳过耗时分析)
golangci-lint run --fast-only
# 设置超时时间(大型项目建议 5m)
golangci-lint run --timeout=5m
# 查看当前配置启用了哪些 linter
golangci-lint linters
# 查看所有可用 linter(含默认启用/禁用状态)
golangci-lint help linters
# 验证配置文件是否有效
golangci-lint config verify
# 指定配置文件
golangci-lint run --config=.golangci.yml
# 指定输出格式
golangci-lint run --out-format=json
golangci-lint run --out-format=github-actions
# 格式化代码(使用内置 formatter)
golangci-lint fmt
增量检查:golangci-lint 提供多种原生增量参数,也支持基于 Git 手动筛选变更文件。
--new(自动检测工作区变更)
自动检测工作区状态,只分析未暂存的更改或未跟踪的文件:
golangci-lint run --new
注意:如果 CI 脚本在运行 golangci-lint 之前生成了未暂存的文件,
--new可能只指向这些文件而非最新提交。此时推荐使用--new-from-rev或--new-from-patch。
--new-from-rev(指定基准版本)
指定一个 Git 修订版本,只检查该版本之后引入的问题:
# 本地开发:检查相对于上一个 commit 的变更
golangci-lint run --new-from-rev=HEAD~1
# CI 环境:检查相对于 base 分支的变更
golangci-lint run --new-from-rev=origin/main
--new-from-merge-base(基于 merge-base)
找到与当前分支的最佳共同祖先,只检查之后引入的变更:
golangci-lint run --new-from-merge-base=main
--new-from-patch(基于补丁文件)
基于 Git 补丁文件只检查补丁中引入的变更:
golangci-lint run --new-from-patch=changes.patch
--whole-files(整文件检查)
当 --new-from-xxx 选项无法正确关联问题行与变更行时,可配合 --whole-files 对包含变更的整个文件进行检查:
golangci-lint run --new-from-rev=origin/main --whole-files
基于 Git 的命令行增量方案
对于需要手动筛选变更文件并传给 golangci-lint 的场景:
# 获取新增或修改的 Go 文件(排除删除的文件)
git diff --name-only --diff-filter=ACMR HEAD~1 -- '*.go' | xargs golangci-lint run
# 获取暂存区的变更文件
git diff --cached --name-only --diff-filter=ACMR -- '*.go' | xargs golangci-lint run
CI 脚本调用:
GitLab CI
# .gitlab-ci.yml
golangci-lint:
image: golang:1.24
stage: test
before_script:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.12.2
script:
- golangci-lint run --timeout=5m --out-format=gitlab-code-quality > gl-codequality-report.json
artifacts:
reports:
code_quality: gl-codequality-report.json
GitLab CI(增量)
golangci-lint:
image: golang:1.24
stage: test
before_script:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.12.2
script:
- golangci-lint run --new-from-rev=$CI_MERGE_REQUEST_DIFF_BASE_SHA --timeout=5m
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
5.5 GitHub Action 插件
官方 golangci-lint-action 当前最新主版本为 v9。
# .github/workflows/lint.yml
name: golangci-lint
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
golangci-lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.12.2
args: --timeout=5m
# 只检查新代码(PR 场景推荐)
# only-new-issues: true
增量检查:CI/CD 场景下可通过 only-new-issues 或 --new-from-rev 实现增量检查。官方 golangci-lint-action 内置了 only-new-issues 选项,自动通过 GitHub API 获取 PR diff 并使用 --new-from-patch:
# .github/workflows/lint.yml
name: golangci-lint
on:
pull_request:
permissions:
contents: read
pull-requests: read # only-new-issues 需要 PR 读取权限
jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: stable
- uses: golangci/golangci-lint-action@v9
with:
version: v2.12.2
only-new-issues: true
GitHub Actions(增量:手动指定 base revision)
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.12.2
args: --new-from-rev=origin/main --timeout=5m
6. 告警抑制(屏蔽)方法
golangci-lint 提供了多层次的告警抑制机制,从代码级到配置级均可控制。
6.1 通过代码注释屏蔽(nolint 指令)
在代码中使用 //nolint 注释屏蔽特定行或代码块的检查。
行级注释屏蔽:
var badName int //nolint:revive // 屏蔽指定 linter
屏蔽多个 linter:
var badName int //nolint:revive,govet // 屏蔽多个 linter
屏蔽所有 linter:
var badName int //nolint:all // 屏蔽所有 linter(不推荐)
函数级屏蔽:
//nolint:errcheck // 屏蔽整个函数的 errcheck 检查
func oldFunction() error {
_ = doSomething()
return nil
}
文件级注释屏蔽:
//nolint:unparam // 文件顶部放置,屏蔽整个文件的 unparam 检查
package mypackage
带解释的屏蔽(推荐):
var legacyKey int //nolint:gosec // G101: legacy config key, migration planned
启用 nolintlint linter 可以检查 nolint 指令的规范性(如是否带解释、是否指向有效 linter)。
6.2 通过配置文件排除规则(linters.exclusions)
在 .golangci.yml 中通过 linters.exclusions.rules 按路径、linter、文本模式排除问题(v2 配置格式):
linters:
exclusions:
rules:
# 按文件路径排除
- path: _test\.go
linters:
- errcheck # 测试文件允许忽略 error
- gosec # 测试文件不检查安全问题
- gocognit # 测试文件允许更高认知复杂度
# 按路径前缀排除(生成代码)
- path: (\.gen\.go|pb/|generated/)
linters:
- all
# 按文本内容排除
- text: "should have a package comment"
linters:
- revive
# 按源码内容排除
- source: "^//go:generate "
linters:
- lll
# 按文件路径排除(简单模式)
paths:
- ".*\\.gen\\.go$"
- third_party/
# 排除预设
presets:
- comments
- std-error-handling
- common-false-positives
- legacy
参考:排除规则官方文档
6.3 通过禁用特定 Linter
在 .golangci.yml 中完全禁用某个 linter:
linters:
disable:
- dupl # 代码重复检测(阈值难调,易误报)
- lll # 行长度限制(纯风格偏好)
- gochecknoinits # 允许使用 init 函数
参考:linters 配置文档
6.4 通过禁用特定规则(Linter 级别 settings)
部分 linter 支持禁用其内部特定规则:
linters:
settings:
# staticcheck 禁用特定规则
staticcheck:
checks: ["all", "-SA1019", "-SA4006"]
# govet 禁用特定检查
govet:
disable:
- shadow
# revive 禁用特定规则
revive:
rules:
- name: exported
disabled: true
6.5 通过命令行参数屏蔽
# 禁用特定 linter
golangci-lint run --disable errcheck,gosec
# 设置最大问题数(超过后停止分析)
golangci-lint run --max-issues-per-linter=50 --max-same-issues=5
# 指定默认 linter 集合
golangci-lint run --default=none --enable govet,errcheck
参考:CLI 参数文档
6.6 通过集成调度工具屏蔽
pre-commit 的文件匹配
pre-commit 框架可通过 hook 级别的 files 和 exclude 限制检查范围:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/golangci/golangci-lint
rev: v2.12.2
hooks:
- id: golangci-lint
files: \.go$ # 只检查 .go 文件
exclude: ^vendor/ # 排除 vendor 目录
args:
- --fast-only
GitHub Actions 路径过滤
在 workflow 级别通过 paths 过滤触发条件:
on:
pull_request:
paths:
- "**.go"
- "go.mod"
- "go.sum"
- ".golangci.yml"
相关工具推荐
- Gosec -- Go 语言安全漏洞扫描工具(已集成到 golangci-lint 中作为
goseclinter) - Gofmt / Gofumpt -- Go 官方代码格式化工具(已集成到 golangci-lint 中作为 formatter)
- Govet -- Go 官方静态分析工具(已集成到 golangci-lint 中作为
govetlinter) - Pre-commit -- 通用 Git hooks 框架,可与 golangci-lint 配合使用