From 649d152548a609806dc60b4a1b952c050d2b43ed Mon Sep 17 00:00:00 2001 From: Colm O hEigeartaigh Date: Thu, 14 Dec 2023 17:41:41 +0000 Subject: [PATCH] Parse Python licenses from LicenseExpression entry in the Wheel Metadata (#2431) Signed-off-by: Colm O hEigeartaigh --- syft/pkg/cataloger/python/package.go | 9 +++++++-- syft/pkg/cataloger/python/parse_wheel_egg_metadata.go | 3 ++- .../cataloger/python/parse_wheel_egg_metadata_test.go | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/python/package.go b/syft/pkg/cataloger/python/package.go index 76c092a052a..7e6f39a22fa 100644 --- a/syft/pkg/cataloger/python/package.go +++ b/syft/pkg/cataloger/python/package.go @@ -59,9 +59,13 @@ func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.Py func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.Location) pkg.Package { var licenseSet pkg.LicenseSet - if m.Licenses != "" { + + switch { + case m.LicenseExpression != "": + licenseSet = pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.LicenseExpression)...) + case m.Licenses != "": licenseSet = pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...) - } else if m.LicenseLocation.Path() != "" { + case m.LicenseLocation.Path() != "": // If we have a license file then resolve and parse it found, err := resolver.FilesByPath(m.LicenseLocation.Path()) if err != nil { @@ -82,6 +86,7 @@ func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file. } } } + p := pkg.Package{ Name: m.Name, Version: m.Version, diff --git a/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go b/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go index 81910483dab..4522dd45296 100644 --- a/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go +++ b/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go @@ -18,6 +18,7 @@ import ( type parsedData struct { Licenses string `mapstructure:"License"` LicenseFile string `mapstructure:"LicenseFile"` + LicenseExpression string `mapstructure:"LicenseExpression"` LicenseLocation file.Location pkg.PythonPackage `mapstructure:",squash"` } @@ -81,7 +82,7 @@ func parseWheelOrEggMetadata(path string, reader io.Reader) (parsedData, error) // add additional metadata not stored in the egg/wheel metadata file pd.SitePackagesRootPath = determineSitePackagesRootPath(path) - if pd.Licenses != "" { + if pd.Licenses != "" || pd.LicenseExpression != "" { pd.LicenseLocation = file.NewLocation(path) } else if pd.LicenseFile != "" { pd.LicenseLocation = file.NewLocation(filepath.Join(filepath.Dir(path), pd.LicenseFile)) diff --git a/syft/pkg/cataloger/python/parse_wheel_egg_metadata_test.go b/syft/pkg/cataloger/python/parse_wheel_egg_metadata_test.go index e661dc5796e..0c048b3a327 100644 --- a/syft/pkg/cataloger/python/parse_wheel_egg_metadata_test.go +++ b/syft/pkg/cataloger/python/parse_wheel_egg_metadata_test.go @@ -20,6 +20,7 @@ func TestParseWheelEggMetadata(t *testing.T) { ExpectedMetadata: parsedData{ "Apache 2.0", "", + "", file.NewLocation("test-fixtures/egg-info/PKG-INFO"), pkg.PythonPackage{ Name: "requests", @@ -36,6 +37,7 @@ func TestParseWheelEggMetadata(t *testing.T) { ExpectedMetadata: parsedData{ "BSD License", "", + "", file.NewLocation("test-fixtures/dist-info/METADATA"), pkg.PythonPackage{ Name: "Pygments", @@ -136,6 +138,7 @@ func TestParseWheelEggMetadataInvalid(t *testing.T) { { Fixture: "test-fixtures/egg-info/PKG-INFO-INVALID", ExpectedMetadata: parsedData{ + "", "", "", file.Location{},