@@ -18,6 +18,7 @@ package main
18
18
19
19
import (
20
20
"bytes"
21
+ "errors"
21
22
"flag"
22
23
"fmt"
23
24
"html/template"
@@ -46,11 +47,12 @@ Flags:
46
47
`
47
48
48
49
var (
49
- holder = flag .String ("c" , "Google LLC" , "copyright holder" )
50
- license = flag .String ("l" , "apache" , "license type: apache, bsd, mit" )
51
- licensef = flag .String ("f" , "" , "license file" )
52
- year = flag .String ("y" , fmt .Sprint (time .Now ().Year ()), "copyright year(s)" )
53
- verbose = flag .Bool ("v" , false , "verbose mode: print the name of the files that are modified" )
50
+ holder = flag .String ("c" , "Google LLC" , "copyright holder" )
51
+ license = flag .String ("l" , "apache" , "license type: apache, bsd, mit" )
52
+ licensef = flag .String ("f" , "" , "license file" )
53
+ year = flag .String ("y" , fmt .Sprint (time .Now ().Year ()), "copyright year(s)" )
54
+ verbose = flag .Bool ("v" , false , "verbose mode: print the name of the files that are modified" )
55
+ checkonly = flag .Bool ("check" , false , "check only mode: verify presence of license headers and exit with non-zero code if missing" )
54
56
)
55
57
56
58
func main () {
@@ -97,13 +99,35 @@ func main() {
97
99
for f := range ch {
98
100
f := f // https://golang.org/doc/faq#closures_and_goroutines
99
101
wg .Go (func () error {
100
- modified , err := addLicense (f .path , f .mode , t , data )
101
- if err != nil {
102
- log .Printf ("%s: %v" , f .path , err )
103
- return err
104
- }
105
- if * verbose && modified {
106
- log .Printf ("%s modified" , f .path )
102
+ if * checkonly {
103
+ // Check if file extension is known
104
+ lic , err := licenseHeader (f .path , t , data )
105
+ if err != nil {
106
+ log .Printf ("%s: %v" , f .path , err )
107
+ return err
108
+ }
109
+ if lic == nil { // Unknown fileExtension
110
+ return nil
111
+ }
112
+ // Check if file has a license
113
+ isMissingLicenseHeader , err := fileHasLicense (f .path )
114
+ if err != nil {
115
+ log .Printf ("%s: %v" , f .path , err )
116
+ return err
117
+ }
118
+ if isMissingLicenseHeader {
119
+ fmt .Printf ("%s\n " , f .path )
120
+ return errors .New ("missing license header" )
121
+ }
122
+ } else {
123
+ modified , err := addLicense (f .path , f .mode , t , data )
124
+ if err != nil {
125
+ log .Printf ("%s: %v" , f .path , err )
126
+ return err
127
+ }
128
+ if * verbose && modified {
129
+ log .Printf ("%s modified" , f .path )
130
+ }
107
131
}
108
132
return nil
109
133
})
@@ -142,11 +166,45 @@ func walk(ch chan<- *file, start string) {
142
166
}
143
167
144
168
func addLicense (path string , fmode os.FileMode , tmpl * template.Template , data * copyrightData ) (bool , error ) {
169
+ var lic []byte
170
+ var err error
171
+ lic , err = licenseHeader (path , tmpl , data )
172
+ if err != nil || lic == nil {
173
+ return false , err
174
+ }
175
+
176
+ b , err := ioutil .ReadFile (path )
177
+ if err != nil || hasLicense (b ) {
178
+ return false , err
179
+ }
180
+
181
+ line := hashBang (b )
182
+ if len (line ) > 0 {
183
+ b = b [len (line ):]
184
+ if line [len (line )- 1 ] != '\n' {
185
+ line = append (line , '\n' )
186
+ }
187
+ lic = append (line , lic ... )
188
+ }
189
+ b = append (lic , b ... )
190
+ return true , ioutil .WriteFile (path , b , fmode )
191
+ }
192
+
193
+ // fileHasLicense reports whether the file at path contains a license header.
194
+ func fileHasLicense (path string ) (bool , error ) {
195
+ b , err := ioutil .ReadFile (path )
196
+ if err != nil || hasLicense (b ) {
197
+ return false , err
198
+ }
199
+ return true , nil
200
+ }
201
+
202
+ func licenseHeader (path string , tmpl * template.Template , data * copyrightData ) ([]byte , error ) {
145
203
var lic []byte
146
204
var err error
147
205
switch fileExtension (path ) {
148
206
default :
149
- return false , nil
207
+ return nil , nil
150
208
case ".c" , ".h" :
151
209
lic , err = prefix (tmpl , data , "/*" , " * " , " */" )
152
210
case ".js" , ".jsx" , ".tsx" , ".css" , ".tf" , ".ts" :
@@ -168,25 +226,7 @@ func addLicense(path string, fmode os.FileMode, tmpl *template.Template, data *c
168
226
case ".ml" , ".mli" , ".mll" , ".mly" :
169
227
lic , err = prefix (tmpl , data , "(**" , " " , "*)" )
170
228
}
171
- if err != nil || lic == nil {
172
- return false , err
173
- }
174
-
175
- b , err := ioutil .ReadFile (path )
176
- if err != nil || hasLicense (b ) {
177
- return false , err
178
- }
179
-
180
- line := hashBang (b )
181
- if len (line ) > 0 {
182
- b = b [len (line ):]
183
- if line [len (line )- 1 ] != '\n' {
184
- line = append (line , '\n' )
185
- }
186
- lic = append (line , lic ... )
187
- }
188
- b = append (lic , b ... )
189
- return true , ioutil .WriteFile (path , b , fmode )
229
+ return lic , err
190
230
}
191
231
192
232
func fileExtension (name string ) string {
0 commit comments