diff options
Diffstat (limited to 'internal/pkg/exec.go')
| -rw-r--r-- | internal/pkg/exec.go | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/internal/pkg/exec.go b/internal/pkg/exec.go index 7c4133eb..e499ecf1 100644 --- a/internal/pkg/exec.go +++ b/internal/pkg/exec.go @@ -2,6 +2,7 @@ package pkg import ( "bufio" + "bytes" "context" "errors" "fmt" @@ -439,6 +440,34 @@ const ( execWaitDelay = time.Nanosecond ) +// scanLinesCR is like [bufio.ScanLines], but also treats a bare \r as an +// end-of-line marker. +func scanLinesCR(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + ri, ni := bytes.IndexByte(data, '\r'), bytes.IndexByte(data, '\n') + + if ri >= 0 && (ni < 0 || ri < ni) { + if ri+1 == ni { + // We have a full \r\n-terminated line. + return ri + 2, data[:ri], nil + } + // We have a bare \r, probably some kind of progress indicator. + return ri + 1, data[:ri], nil + } + if ni >= 0 && (ri < 0 || ni < ri) { + // We have a full newline-terminated line. + return ni + 1, data[:ni], nil + } + // If we're at EOF, we have a final, non-terminated line. Return it. + if atEOF { + return len(data), data, nil + } + // Request more data. + return 0, nil, nil +} + // scanVerbose prefixes program output for a verbose [message.Msg]. func scanVerbose( msg message.Msg, @@ -449,6 +478,7 @@ func scanVerbose( ) { defer close(done) s := bufio.NewScanner(r) + s.Split(scanLinesCR) s.Buffer( make([]byte, bufio.MaxScanTokenSize), bufio.MaxScanTokenSize<<12, @@ -458,7 +488,7 @@ func scanVerbose( } if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) { cancel() - msg.Verbose("*"+prefix, err) + msg.Verbose("*"+prefix, err.Error()+suffix) } } |
