-
Notifications
You must be signed in to change notification settings - Fork 31
/
cmd.go
123 lines (105 loc) · 2.18 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package godo
import (
"bytes"
"fmt"
"os"
"os/exec"
"github.com/mgutz/ansi"
"gopkg.in/godo.v1/util"
)
// Proccesses are the processes spawned by Start()
var Processes = make(map[string]*os.Process)
type command struct {
// original command string
commandstr string
// parsed executable
executable string
// parsed argv
argv []string
// parsed env
env []string
// working directory
wd string
// whether to capture output
captureOutput bool
// the output recorder
recorder bytes.Buffer
}
func (gcmd *command) toExecCmd() (cmd *exec.Cmd, err error) {
cmd = exec.Command(gcmd.executable, gcmd.argv...)
if gcmd.wd != "" {
cmd.Dir = gcmd.wd
}
cmd.Env = effectiveEnv(gcmd.env)
cmd.Stdin = os.Stdin
if gcmd.captureOutput {
outWrapper := newFileWrapper(os.Stdout, &gcmd.recorder, "")
errWrapper := newFileWrapper(os.Stderr, &gcmd.recorder, ansi.ColorCode("red+b"))
cmd.Stdout = outWrapper
cmd.Stderr = errWrapper
} else {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
}
if verbose {
if Env != "" {
util.Debug("#", "Env: %s\n", Env)
}
util.Debug("#", "%s\n", gcmd.commandstr)
}
return cmd, nil
}
func (gcmd *command) run() (string, error) {
var err error
cmd, err := gcmd.toExecCmd()
if err != nil {
return "", err
}
err = cmd.Run()
if gcmd.captureOutput {
return gcmd.recorder.String(), err
}
return "", err
}
func (gcmd *command) runAsync() (err error) {
cmd, err := gcmd.toExecCmd()
if err != nil {
return
}
id := gcmd.commandstr
// kills previously spawned process (if exists)
killSpawned(id)
waitgroup.Add(1)
waitExit = true
go func() {
err = cmd.Start()
if err != nil {
fmt.Println(err.Error())
return
}
Processes[id] = cmd.Process
if verbose {
util.Debug("#", "Processes[%q] added\n", id)
}
c := make(chan error, 1)
c <- cmd.Wait()
_ = <-c
waitgroup.Done()
}()
return nil
}
func killSpawned(command string) {
process := Processes[command]
if process == nil {
return
}
err := process.Kill()
delete(Processes, command)
if err != nil {
util.Error("Start", "Could not kill existing process %+v\n%s\n", process, err.Error())
return
}
if verbose {
util.Debug("#", "Processes[%q] killed\n", command)
}
}