From 59f60f5ef37872ba9b023705ea6726b21b836c7c Mon Sep 17 00:00:00 2001 From: Nishanth Shanmugham Date: Fri, 5 Nov 2021 03:38:37 +0530 Subject: [PATCH] exhaustive: upgrade to v0.3.6; add new flags and deprecate old ones (#2344) --- .golangci.example.yml | 12 +++++++--- go.mod | 2 +- go.sum | 4 ++-- pkg/config/linters_settings.go | 6 ++++- pkg/golinters/exhaustive.go | 2 ++ .../exhaustive_checking_strategy_name.yml | 3 +++ .../exhaustive_checking_strategy_value.yml | 3 +++ .../exhaustive_ignore_enum_members.yml | 3 +++ .../exhaustive_checking_strategy_name.go | 18 +++++++++++++++ .../exhaustive_checking_strategy_value.go | 22 +++++++++++++++++++ test/testdata/exhaustive_default.go | 4 ++++ .../exhaustive_ignore_enum_members.go | 21 ++++++++++++++++++ 12 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 test/testdata/configs/exhaustive_checking_strategy_name.yml create mode 100644 test/testdata/configs/exhaustive_checking_strategy_value.yml create mode 100644 test/testdata/configs/exhaustive_ignore_enum_members.yml create mode 100644 test/testdata/exhaustive_checking_strategy_name.go create mode 100644 test/testdata/exhaustive_checking_strategy_value.go create mode 100644 test/testdata/exhaustive_ignore_enum_members.go diff --git a/.golangci.example.yml b/.golangci.example.yml index 27b5d7f2b81b..c94e8799a6fe 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -136,10 +136,16 @@ linters-settings: exhaustive: # check switch statements in generated files also check-generated: false - # indicates that switch statements are to be considered exhaustive if a - # 'default' case is present, even if all enum members aren't listed in the - # switch + # presence of "default" case in switch statements satisfies exhaustiveness, + # even if all enum members are not listed default-signifies-exhaustive: false + # enum members matching the supplied regex do not have to be listed in + # switch statements to satisfy exhaustiveness + ignore-enum-members: "" + # strategy to use when checking exhaustiveness of switch statements; one of: + # "name", "value"; see documentation for details: + # https://pkg.go.dev/github.com/nishanths/exhaustive#section-documentation + checking-strategy: "value" exhaustivestruct: # Struct Patterns is list of expressions to match struct packages and names diff --git a/go.mod b/go.mod index 48b6dce56031..dca9706c77d7 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/mitchellh/go-ps v1.0.0 github.com/moricho/tparallel v0.2.1 github.com/nakabonne/nestif v0.3.1 - github.com/nishanths/exhaustive v0.2.3 + github.com/nishanths/exhaustive v0.3.6 github.com/nishanths/predeclared v0.2.1 github.com/pkg/errors v0.9.1 github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349 diff --git a/go.sum b/go.sum index c26026cd2b02..08916429e8b4 100644 --- a/go.sum +++ b/go.sum @@ -550,8 +550,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6Fx github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.2.3 h1:+ANTMqRNrqwInnP9aszg/0jDo+zbXa4x66U19Bx/oTk= -github.com/nishanths/exhaustive v0.2.3/go.mod h1:bhIX678Nx8inLM9PbpvK1yv6oGtoP8BfaIeMzgBNKvc= +github.com/nishanths/exhaustive v0.3.6 h1:uRVZUfvWqSsPv+w4Qv30WgWdJwGOqR1P7QCwyhiKbOs= +github.com/nishanths/exhaustive v0.3.6/go.mod h1:gX+MP7DWMKJmNa1HfMozK+u04hQd3na9i0hyqf3/dOI= github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzjFzG2sw= github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 840b283fec13..56c2d7c6341e 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -57,6 +57,8 @@ var defaultLintersSettings = LintersSettings{ Exhaustive: ExhaustiveSettings{ CheckGenerated: false, DefaultSignifiesExhaustive: false, + IgnoreEnumMembers: "", + CheckingStrategy: "value", }, Gofumpt: GofumptSettings{ LangVersion: "", @@ -184,7 +186,9 @@ type ErrorLintSettings struct { type ExhaustiveSettings struct { CheckGenerated bool `mapstructure:"check-generated"` DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"` - IgnorePattern string `mapstructure:"ignore-pattern"` + IgnorePattern string `mapstructure:"ignore-pattern"` // Deprecated: this setting has no effect; see IgnoreEnumMembers instead. + IgnoreEnumMembers string `mapstructure:"ignore-enum-members"` + CheckingStrategy string `mapstructure:"checking-strategy"` } type ExhaustiveStructSettings struct { diff --git a/pkg/golinters/exhaustive.go b/pkg/golinters/exhaustive.go index 9acee6a80641..f3a138295e40 100644 --- a/pkg/golinters/exhaustive.go +++ b/pkg/golinters/exhaustive.go @@ -18,6 +18,8 @@ func NewExhaustive(settings *config.ExhaustiveSettings) *goanalysis.Linter { exhaustive.CheckGeneratedFlag: settings.CheckGenerated, exhaustive.DefaultSignifiesExhaustiveFlag: settings.DefaultSignifiesExhaustive, exhaustive.IgnorePatternFlag: settings.IgnorePattern, + exhaustive.IgnoreEnumMembersFlag: settings.IgnoreEnumMembers, + exhaustive.CheckingStrategyFlag: settings.CheckingStrategy, }, } } diff --git a/test/testdata/configs/exhaustive_checking_strategy_name.yml b/test/testdata/configs/exhaustive_checking_strategy_name.yml new file mode 100644 index 000000000000..dca93cab4e5d --- /dev/null +++ b/test/testdata/configs/exhaustive_checking_strategy_name.yml @@ -0,0 +1,3 @@ +linters-settings: + exhaustive: + checking-strategy: "name" diff --git a/test/testdata/configs/exhaustive_checking_strategy_value.yml b/test/testdata/configs/exhaustive_checking_strategy_value.yml new file mode 100644 index 000000000000..dd64f0581e9c --- /dev/null +++ b/test/testdata/configs/exhaustive_checking_strategy_value.yml @@ -0,0 +1,3 @@ +linters-settings: + exhaustive: + checking-strategy: "value" diff --git a/test/testdata/configs/exhaustive_ignore_enum_members.yml b/test/testdata/configs/exhaustive_ignore_enum_members.yml new file mode 100644 index 000000000000..d5b8e2166d9f --- /dev/null +++ b/test/testdata/configs/exhaustive_ignore_enum_members.yml @@ -0,0 +1,3 @@ +linters-settings: + exhaustive: + ignore-enum-members: "West$" diff --git a/test/testdata/exhaustive_checking_strategy_name.go b/test/testdata/exhaustive_checking_strategy_name.go new file mode 100644 index 000000000000..55bf12675046 --- /dev/null +++ b/test/testdata/exhaustive_checking_strategy_name.go @@ -0,0 +1,18 @@ +//args: -Eexhaustive +//config_path: testdata/configs/exhaustive_checking_strategy_name.yml +package testdata + +type AccessControl string + +const ( + AccessPublic AccessControl = "public" + AccessPrivate AccessControl = "private" + AccessDefault AccessControl = AccessPublic +) + +func example(v AccessControl) { + switch v { // ERROR "missing cases in switch of type AccessControl: AccessDefault" + case AccessPublic: + case AccessPrivate: + } +} diff --git a/test/testdata/exhaustive_checking_strategy_value.go b/test/testdata/exhaustive_checking_strategy_value.go new file mode 100644 index 000000000000..7e1688190de9 --- /dev/null +++ b/test/testdata/exhaustive_checking_strategy_value.go @@ -0,0 +1,22 @@ +//args: -Eexhaustive +//config_path: testdata/configs/exhaustive_checking_strategy_value.yml +package testdata + +type AccessControl string + +const ( + AccessPublic AccessControl = "public" + AccessPrivate AccessControl = "private" + AccessDefault AccessControl = AccessPublic +) + +// Expect no diagnostics for this switch statement, even though AccessDefault is +// not listed, because AccessPublic (which is listed) has the same value as +// AccessDefault. + +func example(v AccessControl) { + switch v { + case AccessPublic: + case AccessPrivate: + } +} diff --git a/test/testdata/exhaustive_default.go b/test/testdata/exhaustive_default.go index 1dc2637fd198..50898eba2469 100644 --- a/test/testdata/exhaustive_default.go +++ b/test/testdata/exhaustive_default.go @@ -11,6 +11,10 @@ const ( West ) +// Should not report missing cases in the switch statement below even though +// some enum members (East, West) are not listed, because the switch statement +// has a 'default' case and the default-signifies-exhaustive setting is true. + func processDirectionDefault(d Direction) { switch d { case North, South: diff --git a/test/testdata/exhaustive_ignore_enum_members.go b/test/testdata/exhaustive_ignore_enum_members.go new file mode 100644 index 000000000000..65bf8fc8d76f --- /dev/null +++ b/test/testdata/exhaustive_ignore_enum_members.go @@ -0,0 +1,21 @@ +//args: -Eexhaustive +//config_path: testdata/configs/exhaustive_ignore_enum_members.yml +package testdata + +type Direction int + +const ( + North Direction = iota + East + South + West +) + +// Should only report East as missing because the enum member West is ignored +// using the ignore-enum-members setting. + +func processDirectionIgnoreEnumMembers(d Direction) { + switch d { // ERROR "missing cases in switch of type Direction: East" + case North, South: + } +}