diff --git a/src/runner.go b/src/runner.go index 79448e5..e559c0f 100644 --- a/src/runner.go +++ b/src/runner.go @@ -114,24 +114,32 @@ func runCommandWithOutput(cmd *exec.Cmd, outputCh chan string, doneCh chan bool) defer close(dataReadCh) go func() { - defer func() { - dataReadCh <- true - }() - reader := bufio.NewReader(cmdOutput) + readBuffer := 1024 for { - line, err := reader.ReadString('\n') - if errors.Is(err, io.EOF) { + data, err := reader.Peek(readBuffer) + switch { + case errors.Is(err, io.EOF): log.Infoln("Read ended with EOF") - break - } else if err != nil { - log.Infoln("Read ended with error", err) - outputCh <- fmt.Sprintf("Error reading from stdout: %v", err) + outputCh <- string(data) + dataReadCh <- true return + case errors.Is(err, io.ErrShortBuffer): + log.Infoln("Shorter read than wanted", err, data) + if len(data) != 0 { + log.Infoln("Not empty", data) + outputCh <- string(data) + _, err := reader.Discard(len(data)) + if err != nil { + // TODO: what should I do if I want to move the reader + // If I do nothing it can only cause it to be read twice + log.Errorln("Discard failed", err) + } + } + default: + log.Infoln(data, err) } - log.Infoln("Read line: ", line) - outputCh <- line } }() @@ -174,18 +182,15 @@ func executeCommandWithProgress(command string, interpreter string, variables ma for { select { case output := <-outputCh: - // TODO: this has to be sent to dispatcher back to report to UI - // the idea is to send partial output if buffer with given size sent the output to channel - log.Info(output) - - // Append partial to all output bufferedOutput += output case <-ticker.C: // NOTE: If just message without output is also okay we could send just still running log.Infoln("Still running ...") + log.Infoln(bufferedOutput) case <-doneCh: // Execution is done log.Infoln("Execution done ...") + log.Infoln(bufferedOutput) return bufferedOutput } }