Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Timeout for Spin Command #385

Merged
merged 2 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion spin/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func (o Options) Run() error {
title: o.TitleStyle.ToLipgloss().Render(o.Title),
command: o.Command,
align: o.Align,
showOutput: o.ShowOutput && isTTY,
timeout: o.Timeout,
hasTimeout: o.Timeout > 0,
}
p := tea.NewProgram(m, tea.WithOutput(os.Stderr))
mm, err := p.Run()
Expand Down
19 changes: 12 additions & 7 deletions spin/options.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package spin

import "github.com/charmbracelet/gum/style"
import (
"time"

"github.com/charmbracelet/gum/style"
)

// Options is the customization options for the spin command.
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"`
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"`
TitleStyle style.Styles `embed:"" prefix:"title." envprefix:"GUM_SPIN_TITLE_"`
Align string `help:"Alignment of spinner with regard to the title" short:"a" type:"align" enum:"left,right" default:"left" env:"GUM_SPIN_ALIGN"`
ShowOutput bool `help:"Show or pipe output of command during execution" default:"false" env:"GUM_SPIN_SHOW_OUTPUT"`
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"`
TitleStyle style.Styles `embed:"" prefix:"title." envprefix:"GUM_SPIN_TITLE_"`
Align string `help:"Alignment of spinner with regard to the title" short:"a" type:"align" enum:"left,right" default:"left" env:"GUM_SPIN_ALIGN"`
Timeout time.Duration `help:"Timeout until spin command aborts" default:"0" env:"GUM_SPIN_TIMEOUT"`
}
22 changes: 20 additions & 2 deletions spin/spin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ package spin
import (
"os/exec"
"strings"
"time"

"github.com/charmbracelet/gum/internal/exit"
"github.com/charmbracelet/gum/timeout"

"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
Expand All @@ -31,6 +35,8 @@ type model struct {
status int
stdout string
showOutput bool
timeout time.Duration
hasTimeout bool
}

var outbuf strings.Builder
Expand Down Expand Up @@ -71,14 +77,19 @@ func (m model) Init() tea.Cmd {
return tea.Batch(
m.spinner.Tick,
commandStart(m.command),
timeout.Init(m.timeout, nil),
)
}
func (m model) View() string {
var str string
if m.hasTimeout {
str = timeout.Str(m.timeout)
}
var header string
if m.align == "left" {
header = m.spinner.View() + " " + m.title
header = m.spinner.View() + str + " " + m.title
} else {
header = m.title + " " + m.spinner.View()
header = str + " " + m.title + " " + m.spinner.View()
}
if !m.showOutput {
return header
Expand All @@ -89,6 +100,13 @@ func (m model) View() string {
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case timeout.TickTimeoutMsg:
if msg.TimeoutValue <= 0 {
m.status = exit.StatusAborted
return m, tea.Quit
}
m.timeout = msg.TimeoutValue
return m, timeout.Tick(msg.TimeoutValue, msg.Data)
case finishCommandMsg:
m.stdout = msg.stdout
m.status = msg.status
Expand Down