github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/python/package.go (about)

     1  package python
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/anchore/packageurl-go"
     7  	"github.com/anchore/syft/syft/file"
     8  	"github.com/anchore/syft/syft/pkg"
     9  )
    10  
    11  func newPackageForIndex(name, version string, locations ...file.Location) pkg.Package {
    12  	p := pkg.Package{
    13  		Name:      name,
    14  		Version:   version,
    15  		Locations: file.NewLocationSet(locations...),
    16  		PURL:      packageURL(name, version, nil),
    17  		Language:  pkg.Python,
    18  		Type:      pkg.PythonPkg,
    19  	}
    20  
    21  	p.SetID()
    22  
    23  	return p
    24  }
    25  
    26  func newPackageForIndexWithMetadata(name, version string, metadata pkg.PythonPipfileLockMetadata, locations ...file.Location) pkg.Package {
    27  	p := pkg.Package{
    28  		Name:         name,
    29  		Version:      version,
    30  		Locations:    file.NewLocationSet(locations...),
    31  		PURL:         packageURL(name, version, nil),
    32  		Language:     pkg.Python,
    33  		Type:         pkg.PythonPkg,
    34  		MetadataType: pkg.PythonPipfileLockMetadataType,
    35  		Metadata:     metadata,
    36  	}
    37  
    38  	p.SetID()
    39  
    40  	return p
    41  }
    42  
    43  func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsMetadata, locations ...file.Location) pkg.Package {
    44  	p := pkg.Package{
    45  		Name:         name,
    46  		Version:      version,
    47  		Locations:    file.NewLocationSet(locations...),
    48  		PURL:         packageURL(name, version, nil),
    49  		Language:     pkg.Python,
    50  		Type:         pkg.PythonPkg,
    51  		MetadataType: pkg.PythonRequirementsMetadataType,
    52  		Metadata:     metadata,
    53  	}
    54  
    55  	p.SetID()
    56  
    57  	return p
    58  }
    59  
    60  func newPackageForPackage(m parsedData, sources ...file.Location) pkg.Package {
    61  	p := pkg.Package{
    62  		Name:         m.Name,
    63  		Version:      m.Version,
    64  		PURL:         packageURL(m.Name, m.Version, &m.PythonPackageMetadata),
    65  		Locations:    file.NewLocationSet(sources...),
    66  		Licenses:     pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...),
    67  		Language:     pkg.Python,
    68  		Type:         pkg.PythonPkg,
    69  		MetadataType: pkg.PythonPackageMetadataType,
    70  		Metadata:     m.PythonPackageMetadata,
    71  	}
    72  
    73  	p.SetID()
    74  
    75  	return p
    76  }
    77  
    78  func packageURL(name, version string, m *pkg.PythonPackageMetadata) string {
    79  	// generate a purl from the package data
    80  	pURL := packageurl.NewPackageURL(
    81  		packageurl.TypePyPi,
    82  		"",
    83  		name,
    84  		version,
    85  		purlQualifiersForPackage(m),
    86  		"")
    87  
    88  	return pURL.ToString()
    89  }
    90  
    91  func purlQualifiersForPackage(m *pkg.PythonPackageMetadata) packageurl.Qualifiers {
    92  	q := packageurl.Qualifiers{}
    93  	if m == nil {
    94  		return q
    95  	}
    96  	if m.DirectURLOrigin != nil {
    97  		q = append(q, vcsURLQualifierForPackage(m.DirectURLOrigin)...)
    98  	}
    99  	return q
   100  }
   101  
   102  func vcsURLQualifierForPackage(p *pkg.PythonDirectURLOriginInfo) packageurl.Qualifiers {
   103  	if p == nil || p.VCS == "" {
   104  		return nil
   105  	}
   106  	// Taken from https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs
   107  	// packageurl-go still doesn't support all qualifier names
   108  	return packageurl.Qualifiers{
   109  		{Key: pkg.PURLQualifierVCSURL, Value: fmt.Sprintf("%s+%s@%s", p.VCS, p.URL, p.CommitID)},
   110  	}
   111  }