diff --git a/internal/pkg/exec.go b/internal/pkg/exec.go index c7d8c30d..7c4133eb 100644 --- a/internal/pkg/exec.go +++ b/internal/pkg/exec.go @@ -444,7 +444,7 @@ func scanVerbose( msg message.Msg, cancel context.CancelFunc, done chan<- struct{}, - prefix string, + prefix, suffix string, r io.Reader, ) { defer close(done) @@ -454,7 +454,7 @@ func scanVerbose( bufio.MaxScanTokenSize<<12, ) for s.Scan() { - msg.Verbose(prefix, s.Text()) + msg.Verbose(prefix, s.Text()+suffix) } if err := s.Err(); err != nil && !errors.Is(err, os.ErrClosed) { cancel() @@ -728,14 +728,25 @@ func (a *execArtifact) cure(f *FContext, hostNet bool) (err error) { brStdout, brStderr := f.cache.getReader(stdout), f.cache.getReader(stderr) stdoutDone, stderrDone := make(chan struct{}), make(chan struct{}) + + var suffix, prefixO, prefixE string + if f.cache.attr.Flags&CColourOutput != 0 { + suffix = "\x1b[0m" + prefixO = "\x1b[1;37m(" + a.name + ")\x1b[0m" + prefixE = "\x1b[1;97m(" + a.name + ")\x1b[0m" + } else { + prefixO = "(" + a.name + ":1)" + prefixE = "(" + a.name + ":2)" + } + go scanVerbose( msg, cancel, stdoutDone, - "("+a.name+":1)", + prefixO, suffix, io.TeeReader(brStdout, status), ) go scanVerbose( msg, cancel, stderrDone, - "("+a.name+":2)", + prefixE, suffix, io.TeeReader(brStderr, status), ) defer func() { diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go index f837fade..924ece2a 100644 --- a/internal/pkg/pkg.go +++ b/internal/pkg/pkg.go @@ -721,6 +721,9 @@ const ( // CExternShallow arranges for only non-flood inputs to be fetched when // curing an [Artifact] available via the external cache. CExternShallow + + // CColourOutput enables output colouring via ANSI control sequences. + CColourOutput ) // toplevel holds [context.WithCancel] over caller-supplied context, where all