Files
Zoltan Kochan 997a8ca9bf fix(exe): route pn/pnpx/pnx through .exe hardlinks on Windows (#11486) (#11501)
* test(exe): add Windows-only repro for #11486 (pn/pnpx/pnx aliases)

Captures the user-reported failure on a fresh Windows CI: when the
@pnpm/exe install rewrites bin entries to point at .cmd files,
@zkochan/cmd-shim's Bash shim does `exec cmd /C ...target.cmd`, MSYS2
mangles the lone `/C` into a Windows path, and cmd.exe falls into
interactive mode (printing its banner instead of running the alias).

These tests will fail on `windows-latest` until the follow-up commit
points the bin entries at .exe hardlinks of the SEA binary.

* fix(exe): route pn/pnpx/pnx through .exe hardlinks on Windows (#11486)

The @pnpm/exe install rewrote bin to point pn/pnpx/pnx at .cmd files,
which cmd-shim wraps as `exec cmd /C ...target.cmd "$@"` in its Bash
shim. MSYS2 / Git Bash mangles the lone `/C` into a Windows path
before cmd.exe sees it, so cmd.exe finds no /C or /K and falls into
interactive mode — the user sees its banner instead of `pnpm dlx`.

Hardlink pn.exe / pnpx.exe / pnx.exe to the SEA pnpm.exe (in setup.js
preinstall and in self-update's linkExePlatformBinary) and rewrite
those bin entries to the .exe names. cmd-shim emits a direct exec for
.exe sources, taking cmd.exe out of the chain entirely. The SEA reads
process.execPath's basename and prepends `dlx` when launched as
pnpx / pnx.

* test(exe): make Windows alias tests robust to local-dev environments

Two follow-ups from Copilot review on #11501:

* Use `'junction'` instead of `'dir'` for the detect-libc symlink on
  Windows. Non-junction directory symlinks need Developer Mode or
  admin, which the existing failure-path tests already skip on Windows
  for; junctions don't.
* Probe \`bash --version\` before running the Git Bash / MSYS2 alias
  test, and skip cleanly if it isn't on PATH (local Windows dev
  machines often lack it; CI windows-latest ships it). Fold the status
  check into the assertion so a non-zero exit surfaces in the diff.

* test(exe): wire @pnpm/exe into the recursive test runner

The setup.test.ts in this package wasn't running in CI — `@pnpm/exe`
had no `.test` script, so `pn -r .test` (what `test-pkgs-all` runs)
silently skipped it. The existing tests there have apparently been
dead since they were added; the Windows alias repro added in 1e93a1d
inherited the same gap.

Add `.test` (jest invocation, matching every other workspace
package's shape) and a `test` alias so it's picked up by the
recursive runner. meta-updater's @pnpm/exe / artifacts branch
short-circuits before adding test scripts; preserve that behavior by
hand-writing them rather than restructuring the rule.
2026-05-06 22:45:44 +02:00
..