mirror of
				https://github.com/edgelesssys/constellation.git
				synced 2025-10-30 19:28:59 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright (c) Edgeless Systems GmbH
 | |
| 
 | |
| SPDX-License-Identifier: AGPL-3.0-only
 | |
| */
 | |
| 
 | |
| package cmd
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"sync"
 | |
| 	"sync/atomic"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/spf13/cobra"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	spinnerStates = []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"}
 | |
| 	dotsStates    = []string{".", "..", "..."}
 | |
| )
 | |
| 
 | |
| type spinnerInterf interface {
 | |
| 	Start(text string, showDots bool)
 | |
| 	Stop()
 | |
| }
 | |
| 
 | |
| type spinner struct {
 | |
| 	out   *cobra.Command
 | |
| 	delay time.Duration
 | |
| 	wg    *sync.WaitGroup
 | |
| 	stop  int32
 | |
| }
 | |
| 
 | |
| func newSpinner(c *cobra.Command, writer io.Writer) (*spinner, *interruptSpinWriter) {
 | |
| 	spinner := &spinner{
 | |
| 		out:   c,
 | |
| 		wg:    &sync.WaitGroup{},
 | |
| 		delay: 100 * time.Millisecond,
 | |
| 		stop:  0,
 | |
| 	}
 | |
| 
 | |
| 	if writer != nil {
 | |
| 		interruptWriter := &interruptSpinWriter{
 | |
| 			writer:  writer,
 | |
| 			spinner: spinner,
 | |
| 		}
 | |
| 		return spinner, interruptWriter
 | |
| 	}
 | |
| 
 | |
| 	return spinner, nil
 | |
| }
 | |
| 
 | |
| func (s *spinner) Start(text string, showDots bool) {
 | |
| 	s.wg.Add(1)
 | |
| 	go func() {
 | |
| 		defer s.wg.Done()
 | |
| 
 | |
| 		for i := 0; ; i = (i + 1) % len(spinnerStates) {
 | |
| 			if atomic.LoadInt32(&s.stop) != 0 {
 | |
| 				break
 | |
| 			}
 | |
| 			dotsState := ""
 | |
| 			if showDots {
 | |
| 				dotsState = dotsStates[i%len(dotsStates)]
 | |
| 			}
 | |
| 			state := fmt.Sprintf("\r%s %s%s", spinnerStates[i], text, dotsState)
 | |
| 			s.out.Print(state)
 | |
| 			time.Sleep(s.delay)
 | |
| 		}
 | |
| 
 | |
| 		dotsState := ""
 | |
| 		if showDots {
 | |
| 			dotsState = dotsStates[len(dotsStates)-1]
 | |
| 		}
 | |
| 		finalState := fmt.Sprintf("\r%s%s  ", text, dotsState)
 | |
| 		s.out.Println(finalState)
 | |
| 	}()
 | |
| }
 | |
| 
 | |
| func (s *spinner) Stop() {
 | |
| 	atomic.StoreInt32(&s.stop, 1)
 | |
| 	s.wg.Wait()
 | |
| }
 | |
| 
 | |
| type interruptSpinWriter struct {
 | |
| 	spinner *spinner
 | |
| 	writer  io.Writer
 | |
| }
 | |
| 
 | |
| func (w *interruptSpinWriter) Write(p []byte) (n int, err error) {
 | |
| 	w.spinner.Stop()
 | |
| 	return w.writer.Write(p)
 | |
| }
 | |
| 
 | |
| type nopSpinner struct{}
 | |
| 
 | |
| func (s nopSpinner) Start(string, bool) {}
 | |
| func (s nopSpinner) Stop()              {}
 | 
