-
-
Notifications
You must be signed in to change notification settings - Fork 99
/
main.go
207 lines (171 loc) · 4.54 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package main
import (
"errors"
"flag"
"fmt"
"io/fs"
"io/ioutil"
"os"
path "path/filepath"
"runtime"
"strings"
"github.com/silenceper/log"
)
var (
cfg *config
currpath string
exit chan bool
output string
buildPkg string
cmdArgs string
showVersion bool
showHelp bool
logLevel string
started chan bool
)
func init() {
flag.StringVar(&output, "o", "", "go build output")
flag.StringVar(&buildPkg, "p", "", "go build packages")
flag.StringVar(&cmdArgs, "args", "", "app run args,separated by commas. like: -args='-host=:8080,-name=demo'")
flag.BoolVar(&showVersion, "v", false, "show version")
flag.StringVar(&logLevel, "l", "", "log level: debug, info, warn, error, fatal")
flag.BoolVar(&showHelp, "h", false, "help")
}
var ignoredFilesRegExps = []string{
`.#(\w+).go$`,
`.(\w+).go.swp$`,
`(\w+).go~$`,
`(\w+).tmp$`,
}
var defaultYml = `
# gowatch.yml configuration example
# The name of the executable file generated under the current directory execution. The default is the current directory name.
# appname: "app"
# Specify the command to run after builds done
# run_cmd: "./run.sh"
# Specify the directory where the compiled object files are stored
# output: /bin/app
# The file name suffix that needs to be monitored. By default, there is only a '.go' file.
# watch_exts:
# - .yml
# The directory that needs to listen for file changes. By default, only the current directory.
# watch_paths:
# - ../pk
# Additional parameters that need to be added when running the application
# cmd_args:
# - arg1=val1
# Additional parameters that need to be added when building the application
# build_args:
# - -race
# Need to increase environment variables, the current environment variables are loaded by default
# envs:
# - env1=val1
# Whether to listen to file changes in the 'vendor' folder
vendor_watch: false
# Directory that do not need to listen for file changes
# excluded_paths:
# - path
# main package path, can also be a single file, multiple files separated by commas
build_pkg: ""
# build tags
build_tags: ""
# Commands that can be executed before build the app
# prev_build_cmds:
# - swag init
# Whether to prohibit automatic operation
disable_run: false
# log level, support debug, info, warn, error, fatal
log_level: "debug"
`
func main() {
flag.Parse()
// init gowatch.yml
if len(os.Args) > 1 && os.Args[1] == "init" {
if _, err := os.Stat("gowatch.yml"); errors.Is(err, fs.ErrNotExist) {
_ = ioutil.WriteFile("gowatch.yml", []byte(defaultYml), 0755)
fmt.Println("gowatch.yml file created to the current directory with the default settings")
} else {
fmt.Println("gowatch.yml has been exists")
}
os.Exit(0)
}
if showHelp {
fmt.Println("Usage of gowatch:\n\nIf no command is provided gowatch will start the runner with the provided flags\n\nCommands:\n init creates a gowatch.yml file with default settings to the current directory\n\nFlags:")
flag.PrintDefaults()
os.Exit(0)
}
if showVersion {
printVersion()
os.Exit(0)
}
cfg = parseConfig()
currpath, _ = os.Getwd()
if cfg.AppName == "" {
// The app name defaults to the directory name
if output == "" {
cfg.AppName = path.Base(currpath)
} else {
cfg.AppName = path.Base(output)
}
}
if output != "" {
cfg.Output = output
}
// If output is not specified, it is "./appname"
if cfg.Output == "" {
outputExt := ""
if runtime.GOOS == "windows" {
outputExt = ".exe"
}
cfg.Output = "./" + cfg.AppName + outputExt
}
if cmdArgs != "" {
cfg.CmdArgs = strings.Split(cmdArgs, ",")
}
// File suffix to be watched
cfg.WatchExts = append(cfg.WatchExts, ".go")
// set log level, default is debug
if cfg.LogLevel != "" {
setLogLevel(cfg.LogLevel)
}
// flags override config
if logLevel != "" {
setLogLevel(logLevel)
}
runApp()
}
func runApp() {
var paths []string
readAppDirectories(currpath, &paths)
// In addition to the current directory, add additional watch directories
for _, path := range cfg.WatchPaths {
readAppDirectories(path, &paths)
}
files := []string{}
if buildPkg == "" {
buildPkg = cfg.BuildPkg
}
if buildPkg != "" {
files = strings.Split(buildPkg, ",")
}
NewWatcher(paths, files)
Autobuild(files)
<-exit
runtime.Goexit()
}
func setLogLevel(level string) {
switch level {
case "debug":
log.SetLogLevel(log.LevelDebug)
case "info":
log.SetLogLevel(log.LevelInfo)
case "warn":
log.SetLogLevel(log.LevelWarning)
case "error":
log.SetLogLevel(log.LevelError)
case "fatal":
log.SetLogLevel(log.LevelFatal)
default:
log.SetLogLevel(log.LevelDebug)
}
}