-
-
Notifications
You must be signed in to change notification settings - Fork 153
Expand file tree
/
Copy pathspinner_utils.go
More file actions
84 lines (71 loc) · 2 KB
/
spinner_utils.go
File metadata and controls
84 lines (71 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package exec
import (
"fmt"
"os"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
"github.com/cloudposse/atmos/internal/tui/templates/term"
log "github.com/cloudposse/atmos/pkg/logger"
"github.com/cloudposse/atmos/pkg/ui/theme"
)
type modelSpinner struct {
spinner spinner.Model
message string
}
func (m modelSpinner) Init() tea.Cmd {
return m.spinner.Tick
}
func (m modelSpinner) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
default:
return m, nil
}
case spinner.TickMsg:
var cmd tea.Cmd
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
default:
return m, nil
}
}
func (m modelSpinner) View() string {
return fmt.Sprintf("\r%s %s", m.spinner.View(), m.message)
}
// NewSpinner initializes a spinner and returns a pointer to a tea.Program.
func NewSpinner(message string) *tea.Program {
s := spinner.New()
styles := theme.GetCurrentStyles()
s.Style = styles.Link
var opts []tea.ProgramOption
if !term.IsTTYSupportForStdout() {
// Workaround for non-TTY environments.
opts = []tea.ProgramOption{tea.WithoutRenderer(), tea.WithInput(nil)}
log.Debug("No TTY detected. Falling back to basic output. This can happen when no terminal is attached or when commands are pipelined.")
fmt.Fprintln(os.Stderr, message)
}
p := tea.NewProgram(modelSpinner{
spinner: s,
message: message,
}, opts...)
return p
}
// RunSpinner executes the spinner program in a goroutine.
func RunSpinner(p *tea.Program, spinnerChan chan struct{}, message string) {
go func() {
defer close(spinnerChan)
if _, err := p.Run(); err != nil {
// If there's any error running the spinner, print the message and the error.
fmt.Println(message)
log.Error("Failed to run spinner:", "error", err)
}
}()
}
// StopSpinner stops the spinner program and waits for the completion.
func StopSpinner(p *tea.Program, spinnerChan chan struct{}) {
p.Quit()
<-spinnerChan
}