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-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-11-14 07:59:47 +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-11-01 09:56:12 +00:00
|
|
|
var build *exec.Cmd
|
2016-12-16 22:54:07 +00:00
|
|
|
var params []string
|
|
|
|
var path = ""
|
|
|
|
|
|
|
|
for _, param := range p.Params {
|
|
|
|
arr := strings.Fields(param)
|
|
|
|
params = append(params, arr...)
|
|
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(p.base, p.path)); err == nil {
|
|
|
|
path = filepath.Join(p.base, p.path)
|
|
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(p.base, p.path+".exe")); err == nil {
|
|
|
|
path = filepath.Join(p.base, p.path+".exe")
|
|
|
|
}
|
|
|
|
|
|
|
|
if path != "" {
|
|
|
|
build = exec.Command(path, params...)
|
2016-08-27 13:07:00 +00:00
|
|
|
} else {
|
2016-12-16 22:54:07 +00:00
|
|
|
if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))); err == nil {
|
|
|
|
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)), params...)
|
|
|
|
} else {
|
|
|
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Can't run a not compiled project"})
|
|
|
|
p.Fatal(err, "Can't run a not compiled project", ":")
|
|
|
|
}
|
2016-08-26 12:52:27 +00:00
|
|
|
}
|
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-10-14 08:47:43 +00:00
|
|
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Failed to stop: " + err.Error()})
|
2016-12-16 22:54:07 +00:00
|
|
|
p.Fatal(err, "Failed to stop", ":")
|
2016-08-16 16:36:54 +00:00
|
|
|
}
|
2016-10-14 08:47:43 +00:00
|
|
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Ended"})
|
2016-11-01 09:56:12 +00:00
|
|
|
log.Println(p.pname(p.Name, 2), ":", p.Red.Regular("Ended"))
|
2016-11-17 00:02:25 +00:00
|
|
|
p.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-11-01 09:56:12 +00:00
|
|
|
log.Println(p.Red.Bold(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-11-01 09:56:12 +00:00
|
|
|
log.Println(p.Red.Bold(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)
|
2016-09-17 14:46:26 +00:00
|
|
|
|
|
|
|
scanner := func(stop chan bool, output *bufio.Scanner, isError bool) {
|
|
|
|
for output.Scan() {
|
2016-08-17 14:56:06 +00:00
|
|
|
select {
|
|
|
|
default:
|
2016-09-17 14:46:26 +00:00
|
|
|
if isError {
|
2016-11-17 00:02:25 +00:00
|
|
|
p.Buffer.StdErr = append(p.Buffer.StdErr, BufferOut{Time: time.Now(), Text: output.Text(), Type: "Go Run"})
|
2016-09-17 14:46:26 +00:00
|
|
|
} else {
|
2016-10-14 08:47:43 +00:00
|
|
|
p.Buffer.StdOut = append(p.Buffer.StdOut, BufferOut{Time: time.Now(), Text: output.Text()})
|
2016-09-17 14:46:26 +00:00
|
|
|
}
|
2016-11-17 00:02:25 +00:00
|
|
|
p.sync()
|
2016-11-11 16:22:25 +00:00
|
|
|
if p.Cli.Streams {
|
2016-11-01 09:56:12 +00:00
|
|
|
log.Println(p.pname(p.Name, 3), ":", p.Blue.Regular(output.Text()))
|
2016-08-31 12:08:15 +00:00
|
|
|
}
|
2016-11-11 16:22:25 +00:00
|
|
|
if p.File.Streams {
|
2016-12-17 00:48:04 +00:00
|
|
|
f := p.Create(p.base, p.parent.Resources.Output)
|
2016-08-31 12:08:15 +00:00
|
|
|
t := time.Now()
|
2016-09-17 14:46:26 +00:00
|
|
|
if _, err := f.WriteString(t.Format("2006-01-02 15:04:05") + " : " + output.Text() + "\r\n"); err != nil {
|
2016-12-16 22:54:07 +00:00
|
|
|
p.Fatal(err, "")
|
2016-08-31 12:08:15 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-17 14:56:06 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-17 19:34:06 +00:00
|
|
|
close(stop)
|
2016-09-17 14:46:26 +00:00
|
|
|
}
|
2016-10-14 08:47:43 +00:00
|
|
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Started"})
|
2016-09-17 14:46:26 +00:00
|
|
|
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
|
2016-09-17 14:46:26 +00:00
|
|
|
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-11-14 07:59:47 +00:00
|
|
|
func (p *Project) goBuild() (string, error) {
|
2016-11-11 17:13:14 +00:00
|
|
|
defer func() {
|
2016-11-14 07:59:47 +00:00
|
|
|
p.sync()
|
2016-11-11 17:13:14 +00:00
|
|
|
}()
|
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-11-14 07:59:47 +00:00
|
|
|
func (p *Project) goInstall() (string, error) {
|
2016-11-11 17:13:14 +00:00
|
|
|
defer func() {
|
2016-11-14 07:59:47 +00:00
|
|
|
p.sync()
|
2016-11-11 17:13:14 +00:00
|
|
|
}()
|
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-11-11 16:22:25 +00:00
|
|
|
return "", err
|
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
|
2016-11-15 19:44:28 +00:00
|
|
|
func (p *Project) goFmt(path string) (string, error) {
|
|
|
|
var out, stderr bytes.Buffer
|
2016-08-23 14:10:17 +00:00
|
|
|
build := exec.Command("gofmt", "-s", "-w", "-e", path)
|
2016-08-21 15:12:11 +00:00
|
|
|
build.Dir = p.base
|
|
|
|
build.Stdout = &out
|
2016-11-15 19:44:28 +00:00
|
|
|
build.Stderr = &stderr
|
2016-08-21 15:12:11 +00:00
|
|
|
if err := build.Run(); err != nil {
|
2016-11-15 19:44:28 +00:00
|
|
|
return stderr.String(), err
|
2016-08-21 15:12:11 +00:00
|
|
|
}
|
2016-11-15 19:44:28 +00:00
|
|
|
return "", nil
|
2016-08-21 15:12:11 +00:00
|
|
|
}
|
2016-08-27 21:57:26 +00:00
|
|
|
|
|
|
|
// GoTest is an implementation of the go test
|
2016-11-15 19:44:28 +00:00
|
|
|
func (p *Project) goTest(path string) (string, error) {
|
|
|
|
var out, stderr bytes.Buffer
|
2016-08-27 21:57:26 +00:00
|
|
|
build := exec.Command("go", "test")
|
|
|
|
build.Dir = path
|
|
|
|
build.Stdout = &out
|
2016-11-15 19:44:28 +00:00
|
|
|
build.Stderr = &stderr
|
2016-08-27 21:57:26 +00:00
|
|
|
if err := build.Run(); err != nil {
|
2016-11-15 19:44:28 +00:00
|
|
|
return stderr.String(), err
|
2016-11-11 16:22:25 +00:00
|
|
|
}
|
2016-11-15 19:44:28 +00:00
|
|
|
return "", nil
|
2016-11-11 16:22:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GoGenerate is an implementation of the go test
|
2016-11-15 19:44:28 +00:00
|
|
|
func (p *Project) goGenerate(path string) (string, error) {
|
|
|
|
var out, stderr bytes.Buffer
|
2016-11-11 16:22:25 +00:00
|
|
|
build := exec.Command("go", "generate")
|
|
|
|
build.Dir = path
|
|
|
|
build.Stdout = &out
|
2016-11-15 19:44:28 +00:00
|
|
|
build.Stderr = &stderr
|
2016-11-11 16:22:25 +00:00
|
|
|
if err := build.Run(); err != nil {
|
2016-11-15 19:44:28 +00:00
|
|
|
return stderr.String(), err
|
2016-08-27 21:57:26 +00:00
|
|
|
}
|
2016-11-15 19:44:28 +00:00
|
|
|
return "", nil
|
2016-08-27 21:57:26 +00:00
|
|
|
}
|
2016-09-05 15:53:37 +00:00
|
|
|
|
2016-11-14 07:59:47 +00:00
|
|
|
// Cmds exec a list of defined commands
|
2016-11-17 00:02:25 +00:00
|
|
|
func (p *Project) cmds(cmds []string) (errors []string) {
|
|
|
|
defer func() {
|
|
|
|
p.sync()
|
|
|
|
}()
|
2016-09-05 15:53:37 +00:00
|
|
|
for _, cmd := range cmds {
|
2016-11-17 00:02:25 +00:00
|
|
|
var out bytes.Buffer
|
|
|
|
var stderr bytes.Buffer
|
2016-09-05 18:11:45 +00:00
|
|
|
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
|
2016-11-17 00:02:25 +00:00
|
|
|
build.Stdout = &out
|
|
|
|
build.Stderr = &stderr
|
2016-09-05 15:53:37 +00:00
|
|
|
if err := build.Run(); err != nil {
|
2016-11-17 00:02:25 +00:00
|
|
|
errors = append(errors, stderr.String())
|
2016-11-14 07:59:47 +00:00
|
|
|
return errors
|
2016-09-05 15:53:37 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-14 07:59:47 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sync datas with the web server
|
|
|
|
func (p *Project) sync() {
|
|
|
|
go func() {
|
|
|
|
p.parent.Sync <- "sync"
|
|
|
|
}()
|
2016-09-05 15:53:37 +00:00
|
|
|
}
|