From 65f18ff7b60dc6abec63d40ef420cc341f158b60 Mon Sep 17 00:00:00 2001 From: rokety <352577442@qq.com> Date: Fri, 28 Jul 2017 22:46:49 +0800 Subject: [PATCH 1/6] auto watch import pkg folders --- runner/start.go | 3 +- runner/watcher.go | 142 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/runner/start.go b/runner/start.go index e22923a..6d34955 100644 --- a/runner/start.go +++ b/runner/start.go @@ -73,6 +73,7 @@ func start() { } run() } + watch() started = true mainLog(strings.Repeat("-", 20)) @@ -113,8 +114,8 @@ func Start() { initSettings() initLogFuncs() initFolders() + initWatcher() setEnvVars() - watch() start() startChannel <- "/" diff --git a/runner/watcher.go b/runner/watcher.go index 1f3f1ac..d718fd7 100644 --- a/runner/watcher.go +++ b/runner/watcher.go @@ -2,18 +2,61 @@ package runner import ( "os" - "path/filepath" "strings" + "fmt" "github.com/howeyc/fsnotify" + "io" + "io/ioutil" + "os/exec" + "runtime" ) -func watchFolder(path string) { - watcher, err := fsnotify.NewWatcher() +var watchedFolders = map[string]struct{}{} +var pkgName = "" +var pkgPath = "" +var goPaths = []string{} +var watcher *fsnotify.Watcher + +func initWatcher() { + // parse running package name + separator := ":" + if runtime.GOOS == "windows" { + separator = ";" + } + goPaths = strings.Split(os.Getenv("GOPATH"), separator) + root := root() + dir, err := os.Getwd() + if err != nil { + fatal(err) + } + if root != "." { + pkgName = root + for _, gopath := range goPaths { + pkgPath = gopath + "/src/" + pkgName + e, err := exists(pkgPath) + if err != nil { + fatal(err) + } + if e { + break + } + } + } else { + for _, gopath := range goPaths { + if strings.HasPrefix(dir, gopath) && len(dir) > len(gopath)+5 { + pkgName = dir[len(gopath)+5:] + pkgPath = dir + break + } + } + } + + // init watcher + watcher, err = fsnotify.NewWatcher() if err != nil { fatal(err) } - go func() { for { select { @@ -27,31 +70,90 @@ func watchFolder(path string) { } } }() +} + +// exists returns whether the given file or directory exists or not +func exists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return true, err +} + +func getFolders() map[string]struct{} { + cmd := exec.Command("go", "list", "-f", `{{ join .Deps "\n" }}`, pkgName) + + stderr, err := cmd.StderrPipe() + if err != nil { + fatal(err) + } + + stdout, err := cmd.StdoutPipe() + if err != nil { + fatal(err) + } + + err = cmd.Start() + if err != nil { + fatal(err) + } - watcherLog("Watching %s", path) - err = watcher.Watch(path) + imps, _ := ioutil.ReadAll(stdout) + io.Copy(os.Stderr, stderr) + err = cmd.Wait() if err != nil { fatal(err) } + + _imps := strings.Split(strings.Trim(string(imps), "\n"), "\n") + _watchedFolders := map[string]struct{}{pkgPath: struct{}{}} + for _, imp := range _imps { + for _, gopath := range goPaths { + path := fmt.Sprintf("%s/src/%s", gopath, imp) + e, err := exists(path) + if err != nil { + fatal(err) + } + if e { + _watchedFolders[path] = struct{}{} + break + } + } + } + + return _watchedFolders } func watch() { - root := root() - filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - if info.IsDir() && !isTmpDir(path) { - if len(path) > 1 && strings.HasPrefix(filepath.Base(path), ".") { - return filepath.SkipDir + _watchedFolders := getFolders() + for folder, _ := range watchedFolders { + _, ok := _watchedFolders[folder] + if !ok { + watcherLog("remove watch %s", folder) + err := watcher.RemoveWatch(folder) + if err != nil { + fatal(err) } - - if isIgnoredFolder(path) { - watcherLog("Ignoring %s", path) - return filepath.SkipDir + } + } + for folder, _ := range _watchedFolders { + _, ok := watchedFolders[folder] + if !ok && !isTmpDir(folder) { + if isIgnoredFolder(folder) { + watcherLog("Ignoring %s", folder) + continue + } + watcherLog("add watch %s", folder) + err := watcher.Watch(folder) + if err != nil { + fatal(err) } - - watchFolder(path) } - - return err - }) + } + watchedFolders = _watchedFolders } From 75eeb8350486e3d238db3d9d5d6938930df20d07 Mon Sep 17 00:00:00 2001 From: rokety <352577442@qq.com> Date: Fri, 28 Jul 2017 22:58:14 +0800 Subject: [PATCH 2/6] space to tab --- runner/start.go | 4 ++-- runner/watcher.go | 59 +++++++++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/runner/start.go b/runner/start.go index 6d34955..a1d4ff1 100644 --- a/runner/start.go +++ b/runner/start.go @@ -73,7 +73,7 @@ func start() { } run() } - watch() + watch() started = true mainLog(strings.Repeat("-", 20)) @@ -114,7 +114,7 @@ func Start() { initSettings() initLogFuncs() initFolders() - initWatcher() + initWatcher() setEnvVars() start() startChannel <- "/" diff --git a/runner/watcher.go b/runner/watcher.go index d718fd7..96818ec 100644 --- a/runner/watcher.go +++ b/runner/watcher.go @@ -3,7 +3,6 @@ package runner import ( "os" "strings" - "fmt" "github.com/howeyc/fsnotify" "io" @@ -19,40 +18,40 @@ var goPaths = []string{} var watcher *fsnotify.Watcher func initWatcher() { - // parse running package name + // parse running package name separator := ":" if runtime.GOOS == "windows" { separator = ";" } goPaths = strings.Split(os.Getenv("GOPATH"), separator) root := root() - dir, err := os.Getwd() - if err != nil { - fatal(err) - } + dir, err := os.Getwd() + if err != nil { + fatal(err) + } if root != "." { - pkgName = root - for _, gopath := range goPaths { - pkgPath = gopath + "/src/" + pkgName - e, err := exists(pkgPath) - if err != nil { - fatal(err) - } - if e { - break - } - } + pkgName = root + for _, gopath := range goPaths { + pkgPath = gopath + "/src/" + pkgName + e, err := exists(pkgPath) + if err != nil { + fatal(err) + } + if e { + break + } + } } else { - for _, gopath := range goPaths { - if strings.HasPrefix(dir, gopath) && len(dir) > len(gopath)+5 { - pkgName = dir[len(gopath)+5:] - pkgPath = dir - break - } - } - } + for _, gopath := range goPaths { + if strings.HasPrefix(dir, gopath) && len(dir) > len(gopath)+5 { + pkgName = dir[len(gopath)+5:] + pkgPath = dir + break + } + } + } - // init watcher + // init watcher watcher, err = fsnotify.NewWatcher() if err != nil { fatal(err) @@ -144,10 +143,10 @@ func watch() { for folder, _ := range _watchedFolders { _, ok := watchedFolders[folder] if !ok && !isTmpDir(folder) { - if isIgnoredFolder(folder) { - watcherLog("Ignoring %s", folder) - continue - } + if isIgnoredFolder(folder) { + watcherLog("Ignoring %s", folder) + continue + } watcherLog("add watch %s", folder) err := watcher.Watch(folder) if err != nil { From 0b5cef689d2849530c547ff355bd3db828c47431 Mon Sep 17 00:00:00 2001 From: rokety <352577442@qq.com> Date: Sat, 29 Jul 2017 22:22:52 +0800 Subject: [PATCH 3/6] add godotenv support --- runner/settings.go | 5 +++++ runner/start.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/runner/settings.go b/runner/settings.go index 10117ec..3304e3f 100644 --- a/runner/settings.go +++ b/runner/settings.go @@ -20,6 +20,7 @@ const ( var settings = map[string]string{ "config_path": "./runner.conf", "root": ".", + "env": ".env", "tmp_path": "./tmp", "build_name": "runner-build", "build_log": "runner-build-errors.log", @@ -112,6 +113,10 @@ func root() string { return settings["root"] } +func envFile() string { + return settings["env"] +} + func tmpPath() string { return settings["tmp_path"] } diff --git a/runner/start.go b/runner/start.go index a1d4ff1..25f10cf 100644 --- a/runner/start.go +++ b/runner/start.go @@ -6,6 +6,7 @@ import ( "runtime" "strings" "time" + "github.com/joho/godotenv" ) var ( @@ -95,6 +96,10 @@ func initLogFuncs() { } func setEnvVars() { + err := godotenv.Load(envFile()) + if err != nil { + fatal(err) + } os.Setenv("DEV_RUNNER", "1") wd, err := os.Getwd() if err == nil { From 6d83ad2329bdb5713e7bda285e945b736245cc9f Mon Sep 17 00:00:00 2001 From: roketyyang Date: Tue, 29 Aug 2017 21:51:45 +0800 Subject: [PATCH 4/6] escape % in app log if app log output has '%', the console output will be something like: %!E(MISSING)4%!B(MISSING)8%!A(MISSING) --- runner/logger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/logger.go b/runner/logger.go index ae2f3b1..d7c26bb 100644 --- a/runner/logger.go +++ b/runner/logger.go @@ -35,7 +35,7 @@ func fatal(err error) { type appLogWriter struct{} func (a appLogWriter) Write(p []byte) (n int, err error) { - appLog(string(p)) + appLog(strings.Replace(string(p), "%", "%%", -1)) return len(p), nil } From 08e5c92aac34b7471958cbc80869baa43ea74ef6 Mon Sep 17 00:00:00 2001 From: roketyyang Date: Tue, 29 Aug 2017 21:55:03 +0800 Subject: [PATCH 5/6] escape % in app log --- runner/logger.go | 1 + 1 file changed, 1 insertion(+) diff --git a/runner/logger.go b/runner/logger.go index d7c26bb..da075f8 100644 --- a/runner/logger.go +++ b/runner/logger.go @@ -4,6 +4,7 @@ import ( "fmt" logPkg "log" "time" + "strings" "github.com/mattn/go-colorable" ) From 117fc3599dea4056187dcb604440facfbea8ab28 Mon Sep 17 00:00:00 2001 From: roketyyang Date: Fri, 1 Sep 2017 22:20:58 +0800 Subject: [PATCH 6/6] fix .env not exists --- runner/start.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/runner/start.go b/runner/start.go index 25f10cf..fab9fb4 100644 --- a/runner/start.go +++ b/runner/start.go @@ -96,10 +96,12 @@ func initLogFuncs() { } func setEnvVars() { - err := godotenv.Load(envFile()) - if err != nil { - fatal(err) - } + if _, err := os.Stat(envFile()); !os.IsNotExist(err) { + err := godotenv.Load(envFile()) + if err != nil { + fatal(err) + } + } os.Setenv("DEV_RUNNER", "1") wd, err := os.Getwd() if err == nil {