Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nodejs): respect peer dependencies for dependency tree #7989

Merged
merged 2 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/dependency/parser/nodejs/npm/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Package struct {
Dependencies map[string]string `json:"dependencies"`
OptionalDependencies map[string]string `json:"optionalDependencies"`
DevDependencies map[string]string `json:"devDependencies"`
PeerDependencies map[string]string `json:"peerDependencies"`
Resolved string `json:"resolved"`
Dev bool `json:"dev"`
Link bool `json:"link"`
Expand Down Expand Up @@ -91,7 +92,7 @@ func (p *Parser) parseV2(packages map[string]Package) ([]ftypes.Package, []ftype
p.resolveLinks(packages)

directDeps := make(map[string]struct{})
for name, version := range lo.Assign(packages[""].Dependencies, packages[""].OptionalDependencies, packages[""].DevDependencies) {
for name, version := range lo.Assign(packages[""].Dependencies, packages[""].OptionalDependencies, packages[""].DevDependencies, packages[""].PeerDependencies) {
pkgPath := joinPaths(nodeModulesDir, name)
if _, ok := packages[pkgPath]; !ok {
p.logger.Debug("Unable to find the direct dependency",
Expand Down Expand Up @@ -165,7 +166,7 @@ func (p *Parser) parseV2(packages map[string]Package) ([]ftypes.Package, []ftype
// └─┬ [email protected]
// ├─┬ [email protected] - optional dependency
// │ └── [email protected].
dependencies := lo.Assign(pkg.Dependencies, pkg.OptionalDependencies)
dependencies := lo.Assign(pkg.Dependencies, pkg.OptionalDependencies, pkg.PeerDependencies)
dependsOn := make([]string, 0, len(dependencies))
for depName, depVersion := range dependencies {
depID, err := findDependsOn(pkgPath, depName, packages)
Expand Down
6 changes: 6 additions & 0 deletions pkg/dependency/parser/nodejs/npm/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ func TestParse(t *testing.T) {
want: npmV3WithWorkspacePkgs,
wantDeps: npmV3WithWorkspaceDeps,
},
{
name: "lock version v3 with peer dependencies",
file: "testdata/package-lock_v3_with_peer.json",
want: npmV3WithPeerDependenciesPkgs,
wantDeps: npmV3WithPeerDependenciesDeps,
},
{
name: "lock file v3 contains same dev and non-dev dependencies",
file: "testdata/package-lock_v3_with-same-dev-and-non-dev.json",
Expand Down
114 changes: 114 additions & 0 deletions pkg/dependency/parser/nodejs/npm/parse_testcase.go
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,120 @@ var (
DependsOn: []string{"[email protected]"},
},
}
// docker run --name node --rm -it node@sha256:51dd437f31812df71108b81385e2945071ec813d5815fa3403855669c8f3432b sh
// mkdir node_v3_with_peer && cd node_v3_with_peer
// npm init --force
// npm install --save [email protected]
// npm install --save-peer [email protected]
// npm update
//
// Delete unnecessary packages from package-lock.json
// Packages are filled manually
npmV3WithPeerDependenciesPkgs = []ftypes.Package{
{
ID: "[email protected]",
Name: "lodash",
Version: "4.17.21",
Relationship: ftypes.RelationshipDirect,
ExternalReferences: []ftypes.ExternalRef{
{
Type: ftypes.RefOther,
URL: "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
},
},
Locations: []ftypes.Location{
{
StartLine: 30,
EndLine: 36,
},
},
},
{
ID: "[email protected]",
Name: "winston-mail",
Version: "2.0.0",
Relationship: ftypes.RelationshipDirect,
ExternalReferences: []ftypes.ExternalRef{
{
Type: ftypes.RefOther,
URL: "https://registry.npmjs.org/winston-mail/-/winston-mail-2.0.0.tgz",
},
},
Locations: []ftypes.Location{
{
StartLine: 60,
EndLine: 74,
},
},
},
{
ID: "[email protected]",
Name: "mustache",
Version: "2.3.2",
Relationship: ftypes.RelationshipIndirect,
ExternalReferences: []ftypes.ExternalRef{
{
Type: ftypes.RefOther,
URL: "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz",
},
},
Locations: []ftypes.Location{
{
StartLine: 18,
EndLine: 29,
},
},
},
{
ID: "[email protected]",
Name: "triple-beam",
Version: "1.4.1",
Relationship: ftypes.RelationshipIndirect,
ExternalReferences: []ftypes.ExternalRef{
{
Type: ftypes.RefOther,
URL: "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
},
},
Locations: []ftypes.Location{
{
StartLine: 37,
EndLine: 46,
},
},
},
{
ID: "[email protected]",
Name: "winston",
Version: "3.17.0",
Relationship: ftypes.RelationshipIndirect,
ExternalReferences: []ftypes.ExternalRef{
{
Type: ftypes.RefOther,
URL: "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
},
},
Locations: []ftypes.Location{
{
StartLine: 47,
EndLine: 59,
},
},
},
}
npmV3WithPeerDependenciesDeps = []ftypes.Dependency{
{
ID: "[email protected]",
DependsOn: []string{
"[email protected]",
"[email protected]",
},
},
{
ID: "[email protected]",
DependsOn: []string{"[email protected]"},
},
}

// docker run --name node --rm -it node@sha256:51dd437f31812df71108b81385e2945071ec813d5815fa3403855669c8f3432b sh
// mkdir node_v3_without_direct_deps && cd node_v3_without_direct_deps
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"name": "node_v3_with_peer",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "node_v3_with_peer",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"winston-mail": "^2.0.0"
},
"peerDependencies": {
"lodash": "^4.17.21"
}
},
"node_modules/mustache": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-2.3.2.tgz",
"integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==",
"license": "MIT",
"bin": {
"mustache": "bin/mustache"
},
"engines": {
"npm": ">=1.4.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT",
"peer": true
},
"node_modules/triple-beam": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
"integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 14.0.0"
}
},
"node_modules/winston": {
"version": "3.17.0",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
"integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
"license": "MIT",
"peer": true,
"dependencies": {
"triple-beam": "^1.3.0"
},
"engines": {
"node": ">= 12.0.0"
}
},
"node_modules/winston-mail": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/winston-mail/-/winston-mail-2.0.0.tgz",
"integrity": "sha512-Wp+mKiieoV6FAZJNyNMS62Zsf5FBSxe17j0f4fpFYeA+rfW8nEZ2eBGGl7+vq+dr3dEpefV5D+ZI3d9jaqdRfw==",
"license": "MIT",
"dependencies": {
"mustache": "^2.2.1"
},
"engines": {
"node": ">= 0.6.0"
},
"peerDependencies": {
"winston": ">=0.5.0"
}
}
}
}
Loading