Updates tailscale/corp#29650 Change-Id: Iad4e4ccd9d68ebb1d1a12f335cc5295d0bd05b60 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
86985228bc
commit
259bab9bff
@ -0,0 +1,117 @@ |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package tailscaleroot |
||||
|
||||
import ( |
||||
"bytes" |
||||
"fmt" |
||||
"io" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
"testing" |
||||
|
||||
"tailscale.com/util/set" |
||||
) |
||||
|
||||
func normalizeLineEndings(b []byte) []byte { |
||||
return bytes.ReplaceAll(b, []byte("\r\n"), []byte("\n")) |
||||
} |
||||
|
||||
// TestLicenseHeaders checks that all Go files in the tree
|
||||
// directory tree have a correct-looking Tailscale license header.
|
||||
func TestLicenseHeaders(t *testing.T) { |
||||
want := normalizeLineEndings([]byte(strings.TrimLeft(` |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
`, "\n"))) |
||||
|
||||
exceptions := set.Of( |
||||
// Subprocess test harness code
|
||||
"util/winutil/testdata/testrestartableprocesses/main.go", |
||||
"util/winutil/subprocess_windows_test.go", |
||||
|
||||
// WireGuard copyright
|
||||
"cmd/tailscale/cli/authenticode_windows.go", |
||||
"wgengine/router/ifconfig_windows.go", |
||||
|
||||
// noiseexplorer.com copyright
|
||||
"control/controlbase/noiseexplorer_test.go", |
||||
|
||||
// Generated eBPF management code
|
||||
"derp/xdp/bpf_bpfeb.go", |
||||
"derp/xdp/bpf_bpfel.go", |
||||
|
||||
// Generated kube deepcopy funcs file starts with a Go build tag + an empty line
|
||||
"k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go", |
||||
) |
||||
|
||||
err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error { |
||||
if err != nil { |
||||
return fmt.Errorf("path %s: %v", path, err) |
||||
} |
||||
if exceptions.Contains(filepath.ToSlash(path)) { |
||||
return nil |
||||
} |
||||
base := filepath.Base(path) |
||||
switch base { |
||||
case ".git", "node_modules", "tempfork": |
||||
return filepath.SkipDir |
||||
} |
||||
switch base { |
||||
case "zsyscall_windows.go": |
||||
// Generated code.
|
||||
return nil |
||||
} |
||||
|
||||
if strings.HasSuffix(base, ".config.ts") { |
||||
return nil |
||||
} |
||||
if strings.HasSuffix(base, "_string.go") { |
||||
// Generated file from go:generate stringer
|
||||
return nil |
||||
} |
||||
|
||||
ext := filepath.Ext(base) |
||||
switch ext { |
||||
default: |
||||
return nil |
||||
case ".go", ".ts", ".tsx": |
||||
} |
||||
|
||||
buf := make([]byte, 512) |
||||
f, err := os.Open(path) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer f.Close() |
||||
if n, err := io.ReadAtLeast(f, buf, 512); err != nil && err != io.ErrUnexpectedEOF { |
||||
return err |
||||
} else { |
||||
buf = buf[:n] |
||||
} |
||||
|
||||
buf = normalizeLineEndings(buf) |
||||
|
||||
bufNoTrunc := buf |
||||
if i := bytes.Index(buf, []byte("\npackage ")); i != -1 { |
||||
buf = buf[:i] |
||||
} |
||||
|
||||
if bytes.Contains(buf, want) { |
||||
return nil |
||||
} |
||||
|
||||
if bytes.Contains(bufNoTrunc, []byte("BSD-3-Clause\npackage ")) { |
||||
t.Errorf("file %s has license header as a package doc; add a blank line before the package line", path) |
||||
return nil |
||||
} |
||||
|
||||
t.Errorf("file %s is missing Tailscale copyright header:\n\n%s", path, want) |
||||
return nil |
||||
}) |
||||
if err != nil { |
||||
t.Fatalf("Walk: %v", err) |
||||
} |
||||
} |
||||
@ -1,77 +0,0 @@ |
||||
#!/bin/sh |
||||
# |
||||
# Copyright (c) Tailscale Inc & AUTHORS |
||||
# SPDX-License-Identifier: BSD-3-Clause |
||||
# |
||||
# check_license_headers.sh checks that all Go files in the given |
||||
# directory tree have a correct-looking Tailscale license header. |
||||
|
||||
check_file() { |
||||
got=$1 |
||||
|
||||
want=$(cat <<EOF |
||||
// Copyright (c) Tailscale Inc & AUTHORS |
||||
// SPDX-License-Identifier: BSD-3-Clause |
||||
EOF |
||||
) |
||||
if [ "$got" = "$want" ]; then |
||||
return 0 |
||||
fi |
||||
return 1 |
||||
} |
||||
|
||||
if [ $# != 1 ]; then |
||||
echo "Usage: $0 rootdir" >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
fail=0 |
||||
for file in $(find $1 \( -name '*.go' -or -name '*.tsx' -or -name '*.ts' -not -name '*.config.ts' \) -not -path '*/.git/*' -not -path '*/node_modules/*'); do |
||||
case $file in |
||||
$1/tempfork/*) |
||||
# Skip, tempfork of third-party code |
||||
;; |
||||
$1/wgengine/router/ifconfig_windows.go) |
||||
# WireGuard copyright. |
||||
;; |
||||
$1/cmd/tailscale/cli/authenticode_windows.go) |
||||
# WireGuard copyright. |
||||
;; |
||||
*_string.go) |
||||
# Generated file from go:generate stringer |
||||
;; |
||||
$1/control/controlbase/noiseexplorer_test.go) |
||||
# Noiseexplorer.com copyright. |
||||
;; |
||||
*/zsyscall_windows.go) |
||||
# Generated syscall wrappers |
||||
;; |
||||
$1/util/winutil/subprocess_windows_test.go) |
||||
# Subprocess test harness code |
||||
;; |
||||
$1/util/winutil/testdata/testrestartableprocesses/main.go) |
||||
# Subprocess test harness code |
||||
;; |
||||
*$1/k8s-operator/apis/v1alpha1/zz_generated.deepcopy.go) |
||||
# Generated kube deepcopy funcs file starts with a Go build tag + an empty line |
||||
header="$(head -5 $file | tail -n+3 )" |
||||
;; |
||||
$1/derp/xdp/bpf_bpfe*.go) |
||||
# Generated eBPF management code |
||||
;; |
||||
*) |
||||
header="$(head -2 $file)" |
||||
;; |
||||
esac |
||||
if [ ! -z "$header" ]; then |
||||
if ! check_file "$header"; then |
||||
fail=1 |
||||
echo "${file#$1/} doesn't have the right copyright header:" |
||||
echo "$header" | sed -e 's/^/ /g' |
||||
fi |
||||
fi |
||||
done |
||||
|
||||
if [ $fail -ne 0 ]; then |
||||
exit 1 |
||||
fi |
||||
Loading…
Reference in new issue