|
|
@@ -0,0 +1,75 @@
|
|
|
+// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
+// SPDX-License-Identifier: BSD-3-Clause
|
|
|
+
|
|
|
+package tailscaleroot
|
|
|
+
|
|
|
+import (
|
|
|
+ "go/parser"
|
|
|
+ "go/token"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+ "runtime"
|
|
|
+ "strings"
|
|
|
+ "testing"
|
|
|
+)
|
|
|
+
|
|
|
+func TestPackageDocs(t *testing.T) {
|
|
|
+ switch runtime.GOOS {
|
|
|
+ case "darwin", "linux":
|
|
|
+ // Enough coverage for CI+devs.
|
|
|
+ default:
|
|
|
+ t.Skipf("skipping on %s", runtime.GOOS)
|
|
|
+ }
|
|
|
+
|
|
|
+ var goFiles []string
|
|
|
+ err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error {
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if fi.Mode().IsRegular() && strings.HasSuffix(path, ".go") {
|
|
|
+ if strings.HasSuffix(path, "_test.go") {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ goFiles = append(goFiles, path)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ t.Fatal(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ byDir := map[string][]string{} // dir => files
|
|
|
+ for _, fileName := range goFiles {
|
|
|
+ fset := token.NewFileSet()
|
|
|
+ f, err := parser.ParseFile(fset, fileName, nil, parser.PackageClauseOnly|parser.ParseComments)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to ParseFile %q: %v", fileName, err)
|
|
|
+ }
|
|
|
+ dir := filepath.Dir(fileName)
|
|
|
+ if _, ok := byDir[dir]; !ok {
|
|
|
+ byDir[dir] = nil
|
|
|
+ }
|
|
|
+ if f.Doc != nil {
|
|
|
+ byDir[dir] = append(byDir[dir], fileName)
|
|
|
+ txt := f.Doc.Text()
|
|
|
+ if strings.Contains(txt, "SPDX-License-Identifier") {
|
|
|
+ t.Errorf("the copyright header for %s became its package doc due to missing blank line", fileName)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for dir, ff := range byDir {
|
|
|
+ switch dir {
|
|
|
+ case "tstest/integration/vms":
|
|
|
+ // This package has a couple go:build ignore commands and this test doesn't
|
|
|
+ // handle parsing those. Just allowlist that package for now (2024-07-10).
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if len(ff) > 1 {
|
|
|
+ t.Logf("multiple files with package doc in %s: %q", dir, ff)
|
|
|
+ }
|
|
|
+ if len(ff) == 0 {
|
|
|
+ t.Errorf("no package doc in %s", dir)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ t.Logf("parsed %d files", len(goFiles))
|
|
|
+}
|