pkgdoc_test.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tailscaleroot
  4. import (
  5. "go/parser"
  6. "go/token"
  7. "os"
  8. "path/filepath"
  9. "runtime"
  10. "strings"
  11. "testing"
  12. )
  13. func TestPackageDocs(t *testing.T) {
  14. switch runtime.GOOS {
  15. case "darwin", "linux":
  16. // Enough coverage for CI+devs.
  17. default:
  18. t.Skipf("skipping on %s", runtime.GOOS)
  19. }
  20. var goFiles []string
  21. err := filepath.Walk(".", func(path string, fi os.FileInfo, err error) error {
  22. if err != nil {
  23. return err
  24. }
  25. if fi.Mode().IsDir() && path == ".git" {
  26. return filepath.SkipDir // No documentation lives in .git
  27. }
  28. if fi.Mode().IsRegular() && strings.HasSuffix(path, ".go") {
  29. if strings.HasSuffix(path, "_test.go") {
  30. return nil
  31. }
  32. goFiles = append(goFiles, path)
  33. }
  34. return nil
  35. })
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. byDir := map[string][]string{} // dir => files
  40. for _, fileName := range goFiles {
  41. fset := token.NewFileSet()
  42. f, err := parser.ParseFile(fset, fileName, nil, parser.PackageClauseOnly|parser.ParseComments)
  43. if err != nil {
  44. t.Fatalf("failed to ParseFile %q: %v", fileName, err)
  45. }
  46. dir := filepath.Dir(fileName)
  47. if _, ok := byDir[dir]; !ok {
  48. byDir[dir] = nil
  49. }
  50. if f.Doc != nil {
  51. byDir[dir] = append(byDir[dir], fileName)
  52. txt := f.Doc.Text()
  53. if strings.Contains(txt, "SPDX-License-Identifier") {
  54. t.Errorf("the copyright header for %s became its package doc due to missing blank line", fileName)
  55. }
  56. }
  57. }
  58. for dir, ff := range byDir {
  59. switch dir {
  60. case "tstest/integration/vms":
  61. // This package has a couple go:build ignore commands and this test doesn't
  62. // handle parsing those. Just allowlist that package for now (2024-07-10).
  63. continue
  64. }
  65. if len(ff) > 1 {
  66. t.Logf("multiple files with package doc in %s: %q", dir, ff)
  67. }
  68. if len(ff) == 0 {
  69. t.Errorf("no package doc in %s", dir)
  70. }
  71. }
  72. t.Logf("parsed %d files", len(goFiles))
  73. }