...
1
2 package main
3
4 import (
5 "bytes"
6 "flag"
7 "fmt"
8 "go/build"
9 "io"
10 "log"
11 "os"
12 "os/exec"
13 "path/filepath"
14 )
15
16 var (
17 sourceFlag = flag.String("source", "", "Specifies the http.FileSystem variable to use as source.")
18 tagFlag = flag.String("tag", "dev", "Specifies a single build tag to use for source. The output will include a negated version.")
19 nFlag = flag.Bool("n", false, "Print the generated source but do not run it.")
20 )
21
22 func usage() {
23 fmt.Fprintln(os.Stderr, `Usage: vfsgendev [flags] -source="import/path".VariableName`)
24 flag.PrintDefaults()
25 }
26
27 func main() {
28 flag.Usage = usage
29 flag.Parse()
30 if flag.NArg() != 0 {
31 flag.Usage()
32 os.Exit(2)
33 }
34 importPath, variableName, err := parseSourceFlag(*sourceFlag)
35 if err != nil {
36 fmt.Fprintln(os.Stderr, "-source flag has invalid value:", err)
37 fmt.Fprintln(os.Stderr)
38 flag.Usage()
39 os.Exit(2)
40 }
41 tag, err := parseTagFlag(*tagFlag)
42 if err != nil {
43 fmt.Fprintln(os.Stderr, "-tag flag has invalid value:", err)
44 fmt.Fprintln(os.Stderr)
45 flag.Usage()
46 os.Exit(2)
47 }
48
49 err = run(importPath, variableName, tag)
50 if err != nil {
51 log.Fatalln(err)
52 }
53 }
54
55 func run(importPath, variableName, tag string) error {
56 bctx := build.Default
57 bctx.BuildTags = []string{tag}
58 packageName, variableComment, err := lookupNameAndComment(bctx, importPath, variableName)
59 if err != nil {
60 return err
61 }
62
63 var buf bytes.Buffer
64 err = generateTemplate.Execute(&buf, data{
65 ImportPath: importPath,
66 PackageName: packageName,
67 BuildTags: "!" + tag,
68 VariableName: variableName,
69 VariableComment: variableComment,
70 })
71 if err != nil {
72 return err
73 }
74
75 if *nFlag {
76 io.Copy(os.Stdout, &buf)
77 return nil
78 }
79
80 err = goRun(buf.String(), tag)
81 return err
82 }
83
84
85 func goRun(src string, tags string) error {
86
87 tempDir, err := os.MkdirTemp("", "vfsgendev_")
88 if err != nil {
89 return err
90 }
91 defer func() {
92 err := os.RemoveAll(tempDir)
93 if err != nil {
94 fmt.Fprintln(os.Stderr, "warning: error removing temp dir:", err)
95 }
96 }()
97
98
99 tempFile := filepath.Join(tempDir, "generate.go")
100 err = os.WriteFile(tempFile, []byte(src), 0600)
101 if err != nil {
102 return err
103 }
104
105
106 cmd := exec.Command("go", "run", "-tags="+tags, tempFile)
107 cmd.Stdout = os.Stdout
108 cmd.Stderr = os.Stderr
109 return cmd.Run()
110 }
111
View as plain text