Repository navigation
Expand file tree
/
Copy path.golangci.yml
More file actions
154 lines (130 loc) · 5.64 KB
/
Copy path.golangci.yml
File metadata and controls
154 lines (130 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# Copyright 2026 Phillip Cloud
# Licensed under the Apache License, Version 2.0
version: "2"
linters:
default: all
disable:
# Style/formatting -- conflicts with project conventions or tooling
- nlreturn # forces blank lines before returns; noisy
- wsl # whitespace style; too opinionated
- varnamelen # short var names are idiomatic Go
- ireturn # forbids returning interfaces; conflicts with stdlib patterns
- lll # line length; golines handles this
- tagliatelle # enforces JSON tag casing; we set tags explicitly
- exhaustruct # requires all struct fields; too noisy for large structs
- nonamedreturns # forbids named returns; sometimes useful for docs
- tagalign # aligns struct tags; cosmetic
- noinlineerr # forbids inline err assignments; standard Go idiom
- dupl # duplicate code detection; tests excluded, remaining are HTTP boilerplate
# Complexity metrics -- we trust reviewer judgment
- funlen # function length limits
- cyclop # cyclomatic complexity
- gocognit # cognitive complexity
- maintidx # maintainability index
- gocyclo # cyclomatic complexity (redundant with cyclop)
- nestif # deeply nested ifs; overlaps complexity linters
# Opinionated rules that don't fit this project
- depguard # dependency allowlist; not needed
- mnd # magic numbers; too aggressive
- gochecknoglobals # flags all globals; we use them intentionally
- testpackage # requires _test package suffix; we test internals
- paralleltest # requires t.Parallel(); not always appropriate
- tparallel # similar to paralleltest
- gosmopolitan # i18n checks; not applicable
- prealloc # premature optimization; not useful
- err113 # forbids dynamic errors; too aggressive for user-facing messages
- forbidigo # forbids fmt.Print*; CLI programs need them
- funcorder # forces exported-before-unexported ordering; too noisy
- containedctx # flags context in structs; TUI models legitimately store context
- wsl_v5 # whitespace style v5; too opinionated
- exhaustruct_v5 # exhaustruct v5; disabled for the same reason as exhaustruct
# Deprecated linter names; we use the v2 replacement instead
- gomodguard # superseded by gomodguard_v2 in golangci-lint v2.12.x
enable:
- gomodguard_v2 # explicit v2 opt-in (default: all enables the deprecated v1 alias)
settings:
errorlint:
# Catch direct comparison of errors (require errors.Is).
comparison: true
# Catch type assertions on errors (require errors.As).
asserts: true
# Catch fmt.Errorf without %w when wrapping an error.
errorf: true
# Allow multiple %w verbs in a single fmt.Errorf (Go 1.20+).
errorf-multi: true
exhaustive:
default-signifies-exhaustive: false
goconst:
min-occurrences: 5
revive:
enable-default-rules: true
rules:
- name: exported
disabled: true
- name: package-comments
disabled: true
wrapcheck:
ignore-package-globs:
- github.com/micasa-dev/micasa/*
- database/sql
- database/sql/*
- gorm.io/gorm
- gorm.io/gorm/*
testifylint:
disable:
- suite-broken-parallel # Our suites capture t := s.T() before Parallel()
interfacebloat:
max: 25 # relay Store has 24 methods; default 10 is too low
recvcheck:
exclusions:
# Like the built-in Unmarshal* excludes: decoding must mutate the receiver
- "*.UnmarshalTOML"
gocritic:
enable-all: true
disabled-tags:
- experimental
- opinionated
disabled-checks:
- hugeParam
- rangeValCopy
- ifElseChain
- singleCaseSwitch
exclusions:
rules:
# staticcheck nil-after-Fatal false positives in tests
- linters: [staticcheck]
path: _test\.go
text: "SA5011"
# gosec G204/G704: test binaries and URLs are controlled, not user input
- linters: [gosec]
path: _test\.go
text: "G204|G704"
# goconst: test-fixture strings (entity/document/category names, MIME
# types, SQLite type names, column-name map keys, ULIDs, dates)
# legitimately repeat across test cases
- linters: [goconst]
path: _test\.go
# unqueryvet: SELECT * in test SQL fixtures is intentional
- linters: [unqueryvet]
path: internal/(data/query|data/sqlite/sqlite|llm/prompt|sqlfmt/sqlfmt)_test\.go
# unqueryvet: dumpTable intentionally selects all columns for migration testing
- linters: [unqueryvet]
path: internal/data/query\.go
text: "SELECT \\*"
# contextcheck: Open is a constructor; threading context to it adds no value
- linters: [contextcheck]
path: internal/data/backup\.go
text: "Open"
# usetesting: os.MkdirTemp shared via sync.Once; t.TempDir would clean up after first test
- linters: [usetesting]
path: cmd/micasa/main_test\.go
# dogsled: visibleProjection returns 5 values, Load returns 4 — callers use subsets
- linters: [dogsled]
path: internal/app/(bench|view|handler_crud|handler_form_wiring)_test\.go
- linters: [dogsled]
path: internal/app/model\.go
source: "viewportRange"
# modernize/newexpr: ptr[T] helper wraps non-zero values; new() only creates zero values
- linters: [modernize]
path: internal/app/view_test\.go
text: "newexpr"