Skip to content

Commit 38fac89

Browse files
authored
feat: log an error when using previously deprecated linters (#4681)
1 parent e4dae2a commit 38fac89

File tree

7 files changed

+74
-28
lines changed

7 files changed

+74
-28
lines changed

pkg/lint/linter/config.go

+19-1
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,19 @@ const (
2727
// LastLinter nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives.
2828
const LastLinter = "nolintlint"
2929

30+
type DeprecationLevel int
31+
32+
const (
33+
DeprecationNone DeprecationLevel = iota
34+
DeprecationWarning
35+
DeprecationError
36+
)
37+
3038
type Deprecation struct {
3139
Since string
3240
Message string
3341
Replacement string
42+
Level DeprecationLevel
3443
}
3544

3645
type Config struct {
@@ -113,15 +122,24 @@ func (lc *Config) WithSince(version string) *Config {
113122
return lc
114123
}
115124

116-
func (lc *Config) Deprecated(message, version, replacement string) *Config {
125+
func (lc *Config) Deprecated(message, version, replacement string, level DeprecationLevel) *Config {
117126
lc.Deprecation = &Deprecation{
118127
Since: version,
119128
Message: message,
120129
Replacement: replacement,
130+
Level: level,
121131
}
122132
return lc
123133
}
124134

135+
func (lc *Config) DeprecatedWarning(message, version, replacement string) *Config {
136+
return lc.Deprecated(message, version, replacement, DeprecationWarning)
137+
}
138+
139+
func (lc *Config) DeprecatedError(message, version, replacement string) *Config {
140+
return lc.Deprecated(message, version, replacement, DeprecationError)
141+
}
142+
125143
func (lc *Config) IsDeprecated() bool {
126144
return lc.Deprecation != nil
127145
}

pkg/lint/linter/linter.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Noop struct {
1717
name string
1818
desc string
1919
reason string
20+
level DeprecationLevel
2021
}
2122

2223
func NewNoop(l Linter, reason string) Noop {
@@ -27,11 +28,12 @@ func NewNoop(l Linter, reason string) Noop {
2728
}
2829
}
2930

30-
func NewNoopDeprecated(name string, cfg *config.Config) Noop {
31+
func NewNoopDeprecated(name string, cfg *config.Config, level DeprecationLevel) Noop {
3132
noop := Noop{
3233
name: name,
3334
desc: "Deprecated",
3435
reason: "This linter is fully inactivated: it will not produce any reports.",
36+
level: level,
3537
}
3638

3739
if cfg.InternalCmdTest {
@@ -42,9 +44,17 @@ func NewNoopDeprecated(name string, cfg *config.Config) Noop {
4244
}
4345

4446
func (n Noop) Run(_ context.Context, lintCtx *Context) ([]result.Issue, error) {
45-
if n.reason != "" {
47+
if n.reason == "" {
48+
return nil, nil
49+
}
50+
51+
switch n.level {
52+
case DeprecationError:
53+
lintCtx.Log.Errorf("%s: %s", n.name, n.reason)
54+
default:
4655
lintCtx.Log.Warnf("%s: %s", n.name, n.reason)
4756
}
57+
4858
return nil, nil
4959
}
5060

pkg/lint/lintersdb/builder_linter.go

+23-23
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
190190
WithPresets(linter.PresetFormatting, linter.PresetStyle).
191191
WithURL("https://gitlab.com/bosi/decorder"),
192192

193-
linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg)).
193+
linter.NewConfig(linter.NewNoopDeprecated("deadcode", cfg, linter.DeprecationError)).
194194
WithSince("v1.0.0").
195195
WithLoadForGoAnalysis().
196196
WithPresets(linter.PresetUnused).
197197
WithURL("https://github.com/remyoudompheng/go-misc/tree/master/deadcode").
198-
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
198+
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
199199

200200
linter.NewConfig(depguard.New(&cfg.LintersSettings.Depguard)).
201201
WithSince("v1.4.0").
@@ -253,20 +253,20 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
253253
WithPresets(linter.PresetSQL).
254254
WithLoadForGoAnalysis().
255255
WithURL("https://github.com/1uf3/execinquery").
256-
Deprecated("The repository of the linter has been archived by the owner.", "v1.58.0", ""),
256+
DeprecatedWarning("The repository of the linter has been archived by the owner.", "v1.58.0", ""),
257257

258258
linter.NewConfig(exhaustive.New(&cfg.LintersSettings.Exhaustive)).
259259
WithSince(" v1.28.0").
260260
WithPresets(linter.PresetBugs).
261261
WithLoadForGoAnalysis().
262262
WithURL("https://github.com/nishanths/exhaustive"),
263263

264-
linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg)).
264+
linter.NewConfig(linter.NewNoopDeprecated("exhaustivestruct", cfg, linter.DeprecationError)).
265265
WithSince("v1.32.0").
266266
WithPresets(linter.PresetStyle, linter.PresetTest).
267267
WithLoadForGoAnalysis().
268268
WithURL("https://github.com/mbilski/exhaustivestruct").
269-
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"),
269+
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.46.0", "exhaustruct"),
270270

271271
linter.NewConfig(exhaustruct.New(&cfg.LintersSettings.Exhaustruct)).
272272
WithSince("v1.46.0").
@@ -403,12 +403,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
403403
WithAutoFix().
404404
WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"),
405405

406-
linter.NewConfig(linter.NewNoopDeprecated("golint", cfg)).
406+
linter.NewConfig(linter.NewNoopDeprecated("golint", cfg, linter.DeprecationError)).
407407
WithSince("v1.0.0").
408408
WithLoadForGoAnalysis().
409409
WithPresets(linter.PresetStyle).
410410
WithURL("https://github.com/golang/lint").
411-
Deprecated("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
411+
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
412412

413413
linter.NewConfig(mnd.New(&cfg.LintersSettings.Mnd)).
414414
WithSince("v1.22.0").
@@ -418,8 +418,8 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
418418
linter.NewConfig(mnd.NewGoMND(&cfg.LintersSettings.Gomnd)).
419419
WithSince("v1.22.0").
420420
WithPresets(linter.PresetStyle).
421-
Deprecated("The linter has been renamed.", "v1.58.0", "mnd").
422-
WithURL("https://github.com/tommy-muehle/go-mnd"),
421+
WithURL("https://github.com/tommy-muehle/go-mnd").
422+
DeprecatedWarning("The linter has been renamed.", "v1.58.0", "mnd"),
423423

424424
linter.NewConfig(gomoddirectives.New(&cfg.LintersSettings.GoModDirectives)).
425425
WithSince("v1.39.0").
@@ -470,11 +470,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
470470
WithPresets(linter.PresetStyle).
471471
WithURL("https://github.com/leonklingele/grouper"),
472472

473-
linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg)).
473+
linter.NewConfig(linter.NewNoopDeprecated("ifshort", cfg, linter.DeprecationError)).
474474
WithSince("v1.36.0").
475475
WithPresets(linter.PresetStyle).
476476
WithURL("https://github.com/esimonov/ifshort").
477-
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""),
477+
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.0", ""),
478478

479479
linter.NewConfig(importas.New(&cfg.LintersSettings.ImportAs)).
480480
WithSince("v1.38.0").
@@ -498,12 +498,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
498498
WithPresets(linter.PresetStyle).
499499
WithURL("https://github.com/sashamelentyev/interfacebloat"),
500500

501-
linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg)).
501+
linter.NewConfig(linter.NewNoopDeprecated("interfacer", cfg, linter.DeprecationError)).
502502
WithSince("v1.0.0").
503503
WithLoadForGoAnalysis().
504504
WithPresets(linter.PresetStyle).
505505
WithURL("https://github.com/mvdan/interfacer").
506-
Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
506+
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
507507

508508
linter.NewConfig(intrange.New()).
509509
WithSince("v1.57.0").
@@ -538,12 +538,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
538538
WithLoadForGoAnalysis().
539539
WithURL("https://github.com/ashanbrown/makezero"),
540540

541-
linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg)).
541+
linter.NewConfig(linter.NewNoopDeprecated("maligned", cfg, linter.DeprecationError)).
542542
WithSince("v1.0.0").
543543
WithLoadForGoAnalysis().
544544
WithPresets(linter.PresetPerformance).
545545
WithURL("https://github.com/mdempsky/maligned").
546-
Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
546+
DeprecatedError("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
547547

548548
linter.NewConfig(mirror.New()).
549549
WithSince("v1.53.0").
@@ -603,11 +603,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
603603
WithPresets(linter.PresetStyle).
604604
WithURL("https://github.com/firefart/nonamedreturns"),
605605

606-
linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg)).
606+
linter.NewConfig(linter.NewNoopDeprecated("nosnakecase", cfg, linter.DeprecationError)).
607607
WithSince("v1.47.0").
608608
WithPresets(linter.PresetStyle).
609609
WithURL("https://github.com/sivchari/nosnakecase").
610-
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"),
610+
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.48.1", "revive 'var-naming'"),
611611

612612
linter.NewConfig(nosprintfhostport.New()).
613613
WithSince("v1.46.0").
@@ -672,11 +672,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
672672
WithPresets(linter.PresetStyle, linter.PresetFormatting).
673673
WithURL("https://github.com/go-simpler/sloglint"),
674674

675-
linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg)).
675+
linter.NewConfig(linter.NewNoopDeprecated("scopelint", cfg, linter.DeprecationError)).
676676
WithSince("v1.12.0").
677677
WithPresets(linter.PresetBugs).
678678
WithURL("https://github.com/kyoh86/scopelint").
679-
Deprecated("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
679+
DeprecatedError("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
680680

681681
linter.NewConfig(sqlclosecheck.New()).
682682
WithSince("v1.28.0").
@@ -698,12 +698,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
698698
WithAlternativeNames(megacheckName).
699699
WithURL("https://staticcheck.io/"),
700700

701-
linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg)).
701+
linter.NewConfig(linter.NewNoopDeprecated("structcheck", cfg, linter.DeprecationError)).
702702
WithSince("v1.0.0").
703703
WithLoadForGoAnalysis().
704704
WithPresets(linter.PresetUnused).
705705
WithURL("https://github.com/opennota/check").
706-
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
706+
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
707707

708708
linter.NewConfig(stylecheck.New(&cfg.LintersSettings.Stylecheck)).
709709
WithSince("v1.20.0").
@@ -788,12 +788,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
788788
WithPresets(linter.PresetStyle).
789789
WithURL("https://github.com/sashamelentyev/usestdlibvars"),
790790

791-
linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg)).
791+
linter.NewConfig(linter.NewNoopDeprecated("varcheck", cfg, linter.DeprecationError)).
792792
WithSince("v1.0.0").
793793
WithLoadForGoAnalysis().
794794
WithPresets(linter.PresetUnused).
795795
WithURL("https://github.com/opennota/check").
796-
Deprecated("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
796+
DeprecatedError("The owner seems to have abandoned the linter.", "v1.49.0", "unused"),
797797

798798
linter.NewConfig(varnamelen.New(&cfg.LintersSettings.Varnamelen)).
799799
WithSince("v1.43.0").

pkg/lint/lintersdb/manager.go

+4
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ func AllPresets() []string {
303303
func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config {
304304
ret := map[string]*linter.Config{}
305305
for _, lc := range lcs {
306+
if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning {
307+
continue
308+
}
309+
306310
ret[lc.Name()] = lc
307311
}
308312

scripts/website/dump_info/main.go

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"path/filepath"
1111

1212
"github.com/golangci/golangci-lint/pkg/config"
13+
"github.com/golangci/golangci-lint/pkg/lint/linter"
1314
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
1415
"github.com/golangci/golangci-lint/scripts/website/types"
1516
)
@@ -36,6 +37,10 @@ func saveLinters() error {
3637

3738
var wraps []types.LinterWrapper
3839
for _, l := range linters {
40+
if l.IsDeprecated() && l.Deprecation.Level > linter.DeprecationWarning {
41+
continue
42+
}
43+
3944
wrapper := types.LinterWrapper{
4045
Name: l.Linter.Name(),
4146
Desc: l.Linter.Desc(),

scripts/website/expand_templates/thanks.go

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"golang.org/x/exp/maps"
99

1010
"github.com/golangci/golangci-lint/pkg/config"
11+
"github.com/golangci/golangci-lint/pkg/lint/linter"
1112
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
1213
)
1314

@@ -31,6 +32,10 @@ func getThanksList() string {
3132
continue
3233
}
3334

35+
if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning {
36+
continue
37+
}
38+
3439
linterURL := lc.OriginalURL
3540
if lc.Name() == "staticcheck" {
3641
linterURL = "https://github.com/dominikh/go-tools"

test/enabled_linters_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/stretchr/testify/require"
1111

12+
"github.com/golangci/golangci-lint/pkg/lint/linter"
1213
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
1314
"github.com/golangci/golangci-lint/pkg/logutils"
1415
"github.com/golangci/golangci-lint/test/testshared"
@@ -163,15 +164,18 @@ func getEnabledByDefaultFastLintersExcept(t *testing.T, except ...string) []stri
163164
func getAllFastLintersWith(t *testing.T, with ...string) []string {
164165
t.Helper()
165166

167+
ret := append([]string{}, with...)
168+
166169
dbManager, err := lintersdb.NewManager(nil, nil, lintersdb.NewLinterBuilder())
167170
require.NoError(t, err)
168171

169172
linters := dbManager.GetAllSupportedLinterConfigs()
170-
ret := append([]string{}, with...)
173+
171174
for _, lc := range linters {
172-
if lc.IsSlowLinter() || lc.Internal {
175+
if lc.IsSlowLinter() || lc.Internal || (lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning) {
173176
continue
174177
}
178+
175179
ret = append(ret, lc.Name())
176180
}
177181

0 commit comments

Comments
 (0)