@@ -21,16 +21,28 @@ const (
21
21
AuthorEmail = "stemmertech@gmail.com"
22
22
)
23
23
24
+ type patternList []string
25
+
26
+ func (p * patternList ) String () string {
27
+ return fmt .Sprint (* p )
28
+ }
29
+
30
+ func (p * patternList ) Set (value string ) error {
31
+ * p = append (* p , value )
32
+ return nil
33
+ }
34
+
24
35
var (
25
- printVersion bool
26
- inputFile string
27
- outputFile string
28
- recurse bool
29
- sortOutput bool
30
- silent bool
31
- relative bool
32
- listLangs bool
33
- fields string
36
+ printVersion bool
37
+ inputFile string
38
+ outputFile string
39
+ recurse bool
40
+ sortOutput bool
41
+ silent bool
42
+ relative bool
43
+ listLangs bool
44
+ fields string
45
+ excludePatterns patternList
34
46
)
35
47
36
48
// ignore unknown flags
@@ -47,6 +59,7 @@ func init() {
47
59
flags .BoolVar (& relative , "tag-relative" , false , "file paths should be relative to the directory containing the tag file." )
48
60
flags .BoolVar (& listLangs , "list-languages" , false , "list supported languages." )
49
61
flags .StringVar (& fields , "fields" , "" , "include selected extension fields (only +l)." )
62
+ flags .Var (& excludePatterns , "exclude" , "exclude files and directories matching 'pattern'. May be called multiple times." )
50
63
51
64
flags .Usage = func () {
52
65
fmt .Fprintf (os .Stderr , "gotags version %s\n \n " , Version )
@@ -69,6 +82,43 @@ func walkDir(names []string, dir string) ([]string, error) {
69
82
return names , e
70
83
}
71
84
85
+ // includeName checks if the name should be allowed or not based on the exclude patterns
86
+ func includeName (name string , patterns []string ) (bool , error ) {
87
+ for _ , p := range patterns {
88
+ // Compare pattern to full path and then to base filename
89
+ for _ , v := range []string {name , filepath .Base (name )} {
90
+ m , err := filepath .Match (p , v )
91
+ if err != nil {
92
+ // Error - exclude
93
+ return false , err
94
+ }
95
+ if m {
96
+ // Matches filepath - exclude
97
+ return false , nil
98
+ }
99
+ }
100
+ }
101
+
102
+ // No filters matched - include the file
103
+ return true , nil
104
+ }
105
+
106
+ func filterNames (names []string , patterns []string ) ([]string , error ) {
107
+ var ret []string
108
+
109
+ for _ , f := range names {
110
+ ok , err := includeName (f , patterns )
111
+ if err != nil {
112
+ return nil , err
113
+ }
114
+ if ok {
115
+ ret = append (ret , f )
116
+ }
117
+ }
118
+
119
+ return ret , nil
120
+ }
121
+
72
122
func recurseNames (names []string ) ([]string , error ) {
73
123
var ret []string
74
124
for _ , name := range names {
@@ -113,22 +163,32 @@ func readNames(names []string) ([]string, error) {
113
163
return names , nil
114
164
}
115
165
116
- func getFileNames () ([]string , error ) {
166
+ func getFileNames (files [] string , recurse bool , excludes patternList ) ([]string , error ) {
117
167
var names []string
118
168
119
- names = append (names , flags .Args ()... )
169
+ // Start with list of supplied file names
170
+ names = append (names , files ... )
171
+
172
+ // Read filenames from input file if provided
120
173
names , err := readNames (names )
121
174
if err != nil {
122
175
return nil , err
123
176
}
124
177
178
+ // Recurse into directories in the file list
125
179
if recurse {
126
180
names , err = recurseNames (names )
127
181
if err != nil {
128
182
return nil , err
129
183
}
130
184
}
131
185
186
+ // Apply excludes patterns
187
+ names , err = filterNames (names , excludes )
188
+ if err != nil {
189
+ return nil , err
190
+ }
191
+
132
192
return names , nil
133
193
}
134
194
@@ -147,7 +207,7 @@ func main() {
147
207
return
148
208
}
149
209
150
- files , err := getFileNames ()
210
+ files , err := getFileNames (flags . Args (), recurse , excludePatterns )
151
211
if err != nil {
152
212
fmt .Fprintf (os .Stderr , "cannot get specified files\n \n " )
153
213
flags .Usage ()
0 commit comments