File: main.go

package info (click to toggle)
golang-github-azure-azure-sdk-for-go 68.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 556,256 kB
  • sloc: javascript: 196; sh: 96; makefile: 7
file content (116 lines) | stat: -rw-r--r-- 2,776 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main

import (
	"flag"
	"fmt"
	"go/doc"
	"go/parser"
	"go/token"
	"io/fs"
	"os"
	"path/filepath"
	"strings"
)

var isMGMT = false

func filter(f fs.FileInfo) bool {
	return !strings.HasSuffix(f.Name(), "_test.go")
}

func findAllSubDirectories(root string) []string {
	var ret []string

	filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
		if err != nil {
			panic(err)
		}
		if strings.Contains(path, "resourcemanager") {
			isMGMT = true
		}
		if strings.Contains(path, "eng/tools") {
			return filepath.SkipDir
		}
		if info.IsDir() && strings.HasSuffix(path, "internal") {
			return filepath.SkipDir
		} else if info.IsDir() {
			ret = append(ret, path)
		}
		return nil
	})

	return ret
}

// validateDirectory counts the number of missing doc comments
func validateDirectory(directory string) int {
	missingDocCount := 0

	fset := token.NewFileSet() // positions are relative to fset
	d, err := parser.ParseDir(fset, directory, filter, parser.ParseComments)
	if err != nil {
		panic(fmt.Errorf("could not parse directory: %w", err))
	}

	for k, f := range d {
		if strings.Contains("_test", k) {
			continue
		}
		fmt.Println("package", k)
		p := doc.New(f, "./", 2)

		for _, t := range p.Types {
			if !strings.HasPrefix(t.Doc, t.Name) {
				fmt.Println("missing or invalid doc comment. all docs should start with the type they are documenting")
				fmt.Printf("type: '%s' docs: '%s'\n", t.Name, t.Doc)
				missingDocCount += 1
			}

			for _, m := range t.Methods {
				if !strings.HasPrefix(m.Doc, m.Name) {
					fmt.Println("missing or invalid doc comment. all docs should start with the function they are documenting")
					fmt.Printf("type: '%s' method: '%s' docs: '%s'\n", t.Name, m.Name, m.Doc)
					missingDocCount += 1
				}
			}
		}

		for _, f := range p.Funcs {
			if strings.HasPrefix(f.Name, "Example") {
				continue
			}
			if !strings.HasPrefix(f.Doc, f.Name) {
				fmt.Println("missing or invalid doc comment. all docs should start with the function they are documenting")
				if f.Recv != "" {
					fmt.Printf("type: %s receiver: %s docs: %s\n", f.Name, f.Recv, f.Doc)
				} else {
					fmt.Printf("type: %s docs: %s\n", f.Name, f.Doc)
				}
				missingDocCount += 1
			}
		}
	}
	return missingDocCount
}

func main() {
	var root string
	flag.StringVar(&root, "directory", ".", "directory to check docs for")
	flag.Parse()

	fmt.Printf("checking documentation in %s\n", root)
	var totalMissing = 0
	for _, dir := range findAllSubDirectories(root) {
		totalMissing += validateDirectory(dir)
	}

	if totalMissing > 0 {
		fmt.Printf("Found %d missing doc comments\n", totalMissing)
		if !isMGMT {
			os.Exit(1)
		}

	} else {
		fmt.Println("There are no public methods/functions/types with missing documentation")
	}
}