From 65c4d53caed2222b59f5667e23a1e2dfb1df0c22 Mon Sep 17 00:00:00 2001 From: Dieter Eickstaedt Date: Fri, 30 Jun 2023 08:56:49 +0200 Subject: [PATCH 1/2] feat: Timeout for Spin Command --- spin/command.go | 3 ++- spin/options.go | 19 ++++++++++++------- spin/spin.go | 21 +++++++++++++++++++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/spin/command.go b/spin/command.go index 082ef3788..9482b7fae 100644 --- a/spin/command.go +++ b/spin/command.go @@ -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() diff --git a/spin/options.go b/spin/options.go index e277fb5d0..9b55c4aa5 100644 --- a/spin/options.go +++ b/spin/options.go @@ -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"` } diff --git a/spin/spin.go b/spin/spin.go index 2648b9a76..926a62017 100644 --- a/spin/spin.go +++ b/spin/spin.go @@ -17,6 +17,9 @@ package spin import ( "os/exec" "strings" + "time" + + "github.com/charmbracelet/gum/timeout" "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" @@ -31,6 +34,8 @@ type model struct { status int stdout string showOutput bool + timeout time.Duration + hasTimeout bool } var outbuf strings.Builder @@ -71,14 +76,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() + " " + m.title + str } else { - header = m.title + " " + m.spinner.View() + header = str + " " + m.title + " " + m.spinner.View() } if !m.showOutput { return header @@ -89,6 +99,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 = 130 + 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 From 90f8a4aeae3a133b21b7bfe403fb0155d4a2ee3c Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Fri, 30 Jun 2023 09:16:58 -0400 Subject: [PATCH 2/2] fix: spin timeout --- spin/spin.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spin/spin.go b/spin/spin.go index 926a62017..48f6f7faf 100644 --- a/spin/spin.go +++ b/spin/spin.go @@ -19,6 +19,7 @@ import ( "strings" "time" + "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/timeout" "github.com/charmbracelet/bubbles/spinner" @@ -86,7 +87,7 @@ func (m model) View() string { } var header string if m.align == "left" { - header = m.spinner.View() + " " + m.title + str + header = m.spinner.View() + str + " " + m.title } else { header = str + " " + m.title + " " + m.spinner.View() } @@ -101,7 +102,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case timeout.TickTimeoutMsg: if msg.TimeoutValue <= 0 { - m.status = 130 + m.status = exit.StatusAborted return m, tea.Quit } m.timeout = msg.TimeoutValue