github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/cmd/syft/cli/ui/handle_cataloger_task.go (about)

     1  package ui
     2  
     3  import (
     4  	tea "github.com/charmbracelet/bubbletea"
     5  	"github.com/charmbracelet/lipgloss"
     6  	"github.com/wagoodman/go-partybus"
     7  	"github.com/wagoodman/go-progress"
     8  
     9  	"github.com/anchore/bubbly/bubbles/taskprogress"
    10  	"github.com/anchore/syft/internal/log"
    11  	"github.com/anchore/syft/syft/event/monitor"
    12  	syftEventParsers "github.com/anchore/syft/syft/event/parsers"
    13  )
    14  
    15  var _ progress.Stager = (*catalogerTaskStageAdapter)(nil)
    16  
    17  type catalogerTaskStageAdapter struct {
    18  	mon *monitor.CatalogerTask
    19  }
    20  
    21  func newCatalogerTaskStageAdapter(mon *monitor.CatalogerTask) *catalogerTaskStageAdapter {
    22  	return &catalogerTaskStageAdapter{
    23  		mon: mon,
    24  	}
    25  }
    26  
    27  func (c catalogerTaskStageAdapter) Stage() string {
    28  	return c.mon.GetValue()
    29  }
    30  
    31  func (m *Handler) handleCatalogerTaskStarted(e partybus.Event) []tea.Model {
    32  	mon, err := syftEventParsers.ParseCatalogerTaskStarted(e)
    33  	if err != nil {
    34  		log.WithFields("error", err).Warn("unable to parse event")
    35  		return nil
    36  	}
    37  
    38  	var prefix string
    39  	if mon.SubStatus {
    40  		// TODO: support list of sub-statuses, not just a single leaf
    41  		prefix = "└── "
    42  	}
    43  
    44  	tsk := m.newTaskProgress(
    45  		taskprogress.Title{
    46  			// TODO: prefix should not be part of the title, but instead a separate field that is aware of the tree structure
    47  			Default: prefix + mon.Title,
    48  			Running: prefix + mon.Title,
    49  			Success: prefix + mon.TitleOnCompletion,
    50  		},
    51  		taskprogress.WithStagedProgressable(
    52  			struct {
    53  				progress.Stager
    54  				progress.Progressable
    55  			}{
    56  				Progressable: mon.GetMonitor(),
    57  				Stager:       newCatalogerTaskStageAdapter(mon),
    58  			},
    59  		),
    60  	)
    61  
    62  	// TODO: this isn't ideal since the model stays around after it is no longer needed, but it works for now
    63  	tsk.HideOnSuccess = mon.RemoveOnCompletion
    64  	tsk.HideStageOnSuccess = false
    65  	tsk.HideProgressOnSuccess = false
    66  
    67  	tsk.TitleStyle = lipgloss.NewStyle()
    68  	// TODO: this is a hack to get the spinner to not show up, but ideally the component would support making the spinner optional
    69  	tsk.Spinner.Spinner.Frames = []string{" "}
    70  
    71  	return []tea.Model{tsk}
    72  }