diff --git a/pkg/config/config.go b/pkg/config/config.go index 224807390ac6..7f2be2e4c3ff 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -39,6 +39,20 @@ type Version struct { Format string `mapstructure:"format"` } +func IsGreaterThanOrEqualGo118(v string) bool { + v1, err := hcversion.NewVersion(strings.TrimPrefix(v, "go")) + if err != nil { + return false + } + + limit, err := hcversion.NewVersion("1.18") + if err != nil { + return false + } + + return v1.GreaterThanOrEqual(limit) +} + func DetectGo() string { const defaultGo = "1.17" diff --git a/pkg/config/linters_settings.go b/pkg/config/linters_settings.go index 2ae8550e71b4..3f984ce3724e 100644 --- a/pkg/config/linters_settings.go +++ b/pkg/config/linters_settings.go @@ -374,7 +374,8 @@ type GoSecSettings struct { } type GovetSettings struct { - CheckShadowing bool `mapstructure:"check-shadowing"` + Go string `mapstructure:"-"` + CheckShadowing bool `mapstructure:"check-shadowing"` Settings map[string]map[string]interface{} Enable []string @@ -383,7 +384,7 @@ type GovetSettings struct { DisableAll bool `mapstructure:"disable-all"` } -func (cfg GovetSettings) Validate() error { +func (cfg *GovetSettings) Validate() error { if cfg.EnableAll && cfg.DisableAll { return errors.New("enable-all and disable-all can't be combined") } diff --git a/pkg/golinters/govet.go b/pkg/golinters/govet.go index b3860e01705c..c7a58af610f8 100644 --- a/pkg/golinters/govet.go +++ b/pkg/golinters/govet.go @@ -119,7 +119,46 @@ var ( } ) +func NewGovet(cfg *config.GovetSettings) *goanalysis.Linter { + var settings map[string]map[string]interface{} + if cfg != nil { + settings = cfg.Settings + } + return goanalysis.NewLinter( + "govet", + "Vet examines Go source code and reports suspicious constructs, "+ + "such as Printf calls whose arguments do not align with the format string", + analyzersFromConfig(cfg), + settings, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} + +func analyzersFromConfig(cfg *config.GovetSettings) []*analysis.Analyzer { + if cfg == nil { + return defaultAnalyzers + } + + if cfg.CheckShadowing { + // Keeping for backward compatibility. + cfg.Enable = append(cfg.Enable, shadow.Analyzer.Name) + } + + var enabledAnalyzers []*analysis.Analyzer + for _, a := range allAnalyzers { + if isAnalyzerEnabled(a.Name, cfg, defaultAnalyzers) { + enabledAnalyzers = append(enabledAnalyzers, a) + } + } + + return enabledAnalyzers +} + func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers []*analysis.Analyzer) bool { + if (name == nilness.Analyzer.Name || name == unusedwrite.Analyzer.Name) && + config.IsGreaterThanOrEqualGo118(cfg.Go) { + return false + } + if cfg.EnableAll { for _, n := range cfg.Disable { if n == name { @@ -128,20 +167,24 @@ func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers } return true } + // Raw for loops should be OK on small slice lengths. for _, n := range cfg.Enable { if n == name { return true } } + for _, n := range cfg.Disable { if n == name { return false } } + if cfg.DisableAll { return false } + for _, a := range defaultAnalyzers { if a.Name == name { return true @@ -149,37 +192,3 @@ func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers } return false } - -func analyzersFromConfig(cfg *config.GovetSettings) []*analysis.Analyzer { - if cfg == nil { - return defaultAnalyzers - } - - if cfg.CheckShadowing { - // Keeping for backward compatibility. - cfg.Enable = append(cfg.Enable, shadow.Analyzer.Name) - } - - var enabledAnalyzers []*analysis.Analyzer - for _, a := range allAnalyzers { - if isAnalyzerEnabled(a.Name, cfg, defaultAnalyzers) { - enabledAnalyzers = append(enabledAnalyzers, a) - } - } - - return enabledAnalyzers -} - -func NewGovet(cfg *config.GovetSettings) *goanalysis.Linter { - var settings map[string]map[string]interface{} - if cfg != nil { - settings = cfg.Settings - } - return goanalysis.NewLinter( - "govet", - "Vet examines Go source code and reports suspicious constructs, "+ - "such as Printf calls whose arguments do not align with the format string", - analyzersFromConfig(cfg), - settings, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/pkg/lint/linter/config.go b/pkg/lint/linter/config.go index 184b00cc7269..c8e065542e2a 100644 --- a/pkg/lint/linter/config.go +++ b/pkg/lint/linter/config.go @@ -1,9 +1,6 @@ package linter import ( - "strings" - - hcversion "github.com/hashicorp/go-version" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/packages" @@ -126,7 +123,7 @@ func (lc *Config) Name() string { } func (lc *Config) WithNoopFallback(cfg *config.Config) *Config { - if isGreaterThanOrEqualGo118(cfg) { + if cfg != nil && config.IsGreaterThanOrEqualGo118(cfg.Run.Go) { lc.Linter = &Noop{ name: lc.Linter.Name(), desc: lc.Linter.Desc(), @@ -148,21 +145,3 @@ func NewConfig(linter Linter) *Config { } return lc.WithLoadFiles() } - -func isGreaterThanOrEqualGo118(cfg *config.Config) bool { - if cfg == nil { - return false - } - - v1, err := hcversion.NewVersion(strings.TrimPrefix(cfg.Run.Go, "go")) - if err != nil { - return false - } - - limit, err := hcversion.NewVersion("1.18") - if err != nil { - return false - } - - return v1.GreaterThanOrEqual(limit) -} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 736bffd16146..579435e83d6f 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -164,6 +164,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { unusedCfg = &m.cfg.LintersSettings.Unused varnamelenCfg = &m.cfg.LintersSettings.Varnamelen wrapcheckCfg = &m.cfg.LintersSettings.Wrapcheck + + if govetCfg != nil { + govetCfg.Go = m.cfg.Run.Go + } } const megacheckName = "megacheck"