github.com/quay/claircore@v1.5.28/libvuln/driver/updaterset.go (about) 1 package driver 2 3 import ( 4 "context" 5 "fmt" 6 "regexp" 7 ) 8 9 // ErrExists is an error returned if the updater 10 // already exists in the set. 11 type ErrExists struct { 12 Updater []string 13 } 14 15 func (e ErrExists) Error() string { 16 return fmt.Sprintf("reused names: %v", e.Updater) 17 } 18 19 // UpdaterSetFactory is used to construct updaters at run-time. 20 type UpdaterSetFactory interface { 21 UpdaterSet(context.Context) (UpdaterSet, error) 22 } 23 24 type UpdaterSetFactoryFunc func(context.Context) (UpdaterSet, error) 25 26 func (u UpdaterSetFactoryFunc) UpdaterSet(ctx context.Context) (UpdaterSet, error) { 27 return u(ctx) 28 } 29 30 // StaticSet creates an UpdaterSetFunc returning the provided set. 31 func StaticSet(s UpdaterSet) UpdaterSetFactory { 32 return UpdaterSetFactoryFunc(func(_ context.Context) (UpdaterSet, error) { 33 return s, nil 34 }) 35 } 36 37 // UpdaterSet holds a deduplicated set of updaters. 38 type UpdaterSet struct { 39 set map[string]Updater 40 } 41 42 // NewUpdaterSet returns an initialized UpdaterSet. 43 func NewUpdaterSet() UpdaterSet { 44 return UpdaterSet{ 45 set: map[string]Updater{}, 46 } 47 } 48 49 // Add will add an Updater to the set. 50 // 51 // An error will be reported if an updater with the same name already exists. 52 func (s *UpdaterSet) Add(u Updater) error { 53 if _, ok := s.set[u.Name()]; ok { 54 return ErrExists{[]string{u.Name()}} 55 } 56 57 s.set[u.Name()] = u 58 return nil 59 } 60 61 // Merge will merge the UpdaterSet provided as argument 62 // into the UpdaterSet provided as the function receiver. 63 // 64 // If an updater exists in the target set an error 65 // specifying which updaters could not be merged is returned. 66 func (s *UpdaterSet) Merge(set UpdaterSet) error { 67 exists := make([]string, 0, len(set.set)) 68 for n := range set.set { 69 if _, ok := s.set[n]; ok { 70 exists = append(exists, n) 71 } 72 } 73 74 if len(exists) > 0 { 75 return ErrExists{exists} 76 } 77 78 for n, u := range set.set { 79 s.set[n] = u 80 } 81 return nil 82 } 83 84 // Updaters returns the updaters within the set as slice. 85 func (s *UpdaterSet) Updaters() []Updater { 86 u := make([]Updater, 0, len(s.set)) 87 for _, v := range s.set { 88 u = append(u, v) 89 } 90 return u 91 } 92 93 // RegexFilter will remove any updaters from the set whose reported names do not 94 // match the provided regexp string. 95 func (s *UpdaterSet) RegexFilter(regex string) error { 96 re, err := regexp.Compile(regex) 97 if err != nil { 98 return fmt.Errorf("regex failed to compile: %v", err) 99 } 100 for name, u := range s.set { 101 if !re.MatchString(u.Name()) { 102 delete(s.set, name) 103 } 104 } 105 return nil 106 }