aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/exec.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-08-27 16:07:05 +0900
committerOphestra <cat@gensokyo.uk>2026-08-27 16:07:05 +0900
commitccb004e2174ca9fedba7bc95b036fc62dbdc28b1 (patch)
treed8b0603060d3cec0ee28f4cd55ac88c2560c1ce0 /internal/pkg/exec.go
parentebb1144efc6c09dff8a732c5baf11db5b8f515b2 (diff)
internal/pkg: treat bare carriage return as end-of-line marker
This avoids having progress indicators mess up logging. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg/exec.go')
-rw-r--r--internal/pkg/exec.go32
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)
}
}