github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/file/cataloger/filemetadata/cataloger.go (about)

     1  package filemetadata
     2  
     3  import (
     4  	"github.com/wagoodman/go-partybus"
     5  	"github.com/wagoodman/go-progress"
     6  
     7  	"github.com/anchore/syft/syft/event"
     8  	"github.com/anchore/syft/syft/file"
     9  	"github.com/lineaje-labs/syft/internal/bus"
    10  	"github.com/lineaje-labs/syft/internal/log"
    11  )
    12  
    13  type Cataloger struct {
    14  }
    15  
    16  func NewCataloger() *Cataloger {
    17  	return &Cataloger{}
    18  }
    19  
    20  func (i *Cataloger) Catalog(
    21  	resolver file.Resolver, coordinates ...file.Coordinates,
    22  ) (map[file.Coordinates]file.Metadata, error) {
    23  	results := make(map[file.Coordinates]file.Metadata)
    24  	var locations <-chan file.Location
    25  
    26  	if len(coordinates) == 0 {
    27  		locations = resolver.AllLocations()
    28  	} else {
    29  		locations = func() <-chan file.Location {
    30  			ch := make(chan file.Location)
    31  			go func() {
    32  				defer close(ch)
    33  				for _, c := range coordinates {
    34  					locs, err := resolver.FilesByPath(c.RealPath)
    35  					if err != nil {
    36  						log.Warn("unable to get file locations for path %q: %w", c.RealPath, err)
    37  						continue
    38  					}
    39  					for _, loc := range locs {
    40  						ch <- loc
    41  					}
    42  				}
    43  			}()
    44  			return ch
    45  		}()
    46  	}
    47  
    48  	stage, prog := metadataCatalogingProgress(int64(len(locations)))
    49  	for location := range locations {
    50  		stage.Current = location.RealPath
    51  		metadata, err := resolver.FileMetadataByLocation(location)
    52  		if err != nil {
    53  			return nil, err
    54  		}
    55  
    56  		results[location.Coordinates] = metadata
    57  		prog.Increment()
    58  	}
    59  	log.Debugf("file metadata cataloger processed %d files", prog.Current())
    60  	prog.SetCompleted()
    61  	return results, nil
    62  }
    63  
    64  func metadataCatalogingProgress(locations int64) (*progress.Stage, *progress.Manual) {
    65  	stage := &progress.Stage{}
    66  	prog := progress.NewManual(locations)
    67  
    68  	bus.Publish(partybus.Event{
    69  		Type: event.FileMetadataCatalogerStarted,
    70  		Value: struct {
    71  			progress.Stager
    72  			progress.Progressable
    73  		}{
    74  			Stager:       progress.Stager(stage),
    75  			Progressable: prog,
    76  		},
    77  	})
    78  
    79  	return stage, prog
    80  }