-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
154 lines (133 loc) · 3.91 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package main
import (
"flag"
"fmt"
"go/format"
"os"
"os/exec"
"strings"
)
var (
packageName string
funcName string
inFilenames []string
inFiles []*os.File
outFilename string
verbose bool
backup, fixSource, structKeys bool
)
func init() {
flag.StringVar(&packageName, "package", "", "the Go package name to produce code for; defaults to the GOPACKAGE environment variable, or 'main' if not set")
flag.BoolVar(&verbose, "v", false, "more verbose output (to stderr)")
flag.StringVar(&outFilename, "out", "", "filename to write to instead of stdout")
flag.BoolVar(&fixSource, "fix", true, "cleans up common JSON syntax errors comming from MongoDB Compass; see README.md for details")
flag.BoolVar(&backup, "backup", false, "when used with -fix, writes a copy of the original file before attempting to fix and format")
flag.BoolVar(&structKeys, "keys", true, "generate output with keyed struct initialization; unkeyed syntax is legal but your linter may complain")
}
func main() {
flag.Parse()
if packageName == "" {
packageName = os.Getenv("GOPACKAGE")
}
if packageName == "" { // if packageName is still empty
packageName = "main"
}
processFileNames()
if verbose {
if len(inFilenames) == 1 {
if inFilenames[0] == "-" {
fmt.Fprint(os.Stderr, "Reading from stdin\n")
} else {
fmt.Fprintf(os.Stderr, "Reading from %s\n", inFilenames[0])
}
} else {
fmt.Fprintf(os.Stderr, "Reading from %d files\n", len(inFilenames))
}
}
commandLine := ""
for _, arg := range os.Args {
commandLine = commandLine + " " + arg
}
outString := fmt.Sprintf(fileTemplate, strings.TrimLeft(commandLine, " "), packageName)
for _, filename := range inFilenames {
outString += buildFunctionFromFile(filename)
// In the unusual case that we aren't building a mongo.Pipeline, remove the mongo import. mongo-driver/bson
// import will still be present.
if !strings.Contains(outString, "mongo.Pipeline") {
outString = strings.Replace(outString, `"go.mongodb.org/mongo-driver/mongo"`, ``, 1)
}
}
output, err := format.Source([]byte(outString))
if err != nil {
fmt.Fprintln(os.Stderr, "WARNING: Could not gofmt output: ", err.Error())
output = []byte(outString)
}
var outFile *os.File
if outFilename == "" {
outFilename = "<stdout>"
outFile = os.Stdout
} else {
var err error
outFile, err = os.OpenFile(outFilename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
defer outFile.Close()
if err != nil {
panic(err)
}
}
if verbose {
fmt.Fprintln(os.Stderr, "Writing to", outFilename)
}
_, err = outFile.Write(output)
if err != nil {
panic(err)
}
if outFilename != "<stdout>" {
outFile.Close()
// if flag "pls"...
cmd := exec.Command("goimports", "-w", outFilename)
cmd.Stderr = os.Stderr
goimpErr := cmd.Run()
if goimpErr != nil {
fmt.Fprintf(os.Stderr, "Failed to process imports for %s: %s\n", outFilename, goimpErr.Error())
}
}
}
func processFileNames() {
if len(flag.Args()) == 0 {
// if verbose {
// // fmt.Fprintln(os.Stderr, "No input files provided, reading from stdin")
// }
inFilenames = []string{"-"}
inFiles = []*os.File{os.Stdin}
return
} else {
for _, path := range flag.Args() {
fi, err := os.Stat(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
if fi.IsDir() {
dir, err := os.Open(fi.Name())
if err != nil {
fmt.Fprintf(os.Stderr, "Could not open directory %s: %s\n", path, err.Error())
os.Exit(1)
}
entries, err := dir.Readdir(0)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not read directory entries %s: %s\n", path, err.Error())
os.Exit(1)
}
for _, entry := range entries {
if strings.HasSuffix(entry.Name(), ".json") && !entry.IsDir() {
fullName := fmt.Sprint(path, string(os.PathSeparator), entry.Name())
inFilenames = append(inFilenames, fullName)
}
}
dir.Close()
} else {
inFilenames = append(inFilenames, path)
}
}
}
}