Skip to content

Commit 6238763

Browse files
committed
chore(lint): 扩展 .golangci.yml 至 37 个 linter
从 16 个扩展到 37 个(占 golangci-lint 全部 113 个的 33%)。 ## 新增 21 个 Bug catchers: - exhaustive: switch/type switch 缺少 case - gochecksumtype: sum-type 类型穷举 - nilnil: 同时返回 nil error + nil value - wastedassign: 被覆盖前从未读取的赋值 - reassign: 包级变量被重新赋值 - unparam: 未使用的函数参数 - errchkjson: json.Marshal 不支持的类型 - durationcheck: 两个 Duration 相乘 - makezero: make 非零长度后 append Modernization: - modernize: CutPrefix/SplitSeq/slices.Contains/min()/any/… - intrange: for i := range N - copyloopvar: Go 1.22+ loop var capture Meta: - nolintlint: 验证 //nolint / #nosec 指令格式 Input safety: - bidichk: 危险 Unicode(trojan source) - asciicheck: 非 ASCII 标识符 - gocheckcompilerdirectives: 畸形 //go: 指令 Performance: - perfsprint: fmt.Sprintf → strconv/errors.New Style (regression fence): - dupword: 重复词("the the") - godot: 注释句号 - errname: ErrXxx 命名规范 - dupl: 复制粘贴代码块 ## 明确不启用(附理由) - goconst: 46 findings,几乎全是测试数据("--bogus", "rm", "list"…), 提取成常量损害可读性 - gocognit: 和 gocyclo 重复,只是复杂度算法不同 - nestif: 和 gocyclo 重复,只看嵌套深度 - 其他 framework-specific linter(bodyclose, sqlclosecheck, protogetter 等):cmdguard 无 HTTP/SQL/protobuf ## 验证 $ golangci-lint run ./... 0 issues. $ go test ./... -count=1 全部 7 个包 PASS $ govulncheck ./... No vulnerabilities found.
1 parent e7ce182 commit 6238763

1 file changed

Lines changed: 71 additions & 36 deletions

File tree

.golangci.yml

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# golangci-lint configuration.
22
#
3-
# We run golangci-lint v2 (`brew install golangi-lint` on macOS).
3+
# We run golangci-lint v2 (`brew install golangci-lint` on macOS).
44
# v2 changed the schema: linters live under `linters.enable`, and
55
# per-rule exclusions live under `linters.exclusions.rules`.
66
#
@@ -9,54 +9,92 @@
99
# reproducible across contributors and CI (no "default changed
1010
# in v2.13"). `default: none` means ONLY the linters listed below
1111
# run — nothing implicit.
12-
# 2. Suppress errcheck noise inside *_test.go where the standard
13-
# pattern is os.Setenv / w.Close / buf.ReadFrom / os.MkdirAll
14-
# without explicit error handling. Production code still gets
15-
# the full check.
12+
# 2. Suppress noise inside *_test.go where the standard pattern is
13+
# os.Setenv / w.Close / buf.ReadFrom / os.MkdirAll without explicit
14+
# error handling. Production code still gets the full check.
1615
#
1716
# Linter philosophy:
18-
# - Real-bug catchers (errcheck, gosec, errorlint, nilerr, …) are
19-
# ON at default thresholds. Every finding they surface is either a
20-
# bug we fix or a documented false positive (`// #nosec`).
17+
# - Real-bug catchers (errcheck, gosec, errorlint, nilerr, exhaustive,
18+
# …) are ON at default thresholds. Every finding they surface is
19+
# either a bug we fix or a documented false positive (`// #nosec`).
2120
# - gocyclo is kept at a deliberately high threshold (70) because the
2221
# three CLI dispatchers (RunGuard/RunInit/RunUndo) are inherently
2322
# big switch-on-subcommand functions; the value is in preventing NEW
2423
# complexity, not flagging what we already know about.
25-
# - misspell / gocritic / unconvert / predeclared / forcetypeassert
26-
# currently produce zero findings on this codebase, but we keep them
27-
# enabled as a regression fence: the day someone adds a typo or an
24+
# - Modernisation linters (modernize, intrange, copyloopvar) push us
25+
# toward Go 1.22+ idioms (CutPrefix, SplitSeq, slices.Contains,
26+
# min(), interface{}→any, range-over-int).
27+
# - misspell / gocritic / unconvert / predeclared / forcetypeassert /
28+
# dupword / godot / asciicheck / bidichk / dupl / etc. currently
29+
# produce zero findings on this codebase, but we keep them enabled
30+
# as a regression fence: the day someone adds a typo or an
2831
# unnecessary conversion, CI catches it instead of a reviewer.
2932
#
33+
# Deliberately NOT enabled:
34+
# - goconst — 46 findings, almost all test data ("--bogus", "rm",
35+
# "list"…). Extracting test literals to constants harms readability.
36+
# - gocognit — duplicates gocyclo with a different complexity metric.
37+
# - nestif — duplicates gocyclo for nesting depth.
38+
# - Various framework-specific linters (bodyclose, sqlclosecheck,
39+
# protogetter, …) — cmdguard has no HTTP / SQL / protobuf.
40+
#
3041
# Run: golangci-lint run ./...
3142
# Update: golangci-lint config verify
3243
version: "2"
3344

3445
linters:
3546
default: none
3647
enable:
37-
# --- Built-ins that always pay off ---
38-
- errcheck # unchecked error returns (the most frequent real bug)
39-
- govet # the official `go vet` rules
40-
- ineffassign # assignments whose result is never read
41-
- staticcheck # SA-/ST-/QF- rules; the single most valuable set
42-
- unused # dead code (functions, vars, types, consts)
48+
# ── Built-ins that always pay off ──────────────────────────
49+
- errcheck # unchecked error returns (the most frequent real bug)
50+
- govet # the official `go vet` rules
51+
- ineffassign # assignments whose result is never read
52+
- staticcheck # SA-/ST-/QF- rules; the single most valuable set
53+
- unused # dead code (functions, vars, types, consts)
4354

44-
# --- Security & correctness ---
45-
- gosec # G1xx/G3xx/G7xx security checks (path traversal, hardcoded creds, …)
46-
- errorlint # use errors.As/Is/wrap instead of == / type-assertion
55+
# ── Security & correctness ─────────────────────────────────
56+
- gosec # G1xx/G3xx/G7xx security checks (path traversal, hardcoded creds, …)
57+
- errorlint # use errors.As/Is/wrap instead of == / type-assertion
4758
- nilerr # detect `if err != nil { return nil }` patterns that drop errors
59+
- nilnil # simultaneous return of nil error + invalid value
60+
- exhaustive # missing cases in switch / type switch
61+
- gochecksumtype # exhaustiveness for sum-type-style type switches
62+
- wastedassign # assignments that are overwritten before being read
63+
- reassign # package-level variables that get reassigned
64+
- unparam # unused function parameters
65+
66+
# ── Input validation & safety ──────────────────────────────
67+
- bidichk # dangerous Unicode (trojan source / bidi override)
68+
- asciicheck # non-ASCII identifiers
69+
- gocheckcompilerdirectives # malformed //go: directives
70+
71+
# ── Modernisation (Go 1.22–1.26 idioms) ───────────────────
72+
- modernize # CutPrefix/CutSuffix, SplitSeq, slices.Contains, min(), any, …
73+
- intrange # for i := range N instead of for i := 0; i < N; i++
74+
- copyloopvar # Go 1.22+ loop variable capture semantics
4875

49-
# --- Performance micro-optimisation ---
50-
- prealloc # preallocate slices when size is known upfront
76+
# ── Performance micro-optimisation ─────────────────────────
77+
- prealloc # preallocate slices when size is known upfront
78+
- perfsprint # fmt.Sprintf → strconv/errors.New where applicable
5179

52-
# --- Style & polish (zero findings today, fence for tomorrow) ---
53-
- misspell # typos in comments/strings
54-
- gocritic # style/perf/bug-prone patterns
55-
- unconvert # unnecessary type conversions
56-
- predeclared # shadowing predeclared identifiers (e.g. `cap`, `len`)
57-
- forcetypeassert # unchecked type assertions (panic risk)
80+
# ── Meta-linter ────────────────────────────────────────────
81+
- nolintlint # validate //nolint / #nosec directives are well-formed
5882

59-
# --- Complexity (high threshold — see comment above) ---
83+
# ── Style & polish (regression fence — 0 findings today) ──
84+
- misspell # typos in comments/strings
85+
- gocritic # style/perf/bug-prone patterns
86+
- unconvert # unnecessary type conversions
87+
- predeclared # shadowing predeclared identifiers (e.g. `cap`, `len`)
88+
- forcetypeassert # unchecked type assertions (panic risk)
89+
- dupword # duplicate words ("the the") in comments/strings
90+
- godot # comments should end with a period
91+
- errname # error variables should be named ErrXxx
92+
- dupl # duplicate code blocks (copy-paste detection)
93+
- errchkjson # unsupported types passed to json.Marshal/Encode
94+
- durationcheck # two time.Duration values multiplied together
95+
- makezero # make() with non-zero length followed by append
96+
97+
# ── Complexity (high threshold — see header comment) ──────
6098
- gocyclo
6199

62100
settings:
@@ -68,10 +106,8 @@ linters:
68106
# nagging about the existing ones.
69107
min-complexity: 70
70108
gosec:
71-
# #nosec directives already cover the genuine false positives
72-
# (user-supplied command launching, PATH-walk file reads, …).
73-
# No global exclusion rules — every suppression is per-site with
74-
# a justification comment.
109+
# #nosec directives cover genuine false positives per-site.
110+
# No global exclusions — keeping it explicit.
75111
excludes: []
76112

77113
exclusions:
@@ -86,7 +122,6 @@ linters:
86122
- gosec
87123
- forcetypeassert
88124
- prealloc
89-
# gocyclo is meaningless in test table-drivers and helpers.
90-
- path: _test\.go
91-
linters:
92125
- gocyclo
126+
- wastedassign
127+
- unparam

0 commit comments

Comments
 (0)