Skip to content

Commit 222076f

Browse files
authored
Add forbidigo linter (#1569)
1 parent be02979 commit 222076f

File tree

8 files changed

+96
-2
lines changed

8 files changed

+96
-2
lines changed

.golangci.example.yml

+6
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,12 @@ linters-settings:
392392
makezero:
393393
# Allow only slices initialized with a length of zero. Default is false.
394394
always: false
395+
forbidigo:
396+
# Forbid the following identifiers
397+
forbid:
398+
- fmt.Errorf # consider errors.Errorf in github.com/pkg/errors
399+
- fmt.Print.* # too much log noise
400+
- ginkgo\\.F.* # these are used just for local development
395401

396402
# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
397403
# for more info.

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a
77
github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5
88
github.com/OpenPeeDeeP/depguard v1.0.1
9+
github.com/ashanbrown/forbidigo v1.0.0
910
github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a
1011
github.com/bombsimon/wsl/v3 v3.1.0
1112
github.com/daixiang0/gci v0.2.7

go.sum

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/config.go

+5
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ type LintersSettings struct {
269269
ErrorLint ErrorLintSettings
270270
Makezero MakezeroSettings
271271
Thelper ThelperSettings
272+
Forbidigo ForbidigoSettings
272273

273274
Custom map[string]CustomLinterSettings
274275
}
@@ -406,6 +407,10 @@ type ThelperSettings struct {
406407
} `mapstructure:"benchmark"`
407408
}
408409

410+
type ForbidigoSettings struct {
411+
Forbid []string `mapstructure:"forbid"`
412+
}
413+
409414
var defaultLintersSettings = LintersSettings{
410415
Lll: LllSettings{
411416
LineLength: 120,

pkg/golinters/forbidigo.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package golinters
2+
3+
import (
4+
"sync"
5+
6+
"github.com/ashanbrown/forbidigo/forbidigo"
7+
"github.com/pkg/errors"
8+
"golang.org/x/tools/go/analysis"
9+
10+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
11+
"github.com/golangci/golangci-lint/pkg/lint/linter"
12+
"github.com/golangci/golangci-lint/pkg/result"
13+
)
14+
15+
const forbidigoName = "forbidigo"
16+
17+
func NewForbidigo() *goanalysis.Linter {
18+
var mu sync.Mutex
19+
var resIssues []goanalysis.Issue
20+
21+
analyzer := &analysis.Analyzer{
22+
Name: forbidigoName,
23+
Doc: goanalysis.TheOnlyanalyzerDoc,
24+
}
25+
return goanalysis.NewLinter(
26+
forbidigoName,
27+
"Forbids identifiers",
28+
[]*analysis.Analyzer{analyzer},
29+
nil,
30+
).WithContextSetter(func(lintCtx *linter.Context) {
31+
s := &lintCtx.Settings().Forbidigo
32+
33+
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
34+
var res []goanalysis.Issue
35+
forbid, err := forbidigo.NewLinter(s.Forbid)
36+
if err != nil {
37+
return nil, errors.Wrapf(err, "failed to create linter %q", forbidigoName)
38+
}
39+
40+
for _, file := range pass.Files {
41+
hints, err := forbid.Run(pass.Fset, file)
42+
if err != nil {
43+
return nil, errors.Wrapf(err, "forbidigo linter failed on file %q", file.Name.String())
44+
}
45+
for _, hint := range hints {
46+
res = append(res, goanalysis.NewIssue(&result.Issue{
47+
Pos: hint.Position(),
48+
Text: hint.Details(),
49+
FromLinter: makezeroName,
50+
}, pass))
51+
}
52+
}
53+
54+
if len(res) == 0 {
55+
return nil, nil
56+
}
57+
58+
mu.Lock()
59+
resIssues = append(resIssues, res...)
60+
mu.Unlock()
61+
return nil, nil
62+
}
63+
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
64+
return resIssues
65+
}).WithLoadMode(goanalysis.LoadModeSyntax)
66+
}

pkg/lint/lintersdb/manager.go

+3
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
337337
linter.NewConfig(golinters.NewMakezero()).
338338
WithPresets(linter.PresetStyle, linter.PresetBugs).
339339
WithURL("https://github.com/ashanbrown/makezero"),
340+
linter.NewConfig(golinters.NewForbidigo()).
341+
WithPresets(linter.PresetStyle).
342+
WithURL("https://github.com/ashanbrown/forbidigo"),
340343

341344
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
342345
linter.NewConfig(golinters.NewNoLintLint()).

test/testdata/configs/forbidigo.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
linters-settings:
2+
forbidigo:
3+
forbid:
4+
- fmt\.Print.*

test/testdata/forbidigo.go

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//args: -Eforbidigo
2+
//config_path: testdata/configs/forbidigo.yml
3+
package testdata
4+
5+
import "fmt"
6+
7+
func Forbidigo() {
8+
fmt.Printf("too noisy!!!") // ERROR "use of `fmt.Printf` forbidden by pattern `fmt\\.Print.*`"
9+
}

0 commit comments

Comments
 (0)