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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃悶 Fix the hang of the spinner and progress bar on stop #162

Merged
merged 3 commits into from Mar 22, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 16 additions & 9 deletions pkg/output/tui/progress.go
Expand Up @@ -78,7 +78,7 @@ type BubbleProgress struct {
speed int
prevSpeed []int
err error
ended chan struct{}
quitChan chan struct{}
}

func (b *BubbleProgress) With(fn func(ProgressControl) error) error {
Expand Down Expand Up @@ -175,17 +175,23 @@ func (b bubbleProgressHandler) speedChange() (tea.Model, tea.Cmd) {
}

func (b bubbleProgressHandler) percentChange(event percentChange) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd

cmds := make([]tea.Cmd, 0, 1)
cmds = append(cmds, b.prog.SetPercent(float64(event)))

if event >= 1.0 {
cmds = append(cmds, tea.Sequence(b.finalPause(), tea.Quit))
cmds = append(cmds, b.quitSignal())
}

return b, tea.Batch(cmds...)
}

func (b *BubbleProgress) quitSignal() tea.Cmd {
// The final pause is to give the progress bar a chance to finish its
// animation before quitting. Otherwise, it ends abruptly, and the user
// might not see the progress bar at 100%.
return tea.Sequence(b.finalPause(), tea.Quit)
cardil marked this conversation as resolved.
Show resolved Hide resolved
}

func (b bubbleProgressHandler) progressFrame(event progress.FrameMsg) (tea.Model, tea.Cmd) {
progressModel, cmd := b.prog.Update(event)
if m, ok := progressModel.(progress.Model); ok {
Expand Down Expand Up @@ -235,11 +241,11 @@ func (b *BubbleProgress) start() {
tea.WithInput(b.InOrStdin()),
tea.WithOutput(out),
)
b.ended = make(chan struct{})
b.quitChan = make(chan struct{})
go func() {
t := b.tea
_, _ = t.Run()
close(b.ended)
close(b.quitChan)
if term.IsTerminal(out) {
if err := t.ReleaseTerminal(); err != nil {
panic(err)
Expand All @@ -252,11 +258,12 @@ func (b *BubbleProgress) stop() {
if b.tea == nil {
return
}
b.tea.Wait()

<-b.ended
b.tea.Send(b.quitSignal())
<-b.quitChan

b.tea = nil
b.ended = nil
b.quitChan = nil
}

func (b *BubbleProgress) onProgress(percent float64) {
Expand Down
12 changes: 9 additions & 3 deletions pkg/output/tui/spinner.go
Expand Up @@ -43,8 +43,9 @@ type BubbleSpinner struct {
output.InputOutput
Message

spin spinner.Model
tea *tea.Program
spin spinner.Model
tea *tea.Program
quitChan chan struct{}
}

func (b *BubbleSpinner) With(fn func(Spinner) error) error {
Expand Down Expand Up @@ -77,9 +78,11 @@ func (b *BubbleSpinner) start() {
tea.WithInput(b.InOrStdin()),
tea.WithOutput(out),
)
b.quitChan = make(chan struct{})
go func() {
t := b.tea
_, _ = t.Run()
close(b.quitChan)
if term.IsTerminal(out) {
_ = t.ReleaseTerminal()
}
Expand All @@ -90,9 +93,12 @@ func (b *BubbleSpinner) stop() {
if b.tea == nil {
return
}

b.tea.Quit()
b.tea.Wait()
<-b.quitChan

b.tea = nil
b.quitChan = nil
endMsg := fmt.Sprintf("%s %s\n",
b.Message.Text, spinnerStyle().Render("Done"))
_, _ = b.OutOrStdout().Write([]byte(endMsg))
Expand Down