feat: log an error when using previously deprecated linters (#4681)

This commit is contained in:
Ludovic Fernandez 2024-04-28 22:06:06 +02:00 committed by GitHub
parent e4dae2a211
commit 38fac89315
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 74 additions and 28 deletions

View File

@ -27,10 +27,19 @@ const (
// LastLinter nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives.
const LastLinter = "nolintlint"
type DeprecationLevel int
const (
DeprecationNone DeprecationLevel = iota
DeprecationWarning
DeprecationError
)
type Deprecation struct {
Since string
Message string
Replacement string
Level DeprecationLevel
}
type Config struct {
@ -113,15 +122,24 @@ func (lc *Config) WithSince(version string) *Config {
return lc
}
func (lc *Config) Deprecated(message, version, replacement string) *Config {
func (lc *Config) Deprecated(message, version, replacement string, level DeprecationLevel) *Config {
lc.Deprecation = &Deprecation{
Since: version,
Message: message,
Replacement: replacement,
Level: level,
}
return lc
}
func (lc *Config) DeprecatedWarning(message, version, replacement string) *Config {
return lc.Deprecated(message, version, replacement, DeprecationWarning)
}
func (lc *Config) DeprecatedError(message, version, replacement string) *Config {
return lc.Deprecated(message, version, replacement, DeprecationError)
}
func (lc *Config) IsDeprecated() bool {
return lc.Deprecation != nil
}

View File

@ -17,6 +17,7 @@ type Noop struct {
name string
desc string
reason string
level DeprecationLevel
}
func NewNoop(l Linter, reason string) Noop {
@ -27,11 +28,12 @@ func NewNoop(l Linter, reason string) Noop {
}
}
func NewNoopDeprecated(name string, cfg *config.Config) Noop {
func NewNoopDeprecated(name string, cfg *config.Config, level DeprecationLevel) Noop {
noop := Noop{
name: name,
desc: "Deprecated",
reason: "This linter is fully inactivated: it will not produce any reports.",
level: level,
}
if cfg.InternalCmdTest {
@ -42,9 +44,17 @@ func NewNoopDeprecated(name string, cfg *config.Config) Noop {
}
func (n Noop) Run(_ context.Context, lintCtx *Context) ([]result.Issue, error) {
if n.reason != "" {
if n.reason == "" {
return nil, nil
}
switch n.level {
case DeprecationError:
lintCtx.Log.Errorf("%s: %s", n.name, n.reason)
default:
lintCtx.Log.Warnf("%s: %s", n.name, n.reason)
}
return nil, nil
}

View File

@ -190,12 +190,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetFormatting, linter.PresetStyle).
WithURL("https://gitlab.com/bosi/decorder"),
linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetUnused).
WithURL("https://github.com/remyoudompheng/go-misc/tree/master/deadcode").
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
linter.NewConfig(depguard.New(&cfg.LintersSettings.Depguard)).
WithSince("v1.4.0").
@ -253,7 +253,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetSQL).
WithLoadForGoAnalysis().
WithURL("https://github.com/1uf3/execinquery").
Deprecated("The repository of the linter has been archived by the owner.", "v1.58.0", ""),
DeprecatedWarning("The repository of the linter has been archived by the owner.", "v1.58.0", ""),
linter.NewConfig(exhaustive.New(&cfg.LintersSettings.Exhaustive)).
WithSince(" v1.28.0").
@ -261,12 +261,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithLoadForGoAnalysis().
WithURL("https://github.com/nishanths/exhaustive"),
linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg, linter.DeprecationError)).
WithSince("v1.32.0").
WithPresets(linter.PresetStyle, linter.PresetTest).
WithLoadForGoAnalysis().
WithURL("https://github.com/mbilski/exhaustivestruct").
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"),
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"),
linter.NewConfig(exhaustruct.New(&cfg.LintersSettings.Exhaustruct)).
WithSince("v1.46.0").
@ -403,12 +403,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithAutoFix().
WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"),
linter.NewConfig(linter.NewNoopDeprecated("golint", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("golint", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle).
WithURL("https://github.com/golang/lint").
Deprecated("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
linter.NewConfig(mnd.New(&cfg.LintersSettings.Mnd)).
WithSince("v1.22.0").
@ -418,8 +418,8 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(mnd.NewGoMND(&cfg.LintersSettings.Gomnd)).
WithSince("v1.22.0").
WithPresets(linter.PresetStyle).
Deprecated("The linter has been renamed.", "v1.58.0", "mnd").
WithURL("https://github.com/tommy-muehle/go-mnd"),
WithURL("https://github.com/tommy-muehle/go-mnd").
DeprecatedWarning("The linter has been renamed.", "v1.58.0", "mnd"),
linter.NewConfig(gomoddirectives.New(&cfg.LintersSettings.GoModDirectives)).
WithSince("v1.39.0").
@ -470,11 +470,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetStyle).
WithURL("https://github.com/leonklingele/grouper"),
linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg, linter.DeprecationError)).
WithSince("v1.36.0").
WithPresets(linter.PresetStyle).
WithURL("https://github.com/esimonov/ifshort").
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""),
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""),
linter.NewConfig(importas.New(&cfg.LintersSettings.ImportAs)).
WithSince("v1.38.0").
@ -498,12 +498,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetStyle).
WithURL("https://github.com/sashamelentyev/interfacebloat"),
linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle).
WithURL("https://github.com/mvdan/interfacer").
Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
linter.NewConfig(intrange.New()).
WithSince("v1.57.0").
@ -538,12 +538,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithLoadForGoAnalysis().
WithURL("https://github.com/ashanbrown/makezero"),
linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetPerformance).
WithURL("https://github.com/mdempsky/maligned").
Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
linter.NewConfig(mirror.New()).
WithSince("v1.53.0").
@ -603,11 +603,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetStyle).
WithURL("https://github.com/firefart/nonamedreturns"),
linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg, linter.DeprecationError)).
WithSince("v1.47.0").
WithPresets(linter.PresetStyle).
WithURL("https://github.com/sivchari/nosnakecase").
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"),
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"),
linter.NewConfig(nosprintfhostport.New()).
WithSince("v1.46.0").
@ -672,11 +672,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetStyle, linter.PresetFormatting).
WithURL("https://github.com/go-simpler/sloglint"),
linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg, linter.DeprecationError)).
WithSince("v1.12.0").
WithPresets(linter.PresetBugs).
WithURL("https://github.com/kyoh86/scopelint").
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
linter.NewConfig(sqlclosecheck.New()).
WithSince("v1.28.0").
@ -698,12 +698,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithAlternativeNames(megacheckName).
WithURL("https://staticcheck.io/"),
linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetUnused).
WithURL("https://github.com/opennota/check").
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
linter.NewConfig(stylecheck.New(&cfg.LintersSettings.Stylecheck)).
WithSince("v1.20.0").
@ -788,12 +788,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithPresets(linter.PresetStyle).
WithURL("https://github.com/sashamelentyev/usestdlibvars"),
linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg)).
linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg, linter.DeprecationError)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetUnused).
WithURL("https://github.com/opennota/check").
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
linter.NewConfig(varnamelen.New(&cfg.LintersSettings.Varnamelen)).
WithSince("v1.43.0").

View File

@ -303,6 +303,10 @@ func AllPresets() []string {
func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config {
ret := map[string]*linter.Config{}
for _, lc := range lcs {
if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning {
continue
}
ret[lc.Name()] = lc
}

View File

@ -10,6 +10,7 @@ import (
"path/filepath"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/scripts/website/types"
)
@ -36,6 +37,10 @@ func saveLinters() error {
var wraps []types.LinterWrapper
for _, l := range linters {
if l.IsDeprecated() && l.Deprecation.Level > linter.DeprecationWarning {
continue
}
wrapper := types.LinterWrapper{
Name: l.Linter.Name(),
Desc: l.Linter.Desc(),

View File

@ -8,6 +8,7 @@ import (
"golang.org/x/exp/maps"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
)
@ -31,6 +32,10 @@ func getThanksList() string {
continue
}
if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning {
continue
}
linterURL := lc.OriginalURL
if lc.Name() == "staticcheck" {
linterURL = "https://github.com/dominikh/go-tools"

View File

@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/test/testshared"
@ -163,15 +164,18 @@ func getEnabledByDefaultFastLintersExcept(t *testing.T, except ...string) []stri
func getAllFastLintersWith(t *testing.T, with ...string) []string {
t.Helper()
ret := append([]string{}, with...)
dbManager, err := lintersdb.NewManager(nil, nil, lintersdb.NewLinterBuilder())
require.NoError(t, err)
linters := dbManager.GetAllSupportedLinterConfigs()
ret := append([]string{}, with...)
for _, lc := range linters {
if lc.IsSlowLinter() || lc.Internal {
if lc.IsSlowLinter() || lc.Internal || (lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning) {
continue
}
ret = append(ret, lc.Name())
}