leptos-rs / cargo-leptos

Build tool for Leptos (Rust)
MIT License
368 stars 106 forks source link

Handle npx not being an exe on Windows #384

Open ilyvion opened 1 month ago

ilyvion commented 1 month ago

Thanks to rust-lang/rust#37519, Command::spawn expects a command to have an .exe extension, but on Windows, a bunch of executable files have other endings, like .bat or .cmd, which causes me trouble when using cargo-leptos:

❯ cargo leptos end-to-end
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.29s
       Cargo finished cargo build --package=inventory-spa --lib --target-dir=C:\Users\alexs\Documents\Projects\inventory\target\front --target=wasm32-unknown-unknown --no-default-features --features=hydrate
       Front compiling WASM
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.37s
       Cargo finished cargo build --package=inventory-spa --bin=inventory-spa --no-default-features --features=ssr
Error: running: npx playwright test at `C:\Users\alexs\.cargo\registry\src\index.crates.io-6f17d22bba15001f\cargo-leptos-0.2.20\src\command\end2end.rs:28:14`

Caused by:
    0: Could not spawn command "npx playwright test" at `C:\Users\alexs\.cargo\registry\src\index.crates.io-6f17d22bba15001f\cargo-leptos-0.2.20\src\command\end2end.rs:50:10`  
    1: program not found

The reason this doesn't work is because npx on my system is an npx.cmd file:

❯ $(Get-Command npx).Source
C:\Program Files\nodejs\npx.cmd

and Command::spawn won't find it, even though the command itself works just fine when run in a shell:

❯ npx playwright test   

Running 3 tests using 3 workers
  3 passed (4.4s)

To open last HTML report run:

  npx playwright show-report

One of the ways to work around this is to preface the command with something like cmd /C on Windows, which runs it through the cmd shell, which knows how to handle those other file types:

❯ cmd /C "npx playwright test"

Running 3 tests using 3 workers
  3 passed (4.5s)

To open last HTML report run:

  npx playwright show-report

This can be fairly easily added to a Command::spawn invocation.

ilyvion commented 1 month ago

Ooh, I should add that there's a comment in the issue I linked that says

If some of you weren't aware, it might help to know that the which crate has logic for handling this without requiring you to append .cmd, .com, .bat, .exe, etc. This is based on the PATHEXT environment variable on Windows, which you don't have to set it yourself.

See https://github.com/harryfei/which-rs/blob/e5ec71143965a7c7751c853fb229cb973bfcaa13/src/finder.rs#L158-L162

Hope that helps others like it helped me!

Which means that there's a Rust-ier solution than having to invoke cmd that should work on any OS:

let result = which("rustc").unwrap();
assert_eq!(result, PathBuf::from("/usr/bin/rustc"));

👍