Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exhaustivestruct: add missing settings #1746

Merged
merged 1 commit into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(),
}