fix(sbom): resolve pnpm dependency edges from the lock graph - #1115
Merged
Conversation
The pnpm parser already builds a complete parent-to-children adjacency map while reading the lockfile, but it was never exposed. collectPnpmPaths truncates it to at most five paths of at most ten segments per package, and the SBOM was reconstructing its dependency graph from those truncated paths, so it lost every route beyond the cap. Exposes the full graph behind the same three-method shape the npm graph already presents, covering both v9 snapshots and legacy packages, and cleaning pnpm's peer-dependency key suffixes so vite@5.0.0(react@19.0.0) and a bare vite@5.0.0 resolve to one package. resolveDependencyEdges now dispatches on the lockfile type. The edge building itself is unchanged, so dedup, the filter that prevents dangling SPDX references, and root anchoring all still apply. Yarn and Bun keep the path-derived fallback.
Adds a v9 fixture with real importer and snapshot structure, where ms is reached through express, vite and body-parser. Path-derived edges lose routes like that; the lock graph must report all three parents. Five tests: multi-parent resolution and root-level parentlessness on the graph itself, then edge resolution, multi-parent retention and root anchoring through resolveDependencyEdges.
Moves pnpm alongside npm in the completeness note and narrows the five-path-cap limitation to Yarn and Bun, linking the issues that track them. Measured on two large pnpm monorepos: edges 5494 to 8678 on one and 3513 to 4638 on the other, with the only parentless package in each being the root project itself.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The pnpm parser already builds a complete parent-to-children adjacency map while
reading the lockfile, but it was never exposed.
collectPnpmPathstruncates itto at most five paths of at most ten segments per package, and the SBOM was
reconstructing its dependency graph from those truncated paths, so it lost every
route beyond the cap. Same root cause as #1106 fixed for npm.
New
pnpm-lock-graph.tsexposes the full graph behind the same three-methodshape the npm graph already presents, covering both v9
snapshotsand legacypackages, and cleaning pnpm's peer-dependency key suffixes sovite@5.0.0(react@19.0.0)and a barevite@5.0.0resolve to one package.resolveDependencyEdgesnow dispatches on lockfile type. The edge buildingitself is unchanged, so dedup, the filter that prevents dangling SPDX references,
and root anchoring all still apply. Yarn and Bun keep the path-derived fallback.
Measured on two real pnpm monorepos:
examples/analogexamples/astroThe one remaining parentless package in each is the root project, which
correctly has none.
Because the edge builder now works against a small shared interface rather than
the npm graph directly, #1108 and #1109 only need Bun and Yarn to satisfy those
three methods.
Closes #1107