diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..418384a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bee +*.exe +*.exe~ diff --git a/run.go b/run.go index 503abf3..4fb3c97 100644 --- a/run.go +++ b/run.go @@ -68,7 +68,8 @@ var conf struct { func runApp(cmd *Command, args []string) { exit := make(chan bool) if len(args) != 1 { - colorLog("[ERRO] Argument [appname] is missing\n") + colorLog("[ERRO] Cannot start running[ %s ]\n", + "argument 'appname' is missing") os.Exit(2) } crupath, _ := os.Getwd() diff --git a/util.go b/util.go index 026d8ed..2846b97 100644 --- a/util.go +++ b/util.go @@ -62,12 +62,16 @@ func colorLog(format string, a ...interface{}) { log = log[i+1:] // Error. - log = strings.Replace(log, "[ ", fmt.Sprintf("[ \033[%dm", Red), -1) - log = strings.Replace(log, " ]", EndColor+" ]", -1) + log = strings.Replace(log, "[ ", fmt.Sprintf("[\033[%dm", Red), -1) + log = strings.Replace(log, " ]", EndColor+"]", -1) // Path. - log = strings.Replace(log, "(", fmt.Sprintf("(\033[%dm", Yellow), -1) - log = strings.Replace(log, ")", EndColor+")", -1) + log = strings.Replace(log, "( ", fmt.Sprintf("(\033[%dm", Yellow), -1) + log = strings.Replace(log, " )", EndColor+")", -1) + + // Highlights. + log = strings.Replace(log, "# ", fmt.Sprintf("\033[%dm", Gray), -1) + log = strings.Replace(log, " #", EndColor, -1) log = clog + log } @@ -79,6 +83,8 @@ func colorLog(format string, a ...interface{}) { func getColorLevel(level string) string { level = strings.ToUpper(level) switch level { + case "TRAC": + return fmt.Sprintf("\033[%dm%s\033[0m", Blue, level) case "ERRO": return fmt.Sprintf("\033[%dm%s\033[0m", Red, level) case "WARN": diff --git a/watch.go b/watch.go index 1ce8d64..9f05e53 100644 --- a/watch.go +++ b/watch.go @@ -14,13 +14,14 @@ import ( var ( cmd *exec.Cmd state sync.Mutex - eventTime = make(map[string]time.Time) + eventTime = make(map[string]int64) ) func NewWatcher(paths []string) { watcher, err := fsnotify.NewWatcher() if err != nil { - log.Fatal(err) + colorLog("[ERRO] Fail to create new Watcher[ %s ]\n", err) + os.Exit(2) } go func() { @@ -37,15 +38,13 @@ func NewWatcher(paths []string) { continue } - if t, ok := eventTime[e.Name]; ok { - // if 500ms change many times, then ignore it. - // for liteide often gofmt code after save. - if t.Add(time.Millisecond * 500).After(time.Now()) { - colorLog("[SKIP] %s\n", e.String()) - isbuild = false - } + mt := getFileModTime(e.Name) + if t := eventTime[e.Name]; mt == t { + colorLog("[SKIP] # %s #\n", e.String()) + isbuild = false } - eventTime[e.Name] = time.Now() + + eventTime[e.Name] = mt if isbuild { colorLog("[EVEN] %s\n", e) @@ -59,15 +58,34 @@ func NewWatcher(paths []string) { colorLog("[INFO] Initializing watcher...\n") for _, path := range paths { - fmt.Println(path) + colorLog("[TRAC] Directory( %s )\n", path) err = watcher.Watch(path) if err != nil { - log.Fatal(err) + colorLog("[ERRO] Fail to watch directory[ %s ]\n", err) + os.Exit(2) } } } +// getFileModTime retuens unix timestamp of `os.File.ModTime` by given path. +func getFileModTime(path string) int64 { + f, err := os.Open(path) + if err != nil { + colorLog("[ERRO] Fail to open file[ %s ]", err) + return time.Now().Unix() + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + colorLog("[ERRO] Fail to get file information[ %s ]", err) + return time.Now().Unix() + } + + return fi.ModTime().Unix() +} + func Autobuild() { state.Lock() defer state.Unlock()