Skip to content

Commit

Permalink
exhaustivestruct: add missing settings (#1746)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez authored Feb 19, 2021
1 parent 4b3fb4c commit ea5f479
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 31 deletions.
6 changes: 6 additions & 0 deletions .golangci.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ linters-settings:
# 'default' case is present, even if all enum members aren't listed in the
# switch
default-signifies-exhaustive: false
exhaustivestruct:
struct-patterns:
- '*.Test'
- '*.Test2'
- '*.Embedded'
- '*.External'
funlen:
lines: 60
statements: 40
Expand Down
55 changes: 30 additions & 25 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,31 +249,32 @@ type LintersSettings struct {
} `mapstructure:"blocked"`
}

WSL WSLSettings
Lll LllSettings
Unparam UnparamSettings
Nakedret NakedretSettings
Prealloc PreallocSettings
Errcheck ErrcheckSettings
Gocritic GocriticSettings
Godox GodoxSettings
Dogsled DogsledSettings
Gocognit GocognitSettings
Godot GodotSettings
Goheader GoHeaderSettings
Testpackage TestpackageSettings
Nestif NestifSettings
NoLintLint NoLintLintSettings
Exhaustive ExhaustiveSettings
Gofumpt GofumptSettings
ErrorLint ErrorLintSettings
Makezero MakezeroSettings
Revive ReviveSettings
Thelper ThelperSettings
Forbidigo ForbidigoSettings
Ifshort IfshortSettings
Predeclared PredeclaredSettings
Cyclop Cyclop
WSL WSLSettings
Lll LllSettings
Unparam UnparamSettings
Nakedret NakedretSettings
Prealloc PreallocSettings
Errcheck ErrcheckSettings
Gocritic GocriticSettings
Godox GodoxSettings
Dogsled DogsledSettings
Gocognit GocognitSettings
Godot GodotSettings
Goheader GoHeaderSettings
Testpackage TestpackageSettings
Nestif NestifSettings
NoLintLint NoLintLintSettings
Exhaustive ExhaustiveSettings
ExhaustiveStruct ExhaustiveStructSettings
Gofumpt GofumptSettings
ErrorLint ErrorLintSettings
Makezero MakezeroSettings
Revive ReviveSettings
Thelper ThelperSettings
Forbidigo ForbidigoSettings
Ifshort IfshortSettings
Predeclared PredeclaredSettings
Cyclop Cyclop

Custom map[string]CustomLinterSettings
}
Expand Down Expand Up @@ -387,6 +388,10 @@ type ExhaustiveSettings struct {
DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"`
}

type ExhaustiveStructSettings struct {
StructPatterns []string `mapstructure:"struct-patterns"`
}

type GofumptSettings struct {
ExtraRules bool `mapstructure:"extra-rules"`
}
Expand Down
24 changes: 19 additions & 5 deletions pkg/golinters/exhaustivestruct.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
package golinters

import (
"strings"

"github.com/mbilski/exhaustivestruct/pkg/analyzer"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"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(
"exhaustivestruct",
"Checks if all struct's fields are initialized",
[]*analysis.Analyzer{analyzer.Analyzer},
nil,
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
cfg,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
4 changes: 3 additions & 1 deletion pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var govetCfg *config.GovetSettings
var testpackageCfg *config.TestpackageSettings
var exhaustiveCfg *config.ExhaustiveSettings
var exhaustiveStructCfg *config.ExhaustiveStructSettings
var errorlintCfg *config.ErrorLintSettings
var thelperCfg *config.ThelperSettings
var predeclaredCfg *config.PredeclaredSettings
Expand All @@ -102,6 +103,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
govetCfg = &m.cfg.LintersSettings.Govet
testpackageCfg = &m.cfg.LintersSettings.Testpackage
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
thelperCfg = &m.cfg.LintersSettings.Thelper
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
Expand Down Expand Up @@ -339,7 +341,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/moricho/tparallel"),
linter.NewConfig(golinters.NewExhaustiveStruct()).
linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)).
WithPresets(linter.PresetStyle).
WithLoadForGoAnalysis().
WithURL("https://github.com/mbilski/exhaustivestruct"),
Expand Down
113 changes: 113 additions & 0 deletions test/testdata/exhaustivestruct_custom.go
Original file line number Diff line number Diff line change
@@ -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(),
}

0 comments on commit ea5f479

Please sign in to comment.