-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
108 lines (89 loc) · 2.32 KB
/
main.go
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
package main
import (
"bufio"
"fmt"
"log"
"os"
"regexp"
uuid "github.com/satori/go.uuid"
)
type check struct {
re *regexp.Regexp
do func([]string) string
}
var checks = []check{
check{regexp.MustCompile(`^(type)\s+([A-Z][^\s{]*).+(\r*)$`), exportedComment},
check{regexp.MustCompile(`^(func)\s+(?:\([^\s]+\s+[^\s]+\)\s+)?([A-Z][^\s(]*).+(\r*)$`), exportedComment},
check{regexp.MustCompile(`^(var|const)\s+(\().*(\r*)$`), exportedBlockComment},
check{regexp.MustCompile(`^(var|const)\s+([A-Z][^\s=]*).+(\r*)$`), exportedComment},
check{regexp.MustCompile(`^(package)\s+([^\s/]+).*(\r*)$`), packageComment},
}
func main() {
for _, inFileName := range os.Args[1:] {
outFileName := inFileName + "." + uuid.NewV4().String()
log.Printf("File %q", inFileName)
inFile, err := os.Open(inFileName)
panicOnErr(err)
outFile, err := os.Create(outFileName)
panicOnErr(err)
fileChanged := false
lastLineIsComment := false
for scanner := bufio.NewScanner(inFile); scanner.Scan(); {
str := scanner.Text()
var comment string
if !lastLineIsComment {
comment = prependFakeGoDocComment(checks, str)
fileChanged = fileChanged || (len(comment) > 0)
}
_, err = fmt.Fprint(outFile, comment, str, "\n")
panicOnErr(err)
lastLineIsComment = (len(str) >= 2 && str[:2] == "//")
}
panicOnErr(outFile.Close())
panicOnErr(inFile.Close())
if fileChanged {
log.Printf("File %q > %q", outFileName, inFileName)
panicOnErr(os.Rename(outFileName, inFileName))
} else {
panicOnErr(os.Remove(outFileName))
}
}
}
func panicOnErr(err error) {
if err != nil {
panic(err)
}
}
func prependFakeGoDocComment(
checks []check,
str string,
) string {
for _, re := range checks {
fields := re.re.FindStringSubmatch(str)
if fields != nil {
comment := re.do(fields)
log.Printf("%q", comment)
return comment + fields[3] + "\n"
}
}
return ""
}
func exportedComment(fields []string) string {
return fmt.Sprintf(
"// %s exported %s should have comment or be unexported",
fields[2],
fields[1],
)
}
func exportedBlockComment(fields []string) string {
return fmt.Sprintf(
"// exported %s should have comment on this block or be unexported",
fields[1],
)
}
func packageComment(fields []string) string {
return fmt.Sprintf(
"// Package %s comment should be of this form",
fields[2],
)
}