|
|
@ -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()
|