@@ -19,7 +19,9 @@ package cmd
1919import (
2020 "bytes"
2121 "context"
22+ "fmt"
2223 "os/exec"
24+ "strings"
2325 "syscall"
2426
2527 "github.com/go-logr/logr"
@@ -40,6 +42,15 @@ type Interface interface {
4042
4143type cmd struct {}
4244
45+ // formatCommandOutput formats command output for logging, making carriage returns visible
46+ func formatCommandOutput (output string ) string {
47+ // Replace carriage returns with [CR] for visibility
48+ formatted := strings .ReplaceAll (output , "\r " , "[CR]" )
49+ // Note: We don't replace \n here because the logger will handle newlines naturally
50+ // when the output is displayed in the log message
51+ return formatted
52+ }
53+
4354// RunCommand is the default implementation of the cmd.Interface.
4455func (c * cmd ) RunCommand (ctx context.Context , command string , args ... string ) (string , string , error ) {
4556 log := logr .FromContextOrDiscard (ctx )
@@ -51,7 +62,21 @@ func (c *cmd) RunCommand(ctx context.Context, command string, args ...string) (s
5162 cmd .Stderr = & stderr
5263
5364 err := cmd .Run ()
54- log .V (1 ).Info ("RunCommand()" , "output" , stdout .String (), "error" , err )
65+
66+ // Format output for logging
67+ stdoutFormatted := formatCommandOutput (stdout .String ())
68+ stderrFormatted := formatCommandOutput (stderr .String ())
69+
70+ // Log with actual line breaks by using string formatting instead of structured logging
71+ logMessage := fmt .Sprintf ("RunCommand() command=%s args=%v error=%v" , command , args , err )
72+ if stdoutFormatted != "" {
73+ logMessage += fmt .Sprintf ("\n stdout:\n %s" , stdoutFormatted )
74+ }
75+ if stderrFormatted != "" {
76+ logMessage += fmt .Sprintf ("\n stderr:\n %s" , stderrFormatted )
77+ }
78+
79+ log .V (1 ).Info (logMessage )
5580 return stdout .String (), stderr .String (), err
5681}
5782
0 commit comments