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 精细控制测试文件和示例代码的排除规则

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

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 适合由工具或脚本自动生成的场景

参考:配置文件文档、完整配置参考文件 .golangci.reference.yml

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 插件,默认启用):

  1. 打开 Settings > Tools > Go Linter
  2. 选择 golangci-lint 可执行文件路径(或使用 Get Latest 自动下载)
  3. 如项目中有 .golangci.yml,插件会自动检测并使用

参考:GoLand 配置 golangci-lint

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

参考:CLI 参数文档 --new 相关选项

基于 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

参考:golangci-lint-action 使用文档

增量检查: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

参考:nolint 指令官方文档

启用 nolintlint linter 可以检查 nolint 指令的规范性(如是否带解释、是否指向有效 linter)。

参考:nolintlint 配置

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

参考:Linter Settings 文档

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 中作为 gosec linter)
  • Gofmt / Gofumpt -- Go 官方代码格式化工具(已集成到 golangci-lint 中作为 formatter)
  • Govet -- Go 官方静态分析工具(已集成到 golangci-lint 中作为 govet linter)
  • Pre-commit -- 通用 Git hooks 框架,可与 golangci-lint 配合使用

← 返回目录 | ← 返回总览