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:
Christopher Angelo Phillips
2023-05-15 16:23:39 -04:00
committed by GitHub
parent 8046f09562
commit 42fa9e4965
126 changed files with 5165 additions and 1503 deletions
+20 -16
View File
@@ -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=="},
},
+10 -15
View File
@@ -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{},