Skip to content

Commit 20335b9

Browse files
authored
Added logic to check headers for different file types (#171)
* Added logic to check headers for different file types * code cleanup * updated dockerfile
1 parent fef21cd commit 20335b9

File tree

5 files changed

+219
-33
lines changed

5 files changed

+219
-33
lines changed

license-checker/Dockerfile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
# Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
114
FROM golang:1.24
215

316
LABEL "com.github.actions.name"="license-checker"
@@ -9,7 +22,7 @@ LABEL version="1.0.0"
922

1023
WORKDIR /app
1124

12-
COPY go.mod go.sum main.go LICENSE-HEADER.txt ./
25+
COPY go.mod go.sum main.go LICENSE-HEADER-GO.txt LICENSE-HEADER-SHELL.txt LICENSE-HEADER-ALL.txt ./
1326
RUN go build .
1427

1528
ENTRYPOINT ["/app/license-checker"]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
# Copyright © 2020-2025 Dell Inc. or its subsidiaries. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#

license-checker/main.go

Lines changed: 179 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,43 @@ import (
2929
"strings"
3030
)
3131

32+
const (
33+
goLicenseFile = "/app/LICENSE-HEADER-GO.txt" // Change this to the path of your license file
34+
genericLicenseHeaderFile = "/app/LICENSE-HEADER-ALL.txt"
35+
shellLicenseHeaderFile = "/app/LICENSE-HEADER-SHELL.txt"
36+
rootDir = "." // Change this to the directory you want to search
37+
shellExtensions = ".sh"
38+
yamlExtensions = ".yaml"
39+
dockerExtensions = "Dockerfile"
40+
goExtensions = ".go"
41+
)
42+
43+
func main() {
44+
isAutofixEnabled := flag.Bool("auto-fix", false, "Autofix enabled")
45+
flag.Parse()
46+
47+
hasLicense, err := checkGoLicenseHeader(isAutofixEnabled)
48+
if err != nil {
49+
fmt.Println("Error checking go license header:", err)
50+
}
51+
hasLicense, err = checkShellLicenseHeader(isAutofixEnabled)
52+
if err != nil {
53+
fmt.Println("Error checking shell license header:", err)
54+
}
55+
hasLicense, err = checkYamlLicenseHeader(isAutofixEnabled)
56+
if err != nil {
57+
fmt.Println("Error checking YAML license header:", err)
58+
}
59+
hasLicense, err = checkDockerFileLicenseHeader(isAutofixEnabled)
60+
if err != nil {
61+
fmt.Println("Error checking Dockerfile license header:", err)
62+
}
63+
// if any of the license headers are missing or incorrect then exit with error
64+
if !hasLicense {
65+
os.Exit(1)
66+
}
67+
}
68+
3269
func readLicenseHeader(filePath string) (string, error) {
3370
file, err := os.Open(filePath)
3471
if err != nil {
@@ -41,7 +78,7 @@ func readLicenseHeader(filePath string) (string, error) {
4178
for scanner.Scan() {
4279
headerLines = append(headerLines, scanner.Text())
4380
}
44-
if err := scanner.Err(); err != nil {
81+
if err = scanner.Err(); err != nil {
4582
return "", err
4683
}
4784
return strings.Join(headerLines, "\n"), nil
@@ -72,22 +109,6 @@ func checkLicenseHeader(filePath, licenseHeader string) (bool, error) {
72109
return true, scanner.Err()
73110
}
74111

75-
func listGoFiles(root string) ([]string, error) {
76-
var files []string
77-
err := filepath.WalkDir(root, func(path string, dirEntry fs.DirEntry, err error) error {
78-
if err != nil {
79-
return err
80-
}
81-
if !dirEntry.IsDir() &&
82-
strings.HasSuffix(dirEntry.Name(), ".go") &&
83-
!strings.Contains(dirEntry.Name(), "mock") &&
84-
!strings.Contains(dirEntry.Name(), "generated") {
85-
files = append(files, path)
86-
}
87-
return nil
88-
})
89-
return files, err
90-
}
91112
func autofixLicenseHeader(filePath, licenseHeader string) error {
92113
input, err := os.ReadFile(filePath)
93114
if err != nil {
@@ -98,25 +119,91 @@ func autofixLicenseHeader(filePath, licenseHeader string) error {
98119
return os.WriteFile(filePath, []byte(output), 0644)
99120
}
100121

101-
func main() {
102-
isAutofixEnabled := flag.Bool("auto-fix", false, "Autofix enabled")
103-
flag.Parse()
104-
105-
licenseFile := "/app/LICENSE-HEADER.txt" // Change this to the path of your license file
122+
func checkGoLicenseHeader(isAutofixEnabled *bool) (bool, error) {
123+
licenseHeader, err := readLicenseHeader(goLicenseFile)
124+
if err != nil {
125+
fmt.Println("Error reading license file:", err)
126+
return false, err
127+
}
128+
files, err := listFilesByExtension(goExtensions)
129+
if err != nil {
130+
return false, err
131+
}
132+
fmt.Println("Checking license header for the following go files:")
133+
for _, file := range files {
134+
fmt.Println(file)
135+
}
136+
var hasLicense bool
137+
for _, file := range files {
138+
hasLicense, err = checkLicenseHeader(file, licenseHeader)
139+
if err != nil {
140+
fmt.Printf("Error checking file %s: %v\n", file, err)
141+
continue
142+
}
143+
if !hasLicense {
144+
fmt.Printf("Missing or incorrect license header: %s\n", file)
145+
// if auto-fix is enabled then only we will fix the license headers else just report valid header and exit
146+
if *isAutofixEnabled {
147+
err = autofixLicenseHeader(file, licenseHeader)
148+
if err != nil {
149+
fmt.Printf("Error updating license header for file %s: %v\n", file, err)
150+
} else {
151+
fmt.Printf("License header updated for file: %s\n", file)
152+
}
153+
}
154+
}
155+
}
156+
return hasLicense, nil
157+
}
106158

107-
licenseHeader, err := readLicenseHeader(licenseFile)
159+
func checkShellLicenseHeader(isAutofixEnabled *bool) (bool, error) {
160+
licenseHeader, err := readLicenseHeader(shellLicenseHeaderFile)
108161
if err != nil {
109162
fmt.Println("Error reading license file:", err)
110-
return
163+
return false, err
164+
}
165+
files, err := listFilesByExtension(shellExtensions)
166+
if err != nil {
167+
return false, err
111168
}
169+
fmt.Println("Checking license header for the following shell script files:")
170+
for _, file := range files {
171+
fmt.Println(file)
172+
}
173+
var hasLicense bool
174+
for _, file := range files {
175+
hasLicense, err = checkLicenseHeader(file, licenseHeader)
176+
if err != nil {
177+
fmt.Printf("Error checking file %s: %v\n", file, err)
178+
continue
179+
}
180+
if !hasLicense {
181+
fmt.Printf("Missing or incorrect license header: %s\n", file)
182+
// if auto-fix is enabled then only we will fix the license headers else just report valid header and exit
183+
if *isAutofixEnabled {
184+
err = autofixLicenseHeader(file, licenseHeader)
185+
if err != nil {
186+
fmt.Printf("Error updating license header for file %s: %v\n", file, err)
187+
} else {
188+
fmt.Printf("License header updated for file: %s\n", file)
189+
}
190+
}
191+
}
192+
}
193+
return hasLicense, nil
194+
}
112195

113-
root := "." // Change this to the directory you want to search
114-
files, err := listGoFiles(root)
196+
func checkDockerFileLicenseHeader(isAutofixEnabled *bool) (bool, error) {
197+
licenseHeader, err := readLicenseHeader(genericLicenseHeaderFile)
115198
if err != nil {
116-
fmt.Println("Error:", err)
117-
return
199+
fmt.Println("Error reading license file:", err)
200+
return false, err
118201
}
119-
fmt.Println("Checking license header for the following files:")
202+
files, err := listFilesByExtension(dockerExtensions)
203+
if err != nil {
204+
return false, err
205+
}
206+
fmt.Println("Checking license header for the following Docker files:")
120207
for _, file := range files {
121208
fmt.Println(file)
122209
}
@@ -131,7 +218,7 @@ func main() {
131218
fmt.Printf("Missing or incorrect license header: %s\n", file)
132219
// if auto-fix is enabled then only we will fix the license headers else just report valid header and exit
133220
if *isAutofixEnabled {
134-
err := autofixLicenseHeader(file, licenseHeader)
221+
err = autofixLicenseHeader(file, licenseHeader)
135222
if err != nil {
136223
fmt.Printf("Error updating license header for file %s: %v\n", file, err)
137224
} else {
@@ -140,7 +227,67 @@ func main() {
140227
}
141228
}
142229
}
143-
if !hasLicense {
144-
os.Exit(1)
230+
return hasLicense, nil
231+
}
232+
233+
func checkYamlLicenseHeader(isAutofixEnabled *bool) (bool, error) {
234+
licenseHeader, err := readLicenseHeader(genericLicenseHeaderFile)
235+
if err != nil {
236+
fmt.Println("Error reading license file:", err)
237+
return false, err
145238
}
239+
files, err := listFilesByExtension(yamlExtensions)
240+
if err != nil {
241+
return false, err
242+
}
243+
fmt.Println("Checking license header for the following YAML files:")
244+
for _, file := range files {
245+
fmt.Println(file)
246+
}
247+
var hasLicense bool
248+
for _, file := range files {
249+
hasLicense, err = checkLicenseHeader(file, licenseHeader)
250+
if err != nil {
251+
fmt.Printf("Error checking file %s: %v\n", file, err)
252+
continue
253+
}
254+
if !hasLicense {
255+
fmt.Printf("Missing or incorrect license header: %s\n", file)
256+
// if auto-fix is enabled then only we will fix the license headers else just report valid header and exit
257+
if *isAutofixEnabled {
258+
err = autofixLicenseHeader(file, licenseHeader)
259+
if err != nil {
260+
fmt.Printf("Error updating license header for file %s: %v\n", file, err)
261+
} else {
262+
fmt.Printf("License header updated for file: %s\n", file)
263+
}
264+
}
265+
}
266+
}
267+
return hasLicense, nil
268+
}
269+
270+
func listFilesByExtension(extension string) ([]string, error) {
271+
var files []string
272+
err := filepath.WalkDir(rootDir, func(path string, dirEntry fs.DirEntry, err error) error {
273+
if err != nil {
274+
return err
275+
}
276+
// we will check for generated and mock files for go extension only else search for other file types
277+
if extension == goExtensions {
278+
if !dirEntry.IsDir() &&
279+
strings.HasSuffix(dirEntry.Name(), extension) &&
280+
!strings.Contains(dirEntry.Name(), "mock") &&
281+
!strings.Contains(dirEntry.Name(), "generated") {
282+
files = append(files, path)
283+
}
284+
} else {
285+
if !dirEntry.IsDir() &&
286+
strings.HasSuffix(dirEntry.Name(), extension) {
287+
files = append(files, path)
288+
}
289+
}
290+
return nil
291+
})
292+
return files, err
146293
}

0 commit comments

Comments
 (0)