forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
132 lines (113 loc) · 2.79 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"flag"
"fmt"
"os"
"strings"
"golang.org/x/mod/modfile"
)
func main() {
if len(os.Args) < 2 {
printUsage()
os.Exit(1)
}
var err error
switch os.Args[1] {
case "list-submodules":
err = listSubmodules()
case "validate-dockerfile":
err = validateDockerfile()
default:
printUsage()
}
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
func printUsage() {
println("Usage: go-workspace <command> [args]")
println("Commands:")
println(" list-submodules - List submodules in go.work")
}
func listSubmodules() error {
fs := flag.NewFlagSet("list-submodules", flag.ExitOnError)
workPath := fs.String("path", "go.work", "Path to go.work")
delimiter := fs.String("delimiter", "\n", "Delimiter to use when printing paths")
skip := fs.String("skip", "", "Skip submodules with this comment tag")
help := fs.Bool("help", false, "Print help message")
if err := fs.Parse(os.Args[2:]); err != nil {
return err
}
if *help {
fs.Usage()
return nil
}
workfile, err := parseGoWork(*workPath)
if err != nil {
return err
}
paths := getSubmodulePaths(workfile, *skip)
for _, p := range paths {
fmt.Printf("%s%s", p, *delimiter)
}
return nil
}
func validateDockerfile() error {
fs := flag.NewFlagSet("validate-dockerfile", flag.ExitOnError)
workPath := fs.String("path", "go.work", "Path to go.work")
dockerfilePath := fs.String("dockerfile-path", "Dockerfile", "Path to Dockerfile")
skip := fs.String("skip", "", "Skip submodules with this comment tag")
if err := fs.Parse(os.Args[2:]); err != nil {
return err
}
dockerFileRaw, err := os.ReadFile(*dockerfilePath)
if err != nil {
return err
}
dockerFile := string(dockerFileRaw)
workfile, err := parseGoWork(*workPath)
if err != nil {
return err
}
paths := getSubmodulePaths(workfile, *skip)
for _, p := range paths {
path := strings.TrimPrefix(p, "./")
if path == "" || path == "." {
continue
}
if !strings.Contains(dockerFile, path) {
return fmt.Errorf("the Dockerfile is missing `COPY %s/go.* %s` for the related module. Please add it and commit the change.", path, path)
}
}
fmt.Println("All submodules are included in the Dockerfile.")
return nil
}
func getSubmodulePaths(wf *modfile.WorkFile, skip string) []string {
var paths []string
for _, d := range wf.Use {
if hasSkipTag(d, skip) {
continue
}
paths = append(paths, d.Path)
}
return paths
}
func hasSkipTag(d *modfile.Use, tag string) bool {
if tag == "" {
return false
}
for _, c := range d.Syntax.Comments.Suffix {
if strings.Contains(c.Token, fmt.Sprintf("skip:%s", tag)) {
return true
}
}
return false
}
func parseGoWork(p string) (*modfile.WorkFile, error) {
contents, err := os.ReadFile(p)
if err != nil {
return nil, err
}
return modfile.ParseWork(p, contents, nil)
}