Skip to content

Rewrite lockfile parsers with transitive pnpm resolution#51

Merged
ctate merged 2 commits into
mainfrom
ctate/fix-lock-support
Apr 16, 2026
Merged

Rewrite lockfile parsers with transitive pnpm resolution#51
ctate merged 2 commits into
mainfrom
ctate/fix-lock-support

Conversation

@ctate
Copy link
Copy Markdown
Collaborator

@ctate ctate commented Apr 16, 2026

Summary

  • pnpm parser rewrite: indent-aware stack parser covering v5 through v9, including importers, devDependencies/optionalDependencies, and nested peer-dep suffixes like 15.5.15(@opentelemetry/api@1.9.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5). Drops the old regex that misidentified versions inside peer-dep parens and returned non-deterministic results in monorepos.
  • Transitive resolution for pnpm: while parsing, build a dep graph from snapshots: (v9) or packages: (v6–v8); on direct-lookup miss, BFS from root-importer deps and return the root-reachable version. Replaces the old lexicographic first-match, which often returned the lowest version among several transitive copies.
  • yarn parser rewrite: block-based parser handling both classic v1 and Berry v2+ in one path. Fixes the regression where multi-specifier headers ("foo@^1", "foo@~1.2":) only matched the first specifier, and adds support for Berry's npm: protocol and comma-separated single-quoted specifiers.
  • Defensive hardening: YAML inline-comment stripping (only when # follows whitespace, so git fragment URLs pass through), CRLF handling, empty/comment-only file handling, cycle-safe BFS.
  • No new dependencies. Cargo.toml untouched.
  • Tests: 31 new unit tests (55 → 86), plus three realistic fixtures under packages/opensrc/cli/tests/fixtures/ covering scoped packages, multi-specifier headers, multi-version resolution, workspace importers, and transitive graphs.

The previous regex-based parsers misidentified versions in several common
real-world cases: yarn multi-specifier headers only matched the first
specifier, pnpm peer-dep suffixes like `18.2.0(react@17.0.0)` leaked false
matches for the inner package, and pnpm monorepos returned whichever
version the regex engine encountered first.

Replace both with format-aware hand-rolled parsers:
- pnpm: indent-aware stack parser covering v5 through v9, including
  importers, devDependencies, optionalDependencies, and nested peer-dep
  suffixes.
- yarn: block-based parser handling both classic v1 and Berry v2+ in one
  code path.

For pnpm, add BFS-based transitive resolution: while parsing, build a dep
graph from `snapshots:` (v9) or `packages:` (v6-v8), and when a direct
lookup misses, walk the graph from root importers to pick the
root-reachable version instead of a lexicographic first match.

Also applies defensive YAML inline-comment stripping in both parsers and
adds realistic yarn v1, yarn Berry, and pnpm v9 monorepo fixtures plus
31 new unit tests. No new dependencies.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
opensrc Ready Ready Preview, Comment Apr 16, 2026 7:51pm

@ctate ctate merged commit ccb13d9 into main Apr 16, 2026
8 checks passed
@ctate ctate mentioned this pull request Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant