Skip to content

fix: make symlink_metadata VPath-aware for Yarn PnP#1183

Merged
graphite-app[bot] merged 1 commit into
mainfrom
fix/symlink-metadata-vpath
May 29, 2026
Merged

fix: make symlink_metadata VPath-aware for Yarn PnP#1183
graphite-app[bot] merged 1 commit into
mainfrom
fix/symlink-metadata-vpath

Conversation

@Boshen

@Boshen Boshen commented May 29, 2026

Copy link
Copy Markdown
Member

Summary

FileSystemOs::metadata already translates Yarn PnP virtual and zip paths through VPath before hitting the filesystem, but symlink_metadata did not — it lstat'd the raw path directly:

fn symlink_metadata(&self, path: &Path) -> io::Result<FileMetadata> {
    Self::symlink_metadata(path)   // no VPath translation
}

For a virtual/zip path that has no physical existence, that lstat fails, so canonicalization (canonicalize_with_visited) sees the error, treats the path as a non-symlink, and cannot resolve symlinks correctly under PnP.

This makes symlink_metadata mirror metadata's VPath handling. Zip entries are never symlinks, so they reuse the same file_type lookup as metadata; virtual/native paths fall through to the real lstat on the translated physical path.

This is also a prerequisite for #1182, which routes is_file/is_dir through the cached lstat and so requires symlink_metadata to be VPath-aware.

Verification

  • cargo test --all-features (includes the Yarn PnP suite) — green
  • fixtures/pnp JS resolver test — green

🤖 Generated with Claude Code

@Boshen Boshen added the merge label May 29, 2026

Boshen commented May 29, 2026

Copy link
Copy Markdown
Member Author

Merge activity

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.33%. Comparing base (403600f) to head (a539c40).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1183   +/-   ##
=======================================
  Coverage   93.33%   93.33%           
=======================================
  Files          22       22           
  Lines        4184     4184           
=======================================
  Hits         3905     3905           
  Misses        279      279           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

## Summary

`FileSystemOs::metadata` already translates Yarn PnP **virtual** and **zip** paths through `VPath` before hitting the filesystem, but `symlink_metadata` did not — it `lstat`'d the raw path directly:

```rust
fn symlink_metadata(&self, path: &Path) -> io::Result<FileMetadata> {
    Self::symlink_metadata(path)   // no VPath translation
}
```

For a virtual/zip path that has no physical existence, that `lstat` fails, so canonicalization (`canonicalize_with_visited`) sees the error, treats the path as a non-symlink, and cannot resolve symlinks correctly under PnP.

This makes `symlink_metadata` mirror `metadata`'s `VPath` handling. Zip entries are never symlinks, so they reuse the same `file_type` lookup as `metadata`; virtual/native paths fall through to the real `lstat` on the translated physical path.

This is also a prerequisite for #1182, which routes `is_file`/`is_dir` through the cached `lstat` and so requires `symlink_metadata` to be VPath-aware.

## Verification

- `cargo test --all-features` (includes the Yarn PnP suite) — green
- `fixtures/pnp` JS resolver test — green

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@graphite-app graphite-app Bot force-pushed the fix/symlink-metadata-vpath branch from 96c398e to a539c40 Compare May 29, 2026 13:27
@graphite-app graphite-app Bot merged commit a539c40 into main May 29, 2026
18 checks passed
@graphite-app graphite-app Bot removed the merge label May 29, 2026
@graphite-app graphite-app Bot deleted the fix/symlink-metadata-vpath branch May 29, 2026 13:30
@oxc-guard oxc-guard Bot mentioned this pull request May 29, 2026
@codspeed-hq

codspeed-hq Bot commented May 29, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 4.45%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 6 improved benchmarks
❌ 1 regressed benchmark
✅ 14 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
pm/pnpm-isolated 1.1 ms 1.1 ms +3.48%
pm/npm-flat 1,030.4 µs 954.4 µs +7.97%
pm/yarn-flat 1,037.5 µs 951.8 µs +9%
pm/pnpm-hoisted 1.1 ms 1.1 ms +3.17%
small 11.4 µs 11.8 µs -3.61%
resolver_real[multi-thread] 407.9 µs 382.6 µs +6.61%
resolver_memory[multi-thread] 409 µs 389.4 µs +5.04%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/symlink-metadata-vpath (a539c40) with main (4654e32)2

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (a539c40) during the generation of this report, so 4654e32 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Boshen pushed a commit that referenced this pull request Jun 3, 2026
## 🤖 New release

* `oxc_resolver`: 11.20.0 -> 11.21.0
* `oxc_resolver_napi`: 11.20.0 -> 11.21.0

<details><summary><i><b>Changelog</b></i></summary><p>

## `oxc_resolver`

<blockquote>

##
[11.21.0](v11.20.0...v11.21.0)
- 2026-06-03

### <!-- 0 -->🚀 Features

- *(tsconfig)* support package.json imports field in extends
([#1199](#1199)) (by
@Boshen)

### <!-- 1 -->🐛 Bug Fixes

- *(tsconfig)* apply each referenced project's own `allowJs`
([#1198](#1198)) (by
@shulaoda)
- make symlink_metadata VPath-aware for Yarn PnP
([#1183](#1183)) (by
@Boshen)

### <!-- 4 -->⚡ Performance

- borrow relative main field instead of allocating a "./" prefix
([#1187](#1187)) (by
@Boshen)
- *(cache)* move package.json path into parse instead of cloning
([#1186](#1186)) (by
@Boshen)
- eliminate symlink stat syscalls by reusing canonicalization
([#1184](#1184)) (by
@Boshen)
- reduce resolution syscalls by unifying stat and lstat
([#1182](#1182)) (by
@Boshen)

### <!-- 9 -->💼 Other

- add baselines for each package manager x node_modules layout
([#1176](#1176)) (by
@Boshen)

### Contributors

* @shulaoda
* @Boshen
* @renovate[bot]
</blockquote>



</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
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