From a93a147212b24b39d31bbbfe2ee173e89bade0f4 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Sat, 1 Nov 2025 22:35:50 -0400 Subject: [PATCH] fix(noninteractive): always print newline after output This is particularly important to keep the last line of output from being overwritten by the prompt when output's a TTY. --- internal/app/app.go | 20 ++++++++++++++------ internal/cmd/run.go | 7 ++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/internal/app/app.go b/internal/app/app.go index 811a496f177d6cf9e7f8cace5cbc3c3d9e44fa07..a49273a2ad96c24127fd14642c51a768d5e20dd0 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -101,8 +101,8 @@ func (app *App) Config() *config.Config { return app.config } -// RunNonInteractive handles the execution flow when a prompt is provided via -// CLI flag. +// RunNonInteractive runs the application in non-interactive mode with the +// given prompt, printing to stdout. func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool) error { slog.Info("Running in non-interactive mode") @@ -165,11 +165,19 @@ func (app *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool messageEvents := app.Messages.Subscribe(ctx) messageReadBytes := make(map[string]int) - defer fmt.Printf(ansi.ResetProgressBar) + defer func() { + _, _ = fmt.Printf(ansi.ResetProgressBar) + + // Always print a newline at the end. If output is a TTY this will + // prevent the prompt from overwriting the last line of output. + _, _ = fmt.Print('\n') + }() + for { - // HACK: add it again on every iteration so it doesn't get hidden by - // the terminal due to inactivity. - fmt.Printf(ansi.SetIndeterminateProgressBar) + // HACK: Reinitialize the terminal progress bar on every iteration so + // it doesn't get hidden by the terminal due to inactivity. + _, _ = fmt.Printf(ansi.SetIndeterminateProgressBar) + select { case result := <-done: stopSpinner() diff --git a/internal/cmd/run.go b/internal/cmd/run.go index 219239298bfe89cc8085e1021a0d510ad760898c..4340334712c76b3aac11e8c9fb47b663b8679597 100644 --- a/internal/cmd/run.go +++ b/internal/cmd/run.go @@ -48,7 +48,12 @@ crush run -q "Generate a README for this project" return fmt.Errorf("no prompt provided") } - // Run non-interactive flow using the App method + // TODO: Make this work when redirected to something other than stdout. + // For example: + // crush run "Do something fancy" > output.txt + // echo "Do something fancy" | crush run > output.txt + // + // TODO: We currently need to press ^c twice to cancel. Fix that. return app.RunNonInteractive(cmd.Context(), prompt, quiet) }, }