Skip to content

Commit

Permalink
feat(spin): Add support for --show-error for the spinner. (rebase #440)…
Browse files Browse the repository at this point in the history
… (#518)

* feat(spin): Add support for `--show-error` for the spinner.

This makes it so that if the `--show-error` flag is provided then the
full output of the command will be printed if the command fails. This
kind of works in conjuncture with `--show-output` in that if the command
succeeds only STDOUT is pushed. If the command fails both `STDOUT` and
`STDERR` are pushed.

This builds off of #371

Resolves #55

* chore: Fix formatting

---------

Co-authored-by: Elliot Courant <[email protected]>
  • Loading branch information
pingiun and elliotcourant authored Mar 28, 2024
1 parent 2f2fa3b commit f4d1983
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 9 deletions.
25 changes: 18 additions & 7 deletions spin/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,26 @@ func (o Options) Run() error {
return fmt.Errorf("failed to access stdout: %w", err)
}

if o.ShowOutput {
// BubbleTea writes the View() to stderr.
// If the program is being piped then put the accumulated output in stdout.
if !isTTY {
_, err := os.Stdout.WriteString(m.stdout)
if err != nil {
return fmt.Errorf("failed to write to stdout: %w", err)
// If the command succeeds, and we are printing output and we are in a TTY then push the STDOUT we got to the actual
// STDOUT for piping or other things.
if m.status == 0 {

Check failure on line 49 in spin/command.go

View workflow job for this annotation

GitHub Actions / lint-soft

`if m.status == 0` has complex nested blocks (complexity: 8) (nestif)
if o.ShowOutput {
// BubbleTea writes the View() to stderr.
// If the program is being piped then put the accumulated output in stdout.
if !isTTY {
_, err := os.Stdout.WriteString(m.stdout)
if err != nil {
return fmt.Errorf("failed to write to stdout: %w", err)
}
}
}
} else if o.ShowError {
// Otherwise if we are showing errors and the command did not exit with a 0 status code then push all of the command
// output to the terminal. This way failed commands can be debugged.
_, err := os.Stdout.WriteString(m.output)
if err != nil {
return fmt.Errorf("failed to write to stdout: %w", err)
}
}

os.Exit(m.status)
Expand Down
1 change: 1 addition & 0 deletions spin/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Options struct {
Command []string `arg:"" help:"Command to run"`

ShowOutput bool `help:"Show or pipe output of command during execution" default:"false" env:"GUM_SPIN_SHOW_OUTPUT"`
ShowError bool `help:"Show output of command only if the command fails" default:"false" env:"GUM_SPIN_SHOW_ERROR"`
Spinner string `help:"Spinner type" short:"s" type:"spinner" enum:"line,dot,minidot,jump,pulse,points,globe,moon,monkey,meter,hamburger" default:"dot" env:"GUM_SPIN_SPINNER"`
SpinnerStyle style.Styles `embed:"" prefix:"spinner." set:"defaultForeground=212" envprefix:"GUM_SPIN_SPINNER_"`
Title string `help:"Text to display to user while spinning" default:"Loading..." env:"GUM_SPIN_TITLE"`
Expand Down
18 changes: 16 additions & 2 deletions spin/spin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package spin

import (
"io"
"os"
"os/exec"
"strings"
Expand All @@ -37,16 +38,22 @@ type model struct {
aborted bool
status int
stdout string
stderr string
output string
showOutput bool
showError bool

Check failure on line 44 in spin/spin.go

View workflow job for this annotation

GitHub Actions / lint-soft

field `showError` is unused (unused)

Check failure on line 44 in spin/spin.go

View workflow job for this annotation

GitHub Actions / lint

field `showError` is unused (unused)
timeout time.Duration
hasTimeout bool
}

var bothbuf strings.Builder
var outbuf strings.Builder
var errbuf strings.Builder

type finishCommandMsg struct {
stdout string
stderr string
output string
status int
}

Expand All @@ -59,8 +66,11 @@ func commandStart(command []string) tea.Cmd {
cmd := exec.Command(command[0], args...) //nolint:gosec

if isatty.IsTerminal(os.Stdout.Fd()) {
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
stdout := io.MultiWriter(&bothbuf, &errbuf)
stderr := io.MultiWriter(&bothbuf, &outbuf)

cmd.Stdout = stdout
cmd.Stderr = stderr
} else {
cmd.Stdout = os.Stdout
}
Expand All @@ -75,6 +85,8 @@ func commandStart(command []string) tea.Cmd {

return finishCommandMsg{
stdout: outbuf.String(),
stderr: errbuf.String(),
output: bothbuf.String(),
status: status,
}
}
Expand Down Expand Up @@ -123,6 +135,8 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, timeout.Tick(msg.TimeoutValue, msg.Data)
case finishCommandMsg:
m.stdout = msg.stdout
m.stderr = msg.stderr
m.output = msg.output
m.status = msg.status
m.quitting = true
return m, tea.Quit
Expand Down

0 comments on commit f4d1983

Please sign in to comment.