I was wondering if you could provide some implementation advice. Refer to this stackoverflow question for the original question.
I refactored since the post, and almost have it working the way I would want it, but because I am stopping and then starting the spinner because before logger print, it is adding a new line which I cannot get rid off.
package main
import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/theckman/yacspin"
)
var stdOut = zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "Jan 02 15:04:05"}
func main() {
var Logger = log.Output(stdOut)
// pauseItForAMoment := false
// create a spinner
spinner, err := createSpinner()
if err != nil {
fmt.Printf("failed to make spinner from config struct: %v\n", err)
os.Exit(1)
}
// start the spinner
if err := spinner.Start(); err != nil {
panic(err)
}
wg := &sync.WaitGroup{}
wg.Add(1)
var (
total int
current int
)
data := make(chan string)
// only want one go routine at a time but this is not important
max := make(chan struct{}, 1)
go func() {
defer wg.Done()
for d := range data {
wg.Add(1)
go func(wg *sync.WaitGroup, d string) {
max <- struct{}{}
defer func() {
<-max
}()
// function is doing work and printing the result once done.
// pauseItForAMoment = true
// spinner.Prefix(d)
if spinner.Status() == yacspin.SpinnerRunning {
spinner.Stop()
}
// fmt.Println(d)
Logger.Info().Str("data", d).Send()
// fmt.Println(d)
if spinner.Status() == yacspin.SpinnerStopped {
spinner.Start()
}
current += 1
spinner.Message(fmt.Sprintf("%d/%d", current, total))
// pauseItForAMoment = false
// sends a value to the spinner go routine so that it can show
// the updated count
time.Sleep(100 * time.Millisecond)
// spinnerCh <- 1
wg.Done()
}(wg, d)
}
}()
// simulate queing some work
ss := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
for _, s := range ss {
data <- s
}
total = len(ss)
close(data)
wg.Wait()
if err := spinner.Stop(); err != nil {
spinner.StopFail()
}
}
func createSpinner() (*yacspin.Spinner, error) {
// build the configuration, each field is documented
cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[11],
Suffix: "", // puts a least one space between the animating spinner and the Message
// Message: "collecting files",
// SuffixAutoColon: true,
// ColorAll: true,
Colors: []string{"fgYellow"},
StopCharacter: " ",
StopColors: []string{"fgGreen"},
// StopMessage: "done",
StopFailCharacter: "✗",
StopFailColors: []string{"fgRed"},
StopFailMessage: "failed",
}
s, err := yacspin.New(cfg)
if err != nil {
return nil, fmt.Errorf("failed to make spinner from struct: %w", err)
}
return s, nil
}
func stopOnSignal(spinner *yacspin.Spinner) {
// ensure we stop the spinner before exiting, otherwise cursor will remain
// hidden and terminal will require a `reset`
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigCh
spinner.StopFailMessage("interrupted")
// ignoring error intentionally
_ = spinner.StopFail()
os.Exit(0)
}()
}
Hey, first off, love the lib! Great work!
I was wondering if you could provide some implementation advice. Refer to this stackoverflow question for the original question.
I refactored since the post, and almost have it working the way I would want it, but because I am stopping and then starting the spinner because before logger print, it is adding a new line which I cannot get rid off.
Any advice on how to fix this?
Currently, the output is:
What I am hoping for is (no extra newline):
This is my working code so far:
Thanks in advance!