Skip to content

Commit 020b9e7

Browse files
committed
added new linter gomodguard, disabled by default
1 parent 4958e50 commit 020b9e7

File tree

39 files changed

+4479
-0
lines changed

39 files changed

+4479
-0
lines changed

.golangci.example.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ linters-settings:
148148
mnd:
149149
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
150150
checks: argument,case,condition,operation,return,assign
151+
gomodguard:
152+
allowed:
153+
modules: # List of allowed modules
154+
# - gopkg.in/yaml.v2
155+
domains: # List of allowed module domains
156+
# - golang.org
157+
blocked:
158+
modules: # List of blocked modules
159+
# - github.com/uudashr/go-module: # Blocked module
160+
# recommendations: # Recommended modules that should be used instead (Optional)
161+
# - golang.org/x/mod
162+
# reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional)
151163
govet:
152164
# report about shadowed variables
153165
check-shadowing: true

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ gofmt: Gofmt checks whether code was gofmt-ed. By default this tool runs with -s
222222
goimports: Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true, auto-fix: true]
223223
golint: Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false]
224224
gomnd: An analyzer to detect magic numbers. [fast: true, auto-fix: false]
225+
gomodguard: Allow and block list linter for direct Go module dependencies. [fast: true, auto-fix: false]
225226
goprintffuncname: Checks that printf-like functions are named with `f` at the end [fast: true, auto-fix: false]
226227
gosec (gas): Inspects source code for security problems [fast: true, auto-fix: false]
227228
interfacer: Linter that suggests narrower interface types [fast: true, auto-fix: false]
@@ -488,6 +489,7 @@ golangci-lint help linters
488489
- [wsl](https://github.com/bombsimon/wsl) - Whitespace Linter - Forces you to use empty lines!
489490
- [goprintffuncname](https://github.com/jirfag/go-printf-func-name) - Checks that printf-like functions are named with `f` at the end
490491
- [gomnd](https://github.com/tommy-muehle/go-mnd) - An analyzer to detect magic numbers.
492+
- [gomodguard](https://github.com/rcurrah/gomodguard) - Allow and block list linter for direct Go module dependencies.
491493
492494
## Configuration
493495
@@ -758,6 +760,18 @@ linters-settings:
758760
mnd:
759761
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
760762
checks: argument,case,condition,operation,return,assign
763+
gomodguard:
764+
allowed:
765+
modules: # List of allowed modules
766+
# - gopkg.in/yaml.v2
767+
domains: # List of allowed module domains
768+
# - golang.org
769+
blocked:
770+
modules: # List of blocked modules
771+
# - github.com/uudashr/go-module: # Blocked module
772+
# recommendations: # Recommended modules that should be used instead (Optional)
773+
# - golang.org/x/mod
774+
# reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional)
761775
govet:
762776
# report about shadowed variables
763777
check-shadowing: true
@@ -1261,6 +1275,7 @@ Thanks to developers and authors of used linters:
12611275
- [bombsimon](https://github.com/bombsimon)
12621276
- [jirfag](https://github.com/jirfag)
12631277
- [tommy-muehle](https://github.com/tommy-muehle)
1278+
- [rcurrah](https://github.com/rcurrah)
12641279
12651280
## Changelog
12661281

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ require (
3030
github.com/mitchellh/go-homedir v1.1.0
3131
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b
3232
github.com/pkg/errors v0.8.1
33+
github.com/ryancurrah/gomodguard v1.0.1
3334
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83
3435
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada // v2.19.8
3536
github.com/sirupsen/logrus v1.4.2

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUD
6868
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
6969
github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA=
7070
github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
71+
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
7172
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
7273
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
7374
github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw=
@@ -196,6 +197,7 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
196197
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
197198
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
198199
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
200+
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
199201
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
200202
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
201203
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -215,6 +217,10 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:
215217
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
216218
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
217219
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
220+
github.com/ryancurrah/gomodguard v1.0.0 h1:8bN8VUp6VLagAt8WpDwBuztk6axd43VjtxYDJp+3ykQ=
221+
github.com/ryancurrah/gomodguard v1.0.0/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE=
222+
github.com/ryancurrah/gomodguard v1.0.1 h1:bJQqszMqi0EqsxuQB55rjFQnLjOirbAL0Ww4WyT0IiM=
223+
github.com/ryancurrah/gomodguard v1.0.1/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE=
218224
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83 h1:AtnWoOvTioyDXFvu96MWEeE8qj4COSQnJogzLy/u41A=
219225
github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
220226
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I=
@@ -297,6 +303,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
297303
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
298304
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
299305
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
306+
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
307+
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
300308
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
301309
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
302310
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -346,6 +354,7 @@ golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBn
346354
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
347355
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
348356
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
357+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
349358
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
350359
golang.org/x/tools v0.0.0-20200102140908-9497f49d5709 h1:AfG1EmoRkFK24HWWLxSrRKNg2G+oA3JVOG8GJsHWypQ=
351360
golang.org/x/tools v0.0.0-20200102140908-9497f49d5709/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=

pkg/config/config.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ type LintersSettings struct {
185185
RowsErrCheck struct {
186186
Packages []string
187187
}
188+
Gomodguard struct {
189+
Allowed struct {
190+
Modules []string `mapstructure:"modules"`
191+
Domains []string `mapstructure:"domains"`
192+
} `mapstructure:"allowed"`
193+
Blocked struct {
194+
Modules []map[string]struct {
195+
Recommendations []string `mapstructure:"recommendations"`
196+
Reason string `mapstructure:"reason"`
197+
} `mapstructure:"modules"`
198+
} `mapstructure:"blocked"`
199+
}
188200

189201
WSL WSLSettings
190202
Lll LllSettings

pkg/golinters/gomodguard.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package golinters
2+
3+
import (
4+
"log"
5+
"os"
6+
"sync"
7+
8+
"github.com/ryancurrah/gomodguard"
9+
"golang.org/x/tools/go/analysis"
10+
11+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
12+
"github.com/golangci/golangci-lint/pkg/lint/linter"
13+
"github.com/golangci/golangci-lint/pkg/result"
14+
)
15+
16+
const (
17+
gomodguardName = "gomodguard"
18+
)
19+
20+
// NewGomodguard returns a new Gomodguard linter.
21+
func NewGomodguard() *goanalysis.Linter {
22+
var (
23+
issues []goanalysis.Issue
24+
mu = sync.Mutex{}
25+
analyzer = &analysis.Analyzer{
26+
Name: goanalysis.TheOnlyAnalyzerName,
27+
Doc: goanalysis.TheOnlyanalyzerDoc,
28+
}
29+
)
30+
31+
return goanalysis.NewLinter(
32+
gomodguardName,
33+
"Allow and block list linter for direct Go module dependencies.",
34+
[]*analysis.Analyzer{analyzer},
35+
nil,
36+
).WithContextSetter(func(lintCtx *linter.Context) {
37+
analyzer.Run = func(pass *analysis.Pass) (interface{}, error) {
38+
var (
39+
files = []string{}
40+
linterCfg = lintCtx.Cfg.LintersSettings.Gomodguard
41+
processorCfg = gomodguard.Configuration{}
42+
)
43+
processorCfg.Allowed.Modules = linterCfg.Allowed.Modules
44+
processorCfg.Allowed.Domains = linterCfg.Allowed.Domains
45+
for n := range linterCfg.Blocked.Modules {
46+
for k, v := range linterCfg.Blocked.Modules[n] {
47+
m := gomodguard.BlockedModule{k: gomodguard.Recommendations{
48+
Recommendations: v.Recommendations,
49+
Reason: v.Reason,
50+
}}
51+
processorCfg.Blocked.Modules = append(processorCfg.Blocked.Modules, m)
52+
break
53+
}
54+
}
55+
56+
for _, file := range pass.Files {
57+
files = append(files, pass.Fset.Position(file.Pos()).Filename)
58+
}
59+
60+
processor, err := gomodguard.NewProcessor(processorCfg, log.New(os.Stderr, "", 0))
61+
if err != nil {
62+
return nil, err
63+
}
64+
65+
gomodguardErrors := processor.ProcessFiles(files)
66+
if len(gomodguardErrors) == 0 {
67+
return nil, nil
68+
}
69+
70+
mu.Lock()
71+
defer mu.Unlock()
72+
73+
for _, err := range gomodguardErrors {
74+
issues = append(issues, goanalysis.NewIssue(&result.Issue{ //nolint:scopelint
75+
FromLinter: gomodguardName,
76+
Pos: err.Position,
77+
Text: err.Reason,
78+
}, pass))
79+
}
80+
81+
return nil, nil
82+
}
83+
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
84+
return issues
85+
}).WithLoadMode(goanalysis.LoadModeSyntax)
86+
}

pkg/lint/lintersdb/manager.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
247247
linter.NewConfig(golinters.NewGoMND(m.cfg)).
248248
WithPresets(linter.PresetStyle).
249249
WithURL("https://github.com/tommy-muehle/go-mnd"),
250+
linter.NewConfig(golinters.NewGomodguard()).
251+
WithPresets(linter.PresetStyle).
252+
WithURL("https://github.com/rcurrah/gomodguard"),
250253
}
251254

252255
isLocalRun := os.Getenv("GOLANGCI_COM_RUN") == ""

test/testdata/configs/gomodguard.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
linters-settings:
2+
gomodguard:
3+
allowed:
4+
modules: # List of allowed modules
5+
- golang.org/x/mod/modfile
6+
blocked:
7+
modules: # List of blocked modules
8+
- gopkg.in/yaml.v2: # Blocked module
9+
recommendations: # Recommended modules that should be used instead (Optional)
10+
- github.com/kylelemons/go-gypsy
11+
reason: "This is an example of recommendations." # Reason why the recommended module should be used (Optional)

test/testdata/gomodguard.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//args: -Egomodguard
2+
//config_path: testdata/configs/gomodguard.yml
3+
package testdata
4+
5+
import (
6+
"log"
7+
8+
"golang.org/x/mod/modfile"
9+
"gopkg.in/yaml.v2" // ERROR : "import of package `gopkg.in/yaml.v2` is blocked because the module is in the blocked modules list. `github.com/kylelemons/go-gypsy` is a recommended module. This is an example of recommendations."
10+
)
11+
12+
// Something just some struct
13+
type Something struct{}
14+
15+
func aAllowedImport() { // nolint: deadcode,unused
16+
mfile, _ := modfile.Parse("go.mod", []byte{}, nil)
17+
18+
log.Println(mfile)
19+
}
20+
21+
func aBlockedImport() { // nolint: deadcode,unused
22+
data := []byte{}
23+
something := Something{}
24+
_ = yaml.Unmarshal(data, &something)
25+
26+
log.Println(data)
27+
}

vendor/github.com/ryancurrah/gomodguard/.gitignore

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

vendor/github.com/ryancurrah/gomodguard/.gomodguard.yaml

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

vendor/github.com/ryancurrah/gomodguard/LICENSE

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

0 commit comments

Comments
 (0)