@@ -9,99 +9,42 @@ import (
99 "golang.org/x/tools/go/analysis"
1010 "golang.org/x/tools/go/loader" //nolint:staticcheck // require changes in github.com/OpenPeeDeeP/depguard
1111
12+ "github.com/golangci/golangci-lint/pkg/config"
1213 "github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
1314 "github.com/golangci/golangci-lint/pkg/lint/linter"
1415 "github.com/golangci/golangci-lint/pkg/result"
1516)
1617
17- func setDepguardListType (dg * depguard.Depguard , lintCtx * linter.Context ) error {
18- listType := lintCtx .Settings ().Depguard .ListType
19- var found bool
20- dg .ListType , found = depguard .StringToListType [strings .ToLower (listType )]
21- if ! found {
22- if listType != "" {
23- return fmt .Errorf ("unsure what list type %s is" , listType )
24- }
25- dg .ListType = depguard .LTBlacklist
26- }
27-
28- return nil
29- }
30-
31- func setupDepguardPackages (dg * depguard.Depguard , lintCtx * linter.Context ) {
32- if dg .ListType == depguard .LTBlacklist {
33- // if the list type was a blacklist the packages with error messages should
34- // be included in the blacklist package list
35-
36- noMessagePackages := make (map [string ]bool )
37- for _ , pkg := range dg .Packages {
38- noMessagePackages [pkg ] = true
39- }
40-
41- for pkg := range lintCtx .Settings ().Depguard .PackagesWithErrorMessage {
42- if _ , ok := noMessagePackages [pkg ]; ! ok {
43- dg .Packages = append (dg .Packages , pkg )
44- }
45- }
46- }
47- }
18+ const depguardLinterName = "depguard"
4819
4920func NewDepguard () * goanalysis.Linter {
50- const linterName = "depguard"
5121 var mu sync.Mutex
5222 var resIssues []goanalysis.Issue
5323
5424 analyzer := & analysis.Analyzer {
55- Name : linterName ,
25+ Name : depguardLinterName ,
5626 Doc : goanalysis .TheOnlyanalyzerDoc ,
5727 }
5828 return goanalysis .NewLinter (
59- linterName ,
29+ depguardLinterName ,
6030 "Go linter that checks if package imports are in a list of acceptable packages" ,
6131 []* analysis.Analyzer {analyzer },
6232 nil ,
6333 ).WithContextSetter (func (lintCtx * linter.Context ) {
64- dgSettings := & lintCtx .Settings ().Depguard
65- analyzer .Run = func (pass * analysis.Pass ) (interface {}, error ) {
66- prog := goanalysis .MakeFakeLoaderProgram (pass )
67- dg := & depguard.Depguard {
68- Packages : dgSettings .Packages ,
69- IncludeGoRoot : dgSettings .IncludeGoRoot ,
70- }
71- if err := setDepguardListType (dg , lintCtx ); err != nil {
72- return nil , err
73- }
74- setupDepguardPackages (dg , lintCtx )
34+ dg , err := newDepGuard (& lintCtx .Settings ().Depguard )
7535
76- loadConfig := & loader.Config {
77- Cwd : "" , // fallbacked to os.Getcwd
78- Build : nil , // fallbacked to build.Default
79- }
80- issues , err := dg .Run (loadConfig , prog )
36+ analyzer .Run = func (pass * analysis.Pass ) (interface {}, error ) {
8137 if err != nil {
8238 return nil , err
8339 }
84- if len (issues ) == 0 {
85- return nil , nil
86- }
87- msgSuffix := "is in the blacklist"
88- if dg .ListType == depguard .LTWhitelist {
89- msgSuffix = "is not in the whitelist"
90- }
91- res := make ([]goanalysis.Issue , 0 , len (issues ))
92- for _ , i := range issues {
93- userSuppliedMsgSuffix := dgSettings .PackagesWithErrorMessage [i .PackageName ]
94- if userSuppliedMsgSuffix != "" {
95- userSuppliedMsgSuffix = ": " + userSuppliedMsgSuffix
96- }
97- res = append (res , goanalysis .NewIssue (& result.Issue {
98- Pos : i .Position ,
99- Text : fmt .Sprintf ("%s %s%s" , formatCode (i .PackageName , lintCtx .Cfg ), msgSuffix , userSuppliedMsgSuffix ),
100- FromLinter : linterName ,
101- }, pass ))
40+
41+ issues , errRun := dg .run (pass )
42+ if errRun != nil {
43+ return nil , errRun
10244 }
45+
10346 mu .Lock ()
104- resIssues = append (resIssues , res ... )
47+ resIssues = append (resIssues , issues ... )
10548 mu .Unlock ()
10649
10750 return nil , nil
@@ -110,3 +53,140 @@ func NewDepguard() *goanalysis.Linter {
11053 return resIssues
11154 }).WithLoadMode (goanalysis .LoadModeTypesInfo )
11255}
56+
57+ type depGuard struct {
58+ loadConfig * loader.Config
59+ guardians []* guardian
60+ }
61+
62+ func newDepGuard (settings * config.DepGuardSettings ) (* depGuard , error ) {
63+ ps , err := newGuardian (settings )
64+ if err != nil {
65+ return nil , err
66+ }
67+
68+ d := & depGuard {
69+ loadConfig : & loader.Config {
70+ Cwd : "" , // fallbacked to os.Getcwd
71+ Build : nil , // fallbacked to build.Default
72+ },
73+ guardians : []* guardian {ps },
74+ }
75+
76+ for _ , additional := range settings .AdditionalGuards {
77+ add := additional
78+ ps , err = newGuardian (& add )
79+ if err != nil {
80+ return nil , err
81+ }
82+
83+ d .guardians = append (d .guardians , ps )
84+ }
85+
86+ return d , nil
87+ }
88+
89+ func (d depGuard ) run (pass * analysis.Pass ) ([]goanalysis.Issue , error ) {
90+ prog := goanalysis .MakeFakeLoaderProgram (pass )
91+
92+ var resIssues []goanalysis.Issue
93+ for _ , g := range d .guardians {
94+ issues , errRun := g .run (d .loadConfig , prog , pass )
95+ if errRun != nil {
96+ return nil , errRun
97+ }
98+
99+ resIssues = append (resIssues , issues ... )
100+ }
101+
102+ return resIssues , nil
103+ }
104+
105+ type guardian struct {
106+ * depguard.Depguard
107+ pkgsWithErrorMessage map [string ]string
108+ }
109+
110+ func newGuardian (settings * config.DepGuardSettings ) (* guardian , error ) {
111+ dg := & depguard.Depguard {
112+ Packages : settings .Packages ,
113+ IncludeGoRoot : settings .IncludeGoRoot ,
114+ IgnoreFileRules : settings .IgnoreFileRules ,
115+ }
116+
117+ var err error
118+ dg .ListType , err = getDepGuardListType (settings .ListType )
119+ if err != nil {
120+ return nil , err
121+ }
122+
123+ // if the list type was a blacklist the packages with error messages should be included in the blacklist package list
124+ if dg .ListType == depguard .LTBlacklist {
125+ noMessagePackages := make (map [string ]bool )
126+ for _ , pkg := range dg .Packages {
127+ noMessagePackages [pkg ] = true
128+ }
129+
130+ for pkg := range settings .PackagesWithErrorMessage {
131+ if _ , ok := noMessagePackages [pkg ]; ! ok {
132+ dg .Packages = append (dg .Packages , pkg )
133+ }
134+ }
135+ }
136+
137+ return & guardian {
138+ Depguard : dg ,
139+ pkgsWithErrorMessage : settings .PackagesWithErrorMessage ,
140+ }, nil
141+ }
142+
143+ func (g guardian ) run (loadConfig * loader.Config , prog * loader.Program , pass * analysis.Pass ) ([]goanalysis.Issue , error ) {
144+ issues , err := g .Run (loadConfig , prog )
145+ if err != nil {
146+ return nil , err
147+ }
148+
149+ res := make ([]goanalysis.Issue , 0 , len (issues ))
150+
151+ for _ , issue := range issues {
152+ res = append (res ,
153+ goanalysis .NewIssue (& result.Issue {
154+ Pos : issue .Position ,
155+ Text : g .createMsg (issue .PackageName ),
156+ FromLinter : depguardLinterName ,
157+ }, pass ),
158+ )
159+ }
160+
161+ return res , nil
162+ }
163+
164+ func (g guardian ) createMsg (pkgName string ) string {
165+ msgSuffix := "is in the blacklist"
166+ if g .ListType == depguard .LTWhitelist {
167+ msgSuffix = "is not in the whitelist"
168+ }
169+
170+ var userSuppliedMsgSuffix string
171+ if g .pkgsWithErrorMessage != nil {
172+ userSuppliedMsgSuffix = g .pkgsWithErrorMessage [pkgName ]
173+ if userSuppliedMsgSuffix != "" {
174+ userSuppliedMsgSuffix = ": " + userSuppliedMsgSuffix
175+ }
176+ }
177+
178+ return fmt .Sprintf ("%s %s%s" , formatCode (pkgName , nil ), msgSuffix , userSuppliedMsgSuffix )
179+ }
180+
181+ func getDepGuardListType (listType string ) (depguard.ListType , error ) {
182+ if listType == "" {
183+ return depguard .LTBlacklist , nil
184+ }
185+
186+ listT , found := depguard .StringToListType [strings .ToLower (listType )]
187+ if ! found {
188+ return depguard .LTBlacklist , fmt .Errorf ("unsure what list type %s is" , listType )
189+ }
190+
191+ return listT , nil
192+ }
0 commit comments