diff --git a/internal/ansi/ansi.go b/internal/ansi/ansi.go index 8970b9254..3ab65b763 100644 --- a/internal/ansi/ansi.go +++ b/internal/ansi/ansi.go @@ -4,10 +4,7 @@ import ( "fmt" "io" "os" - "runtime" - "time" - "github.com/briandowns/spinner" "github.com/logrusorgru/aurora" "github.com/tidwall/pretty" "golang.org/x/crypto/ssh/terminal" @@ -97,70 +94,6 @@ func Linkify(text, url string, w io.Writer) string { return fmt.Sprintf("\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\", url, text) } -type charset = []string - -func getCharset() charset { - // See https://github.com/briandowns/spinner#available-character-sets for - // list of available charsets - if runtime.GOOS == "windows" { - // Less fancy, but uses ASCII characters so works with Windows default - // console. - return spinner.CharSets[8] - } - return spinner.CharSets[11] -} - -const duration = time.Duration(100) * time.Millisecond - -// StartNewSpinner starts a new spinner with the given message. If the writer is not -// a terminal or doesn't support colors, it simply prints the message. -func StartNewSpinner(msg string, w io.Writer) *spinner.Spinner { - if !isTerminal(w) || !shouldUseColors(w) { - fmt.Fprintln(w, msg) - return nil - } - - s := spinner.New(getCharset(), duration) - s.Writer = w - - if msg != "" { - s.Suffix = " " + msg - } - - s.Start() - - return s -} - -// StartSpinner updates an existing spinner's message, and starts it if it was stopped -func StartSpinner(s *spinner.Spinner, msg string, w io.Writer) { - if s == nil { - fmt.Fprintln(w, msg) - return - } - if msg != "" { - s.Suffix = " " + msg - } - if !s.Active() { - s.Start() - } -} - -// StopSpinner stops a spinner with the given message. If the writer is not -// a terminal or doesn't support colors, it simply prints the message. -func StopSpinner(s *spinner.Spinner, msg string, w io.Writer) { - if !isTerminal(w) || !shouldUseColors(w) { - fmt.Fprintln(w, msg) - return - } - - if msg != "" { - s.FinalMSG = "> " + msg + "\n" - } - - s.Stop() -} - // StrikeThrough returns struck though text if the writer supports colors func StrikeThrough(text string) string { color := Color(os.Stdout) diff --git a/internal/ansi/spinner.go b/internal/ansi/spinner.go new file mode 100644 index 000000000..4a85797dc --- /dev/null +++ b/internal/ansi/spinner.go @@ -0,0 +1,45 @@ +package ansi + +import ( + "fmt" + "time" + + "github.com/briandowns/spinner" +) + +const ( + spinnerTextEllipsis = "..." + spinnerTextDone = "done" + spinnerTextFailed = "failed" + + spinnerColor = "red" +) + +func Spinner(text string, fn func() error) error { + done := make(chan struct{}) + errc := make(chan error) + go func() { + defer close(done) + + s := spinner.New(spinner.CharSets[11], 100*time.Millisecond) + s.Prefix = text + spinnerTextEllipsis + " " + s.FinalMSG = s.Prefix + spinnerTextDone + + if err := s.Color(spinnerColor); err != nil { + panic(err) + } + + s.Start() + err := <-errc + if err != nil { + s.FinalMSG = s.Prefix + spinnerTextFailed + } + s.Stop() + }() + + err := fn() + errc <- err + <-done + fmt.Println() + return err +}