github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/cmd/syft/cli/ui/handle_package_cataloger.go (about) 1 package ui 2 3 import ( 4 "fmt" 5 6 tea "github.com/charmbracelet/bubbletea" 7 "github.com/wagoodman/go-partybus" 8 "github.com/wagoodman/go-progress" 9 10 "github.com/anchore/bubbly/bubbles/taskprogress" 11 "github.com/anchore/syft/internal/log" 12 syftEventParsers "github.com/anchore/syft/syft/event/parsers" 13 "github.com/anchore/syft/syft/pkg/cataloger" 14 ) 15 16 var _ progress.StagedProgressable = (*packageCatalogerProgressAdapter)(nil) 17 18 type packageCatalogerProgressAdapter struct { 19 monitor *cataloger.Monitor 20 monitors []progress.Monitorable 21 } 22 23 func newPackageCatalogerProgressAdapter(monitor *cataloger.Monitor) packageCatalogerProgressAdapter { 24 return packageCatalogerProgressAdapter{ 25 monitor: monitor, 26 monitors: []progress.Monitorable{ 27 monitor.FilesProcessed, 28 monitor.PackagesDiscovered, 29 }, 30 } 31 } 32 33 func (p packageCatalogerProgressAdapter) Stage() string { 34 return fmt.Sprintf("%d packages", p.monitor.PackagesDiscovered.Current()) 35 } 36 37 func (p packageCatalogerProgressAdapter) Current() int64 { 38 return p.monitor.PackagesDiscovered.Current() 39 } 40 41 func (p packageCatalogerProgressAdapter) Error() error { 42 completedMonitors := 0 43 for _, monitor := range p.monitors { 44 err := monitor.Error() 45 if err == nil { 46 continue 47 } 48 if progress.IsErrCompleted(err) { 49 completedMonitors++ 50 continue 51 } 52 // something went wrong 53 return err 54 } 55 if completedMonitors == len(p.monitors) && len(p.monitors) > 0 { 56 return p.monitors[0].Error() 57 } 58 return nil 59 } 60 61 func (p packageCatalogerProgressAdapter) Size() int64 { 62 // this is an inherently unknown value (indeterminate total number of packages to discover) 63 return -1 64 } 65 66 func (m *Handler) handlePackageCatalogerStarted(e partybus.Event) []tea.Model { 67 monitor, err := syftEventParsers.ParsePackageCatalogerStarted(e) 68 if err != nil { 69 log.WithFields("error", err).Warn("unable to parse event") 70 return nil 71 } 72 73 tsk := m.newTaskProgress( 74 taskprogress.Title{ 75 Default: "Catalog packages", 76 Running: "Cataloging packages", 77 Success: "Cataloged packages", 78 }, 79 taskprogress.WithStagedProgressable( 80 newPackageCatalogerProgressAdapter(monitor), 81 ), 82 ) 83 84 tsk.HideStageOnSuccess = false 85 86 return []tea.Model{tsk} 87 }