utils/spinner.go (35 lines of code) (raw):

/* Copyright (c) Facebook, Inc. and its affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. */ package utils import ( "context" "time" "github.com/facebookincubator/fbender/log" spin "github.com/tj/go-spin" ) // Default refresh rate. const spinnerRefresh = 100 * time.Millisecond // NewBackgroundSpinner creates a new spinner which runs in background refreshing // its output on a constant rate. The spinner is prefixed with the provided // description. Returns a function which cancels the spinner. The default value // for refresh is used if provided refresh is less than or equal to zero. func NewBackgroundSpinner(description string, refresh time.Duration) context.CancelFunc { if refresh <= 0 { refresh = spinnerRefresh } ctx, cancel := context.WithCancel(context.Background()) spinner := spin.New() spinner.Set(spin.Spin1) sync := make(chan bool) go func() { for { log.Errorf("\r%s... ", description) select { case <-ctx.Done(): log.Errorf("Done.\n") sync <- false return default: log.Errorf("%s", spinner.Next()) } time.Sleep(refresh) } }() return func() { // cancel context and wait for goroutine to clean the output cancel() <-sync } }