mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
feat: add support for licenses in package-lock json v2 (#1164)
This commit is contained in:
parent
13296880cd
commit
c56d3b5eef
@ -77,7 +77,7 @@ func addLicenses(resolver source.FileResolver, location source.Location, p *pkg.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Licenses = licenses
|
p.Licenses = append(p.Licenses, licenses...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
@ -18,6 +19,7 @@ type PackageLock struct {
|
|||||||
Requires bool `json:"requires"`
|
Requires bool `json:"requires"`
|
||||||
LockfileVersion int `json:"lockfileVersion"`
|
LockfileVersion int `json:"lockfileVersion"`
|
||||||
Dependencies map[string]Dependency
|
Dependencies map[string]Dependency
|
||||||
|
Packages map[string]Package
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependency represents a single package dependency listed in the package.lock json file
|
// Dependency represents a single package dependency listed in the package.lock json file
|
||||||
@ -25,7 +27,13 @@ type Dependency struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Resolved string `json:"resolved"`
|
Resolved string `json:"resolved"`
|
||||||
Integrity string `json:"integrity"`
|
Integrity string `json:"integrity"`
|
||||||
Requires map[string]string
|
}
|
||||||
|
|
||||||
|
type Package struct {
|
||||||
|
Version string `json:"version"`
|
||||||
|
Resolved string `json:"resolved"`
|
||||||
|
Integrity string `json:"integrity"`
|
||||||
|
License string `json:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsePackageLock parses a package-lock.json and returns the discovered JavaScript packages.
|
// parsePackageLock parses a package-lock.json and returns the discovered JavaScript packages.
|
||||||
@ -46,12 +54,28 @@ func parsePackageLock(path string, reader io.Reader) ([]*pkg.Package, []artifact
|
|||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to parse package-lock.json file: %w", err)
|
return nil, nil, fmt.Errorf("failed to parse package-lock.json file: %w", err)
|
||||||
}
|
}
|
||||||
|
licenseMap := make(map[string]string)
|
||||||
|
for _, pkgMeta := range lock.Packages {
|
||||||
|
var sb strings.Builder
|
||||||
|
sb.WriteString(pkgMeta.Resolved)
|
||||||
|
sb.WriteString(pkgMeta.Integrity)
|
||||||
|
licenseMap[sb.String()] = pkgMeta.License
|
||||||
|
}
|
||||||
|
|
||||||
for name, pkgMeta := range lock.Dependencies {
|
for name, pkgMeta := range lock.Dependencies {
|
||||||
|
var sb strings.Builder
|
||||||
|
sb.WriteString(pkgMeta.Resolved)
|
||||||
|
sb.WriteString(pkgMeta.Integrity)
|
||||||
|
var licenses []string
|
||||||
|
if license, exists := licenseMap[sb.String()]; exists {
|
||||||
|
licenses = append(licenses, license)
|
||||||
|
}
|
||||||
packages = append(packages, &pkg.Package{
|
packages = append(packages, &pkg.Package{
|
||||||
Name: name,
|
Name: name,
|
||||||
Version: pkgMeta.Version,
|
Version: pkgMeta.Version,
|
||||||
Language: pkg.JavaScript,
|
Language: pkg.JavaScript,
|
||||||
Type: pkg.NpmPkg,
|
Type: pkg.NpmPkg,
|
||||||
|
Licenses: licenses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,3 +111,47 @@ func TestParsePackageLock(t *testing.T) {
|
|||||||
assertPkgsEqual(t, actual, expected)
|
assertPkgsEqual(t, actual, expected)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParsePackageLockV2(t *testing.T) {
|
||||||
|
expected := map[string]pkg.Package{
|
||||||
|
"@types/prop-types": {
|
||||||
|
Name: "@types/prop-types",
|
||||||
|
Version: "15.7.5",
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
Licenses: []string{"MIT"},
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
Name: "@types/prop-types",
|
||||||
|
Version: "18.0.17",
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
Licenses: []string{"MIT"},
|
||||||
|
},
|
||||||
|
"@types/scheduler": {
|
||||||
|
Name: "@types/scheduler",
|
||||||
|
Version: "0.16.2",
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
Licenses: []string{"MIT"},
|
||||||
|
},
|
||||||
|
"csstype": {
|
||||||
|
Name: "csstype",
|
||||||
|
Version: "3.1.0",
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
Licenses: []string{"MIT"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fixture, err := os.Open("test-fixtures/pkg-lock/package-lock-2.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to open fixture: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, _, err := parsePackageLock(fixture.Name(), fixture)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse package-lock.json: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertPkgsEqual(t, actual, expected)
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
{
|
||||||
|
"name": "npm",
|
||||||
|
"version": "6.14.6",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "npm",
|
||||||
|
"version": "6.14.6",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "^18.0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/prop-types": {
|
||||||
|
"version": "15.7.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
|
"integrity": "sha1-XxnSuFqY6VWANvajysyIGUIPBc8=",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/react": {
|
||||||
|
"version": "18.0.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz",
|
||||||
|
"integrity": "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ=",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"@types/scheduler": "*",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/scheduler": {
|
||||||
|
"version": "0.16.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||||
|
"integrity": "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk=",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
|
||||||
|
"integrity": "sha1-TdysNxjXh8+d8NG30VAzklyPKfI=",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/prop-types": {
|
||||||
|
"version": "15.7.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||||
|
"integrity": "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"version": "18.0.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz",
|
||||||
|
"integrity": "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ=",
|
||||||
|
"requires": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"@types/scheduler": "*",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/scheduler": {
|
||||||
|
"version": "0.16.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
|
||||||
|
"integrity": "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="
|
||||||
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz",
|
||||||
|
"integrity": "sha1-TdysNxjXh8+d8NG30VAzklyPKfI="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user