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  }