152 lines
7.7 KiB
YAML
152 lines
7.7 KiB
YAML
version: "2"
|
|
run:
|
|
concurrency: 4
|
|
# Timeout for analysis
|
|
timeout: 5m
|
|
# Include test files
|
|
tests: true
|
|
|
|
issues:
|
|
max-issues-per-linter: 0 # 0 = unlimited (we want ALL issues)
|
|
max-same-issues: 50
|
|
|
|
linters:
|
|
enable:
|
|
# correctness
|
|
- govet # built-in checker: copylocks, printf formats, struct tags, unreachable code
|
|
- staticcheck # extensive static analysis: deprecated APIs, common mistakes, simplifications
|
|
- unused # unused variables, functions, types
|
|
- errcheck # unchecked error returns and type assertions
|
|
- errorlint # correct use of errors.Is/As and %w wrapping (Go 1.13+)
|
|
- nilerr # returning nil error when err is non-nil
|
|
- forcetypeassert # type assertions without comma-ok check
|
|
- copyloopvar # loop variable copy issues (Go 1.22+)
|
|
- durationcheck # detect time.Duration * time.Duration bugs
|
|
- reassign # package-level variable reassignment
|
|
# style
|
|
- gocritic # opinionated style: unnecessary conversions, range copies, redundant code
|
|
- revive # naming conventions, exported types, stuttered package names
|
|
- wsl_v5 # whitespace and blank line rules for readability
|
|
- whitespace # trailing whitespace, unnecessary blank lines
|
|
- godot # exported-symbol comments must end with a period
|
|
- misspell # common English misspellings in identifiers and comments
|
|
- dupword # duplicate words in comments and strings (the the, is is)
|
|
- predeclared # shadowing Go built-ins (len, cap, error)
|
|
- errname # error type/var naming conventions (ErrFoo, FooError)
|
|
- asciicheck # non-ASCII identifiers (prevents homoglyph/trojan source attacks)
|
|
# complexity
|
|
- gocyclo # cyclomatic complexity threshold
|
|
- nestif # deeply nested if/else chains
|
|
- funlen # function length limits (lines and statements)
|
|
- dupl # code duplication detection
|
|
# performance
|
|
- perfsprint # faster alternatives to fmt.Sprintf
|
|
- unconvert # unnecessary type conversions
|
|
- ineffassign # assignments to variables never read
|
|
- goconst # repeated literals that should be constants
|
|
# security & resources
|
|
- gosec # security scanner: SQL injection, hardcoded credentials, weak crypto, path traversal
|
|
- bidichk # dangerous bidirectional Unicode sequences (trojan source CVE-2021-42574)
|
|
- bodyclose # unclosed HTTP response bodies (connection leaks)
|
|
- noctx # HTTP requests missing context.Context
|
|
- containedctx # context.Context stored in struct fields instead of passed as parameter
|
|
- fatcontext # context.WithValue/WithCancel in loops (unbounded context chain, memory leak)
|
|
- sqlclosecheck # unclosed sql.Rows and sql.Stmt
|
|
- rowserrcheck # unchecked sql.Rows.Err() after iteration
|
|
# logging
|
|
- sloglint # consistent log/slog code style
|
|
- loggercheck # key-value pair validation for structured loggers (zap, slog, logr)
|
|
# testing
|
|
- testifylint # testify best practices
|
|
- thelper # test helpers missing t.Helper()
|
|
- usetesting # use t.Setenv/t.TempDir instead of os equivalents in tests
|
|
- paralleltest # tests and subtests missing t.Parallel()
|
|
# modernization & meta
|
|
- modernize # old patterns replaceable with newer Go features
|
|
- exptostd # replace golang.org/x/exp/ functions with stdlib equivalents
|
|
- intrange # range over integer instead of C-style loop (Go 1.22+)
|
|
- usestdlibvars # use stdlib constants instead of hardcoded values
|
|
- exhaustive # switch statements not covering all enum values
|
|
- nolintlint # enforces proper //nolint directive usage
|
|
|
|
disable:
|
|
- lll # line length — handled by gofmt/gofumpt
|
|
- prealloc # high false-positive rate; enable only after performance profiling
|
|
- wrapcheck # forces wrapping all external errors — too noisy as a default
|
|
- err113 # forces package-level sentinel errors — too opinionated, breaks common patterns
|
|
- mnd # magic number detector — extremely noisy, flags obvious constants like HTTP 200
|
|
- iface # interface pollution detector — too opinionated, not mature enough
|
|
- nakedret # naked returns — overlaps with funlen (short functions make naked returns fine)
|
|
- noinlineerr # bans `if err := ...; err != nil {}` — this is idiomatic Go
|
|
- gocognit # cognitive complexity — redundant with gocyclo + nestif
|
|
- cyclop # cyclomatic complexity — redundant with gocyclo
|
|
- depguard # import allow/deny lists — requires per-project configuration
|
|
- goheader # file header enforcement — project-specific policy
|
|
- importas # import alias enforcement — requires per-project configuration
|
|
- funcorder # function ordering — too opinionated for a default
|
|
- godoclint # godoc validation — overlaps with godot and revive
|
|
- varnamelen # variable name length — too opinionated, Go favors short names
|
|
- exhaustruct # all struct fields must be set — extremely noisy, breaks zero-value idiom
|
|
- gochecknoglobals # no global variables — too strict, many valid uses
|
|
- gochecknoinits # no init() functions — too strict, many valid uses
|
|
- unparam # unused function parameters — medium false-positive rate with interfaces
|
|
- makezero # flags make([]T, n) — noisy, often wrong about intent
|
|
- testpackage # forces _test package — valid but too opinionated as a default
|
|
- embeddedstructfieldcheck # embedded type placement — minor style, not worth enforcing
|
|
- iotamixing # iota in mixed const blocks — very rare issue
|
|
- unqueryvet # SELECT * detection — too niche for a default config
|
|
- recvcheck # receiver type consistency — overlaps with gocritic
|
|
- mirror # bytes/strings mirror patterns — very few real hits
|
|
- protogetter # proto field access via getters — only for protobuf users
|
|
- spancheck # OpenTelemetry span checks — only for OTel users
|
|
- zerologlint # zerolog usage — only for zerolog users
|
|
|
|
exclusions:
|
|
paths:
|
|
- vendor$
|
|
- third_party$
|
|
- testutils$
|
|
- examples$
|
|
|
|
settings:
|
|
dupl:
|
|
threshold: 100 # lower => stricter (tokens)
|
|
errcheck:
|
|
check-type-assertions: true
|
|
funlen:
|
|
lines: 120
|
|
statements: 80
|
|
goconst:
|
|
min-len: 3
|
|
min-occurrences: 4
|
|
gocyclo:
|
|
min-complexity: 13 # strict; lower => stricter
|
|
nolintlint:
|
|
require-explanation: true
|
|
require-specific: true
|
|
wsl_v5:
|
|
allow-first-in-block: true
|
|
allow-whole-block: false
|
|
branch-max-lines: 2
|
|
|
|
formatters:
|
|
# formatters are opt-in: only those listed here run. Others are left commented
|
|
# with the reason they stay off (a `disable` block is not valid here and makes
|
|
# `golangci-lint config verify` fail).
|
|
enable:
|
|
- gofumpt # superset of gofmt: applies gofmt's rules first, then its own
|
|
- goimports # import management: adds imports that --fix introduces, drops unused ones
|
|
# - gofmt # redundant: gofumpt already applies gofmt's rules
|
|
# - gci # import grouping/ordering — gofumpt already handles standard grouping
|
|
# - golines # line wrapping — too opinionated, can break readability
|
|
# - swaggo # swaggo comment formatting — only for swaggo users
|
|
settings:
|
|
gofumpt:
|
|
extra-rules: true
|
|
exclusions:
|
|
generated: lax
|
|
paths:
|
|
- third_party$
|
|
- builtin$
|
|
- examples$
|