setup-golangci-lint

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

golangci-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
undefined
bash
undefined

Check 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"
undefined
ls Makefile 2>/dev/null && echo "存在Makefile" || echo "无Makefile"
undefined

2. Select Version

2. 版本选择

Select based on Go version in
go.mod
:
go.mod Versiongolangci-lint Version
< 1.20v1.x
>= 1.20v2.x (recommended)
根据
go.mod
中的Go版本选择对应的golangci-lint版本:
go.mod版本golangci-lint版本
< 1.20v1.x
>= 1.20v2.x(推荐)

3. Install

3. 安装

bash
undefined
bash
undefined

v2 (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
undefined

3.5. Configuration Migration (when v1 config exists)

3.5. 配置迁移(当存在v1版本配置时)

If the project already has
.golangci.yml
in v1 format, use the auto-migration tool:
bash
undefined
如果项目已有v1格式的
.golangci.yml
,使用自动迁移工具:
bash
undefined

Automatically 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
.golangci.yml
already exists.
📌 AI Operation Requirements:
  1. Must first visit official documentation to confirm latest format: https://golangci-lint.run/docs/configuration/file/
  2. Core Principle: Do not modify existing code, only make code pass by adjusting configuration (settings/disable/exclusions)
  3. Formatters Handling:
    • First run
      gofmt -l .
      and
      goimports -l .
      to check code format
    • If both have no output → enable formatters (uncomment)
    • If has output → keep commented, add
      # TODO format code and enable - X files currently non-compliant
      above
  4. Workflow: Create minimal config → Run lint → Categorize and handle → Add standardized TODO comments
  5. Universal Classification Logic (based on keywords in linter description):
    Step 1: Get linter description
    bash
    $(go env GOPATH)/bin/golangci-lint help <linter-name>
    Step 2: Categorize based on keywords in description
    CategoryKeywords in DescriptionActionExample Linters & Descriptions
    a. Configurablecomplexity, long, deeply, count, length, size, max, min, limitAdjust settingsfunlen: "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 Confirmstyle, format, naming, whitespace, align, order, declarationdisable + TODOgodot: "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 Fixbug, security, error, check, nil, unsafe, detect, inspectsdisable + TODOerrcheck: "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)exclusionscanonicalheader: 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-rulesAny linter with few issues
    f. New Features-Defermodern, new, latest, replace, simplification, featuredisable + TODOmodernize: "suggest simplifications using modern language"<br>exptostd: "replaced by std functions"<br>usestdlibvars: "use variables from standard library"
    Step 3: Complete Decision Tree
    1. 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 + TODO
    Example Demonstrations:
    LinterDescriptionKeywordsCategory
    cyclop"Checks function complexity"complexitya
    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/checkc
    goconst"Finds repeated strings that could be replaced by a constant"(style)b
    fatcontext"Detects nested contexts"nested → complexitya
  6. Configuration Priority:
    • 1st Priority: Adjust
      settings
      thresholds (e.g., funlen.lines, gocyclo.min-complexity)
    • 2nd Priority: Use
      linters.exclusions
      path exclusion (code that cannot be modified)
    • 3rd Priority: Use
      issues.exclude-rules
      rule-based exclusion (specific few issues)
    • Last Resort: Completely
      disable
      (many issues and cannot be resolved via config)
  7. 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
    # - goimports
Formatters Handling: First run
gofmt -l .
and
goimports -l .
to check, uncomment to enable if both have no output.
Notes:
  • Start with minimal configuration, no preset disable
  • After running, gradually add
    disable
    and
    exclusions
    based on errors
  • Common linters that need adjustment (add as needed):
    • mnd
      (magic numbers) → style issues, can be permanently ignored
    • wsl
      (whitespace) → style issues, can be permanently ignored
    • lll
      (line length) → style issues, can be permanently ignored
    • err113
      → error handling, temporarily ignore and mark TODO
v1 Configuration Template (.golangci.yml)
Note: v1 does not require
version
field. v2 is recommended.
yaml
run:
  concurrency: 4
  timeout: 5m
  skip-dirs: [vendor, testdata]

linters:
  enable-all: true
After running, add
disable
and
exclude-rules
based on errors.
如果已存在
.golangci.yml
,请跳过此步骤。
📌 AI操作要求:
  1. 必须先访问官方文档确认最新格式:https://golangci-lint.run/docs/configuration/file/
  2. 核心原则不要修改现有代码,仅通过调整配置(设置/禁用/排除规则)让代码通过检查
  3. 格式化工具处理:
    • 先运行
      gofmt -l .
      goimports -l .
      检查代码格式
    • 如果两者都无输出 → 启用格式化工具(取消注释)
    • 如果有输出 → 保持注释状态,并在上方添加
      # TODO 格式化代码后启用 - 目前有X个文件不符合规范
  4. 工作流程:创建最小配置 → 运行lint检查 → 分类处理问题 → 添加标准化TODO注释
  5. 通用分类逻辑(基于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禁用 + TODOgodot: "检查注释是否以句号结尾"<br>tagalign: "检查结构体标签是否对齐良好"<br>misspell: "查找常见的拼写错误"<br>varnamelen: "检查变量名长度"
    c. 严重Bug-建议修复bug, security, error, check, nil, unsafe, detect, inspects禁用 + TODOerrcheck: "检查未处理的错误"<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禁用 + TODOmodernize: "建议使用现代语言特性进行简化"<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"检查函数复杂度"complexitya
    gocritic"检查Bug、性能和风格问题"bugs(优先)c
    revive"golint的替代工具"无明确关键词b
    bodyclose"检查响应体是否成功关闭"error/checkc
    goconst"查找可替换为常量的重复字符串"styleb
    fatcontext"检测嵌套的context"nested → complexitya
  6. 配置优先级:
    • 最高优先级:调整
      settings
      阈值(如funlen.lines、gocyclo.min-complexity)
    • 次优先级:使用
      linters.exclusions
      路径排除(无法修改的代码)
    • 第三优先级:使用
      issues.exclude-rules
      规则排除(特定少量问题)
    • 最后手段:完全
      disable
      (大量问题且无法通过配置解决)
  7. 避免重复:每个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 .
检查,若两者都无输出则取消注释启用。
注意:
  • 从最小配置开始,不预设禁用项
  • 运行检查后,根据错误信息逐步添加
    disable
    exclusions
  • 常见需要调整的linter(按需添加):
    • mnd
      (魔法数字)→ 风格问题,可永久忽略
    • wsl
      (空白符)→ 风格问题,可永久忽略
    • lll
      (行长度)→ 风格问题,可永久忽略
    • err113
      → 错误处理,暂时忽略并标记TODO
v1版本配置模板(.golangci.yml)
注意:v1版本不需要
version
字段。推荐使用v2版本。
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: latest
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: latest

6. 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
undefined
bash
undefined

Run 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
  • gomnd
    mnd
  • goerr113
    err113
  • execinquery
    → removed
  1. Configuration Format Errors:
    • output.formats
      needs map format, not list
    • Use singular form
      output.format
  2. Adjust Configuration Based on Actual Errors:
    Configuration Priority (try in order):
    PriorityActionUse Case
    1️⃣ HighestAdjust
    settings
    thresholds
    Linters with config options for complexity/length
    2️⃣ Second
    linters.exclusions
    path exclusion
    Code that cannot be modified (generated/3rd-party)
    3️⃣ Then
    issues.exclude-rules
    rule exclusion
    Specific few issues
    4️⃣ Last
    disable
    completely
    Many issues and no config options
    Category a: Configurable (Prioritize adjusting settings)
    yaml
    linters:
      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 disable
    Category b: Code Style-Manual Confirm
    yaml
    linters:
      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 suggestion
    Category c: Critical Bugs-Suggest Fix
    yaml
    linters:
      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 assignment
    Category d: Cannot Modify (Path Exclusion)
    yaml
    linters:
      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)
    yaml
    issues:
      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-Defer
    yaml
    linters:
      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
  • gomnd
    mnd
  • goerr113
    err113
  • execinquery
    → 已移除
  1. 配置格式错误:
    • output.formats
      需要map格式,而非列表
    • 使用单数形式
      output.format
  2. 根据实际错误调整配置:
    配置优先级(按顺序尝试):
    优先级操作适用场景
    1️⃣ 最高调整
    settings
    阈值
    支持复杂度/长度配置的linter
    2️⃣ 次高
    linters.exclusions
    路径排除
    无法修改的代码(生成代码/第三方代码)
    3️⃣ 第三
    issues.exclude-rules
    规则排除
    特定少量问题
    4️⃣ 最后完全
    disable
    大量问题且无配置选项的linter
    分类a:可配置型(优先调整设置)
    yaml
    linters:
      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:代码风格-人工确认
    yaml
    linters:
      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-建议修复
    yaml
    linters:
      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:不可修改型(路径排除)
    yaml
    linters:
      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:小问题可修复(特定少量问题)
    yaml
    issues:
      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:新特性-延后处理
    yaml
    linters:
      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
undefined
bash
undefined

Run 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
undefined
make lint
undefined

Output Report Template

输出报告模板

markdown
undefined
markdown
undefined

golangci-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

处理优先级

PriorityMethodLinters
1️⃣ Adjust settingsThreshold tuningfunlen, gocyclo, gocognit, nestif
2️⃣ exclusionsPath exclusionGenerated code, 3rd-party dependencies, specific APIs
3️⃣ exclude-rulesRule exclusionTest files, specific business scenarios
4️⃣ disableCompletely disableLinters with many issues
优先级方法涉及Linter
1️⃣ 调整设置阈值调优funlen, gocyclo, gocognit, nestif
2️⃣ 路径排除路径排除生成代码、第三方依赖、特定API
3️⃣ 规则排除规则排除测试文件、特定业务场景
4️⃣ 完全禁用完全禁用存在大量问题的Linter

Linter Category Statistics

Linter分类统计

CategoryCountDescription
a. Configurable4Prioritize adjusting settings thresholds
b. Code Style-Manual Confirm26Style issues, need confirmation whether to disable
c. Critical Bugs-Suggest Fix18Security/error handling, recommend fixing
d. Cannot Modify-Path exclusion (external constraints)
e. Can Fix Small-Issues exclusion (few issues)
f. New Features-Defer13New 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 5
yaml
linters:
  settings:
    funlen:
      lines: 100        # 默认60
      statements: 60    # 默认40
    gocyclo:
      min-complexity: 25  # 默认15
    gocognit:
      min-complexity: 30  # 默认15
    nestif:
      min-complexity: 8   # 默认5

Path 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:
    non-canonical header
    (canonicalheader)
  • Chinese function names:
    ID.*must match
    (asciicheck)
  • Test files: Relax errcheck, gosec, contextcheck
  • 第三方API:
    non-canonical header
    (canonicalheader)
  • 中文函数名:
    ID.*must match
    (asciicheck)
  • 测试文件:放宽errcheck、gosec、contextcheck的要求

Next Steps

后续步骤

  1. New code must pass lint
  2. Prioritize fixing issues in "c. Critical Bugs-Suggest Fix" category
  3. After code improvements, gradually reduce complexity thresholds
  4. Regularly run
    make lint
    checks
undefined
  1. 新代码必须通过lint检查
  2. 优先修复“c. 严重Bug-建议修复”分类中的问题
  3. 代码优化后,逐步降低复杂度阈值
  4. 定期运行
    make lint
    进行检查
undefined

Notes

注意事项

  1. Core Principle: Do not modify existing code, only adjust configuration to make code pass lint
  2. v2 Configuration Format: Must add
    version: 2
    , use
    linters.default
    instead of
    enable-all
  3. Do Not Modify Existing Configuration
  4. Style Issues Can Be Permanently Ignored: Function length, cyclomatic complexity, etc. do not affect functionality
  5. Critical Issues Need Fix Reminders: errcheck, gosec, staticcheck, etc. (exclude via config, do not fix directly)
  6. New Code Must Not Bypass Checks
  7. CI Needs Sufficient Resources: Recommend at least 2GB memory
  1. 核心原则不要修改现有代码,仅通过调整配置让代码通过lint检查
  2. v2版本配置格式:必须添加
    version: 2
    ,使用
    linters.default
    替代
    enable-all
  3. 不要修改现有配置:如果已有配置,优先使用现有配置进行调整
  4. 风格问题可永久忽略:函数长度、圈复杂度等不影响功能的问题可永久忽略
  5. 严重问题需修复提醒:errcheck、gosec、staticcheck等问题(通过配置排除,不要直接修改代码)
  6. 新代码不可绕过检查:新代码必须符合lint规则
  7. CI需要足够资源:建议至少2GB内存

Related Resources

相关资源