func runClient(ctx *cli.Context) { if len(setting.Cfg.Sync.RemoteAddr) == 0 { log.Fatal("Remote address cannot be empty") } watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal("Fail to create new watcher: %v", err) } defer watcher.Close() go func() { for { select { case e := <-watcher.Events: if isTmpFile(e.Name) { continue } if e.Op&fsnotify.Create == fsnotify.Create || e.Op&fsnotify.Write == fsnotify.Write { if com.IsDir(e.Name) { log.Warn("Hasn't support directory yet") continue } sendFile(strings.TrimPrefix(e.Name, setting.WorkDir+"/")) } } } }() if err = watcher.Add(setting.WorkDir); err != nil { log.Fatal("Fail to watch directory(%s): %v", setting.WorkDir, err) } dirs, err := com.GetAllSubDirs(setting.WorkDir) if err != nil { log.Fatal("Fail to get subdirectories(%s): %v", setting.WorkDir, err) } for _, dir := range dirs { if err = watcher.Add(path.Join(setting.WorkDir, dir)); err != nil { log.Fatal("Fail to watch directory(%s): %v", path.Join(setting.WorkDir, dir), err) } } log.Info("Start watching...") select {} }
func runRun(ctx *cli.Context) { setup(ctx) go catchSignals() go notify(setting.Cfg.Run.InitCmds) watchPathes := append([]string{setting.WorkDir}, setting.Cfg.Run.WatchDirs...) if setting.Cfg.Run.WatchAll { subdirs := make([]string, 0, 10) for _, dir := range watchPathes[1:] { dirs, err := com.GetAllSubDirs(setting.UnpackPath(dir)) if err != nil { log.Fatal("Fail to get sub-directories: %v", err) } for i := range dirs { if !setting.IgnoreDir(dirs[i]) { subdirs = append(subdirs, path.Join(dir, dirs[i])) } } } watchPathes = append(watchPathes, subdirs...) } watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal("Fail to create new watcher: %v", err) } defer watcher.Close() go func() { for { select { case e := <-watcher.Events: needsNotify := true if isTmpFile(e.Name) || !hasWatchExt(e.Name) || setting.IgnoreFile(e.Name) { continue } // Prevent duplicated builds. if lastBuild.Add(time.Duration(setting.Cfg.Run.BuildDelay) * time.Millisecond). After(time.Now()) { continue } lastBuild = time.Now() showName := e.String() if !log.NonColor { showName = strings.Replace(showName, setting.WorkDir, "\033[47;30m$WORKDIR\033[0m", 1) } if e.Op&fsnotify.Remove != fsnotify.Remove { mt, err := com.FileMTime(e.Name) if err != nil { log.Error("Fail to get file modify time: %v", err) continue } if eventTime[e.Name] == mt { log.Debug("Skipped %s", showName) needsNotify = false } eventTime[e.Name] = mt } if needsNotify { log.Info(showName) if runningCmd != nil && runningCmd.Process != nil { if runningCmd.Args[0] == "sudo" && runtime.GOOS == "linux" { // 给父进程发送一个TERM信号,试图杀死它和它的子进程 rootCmd := exec.Command("sudo", "kill", "-TERM", com.ToStr(runningCmd.Process.Pid)) rootCmd.Stdout = os.Stdout rootCmd.Stderr = os.Stderr if err := rootCmd.Run(); err != nil { log.Error("Fail to start rootCmd %s", err.Error()) fmt.Print("\x07") } } else { shutdown <- true } } go notify(setting.Cfg.Run.Cmds) } } } }() log.Info("Following directories are monitored:") for i, p := range watchPathes { if err = watcher.Add(setting.UnpackPath(p)); err != nil { log.Fatal("Fail to watch diretory(%s): %v", p, err) } if i > 0 && !log.NonColor { p = strings.Replace(p, setting.WorkDir, "\033[47;30m$WORKDIR\033[0m", 1) p = strings.Replace(p, "$WORKDIR", "\033[47;30m$WORKDIR\033[0m", 1) } fmt.Printf("-> %s\n", p) } select {} }