func (this *gowatch) drainExec() { log.Println("command:", this.cmd) var msg string for { startTime := time.Now() cmd := this.cmd if len(cmd) == 0 { cmd = []string{"echo", "no command specified"} } cprintf(CGREEN, "exec start") c := StartCmd(cmd[0], cmd[1:]...) // Start to run command err := c.Start() if err != nil { cprintf("35", err.Error()) } // Wait until killed or finished select { case msg = <-this.sig: cprintf(CYELLOW, "program terminated, signal(%s)", this.KillSignal) if err := KillCmd(c, this.KillSignal); err != nil { log.Errorf("group kill: %v", err) } if msg == "EXIT" { os.Exit(1) } goto SKIP_WAITING case err = <-Go(c.Wait): if err != nil { cprintf(CPURPLE, "program exited: %v", err) } } log.Infof("finish in %s", time.Since(startTime)) // Whether to restart right now if this.AutoRestart { goto SKIP_WAITING } cprintf("33", "-- wait signal --") if msg = <-this.sig; msg == "EXIT" { os.Exit(1) } SKIP_WAITING: if this.RestartInterval > 0 { log.Infof("restart after %s", this.RestartInterval) } time.Sleep(this.RestartInterval) } }
func groupKill(cmd *exec.Cmd, signal string) (err error) { log.Println("\033[33mprogram terminated\033[0m") var pid, pgid int if cmd.Process != nil { pid = cmd.Process.Pid sess := sh.NewSession() if *verbose { sess.ShowCMD = true } c := sess.Command("/bin/ps", "-o", "pgid", "-p", strconv.Itoa(pid)).Command("sed", "-n", "2,$p") var out []byte out, err = c.Output() if err != nil { return } _, err = fmt.Sscanf(string(out), "%d", &pgid) if err != nil { return } err = sess.Command("pkill", "-"+signal, "--pgroup", strconv.Itoa(pgid)).Run() } return }
func actionPack(c *cli.Context) { var goos, goarch = c.String("os"), c.String("arch") //var depth = c.Int("depth") var output = c.String("output") var gom = c.String("gom") var nobuild = c.Bool("nobuild") var adds = c.StringSlice("add") var rmflag = c.Bool("rm") if c.GlobalBool("debug") { log.SetOutputLevel(log.Ldebug) } if c.Bool("quiet") { log.SetOutputLevel(log.Lwarn) } log.Debugf("os: %s, arch: %s", goos, goarch) var err error defer func() { if err != nil { log.Fatal(err) } }() sess := sh.NewSession() sess.SetEnv("GOOS", goos) sess.SetEnv("GOARCH", goarch) sess.ShowCMD = !c.Bool("quiet") gomarr := strings.Fields(gom) if len(gomarr) >= 1 { sess.Alias("go", gomarr[0], gomarr[1:]...) } // parse yaml pcfg := DefaultPcfg log.Debug("config:", pcfg) var skips []*regexp.Regexp for _, str := range pcfg.Excludes { skips = append(skips, regexp.MustCompile("^"+str+"$")) } var needs []*regexp.Regexp for _, str := range pcfg.Includes { needs = append(needs, regexp.MustCompile("^"+str+"$")) } os.MkdirAll(filepath.Dir(output), 0755) var z Archiver hasExt := func(ext string) bool { return strings.HasSuffix(output, ext) } switch { case hasExt(".zip"): log.Println("zip format") z, err = CreateZip(output) case hasExt(".tar"): log.Println("tar format") z, err = CreateTar(output) case hasExt(".tgz"): fallthrough case hasExt(".tar.gz"): log.Println("tar.gz format") z, err = CreateTgz(output) default: log.Println("unsupport file archive format") os.Exit(1) } if err != nil { return } var files = []string{} var buildFiles = pcfg.Settings.Outfiles // build source if !nobuild { targetDir := sanitizedName(pcfg.Settings.TargetDir) if !sh.Test("dir", targetDir) { os.MkdirAll(targetDir, 0755) } //gobin := filepath.Join(pwd, sanitizedName(pcfg.Settings.TargetDir)) //sess.SetEnv("GOBIN", gobin) //log.Debugf("set env GOBIN=%s", gobin) /* symdir := filepath.Join(targetDir, goos+"_"+goarch) if err = os.Symlink(gobin, symdir); err != nil { log.Fatalf("os symlink error: %s", err) } */ //defer os.Remove(symdir) // opts := []string{"install", "-v"} // opts = append(opts, strings.Fields(pcfg.Settings.Addopts)...) // TODO: here need to use shell args parse lib //if pcfg.Settings.Build == "" { //pcfg.Settings.Build = DEFAULT_BUILD //} for _, command := range pcfg.Script { if err = shExecString(sess, command); err != nil { return } } //os.Remove(symdir) // I have to do it twice if len(buildFiles) == 0 { cwd, _ := os.Getwd() program := filepath.Base(cwd) buildFiles = append(buildFiles, program) } for _, filename := range buildFiles { if goos == "windows" { filename += ".exe" } files = append(files, filename) } } log.Debug("archive files") depth := pcfg.Depth for _, filename := range pcfg.Includes { fs, err := findFiles(filename, depth, skips) if err != nil { return } files = append(files, fs...) } // adds - parse by cli files = append(files, adds...) uniqset := make(map[string]bool, len(files)) for _, file := range files { file = sanitizedName(file) if uniqset[file] { continue } uniqset[file] = true log.Infof("zip add file: %v", file) if err = z.Add(file); err != nil { return } } log.Info("finish archive file") err = z.Close() if rmflag { for _, filename := range buildFiles { if goos == "windows" { filename += ".exe" } os.Remove(filename) } } }