| name | golangci-lint Setup |
| description | This skill should be used when the user asks to "setup golangci-lint", "configure linting", "Go code quality", "lint configuration", "CI linting", or works with Go code linting and quality tools. |
| version | 0.2.0 |
golangci-lint Setup
golangci-lint is a fast Go linters runner that runs linters in parallel and caches results.
Core Concepts
What is golangci-lint
- Runs multiple Go linters concurrently
- Caches results for faster subsequent runs
- Configurable via YAML/TOML/JSON
- Supports go modules
- Ideal for CI/CD integration
Installation
macOS:
brew install golangci-lint
Linux:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.62.0
Go install:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Verify:
golangci-lint version
Basic Usage
Run all linters:
golangci-lint run
Run with specific config:
golangci-lint run -c .golangci.yml
Run on specific path:
golangci-lint run ./...
golangci-lint run ./pkg/...
Enable verbose output:
golangci-lint run -v
Configuration File (.golangci.yml)
Recommended configuration:
run:
timeout: 5m
skip-dirs:
- vendor
- third_party
- testdata
skip-files:
- ".*\\.pb\\.go$"
- ".*_gen\\.go$"
output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true
linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
govet:
check-shadowing: true
enable-all: true
gocyclo:
min-complexity: 15
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
min-len: 3
min-occurrences: 3
misspell:
locale: US
lll:
line-length: 120
goimports:
local-prefixes: github.com/mycompany/myproject
gocritic:
enabled-tags:
- performance
- style
- experimental
disabled-checks:
- wrapperFunc
- dupImport
funlen:
lines: 100
statements: 50
cyclop:
max-complexity: 15
package-average: 10
linters:
enable:
- bodyclose
- depguard
- dogsled
- dupl
- errcheck
- exportloopref
- gochecknoinits
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- goprintffuncname
- gosec
- gosimple
- govet
- ineffassign
- lll
- misspell
- mnd
- nakedret
- nilerr
- revive
- rowserrcheck
- staticcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- whitespace
disable:
- prealloc
issues:
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- lll
- path: _test\.go
text: "shadow"
linters:
- govet
- path: _test\.go
linters:
- goprintffuncname
- path: pkg/errors
text: "Error return value of .Close. is not checked"
linters:
- errcheck
- text: "shadow: declaration of \"err\""
linters:
- govet
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
Recommended Linters
Essential:
errcheck - Check unchecked errors
gosimple - Simplify code
govet - Vet examines Go source code
ineffassign - Detect ineffectual assignments
staticcheck - Static analysis
unused - Check unused constants/variables/functions/types
Code Quality:
gocyclo - Cyclomatic complexity
cyclop - Cyclomatic complexity (alternative)
funlen - Function length
lll - Line length limit
goconst - Find repeated strings
mnd - Magic number detector (replaces gomnd)
Style:
gofmt - Go formatting
goimports - Import formatting
misspell - Spell checking
whitespace - Trailing whitespace
revive - Fast, configurable linter (replaces golint)
Security:
Bug Detection:
exportloopref - Detect loop variable capture (replaces scopelint)
nilerr - Find code that returns nil even if error is not nil
Makefile Integration
.PHONY: lint lint-fix lint-ci
lint:
golangci-lint run
lint-fix:
golangci-lint run --fix
lint-ci:
golangci-lint run --out-format=github-actions
install-linter:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
CI/CD Integration
GitHub Actions:
name: Lint
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.62.0
args: --timeout=5m
GitLab CI:
lint:
stage: test
image: golangci/golangci-lint:v1.62.0
script:
- golangci-lint run --timeout=5m
only:
- merge_requests
- main
CircleCI:
version: 2.1
jobs:
lint:
docker:
- image: golangci/golangci-lint:v1.62.0
steps:
- checkout
- run: golangci-lint run --timeout=5m
workflows:
test:
jobs:
- lint
VS Code Integration
.vscode/settings.json:
{
"go.lintTool": "golangci-lint",
"go.lintFlags": [
"--fast",
"--fix"
],
"go.formatTool": "goimports",
"go.toolsManagement.autoUpdate": true
}
Pre-commit Hook
.pre-commit-config.yaml:
repos:
- repo: https://github.com/golangci/golangci-lint
rev: v1.62.0
hooks:
- id: golangci-lint
args: ['--fast']
Common Issues and Fixes
Unused parameters:
func process(data string, unused int) error {
return nil
}
func process(data string, _ int) error {
return nil
}
Error not checked:
file.Close()
_ = file.Close()
Line too long:
veryLongFunctionCall(
parameter1,
parameter2,
parameter3,
)
Cyclomatic complexity:
- Break large functions into smaller ones
- Use early returns
- Extract switch cases into functions
Best Practices
- Run locally before committing - Catch issues early
- Use --fix flag - Auto-fix where possible
- Configure per project - Adjust rules to project needs
- Integrate in CI - Enforce in pull requests
- Start with essential linters - Add more gradually
- Exclude test files appropriately - Balance strictness
- Use consistent version - Pin version in CI
Additional Resources
references/.golangci.example.yml - Extended configuration example
scripts/lint.sh - Custom lint script with options