func gatherCmdOutput(taskName string, cmd *exec.Cmd, eventsChan chan *types.Event) error { stdoutReader, err := cmd.StdoutPipe() if err != nil { return err } stderrReader, err := cmd.StderrPipe() if err != nil { return err } stdoutScanner := bufio.NewScanner(stdoutReader) stderrScanner := bufio.NewScanner(stderrReader) go func() { for stdoutScanner.Scan() { eventsChan <- types.NewOutputEvent(taskName, stdoutScanner.Bytes()) } }() go func() { for stderrScanner.Scan() { eventsChan <- types.NewOutputEvent(taskName, stderrScanner.Bytes()) } }() return nil }
// Exec executes the created tmp script and writes the output to the writer. func (ex *Executor) Exec(t *types.Task, eventsChan chan *types.Event) error { f, err := writeTempFile("", "dog", t.Run) if err != nil { return err } defer func() { if err := os.Remove(f.Name()); err != nil { eventsChan <- types.NewOutputEvent(t.Name, []byte(err.Error())) } }() binary, err := exec.LookPath(ex.cmd) if err != nil { return err } if t.Workdir != "" { if err := os.Chdir(t.Workdir); err != nil { return err } } cmd := exec.Command(binary, f.Name()) if err := gatherCmdOutput(t.Name, cmd, eventsChan); err != nil { return err } cmd.Stdin = os.Stdin if err := cmd.Start(); err != nil { return nil } eventsChan <- types.NewStartEvent(t.Name) statusCode := 0 if err := cmd.Wait(); err != nil { if exitError, ok := err.(*exec.ExitError); ok { if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); !ok { // For unknown error status codes set it to 1 statusCode = 1 } else { statusCode = waitStatus.ExitStatus() } } } eventsChan <- types.NewEndEvent(t.Name, statusCode) return nil }