mirror of
https://github.com/charmbracelet/gum
synced 2024-05-20 15:16:42 +02:00
feat: Timeout for Spin Command (#385)
* feat: Timeout for Spin Command * fix: spin timeout --------- Co-authored-by: Maas Lalani <maas@lalani.dev>
This commit is contained in:
parent
0c1cc8e669
commit
f8caeef195
|
@ -26,7 +26,8 @@ func (o Options) Run() error {
|
||||||
title: o.TitleStyle.ToLipgloss().Render(o.Title),
|
title: o.TitleStyle.ToLipgloss().Render(o.Title),
|
||||||
command: o.Command,
|
command: o.Command,
|
||||||
align: o.Align,
|
align: o.Align,
|
||||||
showOutput: o.ShowOutput && isTTY,
|
timeout: o.Timeout,
|
||||||
|
hasTimeout: o.Timeout > 0,
|
||||||
}
|
}
|
||||||
p := tea.NewProgram(m, tea.WithOutput(os.Stderr))
|
p := tea.NewProgram(m, tea.WithOutput(os.Stderr))
|
||||||
mm, err := p.Run()
|
mm, err := p.Run()
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
package spin
|
package spin
|
||||||
|
|
||||||
import "github.com/charmbracelet/gum/style"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/gum/style"
|
||||||
|
)
|
||||||
|
|
||||||
// Options is the customization options for the spin command.
|
// Options is the customization options for the spin command.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Command []string `arg:"" help:"Command to run"`
|
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"`
|
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"`
|
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_"`
|
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"`
|
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_"`
|
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"`
|
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
spin/spin.go
22
spin/spin.go
|
@ -17,6 +17,10 @@ package spin
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/gum/internal/exit"
|
||||||
|
"github.com/charmbracelet/gum/timeout"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
"github.com/charmbracelet/bubbles/spinner"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
@ -31,6 +35,8 @@ type model struct {
|
||||||
status int
|
status int
|
||||||
stdout string
|
stdout string
|
||||||
showOutput bool
|
showOutput bool
|
||||||
|
timeout time.Duration
|
||||||
|
hasTimeout bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var outbuf strings.Builder
|
var outbuf strings.Builder
|
||||||
|
@ -71,14 +77,19 @@ func (m model) Init() tea.Cmd {
|
||||||
return tea.Batch(
|
return tea.Batch(
|
||||||
m.spinner.Tick,
|
m.spinner.Tick,
|
||||||
commandStart(m.command),
|
commandStart(m.command),
|
||||||
|
timeout.Init(m.timeout, nil),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
func (m model) View() string {
|
func (m model) View() string {
|
||||||
|
var str string
|
||||||
|
if m.hasTimeout {
|
||||||
|
str = timeout.Str(m.timeout)
|
||||||
|
}
|
||||||
var header string
|
var header string
|
||||||
if m.align == "left" {
|
if m.align == "left" {
|
||||||
header = m.spinner.View() + " " + m.title
|
header = m.spinner.View() + str + " " + m.title
|
||||||
} else {
|
} else {
|
||||||
header = m.title + " " + m.spinner.View()
|
header = str + " " + m.title + " " + m.spinner.View()
|
||||||
}
|
}
|
||||||
if !m.showOutput {
|
if !m.showOutput {
|
||||||
return header
|
return header
|
||||||
|
@ -89,6 +100,13 @@ func (m model) View() string {
|
||||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
switch msg := msg.(type) {
|
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:
|
case finishCommandMsg:
|
||||||
m.stdout = msg.stdout
|
m.stdout = msg.stdout
|
||||||
m.status = msg.status
|
m.status = msg.status
|
||||||
|
|
Loading…
Reference in a new issue