github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/pkg/terminal/glint_status.go (about)

     1  package terminal
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  
     7  	"github.com/mitchellh/go-glint"
     8  	gc "github.com/mitchellh/go-glint/components"
     9  )
    10  
    11  // glintStatus implements Status and uses a spinner to show updates.
    12  type glintStatus struct {
    13  	mu      sync.Mutex
    14  	closed  bool
    15  	msg     string
    16  	spinner glint.Component
    17  	text    []glint.Component
    18  }
    19  
    20  func newGlintStatus() *glintStatus {
    21  	return &glintStatus{
    22  		spinner: gc.Spinner(),
    23  	}
    24  }
    25  
    26  func (s *glintStatus) Update(msg string) {
    27  	s.mu.Lock()
    28  	defer s.mu.Unlock()
    29  	s.msg = msg
    30  }
    31  
    32  func (s *glintStatus) Step(status, msg string) {
    33  	s.mu.Lock()
    34  	defer s.mu.Unlock()
    35  
    36  	// Determine our color
    37  	var style []glint.StyleOption
    38  	switch status {
    39  	case StatusOK:
    40  		style = append(style, glint.Color("lightGreen"))
    41  
    42  	case StatusError:
    43  		style = append(style, glint.Color("lightRed"))
    44  
    45  	case StatusWarn:
    46  		style = append(style, glint.Color("lightYellow"))
    47  	}
    48  
    49  	// If we have a prefix, set that
    50  	if icon, ok := statusIcons[status]; ok {
    51  		msg = icon + " " + msg
    52  	}
    53  
    54  	// Clear the message so we don't draw a spinner
    55  	s.msg = ""
    56  
    57  	// Add our final message
    58  	s.text = append(s.text, glint.Finalize(glint.Style(
    59  		glint.Text(msg),
    60  		style...,
    61  	)))
    62  }
    63  
    64  func (s *glintStatus) Close() error {
    65  	s.mu.Lock()
    66  	defer s.mu.Unlock()
    67  	s.closed = true
    68  	return nil
    69  }
    70  
    71  func (s *glintStatus) reset() {
    72  	s.mu.Lock()
    73  	defer s.mu.Unlock()
    74  	s.text = nil
    75  	s.msg = ""
    76  }
    77  
    78  func (s *glintStatus) Body(context.Context) glint.Component {
    79  	s.mu.Lock()
    80  	defer s.mu.Unlock()
    81  
    82  	var cs []glint.Component
    83  
    84  	// If we have text we draw that first
    85  	if len(s.text) > 0 {
    86  		cs = append(cs, glint.Finalize(glint.Fragment(s.text...)))
    87  	}
    88  
    89  	// If we have a message the spinner is active and we draw that
    90  	if !s.closed && len(s.msg) > 0 {
    91  		cs = append(cs, glint.Layout(
    92  			s.spinner,
    93  			glint.Text(" "),
    94  			glint.Text(s.msg),
    95  		).Row())
    96  	}
    97  
    98  	c := glint.Fragment(cs...)
    99  	if s.closed {
   100  		c = glint.Finalize(c)
   101  	}
   102  
   103  	return c
   104  }