Skip to content

Commit 110a30c

Browse files
committed
Add forbidigo linter
Forbidigo forbids identifiers. It can be used to forbid code that is useful for debugging but should not be merged to the master branch.
1 parent a893212 commit 110a30c

File tree

8 files changed

+93
-0
lines changed

8 files changed

+93
-0
lines changed

.golangci.example.yml

Lines changed: 6 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/config.go

Lines changed: 5 additions & 0 deletions
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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
linter, err := forbidigo.NewLinter(s.Forbid)
36+
if err != nil {
37+
return nil, errors.Wrapf(err, "failed to create linter %q", forbidigoName)
38+
}
39+
for _, file := range pass.Files {
40+
hints, err := linter.Run(pass.Fset, file)
41+
if err != nil {
42+
return nil, errors.Wrapf(err, "forbidigo linter failed on file %q", file.Name.String())
43+
}
44+
for _, hint := range hints {
45+
res = append(res, goanalysis.NewIssue(&result.Issue{
46+
Pos: hint.Position(),
47+
Text: hint.Details(),
48+
FromLinter: makezeroName,
49+
}, pass))
50+
}
51+
}
52+
if len(res) == 0 {
53+
return nil, nil
54+
}
55+
mu.Lock()
56+
resIssues = append(resIssues, res...)
57+
mu.Unlock()
58+
return nil, nil
59+
}
60+
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
61+
return resIssues
62+
}).WithLoadMode(goanalysis.LoadModeSyntax)
63+
}

pkg/lint/lintersdb/manager.go

Lines changed: 3 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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)