|
|
@ -4,7 +4,8 @@ import ( |
|
|
|
"fmt" |
|
|
|
"os" |
|
|
|
"os/exec" |
|
|
|
"strings" |
|
|
|
"path/filepath" |
|
|
|
"runtime" |
|
|
|
"sync" |
|
|
|
) |
|
|
|
|
|
|
@ -17,46 +18,31 @@ type RunTask interface { |
|
|
|
type T struct { |
|
|
|
sync.Mutex |
|
|
|
|
|
|
|
// ch: 获取时间channel
|
|
|
|
// ch: 获取事件channel
|
|
|
|
ch chan struct{} |
|
|
|
|
|
|
|
// 记录pid 用于kill
|
|
|
|
pid int |
|
|
|
closeChan chan struct{} |
|
|
|
|
|
|
|
// 执行shell命令
|
|
|
|
exec.Cmd |
|
|
|
// 记录process对象
|
|
|
|
p *os.Process |
|
|
|
|
|
|
|
// f: 执行任务
|
|
|
|
f func(chan struct{}) error |
|
|
|
} |
|
|
|
|
|
|
|
// NewT: 实例化方法
|
|
|
|
func NewT(path string, args []string, environment ...[]string) *T { |
|
|
|
env := os.Environ() |
|
|
|
if len(environment) > 0 { |
|
|
|
for k, v := range environment[0] { |
|
|
|
env[k] = v |
|
|
|
} |
|
|
|
} |
|
|
|
func NewT() *T { |
|
|
|
return newT(nil) |
|
|
|
} |
|
|
|
func newT(f func(chan struct{}) error) *T { |
|
|
|
t := &T{ |
|
|
|
Mutex: sync.Mutex{}, |
|
|
|
ch: make(chan struct{}), |
|
|
|
Cmd: exec.Cmd{ |
|
|
|
Path: path, |
|
|
|
Args: []string{path}, |
|
|
|
Env: env, |
|
|
|
Stdin: os.Stdin, |
|
|
|
Stdout: os.Stdout, |
|
|
|
Stderr: os.Stderr, |
|
|
|
ExtraFiles: make([]*os.File, 0), |
|
|
|
}, |
|
|
|
pid: os.Getpid(), |
|
|
|
Mutex: sync.Mutex{}, |
|
|
|
ch: make(chan struct{}, 1), |
|
|
|
closeChan: make(chan struct{}), |
|
|
|
f: f, |
|
|
|
} |
|
|
|
t.Dir, _ = os.Getwd() |
|
|
|
if len(args) > 0 { |
|
|
|
// Exclude of current binary path.
|
|
|
|
start := 0 |
|
|
|
if strings.EqualFold(path, args[0]) { |
|
|
|
start = 1 |
|
|
|
} |
|
|
|
t.Args = append(t.Args, args[start:]...) |
|
|
|
if f == nil { |
|
|
|
t.f = t.DefaultF |
|
|
|
} |
|
|
|
return t |
|
|
|
} |
|
|
@ -73,33 +59,82 @@ func (t *T) AddTask() { |
|
|
|
} |
|
|
|
|
|
|
|
func (t *T) RunTask() { |
|
|
|
fmt.Println("进入") |
|
|
|
// 这里做的make 是用于关闭上一个执行的任务
|
|
|
|
ch := make(chan struct{}) |
|
|
|
// 先run服务
|
|
|
|
err := t.Run() |
|
|
|
if err != nil { |
|
|
|
return |
|
|
|
} |
|
|
|
go t.f(ch) |
|
|
|
for { |
|
|
|
_, ok := <-t.ch |
|
|
|
ch <- struct{}{} |
|
|
|
if !ok { |
|
|
|
return |
|
|
|
} |
|
|
|
// todo 执行任务
|
|
|
|
// 先编译新的文件 然后 kill 然后执行
|
|
|
|
fmt.Println(kill(t.Cmd.Process.Pid)) |
|
|
|
err = t.Run() |
|
|
|
if err != nil { |
|
|
|
fmt.Println(err) |
|
|
|
return |
|
|
|
// 等待上一个关闭
|
|
|
|
<-t.closeChan |
|
|
|
go t.f(ch) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// DefaultF: 默认的StartFunction
|
|
|
|
func (t *T) DefaultF(ch chan struct{}) error { |
|
|
|
|
|
|
|
var buildCmd *exec.Cmd |
|
|
|
var cmd *exec.Cmd |
|
|
|
|
|
|
|
// 判断是否有makefile
|
|
|
|
_, err := os.Stat(filepath.Join("Makefile")) |
|
|
|
if runtime.GOOS != "windows" && err != nil { |
|
|
|
_, err := exec.LookPath("make") |
|
|
|
if err == nil { |
|
|
|
cmd = exec.Command("makefile") |
|
|
|
goto makefile |
|
|
|
} |
|
|
|
} |
|
|
|
// 检测系统是否有编译环境
|
|
|
|
_, err = exec.LookPath("go") |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
// build
|
|
|
|
|
|
|
|
switch runtime.GOOS { |
|
|
|
case "windows": |
|
|
|
buildCmd = exec.Command("go", "build", "-o", "gva.exe", "main.go") |
|
|
|
default: |
|
|
|
buildCmd = exec.Command("go", "build", "-o", "gva", "main.go") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// kill:
|
|
|
|
func kill(pid int) error { |
|
|
|
p, err := os.FindProcess(pid) |
|
|
|
err = buildCmd.Run() |
|
|
|
fmt.Println("build 执行完成") |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
// 执行
|
|
|
|
|
|
|
|
switch runtime.GOOS { |
|
|
|
case "windows": |
|
|
|
cmd = exec.Command("gva.exe") |
|
|
|
default: |
|
|
|
cmd = exec.Command("./gva") |
|
|
|
} |
|
|
|
makefile: |
|
|
|
// 开始执行任务
|
|
|
|
err = cmd.Start() |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
return p.Kill() |
|
|
|
t.p = cmd.Process |
|
|
|
fmt.Println("pid", t.p.Pid) |
|
|
|
go func() { |
|
|
|
err = cmd.Wait() |
|
|
|
}() |
|
|
|
<-ch |
|
|
|
// 回收资源
|
|
|
|
err = cmd.Process.Kill() |
|
|
|
fmt.Println("kill err", err) |
|
|
|
// 发送关闭完成信号
|
|
|
|
t.closeChan <- struct{}{} |
|
|
|
return err |
|
|
|
} |