github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/sbom/cataloger.go (about)

     1  package sbom
     2  
     3  import (
     4  	"github.com/nextlinux/gosbom/gosbom/artifact"
     5  	"github.com/nextlinux/gosbom/gosbom/file"
     6  	"github.com/nextlinux/gosbom/gosbom/formats"
     7  	"github.com/nextlinux/gosbom/gosbom/pkg"
     8  	"github.com/nextlinux/gosbom/gosbom/pkg/cataloger/generic"
     9  	"github.com/nextlinux/gosbom/internal/log"
    10  )
    11  
    12  const catalogerName = "sbom-cataloger"
    13  
    14  // NewSBOMCataloger returns a new SBOM cataloger object loaded from saved SBOM JSON.
    15  func NewSBOMCataloger() *generic.Cataloger {
    16  	return generic.NewCataloger(catalogerName).
    17  		WithParserByGlobs(parseSBOM,
    18  			"**/*.gosbom.json",
    19  			"**/*.bom.*",
    20  			"**/*.bom",
    21  			"**/bom",
    22  			"**/*.sbom.*",
    23  			"**/*.sbom",
    24  			"**/sbom",
    25  			"**/*.cdx.*",
    26  			"**/*.cdx",
    27  			"**/*.spdx.*",
    28  			"**/*.spdx",
    29  		)
    30  }
    31  
    32  func parseSBOM(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
    33  	s, _, err := formats.Decode(reader)
    34  	if err != nil {
    35  		return nil, nil, err
    36  	}
    37  
    38  	if s == nil {
    39  		log.WithFields("path", reader.Location.RealPath).Trace("file is not an SBOM")
    40  		return nil, nil, nil
    41  	}
    42  
    43  	var pkgs []pkg.Package
    44  	relationships := s.Relationships
    45  	for _, p := range s.Artifacts.Packages.Sorted() {
    46  		// replace all locations on the package with the location of the SBOM file.
    47  		// Why not keep the original list of locations? Since the "locations" field is meant to capture
    48  		// where there is evidence of this file, and the catalogers have not run against any file other than,
    49  		// the SBOM, this is the only location that is relevant for this cataloger.
    50  		p.Locations = file.NewLocationSet(
    51  			reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
    52  		)
    53  		p.FoundBy = catalogerName
    54  
    55  		pkgs = append(pkgs, p)
    56  		relationships = append(relationships, artifact.Relationship{
    57  			From: p,
    58  			To:   reader.Location.Coordinates,
    59  			Type: artifact.DescribedByRelationship,
    60  		})
    61  	}
    62  
    63  	return pkgs, relationships, nil
    64  }