Skip to content

Commit 7f81c7a

Browse files
SegaraRaiwan9chiclaude
authored
fix: preserve PATHEXT for Windows cached tasks (#366)
Fixes #365. Preserves PATHEXT in the default Windows environment passthrough so PowerShell package shims can resolve node.exe during cached task execution. <details> <summary>Why PATHEXT is required</summary> In the issue repro, `marker-cli` is exposed through a pnpm-generated `node_modules/.bin/marker-cli.ps1` shim. On Windows, that shim sets `$exe = ".exe"` and then falls back to invoking Node by name: ```powershell & "node$exe" "$basedir/../marker-cli/bin/marker-cli.mjs" $args ``` So the actual command is `& "node.exe" ...`. When `PATHEXT` is missing from the sanitized cached-task environment, PowerShell can still locate `node.exe` with `Get-Command node.exe`, but native invocation by name does not run correctly: `& "node.exe" --version` produces no output, `$LASTEXITCODE` is unset, and the repro marker file is not created. Restoring `PATHEXT` with `.EXE` makes the same shim execute normally and create the marker. This is why preserving `PATHEXT` fixes the cached PowerShell shim path without changing fspy or the shim rewrite itself. </details> Verified with the issue repro on Windows, `cargo fmt --check`, `cargo build -p vite_task_bin`, and `cargo test -p vite_task_plan --test plan_snapshots -- windows_cmd_shim_rewrite`. --------- Co-authored-by: SegaraRai <29276700+SegaraRai@users.noreply.github.com> Co-authored-by: branchseer <dk4rest@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 88bacaa commit 7f81c7a

9 files changed

Lines changed: 74 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Changelog
22

3+
- **Fixed** Windows cached tasks can now run package shims rewritten through PowerShell; default env passthrough now preserves `PATHEXT` ([#366](https://github.com/voidzero-dev/vite-task/pull/366))
34
- **Added** Platform support for targets without `input` auto-inference (e.g. Android). Tasks still run; those relying on auto-inference run uncached, with the summary noting that `input` must be configured manually to enable caching ([#352](https://github.com/voidzero-dev/vite-task/pull/352))
45
- **Fixed** `vp run` no longer aborts with `failed to prepare the command for injection: Invalid argument` when the user environment already has `LD_PRELOAD` (Linux) or `DYLD_INSERT_LIBRARIES` (macOS) set. The tracer shim is now appended to any existing value and placed last, so user preloads keep their symbol-interposition precedence ([#340](https://github.com/voidzero-dev/vite-task/issues/340))
56
- **Changed** Arguments passed after a task name (e.g. `vp run test some-filter`) are now forwarded only to that task. Tasks pulled in via `dependsOn` no longer receive them ([#324](https://github.com/voidzero-dev/vite-task/issues/324))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# This fixture intentionally tracks package-shim files under node_modules/.bin.
2+
!node_modules
3+
!node_modules/**

crates/vite_task_bin/tests/e2e_snapshots/fixtures/windows_powershell_shim_pathext/node_modules/.bin/probe-cli.cmd

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/vite_task_bin/tests/e2e_snapshots/fixtures/windows_powershell_shim_pathext/node_modules/.bin/probe-cli.ps1

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "windows-powershell-shim-pathext"
3+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[[e2e]]
2+
name = "powershell_package_shim_keeps_pathext"
3+
platform = "windows"
4+
comment = """
5+
Cached Windows tasks run with a sanitized environment, and pnpm-style package
6+
`.cmd` shims in `node_modules/.bin` are rewritten at plan time to invoke their
7+
`.ps1` sibling via `powershell.exe -File`. PowerShell needs `PATHEXT` in that
8+
environment to launch native executables — even when the executable name is
9+
written out with a `.exe` extension — so `PATHEXT` must be preserved in the
10+
default untracked env passthrough.
11+
"""
12+
steps = [
13+
{ argv = [
14+
"vt",
15+
"run",
16+
"probe",
17+
], comment = "rewritten to `powershell.exe -File probe-cli.ps1`; the shim launches `vtt.exe write-file` to write `marker.txt`" },
18+
{ argv = [
19+
"vtt",
20+
"print-file",
21+
"marker.txt",
22+
], comment = "marker is present only if the shim's `vtt.exe` launch succeeded" },
23+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# powershell_package_shim_keeps_pathext
2+
3+
Cached Windows tasks run with a sanitized environment, and pnpm-style package
4+
`.cmd` shims in `node_modules/.bin` are rewritten at plan time to invoke their
5+
`.ps1` sibling via `powershell.exe -File`. PowerShell needs `PATHEXT` in that
6+
environment to launch native executables — even when the executable name is
7+
written out with a `.exe` extension — so `PATHEXT` must be preserved in the
8+
default untracked env passthrough.
9+
10+
## `vt run probe`
11+
12+
rewritten to `powershell.exe -File probe-cli.ps1`; the shim launches `vtt.exe write-file` to write `marker.txt`
13+
14+
```
15+
$ probe-cli
16+
shim-ran
17+
```
18+
19+
## `vtt print-file marker.txt`
20+
21+
marker is present only if the shim's `vtt.exe` launch succeeded
22+
23+
```
24+
shim-ran
25+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"cache": true,
3+
"tasks": {
4+
"probe": {
5+
"command": "probe-cli",
6+
"cache": true,
7+
"input": []
8+
}
9+
}
10+
}

crates/vite_task_graph/src/config/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ pub const DEFAULT_UNTRACKED_ENV: &[&str] = &[
382382
"HOMEDRIVE",
383383
"HOMEPATH",
384384
"WINDIR",
385+
"PATHEXT",
385386
"ProgramFiles",
386387
"ProgramFiles[(]x86[)]", // Parens escaped for glob syntax (Turborepo uses literal `ProgramFiles(x86)`)
387388
// IDE specific (exact matches)

0 commit comments

Comments
 (0)