ソースを参照

restart the command when the file changes.

only works when the program has no errors, i think.
Lucas Stadler 11 年 前
コミット
a37990e2a4
共有1 個のファイルを変更した34 個の追加3 個の削除を含む
  1. 34 3
      go/qst.go

+ 34 - 3
go/qst.go

@ -7,6 +7,7 @@ import "os"
7 7
import "os/exec"
8 8
import "path"
9 9
import "strings"
10
import "sync"
10 11
import "time"
11 12
12 13
/*
@ -30,6 +31,8 @@ var mappings = map[string]func(string) string{
30 31
}
31 32
32 33
func main() {
34
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
35
33 36
	flag.Usage = func() {
34 37
		fmt.Fprintf(os.Stderr, "Usage: %s <file>\n", os.Args[0])
35 38
		flag.PrintDefaults()
@ -59,9 +62,12 @@ func main() {
59 62
	}
60 63
}
61 64
62
func runAndWatch(file string, cmd string) {
65
func runAndWatch(file string, cmdLine string) {
63 66
	// run command, if file changes (mtime) restart command
64
	lastMtime := time.Unix(0, 0)
67
	lastMtime := time.Now()
68
	cmd := ShellCmd(cmdLine)
69
	cmd.Start()
70
65 71
	for {
66 72
		info, err := os.Stat(file)
67 73
		if err != nil {
@ -71,7 +77,7 @@ func runAndWatch(file string, cmd string) {
71 77
		mtime := info.ModTime()
72 78
		if mtime.After(lastMtime) {
73 79
			log.Printf("%s changed, rerunning", file)
74
			runShellCmd(cmd)
80
			cmd.Restart()
75 81
		}
76 82
77 83
		lastMtime = mtime
@ -79,6 +85,31 @@ func runAndWatch(file string, cmd string) {
79 85
	}
80 86
}
81 87
88
type RestartableCommand struct {
89
	Cmd  *exec.Cmd
90
	Lock sync.Mutex
91
	Name string
92
	Args []string
93
}
94
95
func ShellCmd(cmd string) RestartableCommand {
96
	return RestartableCommand{nil, sync.Mutex{}, "sh", []string{"-c", cmd}}
97
}
98
99
func (c *RestartableCommand) Start() {
100
	c.Cmd = exec.Command(c.Name, c.Args...)
101
	c.Lock.Lock()
102
	go func() {
103
		c.Cmd.Run()
104
		c.Lock.Unlock()
105
	}()
106
}
107
108
func (c *RestartableCommand) Restart() {
109
	c.Cmd.Process.Kill()
110
	c.Start()
111
}
112
82 113
func runShellCmd(cmd string) {
83 114
	log.Printf("Running: `%s'", cmd)
84 115
	output, err := exec.Command("sh", "-c", cmd).CombinedOutput()