github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/file/cataloger/filemetadata/cataloger.go (about) 1 package filemetadata 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/dustin/go-humanize" 8 9 "github.com/anchore/syft/internal/bus" 10 "github.com/anchore/syft/internal/log" 11 "github.com/anchore/syft/syft/event/monitor" 12 "github.com/anchore/syft/syft/file" 13 ) 14 15 type Cataloger struct { 16 } 17 18 func NewCataloger() *Cataloger { 19 return &Cataloger{} 20 } 21 22 func (i *Cataloger) Catalog(ctx context.Context, resolver file.Resolver, coordinates ...file.Coordinates) (map[file.Coordinates]file.Metadata, error) { 23 results := make(map[file.Coordinates]file.Metadata) 24 var locations <-chan file.Location 25 ctx, cancel := context.WithCancel(ctx) 26 defer cancel() 27 if len(coordinates) == 0 { 28 locations = resolver.AllLocations(ctx) 29 } else { 30 locations = func() <-chan file.Location { 31 ch := make(chan file.Location) 32 go func() { 33 defer close(ch) 34 for _, c := range coordinates { 35 locs, err := resolver.FilesByPath(c.RealPath) 36 if err != nil { 37 log.Warn("unable to get file locations for path %q: %w", c.RealPath, err) 38 continue 39 } 40 for _, loc := range locs { 41 select { 42 case <-ctx.Done(): 43 return 44 case ch <- loc: 45 continue 46 } 47 } 48 } 49 }() 50 return ch 51 }() 52 } 53 54 prog := catalogingProgress(-1) 55 for location := range locations { 56 prog.AtomicStage.Set(location.Path()) 57 58 metadata, err := resolver.FileMetadataByLocation(location) 59 if err != nil { 60 prog.SetError(err) 61 return nil, err 62 } 63 64 prog.Increment() 65 66 results[location.Coordinates] = metadata 67 } 68 69 log.Debugf("file metadata cataloger processed %d files", prog.Current()) 70 71 prog.AtomicStage.Set(fmt.Sprintf("%s locations", humanize.Comma(prog.Current()))) 72 prog.SetCompleted() 73 74 return results, nil 75 } 76 77 func catalogingProgress(locations int64) *monitor.CatalogerTaskProgress { 78 info := monitor.GenericTask{ 79 Title: monitor.Title{ 80 Default: "File metadata", 81 }, 82 ParentID: monitor.TopLevelCatalogingTaskID, 83 } 84 85 return bus.StartCatalogerTask(info, locations, "") 86 }