Skip to content

Commit e6bf0ba

Browse files
authored
license_test.go: add test for license headers in .go files (#42)
This commit adds a CI test to check all .go files in tsidp for the required licence header block. Ported over from tailscale/tailscale repo. Signed-off-by: Benson Wong <benson@tailscale.com>
1 parent 0015645 commit e6bf0ba

3 files changed

Lines changed: 106 additions & 1 deletion

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ build-linux:
1111
GOOS=linux GOARCH=amd64 go build -o build/tsidp-server-linux-amd64-$(shell date +%Y-%m-%d)-$(shell git rev-parse --short=5 HEAD) ./tsidp-server.go
1212

1313
test:
14-
go test -count 1 ./server
14+
go test -count 1 . ./server
1515

1616
clean:
1717
rm -f build/tsidp-server*

cmd/verifier/verifier.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
14
package main
25

36
import (

license_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
package main
5+
6+
import (
7+
"bytes"
8+
"fmt"
9+
"io"
10+
"os"
11+
"path/filepath"
12+
"strings"
13+
"testing"
14+
15+
"tailscale.com/util/set"
16+
)
17+
18+
func normalizeLineEndings(b []byte) []byte {
19+
return bytes.ReplaceAll(b, []byte("\r\n"), []byte("\n"))
20+
}
21+
22+
// TestLicenseHeaders checks that all Go files in the tree
23+
// directory tree have a correct-looking Tailscale license header.
24+
func TestLicenseHeaders(t *testing.T) {
25+
want := normalizeLineEndings([]byte(strings.TrimLeft(`
26+
// Copyright (c) Tailscale Inc & AUTHORS
27+
// SPDX-License-Identifier: BSD-3-Clause
28+
`, "\n")))
29+
30+
exceptions := set.Of(
31+
// Subprocess test harness code
32+
"examples/mcp-server/mcp-server.go",
33+
)
34+
35+
err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error {
36+
if err != nil {
37+
return fmt.Errorf("path %s: %v", path, err)
38+
}
39+
if exceptions.Contains(filepath.ToSlash(path)) {
40+
return nil
41+
}
42+
base := filepath.Base(path)
43+
switch base {
44+
case ".git", "node_modules", "tempfork":
45+
return filepath.SkipDir
46+
}
47+
switch base {
48+
case "zsyscall_windows.go":
49+
// Generated code.
50+
return nil
51+
}
52+
53+
if strings.HasSuffix(base, ".config.ts") {
54+
return nil
55+
}
56+
if strings.HasSuffix(base, "_string.go") {
57+
// Generated file from go:generate stringer
58+
return nil
59+
}
60+
61+
ext := filepath.Ext(base)
62+
switch ext {
63+
default:
64+
return nil
65+
case ".go", ".ts", ".tsx":
66+
}
67+
68+
buf := make([]byte, 512)
69+
f, err := os.Open(path)
70+
if err != nil {
71+
return err
72+
}
73+
defer f.Close()
74+
if n, err := io.ReadAtLeast(f, buf, 512); err != nil && err != io.ErrUnexpectedEOF {
75+
return err
76+
} else {
77+
buf = buf[:n]
78+
}
79+
80+
buf = normalizeLineEndings(buf)
81+
82+
bufNoTrunc := buf
83+
if i := bytes.Index(buf, []byte("\npackage ")); i != -1 {
84+
buf = buf[:i]
85+
}
86+
87+
if bytes.Contains(buf, want) {
88+
return nil
89+
}
90+
91+
if bytes.Contains(bufNoTrunc, []byte("BSD-3-Clause\npackage ")) {
92+
t.Errorf("file %s has license header as a package doc; add a blank line before the package line", path)
93+
return nil
94+
}
95+
96+
t.Errorf("file %s is missing Tailscale copyright header:\n\n%s", path, want)
97+
return nil
98+
})
99+
if err != nil {
100+
t.Fatalf("Walk: %v", err)
101+
}
102+
}

0 commit comments

Comments
 (0)