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

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