@@ -3,7 +3,6 @@ package processors
33import (
44 "path/filepath"
55 "regexp"
6- "sort"
76 "strings"
87
98 "github.com/pkg/errors"
@@ -13,19 +12,15 @@ import (
1312)
1413
1514type SkipDirs struct {
16- patterns []* regexp.Regexp
17- log logutils.Log
18- skippedDirs map [string ]bool
19- sortedAbsArgs []string
15+ patterns []* regexp.Regexp
16+ log logutils.Log
17+ skippedDirs map [string ][] string // regexp to dir mapping
18+ absArgsDirs []string
2019}
2120
2221var _ Processor = SkipFiles {}
2322
24- type sortedByLenStrings []string
25-
26- func (s sortedByLenStrings ) Len () int { return len (s ) }
27- func (s sortedByLenStrings ) Less (i , j int ) bool { return len (s [i ]) > len (s [j ]) }
28- func (s sortedByLenStrings ) Swap (i , j int ) { s [i ], s [j ] = s [j ], s [i ] }
23+ const goFileSuffix = ".go"
2924
3025func NewSkipDirs (patterns []string , log logutils.Log , runArgs []string ) (* SkipDirs , error ) {
3126 var patternsRe []* regexp.Regexp
@@ -40,24 +35,25 @@ func NewSkipDirs(patterns []string, log logutils.Log, runArgs []string) (*SkipDi
4035 if len (runArgs ) == 0 {
4136 runArgs = append (runArgs , "./..." )
4237 }
43- var sortedAbsArgs []string
38+ var absArgsDirs []string
4439 for _ , arg := range runArgs {
45- if filepath .Base (arg ) == "..." {
40+ base := filepath .Base (arg )
41+ if base == "..." || strings .HasSuffix (base , goFileSuffix ) {
4642 arg = filepath .Dir (arg )
4743 }
44+
4845 absArg , err := filepath .Abs (arg )
4946 if err != nil {
5047 return nil , errors .Wrapf (err , "failed to abs-ify arg %q" , arg )
5148 }
52- sortedAbsArgs = append (sortedAbsArgs , absArg )
49+ absArgsDirs = append (absArgsDirs , absArg )
5350 }
54- sort .Sort (sortedByLenStrings (sortedAbsArgs ))
5551
5652 return & SkipDirs {
57- patterns : patternsRe ,
58- log : log ,
59- skippedDirs : map [string ]bool {},
60- sortedAbsArgs : sortedAbsArgs ,
53+ patterns : patternsRe ,
54+ log : log ,
55+ skippedDirs : map [string ][] string {},
56+ absArgsDirs : absArgsDirs ,
6157 }, nil
6258}
6359
@@ -73,38 +69,38 @@ func (p *SkipDirs) Process(issues []result.Issue) ([]result.Issue, error) {
7369 return filterIssues (issues , p .shouldPassIssue ), nil
7470}
7571
76- func (p * SkipDirs ) getLongestArgRelativeIssuePath (i * result.Issue ) string {
77- issueAbsPath , err := filepath .Abs (i .FilePath ())
78- if err != nil {
79- p .log .Warnf ("Can't abs-ify path %q: %s" , i .FilePath (), err )
80- return ""
81- }
82-
83- for _ , arg := range p .sortedAbsArgs {
84- if ! strings .HasPrefix (issueAbsPath , arg ) {
85- continue
86- }
87-
88- return i .FilePath ()
72+ func (p * SkipDirs ) shouldPassIssue (i * result.Issue ) bool {
73+ if filepath .IsAbs (i .FilePath ()) {
74+ p .log .Warnf ("Got abs path in skip dirs processor, it should be relative" )
75+ return true
8976 }
9077
91- p .log .Infof ("Issue path %q isn't relative to any of run args" , i .FilePath ())
92- return ""
93- }
94-
95- func (p * SkipDirs ) shouldPassIssue (i * result.Issue ) bool {
96- relIssuePath := p .getLongestArgRelativeIssuePath (i )
97- if relIssuePath == "" {
78+ issueRelDir := filepath .Dir (i .FilePath ())
79+ issueAbsDir , err := filepath .Abs (issueRelDir )
80+ if err != nil {
81+ p .log .Warnf ("Can't abs-ify path %q: %s" , issueRelDir , err )
9882 return true
9983 }
10084
101- if strings .HasSuffix (filepath .Base (relIssuePath ), ".go" ) {
102- relIssuePath = filepath .Dir (relIssuePath )
85+ for _ , absArgDir := range p .absArgsDirs {
86+ if absArgDir == issueAbsDir {
87+ p .log .Infof ("Pass issue in file %s because it's dir was explicitly set in arg %s" , i .FilePath (), absArgDir )
88+ // we must not skip issues if they are from explicitly set dirs
89+ // even if they match skip patterns
90+ return true
91+ }
10392 }
10493
94+ // We use issueRelDir for matching: it's the relative to the current
95+ // work dir path of directory of source file with the issue. It can lead
96+ // to unexpected behavior if we're analyzing files out of current work dir.
97+ // The alternative solution is to find relative to args path, but it has
98+ // disadvantages (https://github.com/golangci/golangci-lint/pull/313).
99+
105100 for _ , pattern := range p .patterns {
106- if pattern .MatchString (relIssuePath ) {
107- p .skippedDirs [relIssuePath ] = true
101+ if pattern .MatchString (issueRelDir ) {
102+ ps := pattern .String ()
103+ p .skippedDirs [ps ] = append (p .skippedDirs [ps ], issueRelDir )
108104 return false
109105 }
110106 }
@@ -113,11 +109,7 @@ func (p *SkipDirs) shouldPassIssue(i *result.Issue) bool {
113109}
114110
115111func (p SkipDirs ) Finish () {
116- if len (p .skippedDirs ) != 0 {
117- var skippedDirs []string
118- for dir := range p .skippedDirs {
119- skippedDirs = append (skippedDirs , dir )
120- }
121- p .log .Infof ("Skipped dirs: %s" , skippedDirs )
112+ for pattern , dirs := range p .skippedDirs {
113+ p .log .Infof ("Skipped by pattern %s dirs: %s" , pattern , dirs )
122114 }
123115}
0 commit comments