github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/internal/task/task.go (about) 1 package task 2 3 import ( 4 "context" 5 "fmt" 6 "sort" 7 8 "github.com/scylladb/go-set/strset" 9 10 "github.com/anchore/syft/internal/sbomsync" 11 "github.com/anchore/syft/syft/file" 12 ) 13 14 var _ interface { 15 Task 16 Selector 17 } = (*task)(nil) 18 19 // Task is a function that can wrap a cataloger to populate the SBOM with data (coordinated through the mutex). 20 type Task interface { 21 Name() string 22 Execute(context.Context, file.Resolver, sbomsync.Builder) error 23 } 24 25 type Selector interface { 26 HasAllSelectors(...string) bool 27 Selectors() []string 28 } 29 30 type tasks []Task 31 32 type task struct { 33 name string 34 selectors *strset.Set 35 task func(context.Context, file.Resolver, sbomsync.Builder) error 36 } 37 38 func NewTask(name string, tsk func(context.Context, file.Resolver, sbomsync.Builder) error, tags ...string) Task { 39 if tsk == nil { 40 panic(fmt.Errorf("task cannot be nil")) 41 } 42 tags = append(tags, name) 43 return &task{ 44 name: name, 45 selectors: strset.New(tags...), 46 task: tsk, 47 } 48 } 49 50 func (t task) HasAllSelectors(ids ...string) bool { 51 // tags or name 52 return t.selectors.Has(ids...) 53 } 54 55 func (t task) Selectors() []string { 56 return t.selectors.List() 57 } 58 59 func (t task) Name() string { 60 return t.name 61 } 62 63 func (t task) Execute(ctx context.Context, resolver file.Resolver, sbom sbomsync.Builder) error { 64 return t.task(ctx, resolver, sbom) 65 } 66 67 func (ts tasks) Names() []string { 68 var names []string 69 for _, td := range ts { 70 names = append(names, td.Name()) 71 } 72 return names 73 } 74 75 func (ts tasks) Tags() []string { 76 tags := strset.New() 77 for _, td := range ts { 78 if s, ok := td.(Selector); ok { 79 tags.Add(s.Selectors()...) 80 } 81 82 tags.Remove(td.Name()) 83 } 84 85 tagsList := tags.List() 86 sort.Strings(tagsList) 87 88 return tagsList 89 }