setup-golangci-lint
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesegolangci-lint Environment Setup
golangci-lint 环境搭建
Quickly set up a complete golangci-lint environment for Go projects.
Core Principle: Make existing code pass lint by adjusting configuration, do not modify existing code. Only affects new code.
为Go项目快速搭建完整的golangci-lint环境。
核心原则:通过调整配置让现有代码通过lint检查,不要修改现有代码。仅对新代码生效。
When to Use
适用场景
- Initializing Go projects and need to add linter
- Adding code quality checks to existing projects
- Integrating lint into CI/CD workflows
- 初始化Go项目时需要添加代码检查工具
- 为现有项目增加代码质量检查
- 将lint检查集成到CI/CD工作流中
Execution Flow
执行流程
1. Detect Environment
1. 环境检测
bash
undefinedbash
undefinedCheck Go version in go.mod (priority)
优先检查go.mod中的Go版本
cat go.mod | grep "^go "
cat go.mod | grep "^go "
Check system Go version (reference)
检查系统中的Go版本(参考用)
go version
go version
Check for existing configuration (supports 4 formats)
检查是否存在现有配置(支持4种格式)
ls .golangci.* 2>/dev/null || echo "No config"
ls .golangci.* 2>/dev/null || echo "无配置文件"
Check CI configuration
检查CI配置
ls .gitlab-ci.yml .github/workflows/*.yml .circleci/config.yml 2>/dev/null
ls .gitlab-ci.yml .github/workflows/*.yml .circleci/config.yml 2>/dev/null
Check for Makefile
检查是否存在Makefile
ls Makefile 2>/dev/null && echo "Has Makefile" || echo "No Makefile"
undefinedls Makefile 2>/dev/null && echo "存在Makefile" || echo "无Makefile"
undefined2. Select Version
2. 版本选择
Select based on Go version in :
go.mod| go.mod Version | golangci-lint Version |
|---|---|
| < 1.20 | v1.x |
| >= 1.20 | v2.x (recommended) |
根据中的Go版本选择对应的golangci-lint版本:
go.mod| go.mod版本 | golangci-lint版本 |
|---|---|
| < 1.20 | v1.x |
| >= 1.20 | v2.x(推荐) |
3. Install
3. 安装
bash
undefinedbash
undefinedv2 (recommended)
v2版本(推荐)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
v1
v1版本
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.59.1
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.59.1
Verify
验证安装
$(go env GOPATH)/bin/golangci-lint --version
undefined$(go env GOPATH)/bin/golangci-lint --version
undefined3.5. Configuration Migration (when v1 config exists)
3.5. 配置迁移(当存在v1版本配置时)
If the project already has in v1 format, use the auto-migration tool:
.golangci.ymlbash
undefined如果项目已有v1格式的,使用自动迁移工具:
.golangci.ymlbash
undefinedAutomatically migrate v1 config to v2 format
自动将v1配置迁移为v2格式
$(go env GOPATH)/bin/golangci-lint migrate --skip-validation
$(go env GOPATH)/bin/golangci-lint migrate --skip-validation
Notes:
注意事项:
--skip-validation: Skip validation, convert directly (recommended)
--skip-validation: 跳过验证,直接转换(推荐)
migrate command will automatically:
migrate命令会自动执行以下操作:
- Add version: 2
- 添加version: 2字段
- Convert enable-all/disable-all to linters.default
- 将enable-all/disable-all转换为linters.default
- Change linters-settings to linters.settings
- 将linters-settings改为linters.settings
- Change issues.exclude-rules to linters.exclusions.rules
- 将issues.exclude-rules改为linters.exclusions.rules
After migration, manually check the configuration to ensure:
- `linters.default` value meets expectations (standard/all/none/fast)
- Disabled linters still have `# TODO fix later by human` comments
- Complexity thresholds are raised and marked with `# TODO reduce this`
迁移完成后,手动检查配置以确保:
- `linters.default`的值符合预期(standard/all/none/fast)
- 已禁用的linters仍保留`# TODO 后续人工修复`注释
- 复杂度阈值已调高并标记`# TODO 后续降低此阈值`4. Create Configuration
4. 创建配置
Skip this step if already exists.
.golangci.yml📌 AI Operation Requirements:
Must first visit official documentation to confirm latest format: https://golangci-lint.run/docs/configuration/file/ Core Principle: Do not modify existing code, only make code pass by adjusting configuration (settings/disable/exclusions) Formatters Handling:
- First run
andgofmt -l .to check code formatgoimports -l .- If both have no output → enable formatters (uncomment)
- If has output → keep commented, add
above# TODO format code and enable - X files currently non-compliant Workflow: Create minimal config → Run lint → Categorize and handle → Add standardized TODO comments Universal Classification Logic (based on keywords in linter description):Step 1: Get linter descriptionbash$(go env GOPATH)/bin/golangci-lint help <linter-name>Step 2: Categorize based on keywords in description
Category Keywords in Description Action Example Linters & Descriptions a. Configurable complexity, long, deeply, count, length, size, max, min, limit Adjust settings funlen: "Checks for long functions"<br>gocyclo: "Checks cyclomatic complexity"<br>nestif: "Reports deeply nested if"<br>dogsled: "Checks too many blank identifiers" b. Code Style-Manual Confirm style, format, naming, whitespace, align, order, declaration disable + TODO godot: "Check if comments end in period"<br>tagalign: "Check struct tags well aligned"<br>misspell: "Finds commonly misspelled"<br>varnamelen: "Checks variable name length" c. Critical Bugs-Suggest Fix bug, security, error, check, nil, unsafe, detect, inspects disable + TODO errcheck: "Checking for unchecked errors"<br>gosec: "Inspects source code for security"<br>staticcheck: "set of rules from staticcheck"<br>nilerr: "returns nil even if error is not nil" d. Cannot Modify (check specific error message, usually involves external constraints) exclusions canonicalheader: HTTP header spec (3rd-party APIs)<br>asciicheck: Non-ASCII symbols (Chinese function names) e. Can Fix Small (determined by actual issue count, < 5) exclude-rules Any linter with few issues f. New Features-Defer modern, new, latest, replace, simplification, feature disable + TODO modernize: "suggest simplifications using modern language"<br>exptostd: "replaced by std functions"<br>usestdlibvars: "use variables from standard library" Step 3: Complete Decision Tree1. Issue count < 5? ├── Yes → Category e (can fix small): exclude-rules └── No → Continue 2. Description has complexity/long/deeply/max/min/limit/length? ├── Yes → Category a (configurable): Prioritize adjusting settings └── No → Continue 3. Specific error caused by external constraints (3rd-party APIs/generated code/Chinese naming)? ├── Yes → Category d (cannot modify): exclusions path exclusion └── No → Continue 4. Description has modern/new/latest/replace/std/simplification? ├── Yes → Category f (new features-defer): disable + TODO └── No → Continue 5. Description has bug/security/error/check/nil/unsafe/detect/inspects? ├── Yes → Category c (critical bugs-suggest fix): disable + TODO └── No → Category b (code style-manual confirm): disable + TODOExample Demonstrations:
Linter Description Keywords Category cyclop "Checks function complexity" complexity a gocritic "checks for bugs, performance and style" bugs (priority) c revive "replacement of golint" (no clear keywords) b bodyclose "Checks whether response body is closed successfully" error/check c goconst "Finds repeated strings that could be replaced by a constant" (style) b fatcontext "Detects nested contexts" nested → complexity a Configuration Priority:
- 1st Priority: Adjust
thresholds (e.g., funlen.lines, gocyclo.min-complexity)settings- 2nd Priority: Use
path exclusion (code that cannot be modified)linters.exclusions- 3rd Priority: Use
rule-based exclusion (specific few issues)issues.exclude-rules- Last Resort: Completely
(many issues and cannot be resolved via config)disable Avoid Duplicates: Each linter appears only once, check for duplicates
v2 Minimal Configuration Template (.golangci.yml)
yaml
version: "2"
run:
concurrency: 4
timeout: 5m
skip-dirs: [vendor, third_party, testdata, examples, gen-go]
tests: true
output:
format: colored-line-number
print-linter-name: true
linters:
default: all
formatters:
enable:
# TODO format code and enable - 17 files currently non-compliant with goimports
# - gofmt
# - goimportsFormatters Handling: First runandgofmt -l .to check, uncomment to enable if both have no output.goimports -l .
Notes:
- Start with minimal configuration, no preset disable
- After running, gradually add
anddisablebased on errorsexclusions- Common linters that need adjustment (add as needed):
(magic numbers) → style issues, can be permanently ignoredmnd (whitespace) → style issues, can be permanently ignoredwsl (line length) → style issues, can be permanently ignoredlll → error handling, temporarily ignore and mark TODOerr113
v1 Configuration Template (.golangci.yml)
Note: v1 does not requirefield. v2 is recommended.version
yaml
run:
concurrency: 4
timeout: 5m
skip-dirs: [vendor, testdata]
linters:
enable-all: trueAfter running, addanddisablebased on errors.exclude-rules
如果已存在,请跳过此步骤。
.golangci.yml📌 AI操作要求:
必须先访问官方文档确认最新格式:https://golangci-lint.run/docs/configuration/file/ 核心原则:不要修改现有代码,仅通过调整配置(设置/禁用/排除规则)让代码通过检查 格式化工具处理:
- 先运行
和gofmt -l .检查代码格式goimports -l .- 如果两者都无输出 → 启用格式化工具(取消注释)
- 如果有输出 → 保持注释状态,并在上方添加
# TODO 格式化代码后启用 - 目前有X个文件不符合规范 工作流程:创建最小配置 → 运行lint检查 → 分类处理问题 → 添加标准化TODO注释 通用分类逻辑(基于linter描述中的关键词):步骤1:获取linter描述bash$(go env GOPATH)/bin/golangci-lint help <linter-name>步骤2:根据描述中的关键词分类
分类 描述中的关键词 操作 示例Linter及描述 a. 可配置型 complexity, long, deeply, count, length, size, max, min, limit 调整设置 funlen: "检查过长的函数"<br>gocyclo: "检查圈复杂度"<br>nestif: "报告嵌套过深的if语句"<br>dogsled: "检查过多的空白标识符" b. 代码风格-人工确认 style, format, naming, whitespace, align, order, declaration 禁用 + TODO godot: "检查注释是否以句号结尾"<br>tagalign: "检查结构体标签是否对齐良好"<br>misspell: "查找常见的拼写错误"<br>varnamelen: "检查变量名长度" c. 严重Bug-建议修复 bug, security, error, check, nil, unsafe, detect, inspects 禁用 + TODO errcheck: "检查未处理的错误"<br>gosec: "检查源代码中的安全问题"<br>staticcheck: "来自staticcheck的规则集"<br>nilerr: "即使存在错误仍返回nil" d. 不可修改型 (根据具体错误信息判断,通常涉及外部约束) 排除规则 canonicalheader: HTTP头规范(第三方API要求)<br>asciicheck: 非ASCII符号(中文函数名) e. 小问题可修复 (根据实际问题数量判断,少于5个) 排除规则 任何问题数量少的linter f. 新特性-延后处理 modern, new, latest, replace, simplification, feature 禁用 + TODO modernize: "建议使用现代语言特性进行简化"<br>exptostd: "被标准库函数替代"<br>usestdlibvars: "使用标准库中的变量" 步骤3:完整决策树1. 问题数量 < 5? ├── 是 → 分类e(小问题可修复):使用exclude-rules └── 否 → 继续 2. 描述中包含complexity/long/deeply/max/min/limit/length? ├── 是 → 分类a(可配置型):优先调整设置 └── 否 → 继续 3. 特定错误由外部约束导致(第三方API/生成代码/中文命名)? ├── 是 → 分类d(不可修改型):使用路径排除 └── 否 → 继续 4. 描述中包含modern/new/latest/replace/std/simplification? ├── 是 → 分类f(新特性-延后处理):禁用 + TODO └── 否 → 继续 5. 描述中包含bug/security/error/check/nil/unsafe/detect/inspects? ├── 是 → 分类c(严重Bug-建议修复):禁用 + TODO └── 否 → 分类b(代码风格-人工确认):禁用 + TODO示例演示:
Linter 描述 关键词 分类 cyclop "检查函数复杂度" complexity a gocritic "检查Bug、性能和风格问题" bugs(优先) c revive "golint的替代工具" 无明确关键词 b bodyclose "检查响应体是否成功关闭" error/check c goconst "查找可替换为常量的重复字符串" style b fatcontext "检测嵌套的context" nested → complexity a 配置优先级:
- 最高优先级:调整
阈值(如funlen.lines、gocyclo.min-complexity)settings- 次优先级:使用
路径排除(无法修改的代码)linters.exclusions- 第三优先级:使用
规则排除(特定少量问题)issues.exclude-rules- 最后手段:完全
(大量问题且无法通过配置解决)disable 避免重复:每个linter仅出现一次,检查是否有重复项
v2版本最小配置模板(.golangci.yml)
yaml
version: "2"
run:
concurrency: 4
timeout: 5m
skip-dirs: [vendor, third_party, testdata, examples, gen-go]
tests: true
output:
format: colored-line-number
print-linter-name: true
linters:
default: all
formatters:
enable:
# TODO 格式化代码后启用 - 目前有17个文件不符合goimports规范
# - gofmt
# - goimports格式化工具处理:先运行和gofmt -l .检查,若两者都无输出则取消注释启用。goimports -l .
注意:
- 从最小配置开始,不预设禁用项
- 运行检查后,根据错误信息逐步添加
和disableexclusions- 常见需要调整的linter(按需添加):
(魔法数字)→ 风格问题,可永久忽略mnd (空白符)→ 风格问题,可永久忽略wsl (行长度)→ 风格问题,可永久忽略lll → 错误处理,暂时忽略并标记TODOerr113
v1版本配置模板(.golangci.yml)
注意:v1版本不需要字段。推荐使用v2版本。version
yaml
run:
concurrency: 4
timeout: 5m
skip-dirs: [vendor, testdata]
linters:
enable-all: true运行检查后,根据错误信息添加和disable。exclude-rules
5. Integrate CI
5. 集成CI
GitLab CI
yaml
lint:
stage: test
image: golang:1.23-alpine
script:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
- $(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...GitHub Actions
yaml
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latestGitLab CI
yaml
lint:
stage: test
image: golang:1.23-alpine
script:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
- $(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...GitHub Actions
yaml
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest6. Update Makefile (Optional)
6. 更新Makefile(可选)
makefile
lint: ## Run lint check
golangci-lint run --timeout=5m ./...
lint-fix: ## Auto-fix issues
golangci-lint run --fix --timeout=5m ./...makefile
lint: ## 运行lint检查
golangci-lint run --timeout=5m ./...
lint-fix: ## 自动修复问题
golangci-lint run --fix --timeout=5m ./...7. Run and Adjust as Needed
7. 运行并按需调整
bash
undefinedbash
undefinedRun lint
运行lint检查
$(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...
> **Important**: Resolve issues by adjusting configuration, **do not modify existing code**.
**Analyze Based on Error Output**:
1. **Linter Name Errors** (e.g., `unknown linters`):
```bash
# View supported linters
$(go env GOPATH)/bin/golangci-lint help linters- →
gomndmnd - →
goerr113err113 - → removed
execinquery
-
Configuration Format Errors:
- needs map format, not list
output.formats - Use singular form
output.format
-
Adjust Configuration Based on Actual Errors:Configuration Priority (try in order):
Priority Action Use Case 1️⃣ Highest Adjust thresholdssettingsLinters with config options for complexity/length 2️⃣ Second path exclusionlinters.exclusionsCode that cannot be modified (generated/3rd-party) 3️⃣ Then rule exclusionissues.exclude-rulesSpecific few issues 4️⃣ Last completelydisableMany issues and no config options Category a: Configurable (Prioritize adjusting settings)yamllinters: settings: # Complexity linters: Prioritize adjusting thresholds rather than completely disabling funlen: lines: 100 # Default 60, raised to accommodate existing code statements: 60 # Default 40 gocyclo: min-complexity: 25 # Default 15 gocognit: min-complexity: 30 # Default 15 nestif: min-complexity: 8 # Default 5 # If still have issues after adjusting thresholds, then consider disableCategory b: Code Style-Manual Confirmyamllinters: disable: # TODO code style-confirm whether to disable: Does not affect functionality, requires manual confirmation - mnd # 47 issues: magic numbers, style issues - wsl # 39 issues: whitespace, deprecated, replaced by wsl_v5 - wsl_v5 # 50 issues: whitespace v5, code style - lll # 46 issues: line length limit, style issues - godot # 3 issues: comment period - tagalign # 12 issues: struct tag alignment - tagliatelle # 50 issues: struct tag naming convention - whitespace # 3 issues: whitespace issues - goconst # 7 issues: constant extraction suggestion - prealloc # 2 issues: pre-allocate slice suggestion - nakedret # 1 issue: naked return - nlreturn # 9 issues: blank line before return - inamedparam # 1 issue: named parameter - varnamelen # 23 issues: variable name length - nonamedreturns # 2 issues: named return values - paralleltest # 47 issues: parallel test suggestion - testpackage # 3 issues: test package naming - testifylint # 3 issues: testify usage convention - ireturn # 4 issues: interface return - intrange # 3 issues: int range loop - nilnil # 3 issues: nil interface - nilnesserr # 3 issues: nil error check - noinlineerr # 3 issues: inline error - gosmopolitan # 3 issues: internationalization - usestdlibvars # 1 issue: standard library constants - unparam # 1 issue: unused parameter - perfsprint # 9 issues: performance print suggestionCategory c: Critical Bugs-Suggest Fixyamllinters: disable: # TODO critical bugs-suggest fix: Security and error handling issues, recommend gradual fixes - errcheck # 13 issues: unchecked errors - gosec # 10 issues: security checks - staticcheck # 8 issues: static analysis - rowserrcheck # 3 issues: database rows.Err check - errchkjson # 4 issues: JSON error check - errorlint # 1 issue: error handling convention - errname # 2 issues: error variable naming - wrapcheck # 44 issues: error wrapping - noctx # 3 issues: context parameter check - forcetypeassert # 2 issues: force type assertion - contextcheck # 4 issues: context passing check - nilerr # nil error check - govet # 1 issue: vet check - unused # 16 issues: unused variables/packages - err113 # 21 issues: dynamic error definition - ineffassign # 1 issue: ineffective assignment - sqlclosecheck # 3 issues: SQL not closed check - wastedassign # 2 issues: wasted assignmentCategory d: Cannot Modify (Path Exclusion)yamllinters: exclusions: rules: # Generated code (cannot modify) - path: \.pb\.go|\.gen\.go|\.gen-\w+\.go|\.mock\.go linters: [all] # Third-party dependencies (cannot modify) - path: vendor/|third_party/ linters: [all] # Example code (optionally modifiable) - path: examples/ linters: [all] issues: exclude-rules: # Third-party APIs (cannot modify) - text: "non-canonical header" linters: [canonicalheader] # Chinese function names (business requirement, cannot modify) - text: "ID.*must match" linters: [asciicheck] # Internal project using internal packages (business requirement) - text: "import of package" linters: [depguard]Category e: Can Fix Small (Few Specific Issues)yamlissues: exclude-rules: # Specific business scenarios (cannot modify) - text: "G101: potential hardcoded credential" path: config/.*\.go linters: [gosec] # Relax for test files - path: _test\.go linters: [errcheck, gosec, contextcheck] # Relax for main function - path: cmd/ linters: [gocyclo, funlen, errcheck]Category f: New Features-Deferyamllinters: disable: # TODO new features-defer: Does not affect current code, can be selectively enabled later - modernize # 12 issues: modern Go syntax suggestions - revive # 48 issues: revive ruleset - gocritic # 10 issues: code style suggestions - godoclint # 3 issues: godoc format - gomoddirectives # module directive check - dogsled # blank identifier count - embeddedstructfieldcheck # 2 issues: embedded field blank lines - exhaustruct # 49 issues: struct field completeness - forbidigo # 6 issues: forbid specific functions - gochecknoglobals # 15 issues: global variable check - gochecknoinits # 2 issues: init function check - godox # 2 issues: TODO/FIXME markers - nolintlint # 1 issue: nolint comment check
Goal: Existing code passes lint, do not modify existing code, new code must follow rules.
$(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...
> **重要提示**:通过调整配置解决问题,**不要修改现有代码**。
**根据错误输出分析处理**:
1. **Linter名称错误**(如`unknown linters`):
```bash
# 查看支持的linter列表
$(go env GOPATH)/bin/golangci-lint help linters- →
gomndmnd - →
goerr113err113 - → 已移除
execinquery
-
配置格式错误:
- 需要map格式,而非列表
output.formats - 使用单数形式
output.format
-
根据实际错误调整配置:配置优先级(按顺序尝试):
优先级 操作 适用场景 1️⃣ 最高 调整 阈值settings支持复杂度/长度配置的linter 2️⃣ 次高 路径排除linters.exclusions无法修改的代码(生成代码/第三方代码) 3️⃣ 第三 规则排除issues.exclude-rules特定少量问题 4️⃣ 最后 完全 disable大量问题且无配置选项的linter 分类a:可配置型(优先调整设置)yamllinters: settings: # 复杂度相关linter:优先调整阈值而非完全禁用 funlen: lines: 100 # 默认60,调高以适配现有代码 statements: 60 # 默认40 gocyclo: min-complexity: 25 # 默认15 gocognit: min-complexity: 30 # 默认15 nestif: min-complexity: 8 # 默认5 # 调整阈值后仍有问题,再考虑禁用分类b:代码风格-人工确认yamllinters: disable: # TODO 代码风格-确认是否禁用:不影响功能,需人工确认 - mnd # 47个问题:魔法数字,风格问题 - wsl # 39个问题:空白符,已废弃,被wsl_v5替代 - wsl_v5 # 50个问题:空白符v5,代码风格 - lll # 46个问题:行长度限制,风格问题 - godot # 3个问题:注释句号 - tagalign # 12个问题:结构体标签对齐 - tagliatelle # 50个问题:结构体标签命名规范 - whitespace # 3个问题:空白符问题 - goconst # 7个问题:常量提取建议 - prealloc # 2个问题:切片预分配建议 - nakedret # 1个问题:裸返回 - nlreturn # 9个问题:return前空行 - inamedparam # 1个问题:命名参数 - varnamelen # 23个问题:变量名长度 - nonamedreturns # 2个问题:命名返回值 - paralleltest # 47个问题:并行测试建议 - testpackage # 3个问题:测试包命名 - testifylint # 3个问题:testify使用规范 - ireturn # 4个问题:接口返回 - intrange # 3个问题:整数范围循环 - nilnil # 3个问题:nil接口 - nilnesserr # 3个问题:nil错误检查 - noinlineerr # 3个问题:内联错误 - gosmopolitan # 3个问题:国际化 - usestdlibvars # 1个问题:标准库常量 - unparam # 1个问题:未使用参数 - perfsprint # 9个问题:打印性能建议分类c:严重Bug-建议修复yamllinters: disable: # TODO 严重Bug-建议修复:安全和错误处理问题,建议逐步修复 - errcheck # 13个问题:未处理错误 - gosec # 10个问题:安全检查 - staticcheck # 8个问题:静态分析 - rowserrcheck # 3个问题:数据库rows.Err检查 - errchkjson # 4个问题:JSON错误检查 - errorlint # 1个问题:错误处理规范 - errname # 2个问题:错误变量命名 - wrapcheck # 44个问题:错误包装 - noctx # 3个问题:context参数检查 - forcetypeassert # 2个问题:强制类型断言 - contextcheck # 4个问题:context传递检查 - nilerr # nil错误检查 - govet # 1个问题:vet检查 - unused # 16个问题:未使用变量/包 - err113 # 21个问题:动态错误定义 - ineffassign # 1个问题:无效赋值 - sqlclosecheck # 3个问题:SQL未关闭检查 - wastedassign # 2个问题:冗余赋值分类d:不可修改型(路径排除)yamllinters: exclusions: rules: # 生成代码(无法修改) - path: \.pb\.go|\.gen\.go|\.gen-\w+\.go|\.mock\.go linters: [all] # 第三方依赖(无法修改) - path: vendor/|third_party/ linters: [all] # 示例代码(可选修改) - path: examples/ linters: [all] issues: exclude-rules: # 第三方API(无法修改) - text: "non-canonical header" linters: [canonicalheader] # 中文函数名(业务需求,无法修改) - text: "ID.*must match" linters: [asciicheck] # 内部项目使用内部包(业务需求) - text: "import of package" linters: [depguard]分类e:小问题可修复(特定少量问题)yamlissues: exclude-rules: # 特定业务场景(无法修改) - text: "G101: potential hardcoded credential" path: config/.*\.go linters: [gosec] # 对测试文件放宽要求 - path: _test\.go linters: [errcheck, gosec, contextcheck] # 对main函数放宽要求 - path: cmd/ linters: [gocyclo, funlen, errcheck]分类f:新特性-延后处理yamllinters: disable: # TODO 新特性-延后处理:不影响当前代码,可后续选择性启用 - modernize # 12个问题:现代Go语法建议 - revive # 48个问题:revive规则集 - gocritic # 10个问题:代码风格建议 - godoclint # 3个问题:godoc格式 - gomoddirectives # module指令检查 - dogsled # 空白标识符数量 - embeddedstructfieldcheck # 2个问题:嵌入字段空行 - exhaustruct # 49个问题:结构体字段完整性 - forbidigo # 6个问题:禁用特定函数 - gochecknoglobals # 15个问题:全局变量检查 - gochecknoinits # 2个问题:init函数检查 - godox # 2个问题:TODO/FIXME标记 - nolintlint # 1个问题:nolint注释检查
目标:现有代码通过lint检查,不要修改现有代码,新代码必须遵循规则。
8. Final Verification
8. 最终验证
bash
undefinedbash
undefinedRun again to ensure pass
再次运行确保通过
$(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...
$(go env GOPATH)/bin/golangci-lint run --timeout=5m ./...
Or use make
或使用Makefile
make lint
undefinedmake lint
undefinedOutput Report Template
输出报告模板
markdown
undefinedmarkdown
undefinedgolangci-lint Configuration Complete
golangci-lint 配置完成
Environment Information
环境信息
- Go Version (go.mod): go 1.23
- golangci-lint Version: v2.8.0
- Go版本(go.mod):go 1.23
- golangci-lint版本:v2.8.0
Configuration
配置情况
- Created: .golangci.yml (version: 2)
- Initial Config: linters.default: all (minimal config)
- 创建文件:.golangci.yml(版本:2)
- 初始配置:linters.default: all(最小配置)
Issue Handling
问题处理
Handling Priority
处理优先级
| Priority | Method | Linters |
|---|---|---|
| 1️⃣ Adjust settings | Threshold tuning | funlen, gocyclo, gocognit, nestif |
| 2️⃣ exclusions | Path exclusion | Generated code, 3rd-party dependencies, specific APIs |
| 3️⃣ exclude-rules | Rule exclusion | Test files, specific business scenarios |
| 4️⃣ disable | Completely disable | Linters with many issues |
| 优先级 | 方法 | 涉及Linter |
|---|---|---|
| 1️⃣ 调整设置 | 阈值调优 | funlen, gocyclo, gocognit, nestif |
| 2️⃣ 路径排除 | 路径排除 | 生成代码、第三方依赖、特定API |
| 3️⃣ 规则排除 | 规则排除 | 测试文件、特定业务场景 |
| 4️⃣ 完全禁用 | 完全禁用 | 存在大量问题的Linter |
Linter Category Statistics
Linter分类统计
| Category | Count | Description |
|---|---|---|
| a. Configurable | 4 | Prioritize adjusting settings thresholds |
| b. Code Style-Manual Confirm | 26 | Style issues, need confirmation whether to disable |
| c. Critical Bugs-Suggest Fix | 18 | Security/error handling, recommend fixing |
| d. Cannot Modify | - | Path exclusion (external constraints) |
| e. Can Fix Small | - | Issues exclusion (few issues) |
| f. New Features-Defer | 13 | New features, consider later |
| 分类 | 数量 | 描述 |
|---|---|---|
| a. 可配置型 | 4 | 优先调整设置阈值 |
| b. 代码风格-人工确认 | 26 | 风格问题,需确认是否禁用 |
| c. 严重Bug-建议修复 | 18 | 安全/错误处理问题,建议修复 |
| d. 不可修改型 | - | 路径排除(外部约束) |
| e. 小问题可修复 | - | 规则排除(少量问题) |
| f. 新特性-延后处理 | 13 | 新特性,可后续考虑 |
Settings Threshold Adjustments
设置阈值调整
yaml
linters:
settings:
funlen:
lines: 100 # Default 60
statements: 60 # Default 40
gocyclo:
min-complexity: 25 # Default 15
gocognit:
min-complexity: 30 # Default 15
nestif:
min-complexity: 8 # Default 5yaml
linters:
settings:
funlen:
lines: 100 # 默认60
statements: 60 # 默认40
gocyclo:
min-complexity: 25 # 默认15
gocognit:
min-complexity: 30 # 默认15
nestif:
min-complexity: 8 # 默认5Path Exclusions (Cannot Modify)
路径排除(不可修改)
- Generated code: ,
.pb.go,.gen.go.mock.go - Third-party dependencies: ,
vendor/third_party/ - Example code:
examples/
- 生成代码:,
.pb.go,.gen.go.mock.go - 第三方依赖:,
vendor/third_party/ - 示例代码:
examples/
Issues Exclusions (Specific Scenarios)
规则排除(特定场景)
- Third-party APIs: (canonicalheader)
non-canonical header - Chinese function names: (asciicheck)
ID.*must match - Test files: Relax errcheck, gosec, contextcheck
- 第三方API:(canonicalheader)
non-canonical header - 中文函数名:(asciicheck)
ID.*must match - 测试文件:放宽errcheck、gosec、contextcheck的要求
Next Steps
后续步骤
- New code must pass lint
- Prioritize fixing issues in "c. Critical Bugs-Suggest Fix" category
- After code improvements, gradually reduce complexity thresholds
- Regularly run checks
make lint
undefined- 新代码必须通过lint检查
- 优先修复“c. 严重Bug-建议修复”分类中的问题
- 代码优化后,逐步降低复杂度阈值
- 定期运行进行检查
make lint
undefinedNotes
注意事项
- Core Principle: Do not modify existing code, only adjust configuration to make code pass lint
- v2 Configuration Format: Must add , use
version: 2instead oflinters.defaultenable-all - Do Not Modify Existing Configuration
- Style Issues Can Be Permanently Ignored: Function length, cyclomatic complexity, etc. do not affect functionality
- Critical Issues Need Fix Reminders: errcheck, gosec, staticcheck, etc. (exclude via config, do not fix directly)
- New Code Must Not Bypass Checks
- CI Needs Sufficient Resources: Recommend at least 2GB memory
- 核心原则:不要修改现有代码,仅通过调整配置让代码通过lint检查
- v2版本配置格式:必须添加,使用
version: 2替代linters.defaultenable-all - 不要修改现有配置:如果已有配置,优先使用现有配置进行调整
- 风格问题可永久忽略:函数长度、圈复杂度等不影响功能的问题可永久忽略
- 严重问题需修复提醒:errcheck、gosec、staticcheck等问题(通过配置排除,不要直接修改代码)
- 新代码不可绕过检查:新代码必须符合lint规则
- CI需要足够资源:建议至少2GB内存