@@ -10,6 +10,8 @@ import (
10
10
"path/filepath"
11
11
"regexp"
12
12
"strings"
13
+
14
+ "gopkg.in/src-d/enry.v1/data"
13
15
)
14
16
15
17
var (
@@ -28,10 +30,20 @@ var (
28
30
"XML" : true , "JSON" : true , "TOML" : true , "YAML" : true , "INI" : true , "SQL" : true ,
29
31
}
30
32
31
- gitattributes = map [string ]bool {}
32
- languageGitattributes = map [* regexp.Regexp ]string {}
33
+ vendorGitattributes = map [string ]bool {}
34
+ documentationGitattributes = map [string ]bool {}
35
+ languageGitattributes = map [* regexp.Regexp ]string {}
33
36
)
34
37
38
+ type OverrideError struct {
39
+ attribute string
40
+ path string
41
+ }
42
+
43
+ func (e * OverrideError ) Error () string {
44
+ return fmt .Sprintf (".gitattributes: You are overriding a %s attribute of one of your previous lines %s\n " , e .attribute , e .path )
45
+ }
46
+
35
47
// IsAuxiliaryLanguage returns whether or not lang is an auxiliary language.
36
48
func IsAuxiliaryLanguage (lang string ) bool {
37
49
_ , ok := auxiliaryLanguages [lang ]
@@ -52,20 +64,20 @@ func IsDotFile(path string) bool {
52
64
53
65
// IsVendor returns whether or not path is a vendor path.
54
66
func IsVendor (path string ) bool {
55
- if val , ok := gitattributes [path ]; ok {
67
+ if val , ok := vendorGitattributes [path ]; ok {
56
68
return val
57
69
}
58
70
59
- return vendorMatchers .Match (path )
71
+ return data . VendorMatchers .Match (path )
60
72
}
61
73
62
74
// IsDocumentation returns whether or not path is a documentation path.
63
75
func IsDocumentation (path string ) bool {
64
- if val , ok := gitattributes [path ]; ok {
76
+ if val , ok := documentationGitattributes [path ]; ok {
65
77
return val
66
78
}
67
79
68
- return documentationMatchers .Match (path )
80
+ return data . DocumentationMatchers .Match (path )
69
81
}
70
82
71
83
const sniffLen = 8000
@@ -92,8 +104,8 @@ func LoadGitattributes() {
92
104
}
93
105
}
94
106
95
- func loadRawGitattributes (name string ) (map [string ]string , error ) {
96
- gitattributes := map [string ]string {}
107
+ func loadRawGitattributes (name string ) (map [string ][] string , error ) {
108
+ gitattributes := map [string ][] string {}
97
109
data , err := ioutil .ReadFile (name )
98
110
if err != nil {
99
111
if err != os .ErrNotExist {
@@ -113,54 +125,80 @@ func loadRawGitattributes(name string) (map[string]string, error) {
113
125
return gitattributes , nil
114
126
}
115
127
116
- func loadLine (line string , gitattributes map [string ]string ) error {
128
+ func loadLine (line string , gitattributes map [string ][] string ) error {
117
129
tokens := strings .Fields (line )
118
130
if len (tokens ) == 2 {
119
- var err error
120
- if isInside (tokens [0 ], gitattributes ) {
121
- err = errors .New (fmt .Sprintf (".gitattributes: You are overriding one of your previous lines %s\n " , tokens [0 ]))
122
- log .Printf (err .Error ())
123
- }
124
131
125
- gitattributes [tokens [0 ]] = tokens [1 ]
126
- return err
127
- } else {
132
+ gitattributes [tokens [0 ]] = append ( gitattributes [ tokens [0 ]], tokens [ 1 ])
133
+ return nil
134
+ } else if len ( tokens ) != 0 {
128
135
err := errors .New (".gitattributes: Each line only can have a pair of elements E.g. path/to/file attribute" )
129
136
log .Println (err .Error ())
130
-
131
137
return err
132
138
}
139
+ return nil
133
140
}
134
141
135
- func parseAttributes (attributes map [string ]string ) []error {
136
- var errArray []error
137
- for key , val := range attributes {
138
- switch {
139
- case val == "linguist-vendored" || val == "linguist-documentation" :
140
- gitattributes [key ] = true
141
- case val == "linguist-vendored=false" || val == "linguist-documentation=false" :
142
- gitattributes [key ] = false
143
- case strings .Contains (val , "linguist-language=" ):
144
- err := processLanguageAttr (key , val )
142
+ func parseAttributes (attributes map [string ][]string ) []error {
143
+ errArray := []error {}
144
+ for key , values := range attributes {
145
+ for _ , val := range values {
146
+ err := parseAttribute (key , val )
145
147
if err != nil {
146
148
errArray = append (errArray , err )
147
149
}
148
- default :
149
- err := errors .New (fmt .Sprintf ("gitattributes: The matcher %s doesn't exists\n " , val ))
150
- errArray = append (errArray , err )
151
- log .Printf (err .Error ())
152
150
}
153
151
}
154
152
155
153
return errArray
156
154
}
157
155
158
- func isInside (key string , gitattributes map [string ]string ) bool {
159
- if _ , ok := gitattributes [key ]; ok {
160
- return ok
156
+ func parseAttribute (key string , attribute string ) error {
157
+ var err error
158
+ switch {
159
+ case strings .Contains (attribute , "linguist-vendored" ):
160
+ err = processVendorAttr (key , attribute )
161
+ case strings .Contains (attribute , "linguist-documentation" ):
162
+ err = processDocumentationAttr (key , attribute )
163
+ case strings .Contains (attribute , "linguist-language=" ):
164
+ err = processLanguageAttr (key , attribute )
165
+ default :
166
+ err = errors .New (fmt .Sprintf ("gitattributes: The matcher %s doesn't exists\n " , attribute ))
167
+ log .Printf (err .Error ())
168
+ }
169
+ return err
170
+ }
171
+
172
+ func processVendorAttr (key string , attribute string ) error {
173
+ var err error
174
+ if _ , ok := vendorGitattributes [key ]; ok {
175
+ err = & OverrideError {attribute : "vendor" , path : key }
176
+ }
177
+
178
+ switch {
179
+ case attribute == "linguist-vendored" :
180
+ vendorGitattributes [key ] = true
181
+ case attribute == "linguist-vendored=false" :
182
+ vendorGitattributes [key ] = false
183
+ }
184
+
185
+ return err
186
+ }
187
+
188
+ func processDocumentationAttr (key string , attribute string ) error {
189
+ var err error
190
+ if _ , ok := documentationGitattributes [key ]; ok {
191
+ err = & OverrideError {attribute : "documentation" , path : key }
192
+ }
193
+
194
+ switch {
195
+ case attribute == "linguist-documentation" :
196
+ documentationGitattributes [key ] = true
197
+ case attribute == "linguist-documentation=false" :
198
+ documentationGitattributes [key ] = false
161
199
}
162
200
163
- return false
201
+ return err
164
202
}
165
203
166
204
func processLanguageAttr (regExpString string , attribute string ) error {
0 commit comments