staticcheck: configuration for staticcheck
, gosimple
, stylecheck
(#2017)
This commit is contained in:
parent
fb7c90d6ee
commit
b916c9318b
@ -366,6 +366,8 @@ linters-settings:
|
||||
gosimple:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.15"
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all" ]
|
||||
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
@ -514,10 +516,21 @@ linters-settings:
|
||||
staticcheck:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.15"
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all" ]
|
||||
|
||||
stylecheck:
|
||||
# Select the Go version to target. The default is '1.13'.
|
||||
go: "1.15"
|
||||
# https://staticcheck.io/docs/options#checks
|
||||
checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
|
||||
# https://staticcheck.io/docs/options#dot_import_whitelist
|
||||
dot-import-whitelist:
|
||||
- fmt
|
||||
# https://staticcheck.io/docs/options#initialisms
|
||||
initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS" ]
|
||||
# https://staticcheck.io/docs/options#http_status_code_whitelist
|
||||
http-status-code-whitelist: [ "200", "400", "404", "500" ]
|
||||
|
||||
tagliatelle:
|
||||
# check the struck tag name case
|
||||
|
@ -394,6 +394,15 @@ type RowsErrCheckSettings struct {
|
||||
|
||||
type StaticCheckSettings struct {
|
||||
GoVersion string `mapstructure:"go"`
|
||||
|
||||
Checks []string `mapstructure:"checks"`
|
||||
Initialisms []string `mapstructure:"initialisms"` // only for stylecheck
|
||||
DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck
|
||||
HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck
|
||||
}
|
||||
|
||||
func (s *StaticCheckSettings) HasConfiguration() bool {
|
||||
return len(s.Initialisms) > 0 || len(s.HTTPStatusCodeWhitelist) > 0 || len(s.DotImportWhitelist) > 0 || len(s.Checks) > 0
|
||||
}
|
||||
|
||||
type StructCheckSettings struct {
|
||||
|
@ -8,7 +8,9 @@ import (
|
||||
)
|
||||
|
||||
func NewGosimple(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
||||
analyzers := setupStaticCheckAnalyzers(simple.Analyzers, settings)
|
||||
cfg := staticCheckConfig(settings)
|
||||
|
||||
analyzers := setupStaticCheckAnalyzers(simple.Analyzers, getGoVersion(settings), cfg.Checks)
|
||||
|
||||
return goanalysis.NewLinter(
|
||||
"gosimple",
|
||||
|
@ -8,7 +8,9 @@ import (
|
||||
)
|
||||
|
||||
func NewStaticcheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
||||
analyzers := setupStaticCheckAnalyzers(staticcheck.Analyzers, settings)
|
||||
cfg := staticCheckConfig(settings)
|
||||
|
||||
analyzers := setupStaticCheckAnalyzers(staticcheck.Analyzers, getGoVersion(settings), cfg.Checks)
|
||||
|
||||
return goanalysis.NewLinter(
|
||||
"staticcheck",
|
||||
|
@ -1,7 +1,11 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
scconfig "honnef.co/go/tools/config"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||
@ -9,25 +13,155 @@ import (
|
||||
|
||||
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 != "" {
|
||||
func getGoVersion(settings *config.StaticCheckSettings) string {
|
||||
var goVersion string
|
||||
if settings != nil {
|
||||
goVersion = settings.GoVersion
|
||||
}
|
||||
|
||||
if goVersion != "" {
|
||||
return goVersion
|
||||
}
|
||||
|
||||
// TODO: uses "1.13" for backward compatibility, but in the future (v2) must be set by using build.Default.ReleaseTags like staticcheck.
|
||||
return "1.13"
|
||||
}
|
||||
|
||||
func setupStaticCheckAnalyzers(src map[string]*analysis.Analyzer, goVersion string, checks []string) []*analysis.Analyzer {
|
||||
var names []string
|
||||
for name := range src {
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
filter := filterAnalyzerNames(names, checks)
|
||||
|
||||
var ret []*analysis.Analyzer
|
||||
for name, a := range src {
|
||||
if filter[name] {
|
||||
setAnalyzerGoVersion(a, goVersion)
|
||||
ret = append(ret, a)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func setAnalyzerGoVersion(a *analysis.Analyzer, goVersion string) {
|
||||
if v := a.Flags.Lookup("go"); v != nil {
|
||||
if err := v.Value.Set(goVersion); err != nil {
|
||||
debugf("Failed to set go version: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func staticCheckConfig(settings *config.StaticCheckSettings) *scconfig.Config {
|
||||
var cfg *scconfig.Config
|
||||
|
||||
if settings == nil || !settings.HasConfiguration() {
|
||||
return &scconfig.Config{
|
||||
Checks: []string{"*"}, // override for compatibility reason. Must drop in the next major version.
|
||||
Initialisms: scconfig.DefaultConfig.Initialisms,
|
||||
DotImportWhitelist: scconfig.DefaultConfig.DotImportWhitelist,
|
||||
HTTPStatusCodeWhitelist: scconfig.DefaultConfig.HTTPStatusCodeWhitelist,
|
||||
}
|
||||
}
|
||||
|
||||
cfg = &scconfig.Config{
|
||||
Checks: settings.Checks,
|
||||
Initialisms: settings.Initialisms,
|
||||
DotImportWhitelist: settings.DotImportWhitelist,
|
||||
HTTPStatusCodeWhitelist: settings.HTTPStatusCodeWhitelist,
|
||||
}
|
||||
|
||||
if len(cfg.Checks) == 0 {
|
||||
cfg.Checks = append(cfg.Checks, "*") // override for compatibility reason. Must drop in the next major version.
|
||||
}
|
||||
|
||||
if len(cfg.Initialisms) == 0 {
|
||||
cfg.Initialisms = append(cfg.Initialisms, scconfig.DefaultConfig.Initialisms...)
|
||||
}
|
||||
|
||||
if len(cfg.DotImportWhitelist) == 0 {
|
||||
cfg.DotImportWhitelist = append(cfg.DotImportWhitelist, scconfig.DefaultConfig.DotImportWhitelist...)
|
||||
}
|
||||
|
||||
if len(cfg.HTTPStatusCodeWhitelist) == 0 {
|
||||
cfg.HTTPStatusCodeWhitelist = append(cfg.HTTPStatusCodeWhitelist, scconfig.DefaultConfig.HTTPStatusCodeWhitelist...)
|
||||
}
|
||||
|
||||
cfg.Checks = normalizeList(cfg.Checks)
|
||||
cfg.Initialisms = normalizeList(cfg.Initialisms)
|
||||
cfg.DotImportWhitelist = normalizeList(cfg.DotImportWhitelist)
|
||||
cfg.HTTPStatusCodeWhitelist = normalizeList(cfg.HTTPStatusCodeWhitelist)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/lintcmd/lint.go#L437-L477
|
||||
// nolint // Keep the original source code.
|
||||
func filterAnalyzerNames(analyzers []string, checks []string) map[string]bool {
|
||||
allowedChecks := map[string]bool{}
|
||||
|
||||
for _, check := range checks {
|
||||
b := true
|
||||
if len(check) > 1 && check[0] == '-' {
|
||||
b = false
|
||||
check = check[1:]
|
||||
}
|
||||
|
||||
if check == "*" || check == "all" {
|
||||
// Match all
|
||||
for _, c := range analyzers {
|
||||
allowedChecks[c] = b
|
||||
}
|
||||
} else if strings.HasSuffix(check, "*") {
|
||||
// Glob
|
||||
prefix := check[:len(check)-1]
|
||||
isCat := strings.IndexFunc(prefix, func(r rune) bool { return unicode.IsNumber(r) }) == -1
|
||||
|
||||
for _, a := range analyzers {
|
||||
idx := strings.IndexFunc(a, func(r rune) bool { return unicode.IsNumber(r) })
|
||||
if isCat {
|
||||
// Glob is S*, which should match S1000 but not SA1000
|
||||
cat := a[:idx]
|
||||
if prefix == cat {
|
||||
allowedChecks[a] = b
|
||||
}
|
||||
} else {
|
||||
// Glob is S1*
|
||||
if strings.HasPrefix(a, prefix) {
|
||||
allowedChecks[a] = b
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Literal check name
|
||||
allowedChecks[check] = b
|
||||
}
|
||||
}
|
||||
return allowedChecks
|
||||
}
|
||||
|
||||
// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/config/config.go#L95-L116
|
||||
func normalizeList(list []string) []string {
|
||||
if len(list) > 1 {
|
||||
nlist := make([]string, 0, len(list))
|
||||
nlist = append(nlist, list[0])
|
||||
for i, el := range list[1:] {
|
||||
if el != list[i] {
|
||||
nlist = append(nlist, el)
|
||||
}
|
||||
}
|
||||
list = nlist
|
||||
}
|
||||
|
||||
for _, el := range list {
|
||||
if el == "inherit" {
|
||||
// This should never happen, because the default config
|
||||
// should not use "inherit"
|
||||
panic(`unresolved "inherit"`)
|
||||
}
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"golang.org/x/tools/go/analysis"
|
||||
scconfig "honnef.co/go/tools/config"
|
||||
"honnef.co/go/tools/stylecheck"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
@ -8,7 +10,16 @@ import (
|
||||
)
|
||||
|
||||
func NewStylecheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
||||
analyzers := setupStaticCheckAnalyzers(stylecheck.Analyzers, settings)
|
||||
cfg := staticCheckConfig(settings)
|
||||
|
||||
// `scconfig.Analyzer` is a singleton, then it's not possible to have more than one instance for all staticcheck "sub-linters".
|
||||
// When we will merge the 4 "sub-linters", the problem will disappear: https://github.com/golangci/golangci-lint/issues/357
|
||||
// Currently only stylecheck analyzer has a configuration in staticcheck.
|
||||
scconfig.Analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
analyzers := setupStaticCheckAnalyzers(stylecheck.Analyzers, getGoVersion(settings), cfg.Checks)
|
||||
|
||||
return goanalysis.NewLinter(
|
||||
"stylecheck",
|
||||
|
@ -54,7 +54,7 @@ func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
||||
},
|
||||
}
|
||||
|
||||
setAnalyzerGoVersion(analyzer, settings)
|
||||
setAnalyzerGoVersion(analyzer, getGoVersion(settings))
|
||||
|
||||
lnt := goanalysis.NewLinter(
|
||||
name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user