github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/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.PythonPipfileLockEntry, 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  		Metadata:  metadata,
    35  	}
    36  
    37  	p.SetID()
    38  
    39  	return p
    40  }
    41  
    42  func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, locations ...file.Location) pkg.Package {
    43  	p := pkg.Package{
    44  		Name:      name,
    45  		Version:   version,
    46  		Locations: file.NewLocationSet(locations...),
    47  		PURL:      packageURL(name, version, nil),
    48  		Language:  pkg.Python,
    49  		Type:      pkg.PythonPkg,
    50  		Metadata:  metadata,
    51  	}
    52  
    53  	p.SetID()
    54  
    55  	return p
    56  }
    57  
    58  func newPackageForPackage(m parsedData, sources ...file.Location) pkg.Package {
    59  	p := pkg.Package{
    60  		Name:      m.Name,
    61  		Version:   m.Version,
    62  		PURL:      packageURL(m.Name, m.Version, &m.PythonPackage),
    63  		Locations: file.NewLocationSet(sources...),
    64  		Licenses:  pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...),
    65  		Language:  pkg.Python,
    66  		Type:      pkg.PythonPkg,
    67  		Metadata:  m.PythonPackage,
    68  	}
    69  
    70  	p.SetID()
    71  
    72  	return p
    73  }
    74  
    75  func packageURL(name, version string, m *pkg.PythonPackage) string {
    76  	// generate a purl from the package data
    77  	pURL := packageurl.NewPackageURL(
    78  		packageurl.TypePyPi,
    79  		"",
    80  		name,
    81  		version,
    82  		purlQualifiersForPackage(m),
    83  		"")
    84  
    85  	return pURL.ToString()
    86  }
    87  
    88  func purlQualifiersForPackage(m *pkg.PythonPackage) packageurl.Qualifiers {
    89  	q := packageurl.Qualifiers{}
    90  	if m == nil {
    91  		return q
    92  	}
    93  	if m.DirectURLOrigin != nil {
    94  		q = append(q, vcsURLQualifierForPackage(m.DirectURLOrigin)...)
    95  	}
    96  	return q
    97  }
    98  
    99  func vcsURLQualifierForPackage(p *pkg.PythonDirectURLOriginInfo) packageurl.Qualifiers {
   100  	if p == nil || p.VCS == "" {
   101  		return nil
   102  	}
   103  	// Taken from https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst#known-qualifiers-keyvalue-pairs
   104  	// packageurl-go still doesn't support all qualifier names
   105  	return packageurl.Qualifiers{
   106  		{Key: pkg.PURLQualifierVCSURL, Value: fmt.Sprintf("%s+%s@%s", p.VCS, p.URL, p.CommitID)},
   107  	}
   108  }