mirror of
https://github.com/anchore/syft.git
synced 2026-11-05 00:46:38 +01:00
Remove MetadataType from core package object and normalize JSON metadataType values (#1983)
* [wip] Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * distinct the package metadata functions Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * remove metadata type from package core model Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * incorporate review feedback for names Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add RPM archive metadata and split parser helpers Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * clarify the python package metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename the KB metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * break hackage and composer types by use case Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * linting fix Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix encoding and decoding for syft-json and cyclonedx Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump json schema to 11 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update cyclonedx-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update cyclonedx-xml snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update spdx-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update spdx-tv snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update syft-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * correct metadata type in stack yaml parser test Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix bom-ref redactor for cyclonedx-xml Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add tests for legacy package metadata names Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * regenerate json schema v11 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix legacy HackageMetadataType reflect type value check Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * packagemetadata discovery should account for type shadowing Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix cli tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump json schema version to v12 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update json schema to incorporate changes from main Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add syft-json legacy config option Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add tests around v11-v12 json decoding Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add docs for SYFT_JSON_LEGACY Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename structs to be compliant with new naming scheme Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -20,13 +20,12 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
name: "egg-file-no-version",
|
||||
fixtures: []string{"test-fixtures/no-version-py3.8.egg-info"},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "no-version",
|
||||
PURL: "pkg:pypi/no-version",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
Name: "no-version",
|
||||
PURL: "pkg:pypi/no-version",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "no-version",
|
||||
SitePackagesRootPath: "test-fixtures",
|
||||
},
|
||||
@@ -48,9 +47,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/egg-info/PKG-INFO")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "requests",
|
||||
Version: "2.22.0",
|
||||
Platform: "UNKNOWN",
|
||||
@@ -85,9 +83,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/casesensitive/EGG-INFO/PKG-INFO")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "requests",
|
||||
Version: "2.22.0",
|
||||
Platform: "UNKNOWN",
|
||||
@@ -123,9 +120,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/dist-info/METADATA")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "Pygments",
|
||||
Version: "2.6.1",
|
||||
Platform: "any",
|
||||
@@ -163,9 +159,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/casesensitive/DIST-INFO/METADATA")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "Pygments",
|
||||
Version: "2.6.1",
|
||||
Platform: "any",
|
||||
@@ -201,9 +196,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/malformed-record/dist-info/METADATA")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "Pygments",
|
||||
Version: "2.6.1",
|
||||
Platform: "any",
|
||||
@@ -233,9 +227,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/partial.dist-info/METADATA")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "Pygments",
|
||||
Version: "2.6.1",
|
||||
Platform: "any",
|
||||
@@ -257,9 +250,8 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/test.egg-info")),
|
||||
),
|
||||
FoundBy: "python-package-cataloger",
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: pkg.PythonPackageMetadata{
|
||||
FoundBy: "python-package-cataloger",
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "requests",
|
||||
Version: "2.22.0",
|
||||
Platform: "UNKNOWN",
|
||||
|
||||
@@ -23,16 +23,15 @@ func newPackageForIndex(name, version string, locations ...file.Location) pkg.Pa
|
||||
return p
|
||||
}
|
||||
|
||||
func newPackageForIndexWithMetadata(name, version string, metadata pkg.PythonPipfileLockMetadata, locations ...file.Location) pkg.Package {
|
||||
func newPackageForIndexWithMetadata(name, version string, metadata pkg.PythonPipfileLockEntry, locations ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(name, version, nil),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPipfileLockMetadataType,
|
||||
Metadata: metadata,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(name, version, nil),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
@@ -40,16 +39,15 @@ func newPackageForIndexWithMetadata(name, version string, metadata pkg.PythonPip
|
||||
return p
|
||||
}
|
||||
|
||||
func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsMetadata, locations ...file.Location) pkg.Package {
|
||||
func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, locations ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(name, version, nil),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: metadata,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(name, version, nil),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
@@ -59,15 +57,14 @@ func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.Py
|
||||
|
||||
func newPackageForPackage(m parsedData, sources ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: m.Name,
|
||||
Version: m.Version,
|
||||
PURL: packageURL(m.Name, m.Version, &m.PythonPackageMetadata),
|
||||
Locations: file.NewLocationSet(sources...),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPackageMetadataType,
|
||||
Metadata: m.PythonPackageMetadata,
|
||||
Name: m.Name,
|
||||
Version: m.Version,
|
||||
PURL: packageURL(m.Name, m.Version, &m.PythonPackage),
|
||||
Locations: file.NewLocationSet(sources...),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...),
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: m.PythonPackage,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
@@ -75,7 +72,7 @@ func newPackageForPackage(m parsedData, sources ...file.Location) pkg.Package {
|
||||
return p
|
||||
}
|
||||
|
||||
func packageURL(name, version string, m *pkg.PythonPackageMetadata) string {
|
||||
func packageURL(name, version string, m *pkg.PythonPackage) string {
|
||||
// generate a purl from the package data
|
||||
pURL := packageurl.NewPackageURL(
|
||||
packageurl.TypePyPi,
|
||||
@@ -88,7 +85,7 @@ func packageURL(name, version string, m *pkg.PythonPackageMetadata) string {
|
||||
return pURL.ToString()
|
||||
}
|
||||
|
||||
func purlQualifiersForPackage(m *pkg.PythonPackageMetadata) packageurl.Qualifiers {
|
||||
func purlQualifiersForPackage(m *pkg.PythonPackage) packageurl.Qualifiers {
|
||||
q := packageurl.Qualifiers{}
|
||||
if m == nil {
|
||||
return q
|
||||
|
||||
@@ -13,7 +13,7 @@ func Test_packageURL(t *testing.T) {
|
||||
testName string
|
||||
name string
|
||||
version string
|
||||
metadata *pkg.PythonPackageMetadata
|
||||
metadata *pkg.PythonPackage
|
||||
want string
|
||||
}{
|
||||
{
|
||||
@@ -26,7 +26,7 @@ func Test_packageURL(t *testing.T) {
|
||||
testName: "with vcs info",
|
||||
name: "name",
|
||||
version: "v0.1.0",
|
||||
metadata: &pkg.PythonPackageMetadata{
|
||||
metadata: &pkg.PythonPackage{
|
||||
Name: "bogus", // note: ignored
|
||||
Version: "v0.2.0", // note: ignored
|
||||
DirectURLOrigin: &pkg.PythonDirectURLOriginInfo{
|
||||
|
||||
@@ -65,7 +65,7 @@ func parsePipfileLock(_ file.Resolver, _ *generic.Environment, reader file.Locat
|
||||
index = "https://pypi.org/simple"
|
||||
}
|
||||
version := strings.TrimPrefix(pkgMeta.Version, "==")
|
||||
pkgs = append(pkgs, newPackageForIndexWithMetadata(name, version, pkg.PythonPipfileLockMetadata{Index: index, Hashes: pkgMeta.Hashes}, reader.Location))
|
||||
pkgs = append(pkgs, newPackageForIndexWithMetadata(name, version, pkg.PythonPipfileLockEntry{Index: index, Hashes: pkgMeta.Hashes}, reader.Location))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,13 @@ func TestParsePipFileLock(t *testing.T) {
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "aio-pika",
|
||||
Version: "6.8.0",
|
||||
PURL: "pkg:pypi/aio-pika@6.8.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPipfileLockMetadataType,
|
||||
Metadata: pkg.PythonPipfileLockMetadata{
|
||||
Name: "aio-pika",
|
||||
Version: "6.8.0",
|
||||
PURL: "pkg:pypi/aio-pika@6.8.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPipfileLockEntry{
|
||||
Index: "https://pypi.org/simple",
|
||||
Hashes: []string{
|
||||
"sha256:1d4305a5f78af3857310b4fe48348cdcf6c097e0e275ea88c2cd08570531a369",
|
||||
@@ -30,14 +29,13 @@ func TestParsePipFileLock(t *testing.T) {
|
||||
}},
|
||||
},
|
||||
{
|
||||
Name: "aiodns",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/aiodns@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPipfileLockMetadataType,
|
||||
Metadata: pkg.PythonPipfileLockMetadata{
|
||||
Name: "aiodns",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/aiodns@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPipfileLockEntry{
|
||||
Index: "https://test.pypi.org/simple",
|
||||
Hashes: []string{
|
||||
"sha256:815fdef4607474295d68da46978a54481dd1e7be153c7d60f9e72773cd38d77d",
|
||||
@@ -46,14 +44,13 @@ func TestParsePipFileLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "aiohttp",
|
||||
Version: "3.7.4.post0",
|
||||
PURL: "pkg:pypi/aiohttp@3.7.4.post0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPipfileLockMetadataType,
|
||||
Metadata: pkg.PythonPipfileLockMetadata{
|
||||
Name: "aiohttp",
|
||||
Version: "3.7.4.post0",
|
||||
PURL: "pkg:pypi/aiohttp@3.7.4.post0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPipfileLockEntry{
|
||||
Index: "https://pypi.org/simple",
|
||||
Hashes: []string{
|
||||
"sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe",
|
||||
@@ -62,14 +59,13 @@ func TestParsePipFileLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "aiohttp-jinja2",
|
||||
Version: "1.4.2",
|
||||
PURL: "pkg:pypi/aiohttp-jinja2@1.4.2",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonPipfileLockMetadataType,
|
||||
Metadata: pkg.PythonPipfileLockMetadata{
|
||||
Name: "aiohttp-jinja2",
|
||||
Version: "1.4.2",
|
||||
PURL: "pkg:pypi/aiohttp-jinja2@1.4.2",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonPipfileLockEntry{
|
||||
Index: "https://pypi.org/simple",
|
||||
Hashes: []string{
|
||||
"sha256:860da7582efa866744bad5883947557d0f82e457d69903ea65d666b66f8a69ca",
|
||||
|
||||
@@ -141,7 +141,7 @@ func (rp requirementsParser) parseRequirementsTxt(_ file.Resolver, _ *generic.En
|
||||
newPackageForRequirementsWithMetadata(
|
||||
name,
|
||||
version,
|
||||
pkg.PythonRequirementsMetadata{
|
||||
pkg.PythonRequirementsEntry{
|
||||
Name: name,
|
||||
Extras: parseExtras(req.Name),
|
||||
VersionConstraint: req.VersionConstraint,
|
||||
|
||||
@@ -17,94 +17,87 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
|
||||
pinnedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "flask",
|
||||
Version: "4.0.0",
|
||||
PURL: "pkg:pypi/flask@4.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "flask",
|
||||
Version: "4.0.0",
|
||||
PURL: "pkg:pypi/flask@4.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "flask",
|
||||
VersionConstraint: "== 4.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:pypi/foo@1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "foo",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:pypi/foo@1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "foo",
|
||||
VersionConstraint: "== 1.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "SomeProject",
|
||||
Version: "5.4",
|
||||
PURL: "pkg:pypi/SomeProject@5.4",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "SomeProject",
|
||||
Version: "5.4",
|
||||
PURL: "pkg:pypi/SomeProject@5.4",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "SomeProject",
|
||||
VersionConstraint: "==5.4",
|
||||
Markers: "python_version < '3.8'",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "argh",
|
||||
Version: "0.26.2",
|
||||
PURL: "pkg:pypi/argh@0.26.2",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "argh",
|
||||
Version: "0.26.2",
|
||||
PURL: "pkg:pypi/argh@0.26.2",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "argh",
|
||||
VersionConstraint: "==0.26.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "argh",
|
||||
Version: "0.26.3",
|
||||
PURL: "pkg:pypi/argh@0.26.3",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "argh",
|
||||
Version: "0.26.3",
|
||||
PURL: "pkg:pypi/argh@0.26.3",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "argh",
|
||||
VersionConstraint: "==0.26.3",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "celery",
|
||||
Version: "4.4.7",
|
||||
PURL: "pkg:pypi/celery@4.4.7",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "celery",
|
||||
Version: "4.4.7",
|
||||
PURL: "pkg:pypi/celery@4.4.7",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "celery",
|
||||
Extras: []string{"redis", "pytest"},
|
||||
VersionConstraint: "== 4.4.7",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GithubSampleProject",
|
||||
Version: "3.7.1",
|
||||
PURL: "pkg:pypi/GithubSampleProject@3.7.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "GithubSampleProject",
|
||||
Version: "3.7.1",
|
||||
PURL: "pkg:pypi/GithubSampleProject@3.7.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "GithubSampleProject",
|
||||
VersionConstraint: "== 3.7.1",
|
||||
URL: "git+https://github.com/owner/repo@releases/tag/v3.7.1",
|
||||
@@ -135,67 +128,62 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
},
|
||||
expectedPkgs: append([]pkg.Package{
|
||||
{
|
||||
Name: "Mopidy-Dirble",
|
||||
Version: "1.1",
|
||||
PURL: "pkg:pypi/Mopidy-Dirble@1.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "Mopidy-Dirble",
|
||||
Version: "1.1",
|
||||
PURL: "pkg:pypi/Mopidy-Dirble@1.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "Mopidy-Dirble",
|
||||
VersionConstraint: "~= 1.1",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "sqlalchemy",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/sqlalchemy@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "sqlalchemy",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/sqlalchemy@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "sqlalchemy",
|
||||
VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/bar@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "bar",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:pypi/bar@2.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "bar",
|
||||
VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "numpy",
|
||||
Version: "3.4.1",
|
||||
PURL: "pkg:pypi/numpy@3.4.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "numpy",
|
||||
Version: "3.4.1",
|
||||
PURL: "pkg:pypi/numpy@3.4.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "numpy",
|
||||
VersionConstraint: ">= 3.4.1",
|
||||
Markers: `sys_platform == 'win32'`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "requests",
|
||||
Version: "2.8.0",
|
||||
PURL: "pkg:pypi/requests@2.8.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
MetadataType: pkg.PythonRequirementsMetadataType,
|
||||
Metadata: pkg.PythonRequirementsMetadata{
|
||||
Name: "requests",
|
||||
Version: "2.8.0",
|
||||
PURL: "pkg:pypi/requests@2.8.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "requests",
|
||||
Extras: []string{"security"},
|
||||
VersionConstraint: "== 2.8.*",
|
||||
|
||||
@@ -15,7 +15,8 @@ import (
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
// parseWheelOrEgg takes the primary metadata file reference and returns the python package it represents.
|
||||
// parseWheelOrEgg takes the primary metadata file reference and returns the python package it represents. Contained
|
||||
// fields are governed by the PyPA core metadata specification (https://packaging.python.org/en/latest/specifications/core-metadata/).
|
||||
func parseWheelOrEgg(resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
pd, sources, err := assembleEggOrWheelMetadata(resolver, reader.Location)
|
||||
if err != nil {
|
||||
@@ -125,6 +126,27 @@ func fetchTopLevelPackages(resolver file.Resolver, metadataLocation file.Locatio
|
||||
return pkgs, sources, nil
|
||||
}
|
||||
|
||||
type directURLOrigin struct {
|
||||
URL string `json:"url"`
|
||||
VCSInfo vcsInfo `json:"vcs_info"`
|
||||
ArchiveInfo archiveInfo `json:"archive_info"`
|
||||
DirInfo dirInfo `json:"dir_info"`
|
||||
}
|
||||
|
||||
type dirInfo struct {
|
||||
Editable bool `json:"editable"`
|
||||
}
|
||||
|
||||
type archiveInfo struct {
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
type vcsInfo struct {
|
||||
CommitID string `json:"commit_id"`
|
||||
VCS string `json:"vcs"`
|
||||
RequestedRevision string `json:"requested_revision"`
|
||||
}
|
||||
|
||||
func fetchDirectURLData(resolver file.Resolver, metadataLocation file.Location) (d *pkg.PythonDirectURLOriginInfo, sources []file.Location, err error) {
|
||||
parentDir := filepath.Dir(metadataLocation.RealPath)
|
||||
directURLPath := filepath.Join(parentDir, "direct_url.json")
|
||||
@@ -147,7 +169,7 @@ func fetchDirectURLData(resolver file.Resolver, metadataLocation file.Location)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var directURLJson pkg.DirectURLOrigin
|
||||
var directURLJson directURLOrigin
|
||||
if err := json.Unmarshal(buffer, &directURLJson); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ import (
|
||||
)
|
||||
|
||||
type parsedData struct {
|
||||
Licenses string `mapstructure:"License"`
|
||||
LicenseLocation file.Location
|
||||
pkg.PythonPackageMetadata `mapstructure:",squash"`
|
||||
Licenses string `mapstructure:"License"`
|
||||
LicenseLocation file.Location
|
||||
pkg.PythonPackage `mapstructure:",squash"`
|
||||
}
|
||||
|
||||
// parseWheelOrEggMetadata takes a Python Egg or Wheel (which share the same format and values for our purposes),
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestParseWheelEggMetadata(t *testing.T) {
|
||||
ExpectedMetadata: parsedData{
|
||||
"Apache 2.0",
|
||||
file.NewLocation("test-fixtures/egg-info/PKG-INFO"),
|
||||
pkg.PythonPackageMetadata{
|
||||
pkg.PythonPackage{
|
||||
Name: "requests",
|
||||
Version: "2.22.0",
|
||||
Platform: "UNKNOWN",
|
||||
@@ -35,7 +35,7 @@ func TestParseWheelEggMetadata(t *testing.T) {
|
||||
ExpectedMetadata: parsedData{
|
||||
"BSD License",
|
||||
file.NewLocation("test-fixtures/dist-info/METADATA"),
|
||||
pkg.PythonPackageMetadata{
|
||||
pkg.PythonPackage{
|
||||
Name: "Pygments",
|
||||
Version: "2.6.1",
|
||||
Platform: "any",
|
||||
@@ -136,7 +136,7 @@ func TestParseWheelEggMetadataInvalid(t *testing.T) {
|
||||
ExpectedMetadata: parsedData{
|
||||
"",
|
||||
file.Location{},
|
||||
pkg.PythonPackageMetadata{
|
||||
pkg.PythonPackage{
|
||||
Name: "mxnet",
|
||||
Version: "1.8.0",
|
||||
SitePackagesRootPath: "test-fixtures",
|
||||
|
||||
Reference in New Issue
Block a user