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