Skip to content

Commit f2c80d5

Browse files
committed
exhaustivestruct: add missing settings
1 parent 9c47715 commit f2c80d5

File tree

5 files changed

+170
-30
lines changed

5 files changed

+170
-30
lines changed

.golangci.example.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ linters-settings:
111111
# 'default' case is present, even if all enum members aren't listed in the
112112
# switch
113113
default-signifies-exhaustive: false
114+
exhaustivestruct:
115+
struct-patterns:
116+
- '*.Test'
117+
- '*.Test2'
118+
- '*.Embedded'
119+
- '*.External'
114120
funlen:
115121
lines: 60
116122
statements: 40

pkg/config/config.go

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -254,30 +254,31 @@ type LintersSettings struct {
254254
} `mapstructure:"blocked"`
255255
}
256256

257-
WSL WSLSettings
258-
Lll LllSettings
259-
Unparam UnparamSettings
260-
Nakedret NakedretSettings
261-
Prealloc PreallocSettings
262-
Errcheck ErrcheckSettings
263-
Gocritic GocriticSettings
264-
Godox GodoxSettings
265-
Dogsled DogsledSettings
266-
Gocognit GocognitSettings
267-
Godot GodotSettings
268-
Goheader GoHeaderSettings
269-
Testpackage TestpackageSettings
270-
Nestif NestifSettings
271-
NoLintLint NoLintLintSettings
272-
Exhaustive ExhaustiveSettings
273-
Gofumpt GofumptSettings
274-
ErrorLint ErrorLintSettings
275-
Makezero MakezeroSettings
276-
Revive ReviveSettings
277-
Thelper ThelperSettings
278-
Forbidigo ForbidigoSettings
279-
Ifshort IfshortSettings
280-
Predeclared PredeclaredSettings
257+
WSL WSLSettings
258+
Lll LllSettings
259+
Unparam UnparamSettings
260+
Nakedret NakedretSettings
261+
Prealloc PreallocSettings
262+
Errcheck ErrcheckSettings
263+
Gocritic GocriticSettings
264+
Godox GodoxSettings
265+
Dogsled DogsledSettings
266+
Gocognit GocognitSettings
267+
Godot GodotSettings
268+
Goheader GoHeaderSettings
269+
Testpackage TestpackageSettings
270+
Nestif NestifSettings
271+
NoLintLint NoLintLintSettings
272+
Exhaustive ExhaustiveSettings
273+
ExhaustiveStruct ExhaustiveStructSettings
274+
Gofumpt GofumptSettings
275+
ErrorLint ErrorLintSettings
276+
Makezero MakezeroSettings
277+
Revive ReviveSettings
278+
Thelper ThelperSettings
279+
Forbidigo ForbidigoSettings
280+
Ifshort IfshortSettings
281+
Predeclared PredeclaredSettings
281282

282283
Custom map[string]CustomLinterSettings
283284
}
@@ -391,6 +392,10 @@ type ExhaustiveSettings struct {
391392
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
392393
}
393394

395+
type ExhaustiveStructSettings struct {
396+
StructPatterns []string `mapstructure:"struct-patterns"`
397+
}
398+
394399
type GofumptSettings struct {
395400
ExtraRules bool `mapstructure:"extra-rules"`
396401
}

pkg/golinters/exhaustivestruct.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
package golinters
22

33
import (
4+
"strings"
5+
46
"github.com/mbilski/exhaustivestruct/pkg/analyzer"
57
"golang.org/x/tools/go/analysis"
68

9+
"github.com/golangci/golangci-lint/pkg/config"
710
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
811
)
912

10-
func NewExhaustiveStruct() *goanalysis.Linter {
13+
func NewExhaustiveStruct(settings *config.ExhaustiveStructSettings) *goanalysis.Linter {
14+
a := analyzer.Analyzer
15+
16+
var cfg map[string]map[string]interface{}
17+
if settings != nil {
18+
cfg = map[string]map[string]interface{}{
19+
a.Name: {
20+
"struct_patterns": strings.Join(settings.StructPatterns, ","),
21+
},
22+
}
23+
}
24+
1125
return goanalysis.NewLinter(
12-
"exhaustivestruct",
13-
"Checks if all struct's fields are initialized",
14-
[]*analysis.Analyzer{analyzer.Analyzer},
15-
nil,
26+
a.Name,
27+
a.Doc,
28+
[]*analysis.Analyzer{a},
29+
cfg,
1630
).WithLoadMode(goanalysis.LoadModeTypesInfo)
1731
}

pkg/lint/lintersdb/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
9292
var govetCfg *config.GovetSettings
9393
var testpackageCfg *config.TestpackageSettings
9494
var exhaustiveCfg *config.ExhaustiveSettings
95+
var exhaustiveStructCfg *config.ExhaustiveStructSettings
9596
var errorlintCfg *config.ErrorLintSettings
9697
var thelperCfg *config.ThelperSettings
9798
var predeclaredCfg *config.PredeclaredSettings
@@ -101,6 +102,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
101102
govetCfg = &m.cfg.LintersSettings.Govet
102103
testpackageCfg = &m.cfg.LintersSettings.Testpackage
103104
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
105+
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
104106
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
105107
thelperCfg = &m.cfg.LintersSettings.Thelper
106108
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
@@ -337,7 +339,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
337339
WithPresets(linter.PresetStyle).
338340
WithLoadForGoAnalysis().
339341
WithURL("https://github.com/moricho/tparallel"),
340-
linter.NewConfig(golinters.NewExhaustiveStruct()).
342+
linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)).
341343
WithPresets(linter.PresetStyle).
342344
WithLoadForGoAnalysis().
343345
WithURL("https://github.com/mbilski/exhaustivestruct"),
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//args: -Eexhaustivestruct
2+
//config: linters-settings.exhaustivestruct.struct-patterns=*.Test1,*.Test3
3+
package testdata
4+
5+
import "time"
6+
7+
type Test1 struct {
8+
A string
9+
B int
10+
c bool // private field inside the same package are not ignored
11+
D float64
12+
E time.Time
13+
}
14+
15+
var passTest1 = Test1{
16+
A: "a",
17+
B: 0,
18+
c: false,
19+
D: 1.0,
20+
E: time.Now(),
21+
}
22+
23+
var failTest1 = Test1{ // ERROR "B is missing in Test"
24+
A: "a",
25+
c: false,
26+
D: 1.0,
27+
E: time.Now(),
28+
}
29+
30+
var failMultipleTest1 = Test1{ // ERROR "B, D are missing in Test"
31+
A: "a",
32+
c: false,
33+
E: time.Now(),
34+
}
35+
36+
var failPrivateTest1 = Test1{ // ERROR "c is missing in Test"
37+
A: "a",
38+
B: 0,
39+
D: 1.0,
40+
E: time.Now(),
41+
}
42+
43+
type Test2 struct {
44+
A string
45+
B int
46+
c bool // private field inside the same package are not ignored
47+
D float64
48+
E time.Time
49+
}
50+
51+
var passTest2 = Test1{
52+
A: "a",
53+
B: 0,
54+
c: false,
55+
D: 1.0,
56+
E: time.Now(),
57+
}
58+
59+
var failTest2 = Test2{
60+
A: "a",
61+
c: false,
62+
D: 1.0,
63+
E: time.Now(),
64+
}
65+
66+
var failMultipleTest2 = Test2{
67+
A: "a",
68+
c: false,
69+
E: time.Now(),
70+
}
71+
72+
var failPrivateTest2 = Test2{
73+
A: "a",
74+
B: 0,
75+
D: 1.0,
76+
E: time.Now(),
77+
}
78+
79+
type Test3 struct {
80+
A string
81+
B int
82+
c bool // private field inside the same package are not ignored
83+
D float64
84+
E time.Time
85+
}
86+
87+
var passTest3 = Test3{
88+
A: "a",
89+
B: 0,
90+
c: false,
91+
D: 1.0,
92+
E: time.Now(),
93+
}
94+
95+
var failTest3 = Test3{ // ERROR "B is missing in Test"
96+
A: "a",
97+
c: false,
98+
D: 1.0,
99+
E: time.Now(),
100+
}
101+
102+
var failMultipleTest3 = Test3{ // ERROR "B, D are missing in Test"
103+
A: "a",
104+
c: false,
105+
E: time.Now(),
106+
}
107+
108+
var failPrivateTest3 = Test3{ // ERROR "c is missing in Test"
109+
A: "a",
110+
B: 0,
111+
D: 1.0,
112+
E: time.Now(),
113+
}

0 commit comments

Comments
 (0)