staticcheck: configuration for staticcheck
, gosimple
, stylecheck
(#2017)
This commit is contained in:
parent
fb7c90d6ee
commit
b916c9318b
@ -366,6 +366,8 @@ linters-settings:
|
|||||||
gosimple:
|
gosimple:
|
||||||
# Select the Go version to target. The default is '1.13'.
|
# Select the Go version to target. The default is '1.13'.
|
||||||
go: "1.15"
|
go: "1.15"
|
||||||
|
# https://staticcheck.io/docs/options#checks
|
||||||
|
checks: [ "all" ]
|
||||||
|
|
||||||
govet:
|
govet:
|
||||||
# report about shadowed variables
|
# report about shadowed variables
|
||||||
@ -514,10 +516,21 @@ linters-settings:
|
|||||||
staticcheck:
|
staticcheck:
|
||||||
# Select the Go version to target. The default is '1.13'.
|
# Select the Go version to target. The default is '1.13'.
|
||||||
go: "1.15"
|
go: "1.15"
|
||||||
|
# https://staticcheck.io/docs/options#checks
|
||||||
|
checks: [ "all" ]
|
||||||
|
|
||||||
stylecheck:
|
stylecheck:
|
||||||
# Select the Go version to target. The default is '1.13'.
|
# Select the Go version to target. The default is '1.13'.
|
||||||
go: "1.15"
|
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:
|
tagliatelle:
|
||||||
# check the struck tag name case
|
# check the struck tag name case
|
||||||
|
@ -394,6 +394,15 @@ type RowsErrCheckSettings struct {
|
|||||||
|
|
||||||
type StaticCheckSettings struct {
|
type StaticCheckSettings struct {
|
||||||
GoVersion string `mapstructure:"go"`
|
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 {
|
type StructCheckSettings struct {
|
||||||
|
@ -8,7 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewGosimple(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
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(
|
return goanalysis.NewLinter(
|
||||||
"gosimple",
|
"gosimple",
|
||||||
|
@ -8,7 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewStaticcheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
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(
|
return goanalysis.NewLinter(
|
||||||
"staticcheck",
|
"staticcheck",
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package golinters
|
package golinters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"golang.org/x/tools/go/analysis"
|
"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/config"
|
||||||
"github.com/golangci/golangci-lint/pkg/logutils"
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
@ -9,25 +13,155 @@ import (
|
|||||||
|
|
||||||
var debugf = logutils.Debug("megacheck")
|
var debugf = logutils.Debug("megacheck")
|
||||||
|
|
||||||
func setupStaticCheckAnalyzers(m map[string]*analysis.Analyzer, settings *config.StaticCheckSettings) []*analysis.Analyzer {
|
func getGoVersion(settings *config.StaticCheckSettings) string {
|
||||||
var ret []*analysis.Analyzer
|
var goVersion string
|
||||||
for _, v := range m {
|
if settings != nil {
|
||||||
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
|
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 v := a.Flags.Lookup("go"); v != nil {
|
||||||
if err := v.Value.Set(goVersion); err != nil {
|
if err := v.Value.Set(goVersion); err != nil {
|
||||||
debugf("Failed to set go version: %s", err)
|
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
|
package golinters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
scconfig "honnef.co/go/tools/config"
|
||||||
"honnef.co/go/tools/stylecheck"
|
"honnef.co/go/tools/stylecheck"
|
||||||
|
|
||||||
"github.com/golangci/golangci-lint/pkg/config"
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
@ -8,7 +10,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewStylecheck(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
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(
|
return goanalysis.NewLinter(
|
||||||
"stylecheck",
|
"stylecheck",
|
||||||
|
@ -54,7 +54,7 @@ func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
setAnalyzerGoVersion(analyzer, settings)
|
setAnalyzerGoVersion(analyzer, getGoVersion(settings))
|
||||||
|
|
||||||
lnt := goanalysis.NewLinter(
|
lnt := goanalysis.NewLinter(
|
||||||
name,
|
name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user