func (handle *WatchHandle) handleFileEvent(projectName string) { lastEvent, timeSinceLastEvent := "", time.Now().AddDate(-1, 0, 0) watcher := handle.watcher ignorePaths := handle.ignorePaths errorChan := watcher.Errors for { select { case <-time.After(time.Second): continue case err := <-errorChan: if err != nil { gwl.LogError("Closing file watcher error routine %s", err.Error()) } case event, ok := <-watcher.Events: if !ok { gwl.LogDebug("closing file event channel") return } _, filename := filepath.Split(event.Name) // ignore any files that have the same name as the package if projectName == filename || event.Op&fsnotify.Chmod == fsnotify.Chmod { gwl.LogDebug("ignoring go build artifacts") continue } //ignores individual files that may match any ignore paths if shouldIgnore(event.Name, ignorePaths) { gwl.LogDebug("%s in ignore path ", event.Name) continue } // debounces file events if event.Name == lastEvent && timeSinceLastEvent.Add(time.Second).After(time.Now()) { gwl.LogDebug("ignoring extra file watch events") timeSinceLastEvent = time.Now() continue } lastEvent = event.Name timeSinceLastEvent = time.Now() if handle.halted { gwl.LogDebug("\tfilewatcher halteds") return } else if handle.fileUpdateCb != nil { gwl.LogDebug("\tinvoking file callback with %s", event.Name) handle.Lock() handle.fileUpdateCb(event.Name) handle.Unlock() gwl.LogDebug("\tfile callback complete") } } } }
func shouldIgnore(file string, ignorePaths []string) bool { for _, pattern := range ignorePaths { matched, err := filepath.Match(strings.Replace(pattern, "/", "", -1), strings.Replace(file, "/", "", -1)) if err != nil { gwl.LogError(err.Error()) } if matched && err == nil { gwl.LogDebug("\tIgnore %s -> %s\n", pattern, file) return true } } return false }
func handleWatch(projectPath string, ignorePaths []string) { watchHandle := watch.StartWatch(projectPath, ignorePaths) for { gwl.LogDebug("---Starting app monitor---") time.Sleep(*wait) execHandle := project.ExecuteBuildSteps(projectPath, *appArgs, *shouldTest, *shouldLint) gwl.LogDebug("---Setting up watch cb---") watchHandle.Subscribe(func(fileName string) { if !execHandle.Halted() { gwl.LogError("attempting to kill process") execHandle.Kill(nil) gwl.LogDebug("exiting file watch routine in main") } }) gwl.LogDebug("waiting on app to exit") err := execHandle.Error() gwl.LogDebug("---App exited---") watchHandle.Subscribe(nil) exitedSuccessfully := err == nil || err == project.ErrorAppKilled if exitedSuccessfully { color.Green("exited successfully\n") } else { color.Red("%s\n", err.Error()) } sync := make(chan bool) if (!exitedSuccessfully && !*restartOnError) || (!*restartOnExit && err != project.ErrorAppKilled) { watchHandle.Subscribe(func(fileName string) { close(sync) watchHandle.Subscribe(nil) }) gwl.LogDebug("waiting on file notification") <-sync } } }