mirror of
https://github.com/anchore/syft.git
synced 2026-10-31 22:46:36 +01:00
feat: update syft license concept to complex struct (#1743)
this PR makes the following changes to update the underlying license model to have more expressive capabilities it also provides some guarantee's surrounding the license values themselves - Licenses are updated from string -> pkg.LicenseSet which contain pkg.License with the following fields: - original `Value` read by syft - If it's possible to construct licenses will always have a valid SPDX expression for downstream consumption - the above is run against a generated list of SPDX license ID to try and find the correct ID - SPDX concluded vs declared is added to the new struct - URL source for license is added to the new struct - Location source is added to the new struct to show where the expression was pulled from
This commit is contained in:
@@ -12,14 +12,16 @@ func Test_JavascriptCataloger(t *testing.T) {
|
||||
locationSet := source.NewLocationSet(source.NewLocation("package-lock.json"))
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "@actions/core",
|
||||
Version: "1.6.0",
|
||||
FoundBy: "javascript-lock-cataloger",
|
||||
PURL: "pkg:npm/%40actions/core@1.6.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "@actions/core",
|
||||
Version: "1.6.0",
|
||||
FoundBy: "javascript-lock-cataloger",
|
||||
PURL: "pkg:npm/%40actions/core@1.6.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation("package-lock.json")),
|
||||
),
|
||||
MetadataType: pkg.NpmPackageLockJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="},
|
||||
},
|
||||
@@ -35,14 +37,16 @@ func Test_JavascriptCataloger(t *testing.T) {
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="},
|
||||
},
|
||||
{
|
||||
Name: "cowsay",
|
||||
Version: "1.4.0",
|
||||
FoundBy: "javascript-lock-cataloger",
|
||||
PURL: "pkg:npm/cowsay@1.4.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "cowsay",
|
||||
Version: "1.4.0",
|
||||
FoundBy: "javascript-lock-cataloger",
|
||||
PURL: "pkg:npm/cowsay@1.4.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation("package-lock.json")),
|
||||
),
|
||||
MetadataType: pkg.NpmPackageLockJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="},
|
||||
},
|
||||
|
||||
@@ -12,30 +12,30 @@ import (
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func newPackageJSONPackage(u packageJSON, locations ...source.Location) pkg.Package {
|
||||
licenses, err := u.licensesFromJSON()
|
||||
func newPackageJSONPackage(u packageJSON, indexLocation source.Location) pkg.Package {
|
||||
licenseCandidates, err := u.licensesFromJSON()
|
||||
if err != nil {
|
||||
log.Warnf("unable to extract licenses from javascript package.json: %+v", err)
|
||||
}
|
||||
|
||||
license := pkg.NewLicensesFromLocation(indexLocation, licenseCandidates...)
|
||||
p := pkg.Package{
|
||||
Name: u.Name,
|
||||
Version: u.Version,
|
||||
Licenses: licenses,
|
||||
PURL: packageURL(u.Name, u.Version),
|
||||
Locations: source.NewLocationSet(locations...),
|
||||
Locations: source.NewLocationSet(indexLocation),
|
||||
Language: pkg.JavaScript,
|
||||
Licenses: pkg.NewLicenseSet(license...),
|
||||
Type: pkg.NpmPkg,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
Name: u.Name,
|
||||
Version: u.Version,
|
||||
Description: u.Description,
|
||||
Author: u.Author.AuthorString(),
|
||||
Homepage: u.Homepage,
|
||||
URL: u.Repository.URL,
|
||||
Licenses: licenses,
|
||||
Private: u.Private,
|
||||
Description: u.Description,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -77,12 +77,6 @@ func newPackageLockV1Package(resolver source.FileResolver, location source.Locat
|
||||
}
|
||||
|
||||
func newPackageLockV2Package(resolver source.FileResolver, location source.Location, name string, u lockPackage) pkg.Package {
|
||||
var licenses []string
|
||||
|
||||
if u.License != nil {
|
||||
licenses = u.License
|
||||
}
|
||||
|
||||
return finalizeLockPkg(
|
||||
resolver,
|
||||
location,
|
||||
@@ -90,10 +84,10 @@ func newPackageLockV2Package(resolver source.FileResolver, location source.Locat
|
||||
Name: name,
|
||||
Version: u.Version,
|
||||
Locations: source.NewLocationSet(location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(location, u.License...)...),
|
||||
PURL: packageURL(name, u.Version),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: licenses,
|
||||
MetadataType: pkg.NpmPackageLockJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: u.Resolved, Integrity: u.Integrity},
|
||||
},
|
||||
@@ -131,7 +125,8 @@ func newYarnLockPackage(resolver source.FileResolver, location source.Location,
|
||||
}
|
||||
|
||||
func finalizeLockPkg(resolver source.FileResolver, location source.Location, p pkg.Package) pkg.Package {
|
||||
p.Licenses = append(p.Licenses, addLicenses(p.Name, resolver, location)...)
|
||||
licenseCandidate := addLicenses(p.Name, resolver, location)
|
||||
p.Licenses.Add(pkg.NewLicensesFromLocation(location, licenseCandidate...)...)
|
||||
p.SetID()
|
||||
return p
|
||||
}
|
||||
@@ -140,13 +135,13 @@ func addLicenses(name string, resolver source.FileResolver, location source.Loca
|
||||
if resolver == nil {
|
||||
return allLicenses
|
||||
}
|
||||
|
||||
dir := path.Dir(location.RealPath)
|
||||
pkgPath := []string{dir, "node_modules"}
|
||||
pkgPath = append(pkgPath, strings.Split(name, "/")...)
|
||||
pkgPath = append(pkgPath, "package.json")
|
||||
pkgFile := path.Join(pkgPath...)
|
||||
locations, err := resolver.FilesByPath(pkgFile)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("an error occurred attempting to read: %s - %+v", pkgFile, err)
|
||||
return allLicenses
|
||||
|
||||
@@ -140,7 +140,7 @@ func (r *repository) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type license struct {
|
||||
type npmPackageLicense struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func licenseFromJSON(b []byte) (string, error) {
|
||||
}
|
||||
|
||||
// then try as object (this format is deprecated)
|
||||
var licenseObject license
|
||||
var licenseObject npmPackageLicense
|
||||
err = json.Unmarshal(b, &licenseObject)
|
||||
if err == nil {
|
||||
return licenseObject.Type, nil
|
||||
@@ -178,7 +178,7 @@ func (p packageJSON) licensesFromJSON() ([]string, error) {
|
||||
|
||||
// The "licenses" field is deprecated. It should be inspected as a last resort.
|
||||
if multiLicense != nil && err == nil {
|
||||
mapLicenses := func(licenses []license) []string {
|
||||
mapLicenses := func(licenses []npmPackageLicense) []string {
|
||||
mappedLicenses := make([]string, len(licenses))
|
||||
for i, l := range licenses {
|
||||
mappedLicenses[i] = l.Type
|
||||
@@ -192,8 +192,8 @@ func (p packageJSON) licensesFromJSON() ([]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func licensesFromJSON(b []byte) ([]license, error) {
|
||||
var licenseObject []license
|
||||
func licensesFromJSON(b []byte) ([]npmPackageLicense, error) {
|
||||
var licenseObject []npmPackageLicense
|
||||
err := json.Unmarshal(b, &licenseObject)
|
||||
if err == nil {
|
||||
return licenseObject, nil
|
||||
|
||||
@@ -18,12 +18,14 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Language: pkg.JavaScript,
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Language: pkg.JavaScript,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Artistic-2.0", source.NewLocation("test-fixtures/pkg-json/package.json")),
|
||||
),
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
Name: "npm",
|
||||
@@ -31,7 +33,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -39,12 +40,14 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package-license-object.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"ISC"},
|
||||
Language: pkg.JavaScript,
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Language: pkg.JavaScript,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("ISC", source.NewLocation("test-fixtures/pkg-json/package-license-object.json")),
|
||||
),
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
Name: "npm",
|
||||
@@ -52,7 +55,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{"ISC"},
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -60,11 +62,14 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package-license-objects.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT", "Apache-2.0"},
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation("test-fixtures/pkg-json/package-license-objects.json")),
|
||||
pkg.NewLicenseFromLocations("Apache-2.0", source.NewLocation("test-fixtures/pkg-json/package-license-objects.json")),
|
||||
),
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -73,7 +78,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{"MIT", "Apache-2.0"},
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -85,7 +89,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: nil,
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -94,7 +97,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: nil,
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -106,7 +108,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{},
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -115,7 +116,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{},
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -123,11 +123,13 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package-nested-author.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Artistic-2.0", source.NewLocation("test-fixtures/pkg-json/package-nested-author.json")),
|
||||
),
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -136,7 +138,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
},
|
||||
@@ -144,11 +145,13 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package-repo-string.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "function-bind",
|
||||
Version: "1.1.1",
|
||||
PURL: "pkg:npm/function-bind@1.1.1",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "function-bind",
|
||||
Version: "1.1.1",
|
||||
PURL: "pkg:npm/function-bind@1.1.1",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation("test-fixtures/pkg-json/package-repo-string.json")),
|
||||
),
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -157,7 +160,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Raynos <raynos2@gmail.com>",
|
||||
Homepage: "https://github.com/Raynos/function-bind",
|
||||
URL: "git://github.com/Raynos/function-bind.git",
|
||||
Licenses: []string{"MIT"},
|
||||
Description: "Implementation of Function.prototype.bind",
|
||||
},
|
||||
},
|
||||
@@ -165,11 +167,13 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
{
|
||||
Fixture: "test-fixtures/pkg-json/package-private.json",
|
||||
ExpectedPkg: pkg.Package{
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Name: "npm",
|
||||
Version: "6.14.6",
|
||||
PURL: "pkg:npm/npm@6.14.6",
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("Artistic-2.0", source.NewLocation("test-fixtures/pkg-json/package-private.json")),
|
||||
),
|
||||
Language: pkg.JavaScript,
|
||||
MetadataType: pkg.NpmPackageJSONMetadataType,
|
||||
Metadata: pkg.NpmPackageJSONMetadata{
|
||||
@@ -178,7 +182,6 @@ func TestParsePackageJSON(t *testing.T) {
|
||||
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
Homepage: "https://docs.npmjs.com/",
|
||||
URL: "https://github.com/npm/cli",
|
||||
Licenses: []string{"Artistic-2.0"},
|
||||
Private: true,
|
||||
Description: "a package manager for JavaScript",
|
||||
},
|
||||
|
||||
@@ -25,39 +25,6 @@ type packageLock struct {
|
||||
Packages map[string]lockPackage
|
||||
}
|
||||
|
||||
// packageLockLicense
|
||||
type packageLockLicense []string
|
||||
|
||||
func (licenses *packageLockLicense) UnmarshalJSON(data []byte) (err error) {
|
||||
// The license field could be either a string or an array.
|
||||
|
||||
// 1. An array
|
||||
var arr []string
|
||||
if err := json.Unmarshal(data, &arr); err == nil {
|
||||
*licenses = arr
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. A string
|
||||
var str string
|
||||
if err = json.Unmarshal(data, &str); err == nil {
|
||||
*licenses = make([]string, 1)
|
||||
(*licenses)[0] = str
|
||||
return nil
|
||||
}
|
||||
|
||||
// debug the content we did not expect
|
||||
if len(data) > 0 {
|
||||
log.WithFields("license", string(data)).Debug("Unable to parse the following `license` value in package-lock.json")
|
||||
}
|
||||
|
||||
// 3. Unexpected
|
||||
// In case we are unable to parse the license field,
|
||||
// i.e if we have not covered the full specification,
|
||||
// we do not want to throw an error, instead assign nil.
|
||||
return nil
|
||||
}
|
||||
|
||||
// lockDependency represents a single package dependency listed in the package.lock json file
|
||||
type lockDependency struct {
|
||||
Version string `json:"version"`
|
||||
@@ -73,6 +40,9 @@ type lockPackage struct {
|
||||
License packageLockLicense `json:"license"`
|
||||
}
|
||||
|
||||
// packageLockLicense
|
||||
type packageLockLicense []string
|
||||
|
||||
// parsePackageLock parses a package-lock.json and returns the discovered JavaScript packages.
|
||||
func parsePackageLock(resolver source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
// in the case we find package-lock.json files in the node_modules directories, skip those
|
||||
@@ -125,6 +95,36 @@ func parsePackageLock(resolver source.FileResolver, _ *generic.Environment, read
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
func (licenses *packageLockLicense) UnmarshalJSON(data []byte) (err error) {
|
||||
// The license field could be either a string or an array.
|
||||
|
||||
// 1. An array
|
||||
var arr []string
|
||||
if err := json.Unmarshal(data, &arr); err == nil {
|
||||
*licenses = arr
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. A string
|
||||
var str string
|
||||
if err = json.Unmarshal(data, &str); err == nil {
|
||||
*licenses = make([]string, 1)
|
||||
(*licenses)[0] = str
|
||||
return nil
|
||||
}
|
||||
|
||||
// debug the content we did not expect
|
||||
if len(data) > 0 {
|
||||
log.WithFields("license", string(data)).Debug("Unable to parse the following `license` value in package-lock.json")
|
||||
}
|
||||
|
||||
// 3. Unexpected
|
||||
// In case we are unable to parse the license field,
|
||||
// i.e if we have not covered the full specification,
|
||||
// we do not want to throw an error, instead assign nil.
|
||||
return nil
|
||||
}
|
||||
|
||||
func getNameFromPath(path string) string {
|
||||
parts := strings.Split(path, "node_modules/")
|
||||
return parts[len(parts)-1]
|
||||
|
||||
@@ -134,42 +134,50 @@ func TestParsePackageLockV2(t *testing.T) {
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
},
|
||||
{
|
||||
Name: "@types/prop-types",
|
||||
Version: "15.7.5",
|
||||
PURL: "pkg:npm/%40types/prop-types@15.7.5",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "@types/prop-types",
|
||||
Version: "15.7.5",
|
||||
PURL: "pkg:npm/%40types/prop-types@15.7.5",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
),
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="},
|
||||
},
|
||||
{
|
||||
Name: "@types/react",
|
||||
Version: "18.0.17",
|
||||
PURL: "pkg:npm/%40types/react@18.0.17",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "@types/react",
|
||||
Version: "18.0.17",
|
||||
PURL: "pkg:npm/%40types/react@18.0.17",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
),
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", Integrity: "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ="},
|
||||
},
|
||||
{
|
||||
Name: "@types/scheduler",
|
||||
Version: "0.16.2",
|
||||
PURL: "pkg:npm/%40types/scheduler@0.16.2",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "@types/scheduler",
|
||||
Version: "0.16.2",
|
||||
PURL: "pkg:npm/%40types/scheduler@0.16.2",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
),
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="},
|
||||
},
|
||||
{
|
||||
Name: "csstype",
|
||||
Version: "3.1.0",
|
||||
PURL: "pkg:npm/csstype@3.1.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"MIT"},
|
||||
Name: "csstype",
|
||||
Version: "3.1.0",
|
||||
PURL: "pkg:npm/csstype@3.1.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
),
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", Integrity: "sha1-TdysNxjXh8+d8NG30VAzklyPKfI="},
|
||||
},
|
||||
@@ -268,33 +276,35 @@ func TestParsePackageLockAlias(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
v2Pkg := pkg.Package{
|
||||
Name: "alias-check",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/alias-check@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: []string{"ISC"},
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
}
|
||||
|
||||
packageLockV1 := "test-fixtures/pkg-lock/alias-package-lock-1.json"
|
||||
packageLockV2 := "test-fixtures/pkg-lock/alias-package-lock-2.json"
|
||||
packageLocks := []string{packageLockV1, packageLockV2}
|
||||
|
||||
for _, packageLock := range packageLocks {
|
||||
v2Pkg := pkg.Package{
|
||||
Name: "alias-check",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/alias-check@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("ISC", source.NewLocation(packageLockV2)),
|
||||
),
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
}
|
||||
|
||||
for _, pl := range packageLocks {
|
||||
expected := make([]pkg.Package, len(commonPkgs))
|
||||
copy(expected, commonPkgs)
|
||||
|
||||
if packageLock == packageLockV2 {
|
||||
if pl == packageLockV2 {
|
||||
expected = append(expected, v2Pkg)
|
||||
}
|
||||
|
||||
for i := range expected {
|
||||
expected[i].Locations.Add(source.NewLocation(packageLock))
|
||||
expected[i].Locations.Add(source.NewLocation(pl))
|
||||
}
|
||||
pkgtest.TestFileParser(t, packageLock, parsePackageLock, expected, expectedRelationships)
|
||||
pkgtest.TestFileParser(t, pl, parsePackageLock, expected, expectedRelationships)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,31 +313,39 @@ func TestParsePackageLockLicenseWithArray(t *testing.T) {
|
||||
var expectedRelationships []artifact.Relationship
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "tmp",
|
||||
Version: "1.0.0",
|
||||
Licenses: []string{"ISC"},
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Name: "tmp",
|
||||
Version: "1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("ISC", source.NewLocation(fixture)),
|
||||
),
|
||||
PURL: "pkg:npm/tmp@1.0.0",
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
},
|
||||
{
|
||||
Name: "pause-stream",
|
||||
Version: "0.0.11",
|
||||
Licenses: []string{"MIT", "Apache2"},
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Name: "pause-stream",
|
||||
Version: "0.0.11",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
pkg.NewLicenseFromLocations("Apache2", source.NewLocation(fixture)),
|
||||
),
|
||||
PURL: "pkg:npm/pause-stream@0.0.11",
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
},
|
||||
{
|
||||
Name: "through",
|
||||
Version: "2.3.8",
|
||||
Licenses: []string{"MIT"},
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Name: "through",
|
||||
Version: "2.3.8",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", source.NewLocation(fixture)),
|
||||
),
|
||||
PURL: "pkg:npm/through@2.3.8",
|
||||
MetadataType: "NpmPackageLockJsonMetadata",
|
||||
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||
|
||||
Reference in New Issue
Block a user