Skip to content

Commit ee24481

Browse files
ldezashanbrown
authored andcommitted
exhaustivestruct: add missing settings (golangci#1746)
1 parent 42271c0 commit ee24481

File tree

5 files changed

+171
-31
lines changed

5 files changed

+171
-31
lines changed

.golangci.example.yml

+6
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

+30-25
Original file line numberDiff line numberDiff line change
@@ -249,31 +249,32 @@ type LintersSettings struct {
249249
} `mapstructure:"blocked"`
250250
}
251251

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

278279
Custom map[string]CustomLinterSettings
279280
}
@@ -387,6 +388,10 @@ type ExhaustiveSettings struct {
387388
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
388389
}
389390

391+
type ExhaustiveStructSettings struct {
392+
StructPatterns []string `mapstructure:"struct-patterns"`
393+
}
394+
390395
type GofumptSettings struct {
391396
ExtraRules bool `mapstructure:"extra-rules"`
392397
}

pkg/golinters/exhaustivestruct.go

+19-5
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

+3-1
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
@@ -102,6 +103,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
102103
govetCfg = &m.cfg.LintersSettings.Govet
103104
testpackageCfg = &m.cfg.LintersSettings.Testpackage
104105
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
106+
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
105107
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
106108
thelperCfg = &m.cfg.LintersSettings.Thelper
107109
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
@@ -339,7 +341,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
339341
WithPresets(linter.PresetStyle).
340342
WithLoadForGoAnalysis().
341343
WithURL("https://github.com/moricho/tparallel"),
342-
linter.NewConfig(golinters.NewExhaustiveStruct()).
344+
linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)).
343345
WithPresets(linter.PresetStyle).
344346
WithLoadForGoAnalysis().
345347
WithURL("https://github.com/mbilski/exhaustivestruct"),
+113
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)