install(windows-shim): handle `env -S` in bin shebang parser
Fixes #31387
Fixes #22422
Fixes #27924
Problem
Installing a package whose bin uses #!/usr/bin/env -S <prog> <args> on Windows produces a broken .bunx shim. For ocx@2.0.11 (#!/usr/bin/env -S bun --no-env-file) the shim launches with:
error: interpreter executable "-S" not found in %PATH%
Bun failed to remap this bin to its proper location within node_modules.
Root cause
Shebang::parse in src/install/windows-shim/BinLinkingShim.rs tokenizes the shebang. After consuming /usr/bin/env it reads the next token as the interpreter program — but for -S shebangs that token is literally -S, so the encoded launcher becomes -S bun --no-env-file and the shim tries to spawn -S at runtime.
env -S / --split-string is the documented way to forward flags to the real interpreter from a shebang on Linux/BSD (because the kernel collapses everything after the first space into a single arg). Node uses it, Bun-built CLIs like ocx use it, many tools use it.
Fix
In the /usr/bin/env / /bin/env branch of Shebang::parse, if the next token is -S, skip it and re-read the real program token. The remainder of the line stays as the launcher args, so flags like --no-env-file still reach Bun.
It also handles the joined short-option form -Sbun (env accepts -SSTRING as -S STRING). The -u VAR / -C DIR ambiguity where subsequent tokens are flag arguments is deliberately out of scope.
Verification
cargo check --workspace --target x86_64-pc-windows-msvccompiles cleanly (viabun run rust:check-all).- Rust unit tests in
BinLinkingShim.rscover the parse surface:env bun,env node,env -S bun --no-env-file,env -S node --experimental-vm-modules,env -S python3 -u,env -Salone, joined-Sbun/-Snode, multi-space variants, CRLF,/bin/envalias. test/cli/install/shebang-normalize.test.tsdrivesShebang::parsedirectly on all platforms via abun:internal-for-testingbinding (parseBinShebang) for the spaced and joined-Sforms, and on Windows installs a package and decodes the generated.bunxto verify the encoded launcher isbun --no-env-file, not-S bun .... The shim parser only runs on Windows at install time, so the binding is how the Linux lanes exercise it.
Prior PRs
#27925 and #28595 target this same bug but only edit BinLinkingShim.zig — which is no longer compiled (the runtime is BinLinkingShim.rs now). Both are effectively no-ops against current main. This PR supersedes them.