realize/cli/exec.go

169 lines
3.9 KiB
Go
Raw Normal View History

2016-09-01 22:17:19 +00:00
package cli
2016-08-03 08:28:58 +00:00
import (
2016-08-04 19:57:19 +00:00
"bufio"
2016-08-17 23:35:37 +00:00
"bytes"
2016-08-21 15:12:11 +00:00
"io"
2016-08-04 19:57:19 +00:00
"log"
2016-08-17 23:35:37 +00:00
"os"
"os/exec"
2016-08-23 00:07:07 +00:00
"path/filepath"
2016-09-05 15:53:37 +00:00
"strings"
2016-08-17 23:35:37 +00:00
"sync"
"time"
2016-08-03 08:28:58 +00:00
)
2016-08-18 07:29:36 +00:00
// GoRun is an implementation of the bin execution
2016-08-17 22:24:06 +00:00
func (p *Project) GoRun(channel chan bool, runner chan bool, wr *sync.WaitGroup) error {
2016-08-22 11:29:21 +00:00
2016-09-22 22:41:42 +00:00
sync := func() {
p.parent.Sync <- "sync"
}
2016-08-26 12:52:27 +00:00
var build *exec.Cmd
if len(p.Params) != 0 {
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.Path)), p.Params...)
2016-08-27 13:07:00 +00:00
} else {
2016-08-26 12:52:27 +00:00
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.Path)))
}
2016-08-17 19:34:06 +00:00
build.Dir = p.base
2016-08-16 10:20:55 +00:00
defer func() {
2016-08-16 16:36:54 +00:00
if err := build.Process.Kill(); err != nil {
2016-09-22 22:41:42 +00:00
p.Buffer.StdLog = append(p.Buffer.StdLog, "Failed to stop: "+err.Error())
2016-08-24 15:28:31 +00:00
log.Fatal(Red("Failed to stop: "), Red(err))
2016-08-16 16:36:54 +00:00
}
2016-09-22 22:41:42 +00:00
p.Buffer.StdLog = append(p.Buffer.StdLog, "Ended")
2016-09-05 15:53:37 +00:00
log.Println(pname(p.Name, 2), ":", RedS("Ended"))
2016-09-22 22:41:42 +00:00
go sync()
2016-08-16 10:20:55 +00:00
wr.Done()
}()
2016-08-04 19:57:19 +00:00
stdout, err := build.StdoutPipe()
2016-08-23 12:42:01 +00:00
stderr, err := build.StderrPipe()
2016-08-04 19:57:19 +00:00
if err != nil {
2016-08-20 22:29:32 +00:00
log.Println(Red(err.Error()))
2016-08-20 10:47:32 +00:00
return err
2016-08-04 19:57:19 +00:00
}
if err := build.Start(); err != nil {
2016-08-20 22:29:32 +00:00
log.Println(Red(err.Error()))
2016-08-20 10:47:32 +00:00
return err
2016-08-04 19:57:19 +00:00
}
2016-08-17 22:24:06 +00:00
close(runner)
2016-08-04 19:57:19 +00:00
2016-09-17 19:07:22 +00:00
execOutput, execError := bufio.NewScanner(stdout), bufio.NewScanner(stderr)
stopOutput, stopError := make(chan bool, 1), make(chan bool, 1)
scanner := func(stop chan bool, output *bufio.Scanner, isError bool) {
for output.Scan() {
2016-08-17 14:56:06 +00:00
select {
default:
if isError {
p.Buffer.StdErr = append(p.Buffer.StdErr, output.Text())
} else {
p.Buffer.StdOut = append(p.Buffer.StdOut, output.Text())
}
2016-09-22 22:41:42 +00:00
go sync()
2016-08-31 12:08:15 +00:00
if p.Watcher.Output["cli"] {
log.Println(pname(p.Name, 3), ":", BlueS(output.Text()))
2016-08-31 12:08:15 +00:00
}
if p.Watcher.Output["file"] {
2016-09-18 11:50:15 +00:00
path := filepath.Join(p.base, p.parent.Files["output"])
2016-08-31 12:08:15 +00:00
f := create(path)
t := time.Now()
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + output.Text() + "\r\n"); err != nil {
2016-08-31 12:08:15 +00:00
log.Fatal(err)
}
}
2016-08-17 14:56:06 +00:00
}
}
2016-08-17 19:34:06 +00:00
close(stop)
}
go scanner(stopOutput, execOutput, false)
go scanner(stopError, execError, true)
2016-08-17 14:56:06 +00:00
2016-08-17 23:35:37 +00:00
for {
2016-08-04 19:57:19 +00:00
select {
2016-08-17 23:35:37 +00:00
case <-channel:
2016-08-17 19:34:06 +00:00
return nil
case <-stopOutput:
return nil
case <-stopError:
2016-08-04 22:59:41 +00:00
return nil
2016-08-04 19:57:19 +00:00
}
}
2016-08-03 08:28:58 +00:00
}
2016-08-21 15:12:11 +00:00
// GoBuild is an implementation of the "go build"
2016-08-27 21:57:26 +00:00
func (p *Project) GoBuild() (string, error) {
2016-08-03 08:28:58 +00:00
var out bytes.Buffer
2016-08-24 14:13:14 +00:00
var stderr bytes.Buffer
2016-08-20 10:47:32 +00:00
build := exec.Command("go", "build")
build.Dir = p.base
2016-08-03 08:28:58 +00:00
build.Stdout = &out
2016-08-24 14:13:14 +00:00
build.Stderr = &stderr
2016-08-03 08:28:58 +00:00
if err := build.Run(); err != nil {
2016-08-27 21:57:26 +00:00
return stderr.String(), err
2016-08-03 08:28:58 +00:00
}
2016-08-27 21:57:26 +00:00
return "", nil
2016-08-03 08:28:58 +00:00
}
2016-08-21 15:12:11 +00:00
// GoInstall is an implementation of the "go install"
2016-08-27 21:57:26 +00:00
func (p *Project) GoInstall() (string, error) {
2016-08-03 16:49:17 +00:00
var out bytes.Buffer
2016-08-24 14:11:13 +00:00
var stderr bytes.Buffer
2016-08-23 00:07:07 +00:00
err := os.Setenv("GOBIN", filepath.Join(os.Getenv("GOPATH"), "bin"))
2016-08-20 10:47:32 +00:00
if err != nil {
2016-08-27 21:57:26 +00:00
return "", nil
2016-08-20 10:47:32 +00:00
}
2016-08-03 16:49:17 +00:00
build := exec.Command("go", "install")
2016-08-23 00:07:07 +00:00
build.Dir = p.base
2016-08-03 16:49:17 +00:00
build.Stdout = &out
2016-08-24 14:11:13 +00:00
build.Stderr = &stderr
2016-08-03 16:49:17 +00:00
if err := build.Run(); err != nil {
2016-08-27 21:57:26 +00:00
return stderr.String(), err
2016-08-03 16:49:17 +00:00
}
2016-08-27 21:57:26 +00:00
return "", nil
2016-08-21 13:38:00 +00:00
}
2016-08-21 15:12:11 +00:00
2016-08-21 18:30:11 +00:00
// GoFmt is an implementation of the gofmt
func (p *Project) GoFmt(path string) (io.Writer, error) {
2016-08-21 15:12:11 +00:00
var out bytes.Buffer
build := exec.Command("gofmt", "-s", "-w", "-e", path)
2016-08-21 15:12:11 +00:00
build.Dir = p.base
build.Stdout = &out
build.Stderr = &out
if err := build.Run(); err != nil {
2016-08-21 18:29:19 +00:00
return build.Stderr, err
2016-08-21 15:12:11 +00:00
}
return nil, nil
}
2016-08-27 21:57:26 +00:00
// GoTest is an implementation of the go test
func (p *Project) GoTest(path string) (io.Writer, error) {
var out bytes.Buffer
build := exec.Command("go", "test")
build.Dir = path
build.Stdout = &out
build.Stderr = &out
if err := build.Run(); err != nil {
return build.Stdout, err
}
return nil, nil
}
2016-09-05 15:53:37 +00:00
// Cmd exec a list of defined commands
func (p *Project) Cmd(cmds []string) (errors []error) {
for _, cmd := range cmds {
cmd := strings.Replace(strings.Replace(cmd, "'", "", -1), "\"", "", -1)
2016-09-05 15:53:37 +00:00
c := strings.Split(cmd, " ")
build := exec.Command(c[0], c[1:]...)
build.Dir = p.base
if err := build.Run(); err != nil {
errors = append(errors, err)
}
}
return errors
}