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

staticcheck: configurable Go version. #1946

Merged
merged 3 commits into from Apr 30, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 16 additions & 7 deletions .golangci.example.yml
Expand Up @@ -358,6 +358,10 @@ linters-settings:
per_char_threshold: "3.0"
truncate: "32"

gosimple:
# Select the Go version to target. The default is '1.13'.
go: "1.15"

govet:
# report about shadowed variables
check-shadowing: true
Expand Down Expand Up @@ -488,6 +492,14 @@ linters-settings:
- name: indent-error-flow
severity: warning

staticcheck:
# Select the Go version to target. The default is '1.13'.
go: "1.15"

stylecheck:
# Select the Go version to target. The default is '1.13'.
go: "1.15"

tagliatelle:
# check the struck tag name case
case:
Expand Down Expand Up @@ -531,11 +543,8 @@ linters-settings:
check-exported: false

unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
# Select the Go version to target. The default is '1.13'.
go: "1.15"

whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
Expand All @@ -556,8 +565,8 @@ linters-settings:
force-short-decl-cuddling: false
strict-append: true

# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
# for more info.
# The custom section can be used to define linter plugins to be loaded at runtime.
# See README doc for more info.
custom:
# Each custom linter should have a unique name.
example:
Expand Down
13 changes: 8 additions & 5 deletions pkg/config/linters_settings.go
Expand Up @@ -104,6 +104,7 @@ type LintersSettings struct {
GoModDirectives GoModDirectivesSettings
Gomodguard GoModGuardSettings
Gosec GoSecSettings
Gosimple StaticCheckSettings
Govet GovetSettings
Ifshort IfshortSettings
ImportAs ImportAsSettings
Expand All @@ -119,12 +120,14 @@ type LintersSettings struct {
Promlinter PromlinterSettings
Revive ReviveSettings
RowsErrCheck RowsErrCheckSettings
Staticcheck StaticCheckSettings
Structcheck StructCheckSettings
Stylecheck StaticCheckSettings
Tagliatelle TagliatelleSettings
Testpackage TestpackageSettings
Thelper ThelperSettings
Unparam UnparamSettings
Unused UnusedSettings
Unused StaticCheckSettings
Varcheck VarCheckSettings
Whitespace WhitespaceSettings
WSL WSLSettings
Expand Down Expand Up @@ -376,6 +379,10 @@ type RowsErrCheckSettings struct {
Packages []string
}

type StaticCheckSettings struct {
GoVersion string `mapstructure:"go"`
}

type StructCheckSettings struct {
CheckExportedFields bool `mapstructure:"exported-fields"`
}
Expand Down Expand Up @@ -414,10 +421,6 @@ type UnparamSettings struct {
Algo string
}

type UnusedSettings struct {
CheckExported bool `mapstructure:"check-exported"`
}

type VarCheckSettings struct {
CheckExportedFields bool `mapstructure:"exported-fields"`
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/golinters/gosimple.go
Expand Up @@ -3,12 +3,12 @@ package golinters
import (
"honnef.co/go/tools/simple"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewGosimple() *goanalysis.Linter {
analyzers := analyzersMapToSlice(simple.Analyzers)
setAnalyzersGoVersion(analyzers)
func NewGosimple(settings *config.StaticCheckSettings) *goanalysis.Linter {
analyzers := setupStaticCheckAnalyzers(simple.Analyzers, settings)

return goanalysis.NewLinter(
"gosimple",
Expand Down
30 changes: 0 additions & 30 deletions pkg/golinters/megacheck.go

This file was deleted.

6 changes: 3 additions & 3 deletions pkg/golinters/staticcheck.go
Expand Up @@ -3,12 +3,12 @@ package golinters
import (
"honnef.co/go/tools/staticcheck"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewStaticcheck() *goanalysis.Linter {
analyzers := analyzersMapToSlice(staticcheck.Analyzers)
setAnalyzersGoVersion(analyzers)
func NewStaticcheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
analyzers := setupStaticCheckAnalyzers(staticcheck.Analyzers, settings)

return goanalysis.NewLinter(
"staticcheck",
Expand Down
33 changes: 33 additions & 0 deletions pkg/golinters/staticcheck_common.go
@@ -0,0 +1,33 @@
package golinters

import (
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/logutils"
)

var debugf = logutils.Debug("megacheck")

func setupStaticCheckAnalyzers(m map[string]*analysis.Analyzer, settings *config.StaticCheckSettings) []*analysis.Analyzer {
var ret []*analysis.Analyzer
for _, v := range m {
setAnalyzerGoVersion(v, settings)
ret = append(ret, v)
}
return ret
}

func setAnalyzerGoVersion(a *analysis.Analyzer, settings *config.StaticCheckSettings) {
// TODO: uses "1.13" for backward compatibility, but in the future (v2) must be set by using build.Default.ReleaseTags like staticcheck.
goVersion := "1.13"
if settings != nil && settings.GoVersion != "" {
goVersion = settings.GoVersion
}

if v := a.Flags.Lookup("go"); v != nil {
if err := v.Value.Set(goVersion); err != nil {
debugf("Failed to set go version: %s", err)
}
}
}
6 changes: 3 additions & 3 deletions pkg/golinters/stylecheck.go
Expand Up @@ -3,12 +3,12 @@ package golinters
import (
"honnef.co/go/tools/stylecheck"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewStylecheck() *goanalysis.Linter {
analyzers := analyzersMapToSlice(stylecheck.Analyzers)
setAnalyzersGoVersion(analyzers)
func NewStylecheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
analyzers := setupStaticCheckAnalyzers(stylecheck.Analyzers, settings)

return goanalysis.NewLinter(
"stylecheck",
Expand Down
12 changes: 8 additions & 4 deletions pkg/golinters/unused.go
Expand Up @@ -7,12 +7,17 @@ import (
"golang.org/x/tools/go/analysis"
"honnef.co/go/tools/unused"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)

func NewUnused() *goanalysis.Linter {
type UnusedSettings struct {
GoVersion string
}

func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
const name = "unused"

var mu sync.Mutex
Expand Down Expand Up @@ -49,13 +54,12 @@ func NewUnused() *goanalysis.Linter {
},
}

analyzers := []*analysis.Analyzer{analyzer}
setAnalyzersGoVersion(analyzers)
setAnalyzerGoVersion(analyzer, settings)

lnt := goanalysis.NewLinter(
name,
"Checks Go code for unused constants, variables, functions and types",
analyzers,
[]*analysis.Analyzer{analyzer},
nil,
).WithIssuesReporter(func(lintCtx *linter.Context) []goanalysis.Issue {
return resIssues
Expand Down
36 changes: 22 additions & 14 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -113,6 +113,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var goModDirectivesCfg *config.GoModDirectivesSettings
var tagliatelleCfg *config.TagliatelleSettings
var gosecCfg *config.GoSecSettings
var gosimpleCfg *config.StaticCheckSettings
var staticcheckCfg *config.StaticCheckSettings
var stylecheckCfg *config.StaticCheckSettings
var unusedCfg *config.StaticCheckSettings

if m.cfg != nil {
govetCfg = &m.cfg.LintersSettings.Govet
Expand All @@ -129,6 +133,10 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
gosecCfg = &m.cfg.LintersSettings.Gosec
gosimpleCfg = &m.cfg.LintersSettings.Gosimple
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
unusedCfg = &m.cfg.LintersSettings.Unused
}

const megacheckName = "megacheck"
Expand Down Expand Up @@ -166,28 +174,28 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithPresets(linter.PresetBugs, linter.PresetSQL).
WithURL("https://github.com/jingyugao/rowserrcheck"),

linter.NewConfig(golinters.NewStaticcheck()).
linter.NewConfig(golinters.NewStaticcheck(staticcheckCfg)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
WithAlternativeNames(megacheckName).
WithURL("https://staticcheck.io/"),
linter.NewConfig(golinters.NewUnused()).
linter.NewConfig(golinters.NewUnused(unusedCfg)).
WithSince("v1.20.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetUnused).
WithAlternativeNames(megacheckName).
ConsiderSlow().
WithChangeTypes().
WithURL("https://github.com/dominikh/go-tools/tree/master/unused"),
linter.NewConfig(golinters.NewGosimple()).
linter.NewConfig(golinters.NewGosimple(gosimpleCfg)).
WithSince("v1.20.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle).
WithAlternativeNames(megacheckName).
WithURL("https://github.com/dominikh/go-tools/tree/master/simple"),

linter.NewConfig(golinters.NewStylecheck()).
linter.NewConfig(golinters.NewStylecheck(stylecheckCfg)).
WithSince("v1.20.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle).
Expand Down Expand Up @@ -499,16 +507,16 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
}

enabledByDefault := map[string]bool{
golinters.NewGovet(nil).Name(): true,
golinters.NewErrcheck().Name(): true,
golinters.NewStaticcheck().Name(): true,
golinters.NewUnused().Name(): true,
golinters.NewGosimple().Name(): true,
golinters.NewStructcheck().Name(): true,
golinters.NewVarcheck().Name(): true,
golinters.NewIneffassign().Name(): true,
golinters.NewDeadcode().Name(): true,
golinters.NewTypecheck().Name(): true,
golinters.NewGovet(nil).Name(): true,
golinters.NewErrcheck().Name(): true,
golinters.NewStaticcheck(staticcheckCfg).Name(): true,
golinters.NewUnused(unusedCfg).Name(): true,
golinters.NewGosimple(gosimpleCfg).Name(): true,
golinters.NewStructcheck().Name(): true,
golinters.NewVarcheck().Name(): true,
golinters.NewIneffassign().Name(): true,
golinters.NewDeadcode().Name(): true,
golinters.NewTypecheck().Name(): true,
}
return enableLinterConfigs(lcs, func(lc *linter.Config) bool {
return enabledByDefault[lc.Name()]
Expand Down