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 }