diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index cb4095d03aae..3d47951783f3 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -550,26 +550,16 @@ type TestpackageSettings struct { } type ThelperSettings struct { - Test struct { - First bool `mapstructure:"first"` - Name bool `mapstructure:"name"` - Begin bool `mapstructure:"begin"` - } `mapstructure:"test"` - Fuzz struct { - First bool `mapstructure:"first"` - Name bool `mapstructure:"name"` - Begin bool `mapstructure:"begin"` - } `mapstructure:"fuzz"` - Benchmark struct { - First bool `mapstructure:"first"` - Name bool `mapstructure:"name"` - Begin bool `mapstructure:"begin"` - } `mapstructure:"benchmark"` - TB struct { - First bool `mapstructure:"first"` - Name bool `mapstructure:"name"` - Begin bool `mapstructure:"begin"` - } `mapstructure:"tb"` + Test ThelperOptions `mapstructure:"test"` + Fuzz ThelperOptions `mapstructure:"fuzz"` + Benchmark ThelperOptions `mapstructure:"benchmark"` + TB ThelperOptions `mapstructure:"tb"` +} + +type ThelperOptions struct { + First *bool `mapstructure:"first"` + Name *bool `mapstructure:"name"` + Begin *bool `mapstructure:"begin"` } type TenvSettings struct { diff --git a/pkg/golinters/thelper.go b/pkg/golinters/thelper.go index 349c46666df6..41edbe7616fd 100644 --- a/pkg/golinters/thelper.go +++ b/pkg/golinters/thelper.go @@ -13,53 +13,44 @@ import ( func NewThelper(cfg *config.ThelperSettings) *goanalysis.Linter { a := analyzer.NewAnalyzer() - cfgMap := map[string]map[string]interface{}{} - if cfg != nil { - var opts []string + opts := map[string]struct{}{ + "t_name": {}, + "t_begin": {}, + "t_first": {}, - if cfg.Test.Name { - opts = append(opts, "t_name") - } - if cfg.Test.Begin { - opts = append(opts, "t_begin") - } - if cfg.Test.First { - opts = append(opts, "t_first") - } + "f_name": {}, + "f_begin": {}, + "f_first": {}, - if cfg.Fuzz.Name { - opts = append(opts, "f_name") - } - if cfg.Fuzz.Begin { - opts = append(opts, "f_begin") - } - if cfg.Fuzz.First { - opts = append(opts, "f_first") - } + "b_name": {}, + "b_begin": {}, + "b_first": {}, - if cfg.Benchmark.Name { - opts = append(opts, "b_name") - } - if cfg.Benchmark.Begin { - opts = append(opts, "b_begin") - } - if cfg.Benchmark.First { - opts = append(opts, "b_first") - } + "tb_name": {}, + "tb_begin": {}, + "tb_first": {}, + } - if cfg.TB.Name { - opts = append(opts, "tb_name") - } - if cfg.TB.Begin { - opts = append(opts, "tb_begin") - } - if cfg.TB.First { - opts = append(opts, "tb_first") - } + if cfg != nil { + applyTHelperOptions(cfg.Test, "t_", opts) + applyTHelperOptions(cfg.Fuzz, "f_", opts) + applyTHelperOptions(cfg.Benchmark, "b_", opts) + applyTHelperOptions(cfg.TB, "tb_", opts) + } - cfgMap[a.Name] = map[string]interface{}{ - "checks": strings.Join(opts, ","), - } + if len(opts) == 0 { + linterLogger.Fatalf("thelper: at least one option must be enabled") + } + + var args []string + for k := range opts { + args = append(args, k) + } + + cfgMap := map[string]map[string]interface{}{ + a.Name: { + "checks": strings.Join(args, ","), + }, } return goanalysis.NewLinter( @@ -69,3 +60,23 @@ func NewThelper(cfg *config.ThelperSettings) *goanalysis.Linter { cfgMap, ).WithLoadMode(goanalysis.LoadModeTypesInfo) } + +func applyTHelperOptions(o config.ThelperOptions, prefix string, opts map[string]struct{}) { + if o.Name != nil { + if !*o.Name { + delete(opts, prefix+"name") + } + } + + if o.Begin != nil { + if !*o.Begin { + delete(opts, prefix+"begin") + } + } + + if o.First != nil { + if !*o.First { + delete(opts, prefix+"first") + } + } +} diff --git a/test/testdata/configs/thelper.yml b/test/testdata/configs/thelper.yml new file mode 100644 index 000000000000..eaa8f403b206 --- /dev/null +++ b/test/testdata/configs/thelper.yml @@ -0,0 +1,5 @@ +linters-settings: + thelper: + test: + name: false + begin: true diff --git a/test/testdata/thelper_with_options.go b/test/testdata/thelper_with_options.go new file mode 100644 index 000000000000..da835b536164 --- /dev/null +++ b/test/testdata/thelper_with_options.go @@ -0,0 +1,18 @@ +// args: -Ethelper +// config_path: testdata/configs/thelper.yml +package testdata + +import "testing" + +func thelperWithHelperAfterAssignmentWO(t *testing.T) { // ERROR "test helper function should start from t.Helper()" + _ = 0 + t.Helper() +} + +func thelperWithNotFirstWO(s string, t *testing.T, i int) { // ERROR `parameter \*testing.T should be the first` + t.Helper() +} + +func thelperWithIncorrectNameWO(o *testing.T) { + o.Helper() +}