exhaustivestruct: add missing settings (#1746)

This commit is contained in:
Ludovic Fernandez 2021-02-19 19:20:47 +01:00 committed by GitHub
parent 4b3fb4c64f
commit ea5f479087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 171 additions and 31 deletions

View File

@ -111,6 +111,12 @@ linters-settings:
# 'default' case is present, even if all enum members aren't listed in the # 'default' case is present, even if all enum members aren't listed in the
# switch # switch
default-signifies-exhaustive: false default-signifies-exhaustive: false
exhaustivestruct:
struct-patterns:
- '*.Test'
- '*.Test2'
- '*.Embedded'
- '*.External'
funlen: funlen:
lines: 60 lines: 60
statements: 40 statements: 40

View File

@ -265,6 +265,7 @@ type LintersSettings struct {
Nestif NestifSettings Nestif NestifSettings
NoLintLint NoLintLintSettings NoLintLint NoLintLintSettings
Exhaustive ExhaustiveSettings Exhaustive ExhaustiveSettings
ExhaustiveStruct ExhaustiveStructSettings
Gofumpt GofumptSettings Gofumpt GofumptSettings
ErrorLint ErrorLintSettings ErrorLint ErrorLintSettings
Makezero MakezeroSettings Makezero MakezeroSettings
@ -387,6 +388,10 @@ type ExhaustiveSettings struct {
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"` DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
} }
type ExhaustiveStructSettings struct {
StructPatterns []string `mapstructure:"struct-patterns"`
}
type GofumptSettings struct { type GofumptSettings struct {
ExtraRules bool `mapstructure:"extra-rules"` ExtraRules bool `mapstructure:"extra-rules"`
} }

View File

@ -1,17 +1,31 @@
package golinters package golinters
import ( import (
"strings"
"github.com/mbilski/exhaustivestruct/pkg/analyzer" "github.com/mbilski/exhaustivestruct/pkg/analyzer"
"golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis" "github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
) )
func NewExhaustiveStruct() *goanalysis.Linter { func NewExhaustiveStruct(settings *config.ExhaustiveStructSettings) *goanalysis.Linter {
a := analyzer.Analyzer
var cfg map[string]map[string]interface{}
if settings != nil {
cfg = map[string]map[string]interface{}{
a.Name: {
"struct_patterns": strings.Join(settings.StructPatterns, ","),
},
}
}
return goanalysis.NewLinter( return goanalysis.NewLinter(
"exhaustivestruct", a.Name,
"Checks if all struct's fields are initialized", a.Doc,
[]*analysis.Analyzer{analyzer.Analyzer}, []*analysis.Analyzer{a},
nil, cfg,
).WithLoadMode(goanalysis.LoadModeTypesInfo) ).WithLoadMode(goanalysis.LoadModeTypesInfo)
} }

View File

@ -92,6 +92,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var govetCfg *config.GovetSettings var govetCfg *config.GovetSettings
var testpackageCfg *config.TestpackageSettings var testpackageCfg *config.TestpackageSettings
var exhaustiveCfg *config.ExhaustiveSettings var exhaustiveCfg *config.ExhaustiveSettings
var exhaustiveStructCfg *config.ExhaustiveStructSettings
var errorlintCfg *config.ErrorLintSettings var errorlintCfg *config.ErrorLintSettings
var thelperCfg *config.ThelperSettings var thelperCfg *config.ThelperSettings
var predeclaredCfg *config.PredeclaredSettings var predeclaredCfg *config.PredeclaredSettings
@ -102,6 +103,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
govetCfg = &m.cfg.LintersSettings.Govet govetCfg = &m.cfg.LintersSettings.Govet
testpackageCfg = &m.cfg.LintersSettings.Testpackage testpackageCfg = &m.cfg.LintersSettings.Testpackage
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
errorlintCfg = &m.cfg.LintersSettings.ErrorLint errorlintCfg = &m.cfg.LintersSettings.ErrorLint
thelperCfg = &m.cfg.LintersSettings.Thelper thelperCfg = &m.cfg.LintersSettings.Thelper
predeclaredCfg = &m.cfg.LintersSettings.Predeclared predeclaredCfg = &m.cfg.LintersSettings.Predeclared
@ -339,7 +341,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle). WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis(). WithLoadForGoAnalysis().
WithURL("https://github.com/moricho/tparallel"), WithURL("https://github.com/moricho/tparallel"),
linter.NewConfig(golinters.NewExhaustiveStruct()). linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)).
WithPresets(linter.PresetStyle). WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis(). WithLoadForGoAnalysis().
WithURL("https://github.com/mbilski/exhaustivestruct"), WithURL("https://github.com/mbilski/exhaustivestruct"),

113
test/testdata/exhaustivestruct_custom.go vendored Normal file
View File

@ -0,0 +1,113 @@
//args: -Eexhaustivestruct
//config: linters-settings.exhaustivestruct.struct-patterns=*.Test1,*.Test3
package testdata
import "time"
type Test1 struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
var passTest1 = Test1{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
var failTest1 = Test1{ // ERROR "B is missing in Test"
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
var failMultipleTest1 = Test1{ // ERROR "B, D are missing in Test"
A: "a",
c: false,
E: time.Now(),
}
var failPrivateTest1 = Test1{ // ERROR "c is missing in Test"
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
type Test2 struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
var passTest2 = Test1{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
var failTest2 = Test2{
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
var failMultipleTest2 = Test2{
A: "a",
c: false,
E: time.Now(),
}
var failPrivateTest2 = Test2{
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}
type Test3 struct {
A string
B int
c bool // private field inside the same package are not ignored
D float64
E time.Time
}
var passTest3 = Test3{
A: "a",
B: 0,
c: false,
D: 1.0,
E: time.Now(),
}
var failTest3 = Test3{ // ERROR "B is missing in Test"
A: "a",
c: false,
D: 1.0,
E: time.Now(),
}
var failMultipleTest3 = Test3{ // ERROR "B, D are missing in Test"
A: "a",
c: false,
E: time.Now(),
}
var failPrivateTest3 = Test3{ // ERROR "c is missing in Test"
A: "a",
B: 0,
D: 1.0,
E: time.Now(),
}