Disable env clearing for npm subcommands (#42587)

Julia Ryan and John Tur created

Fixes #39448

Several node version managers such as [volta](https://volta.sh) use thin
wrappers that locate the "real" node/npm binary with an env var that
points at their install root. When it finds this, it prepends the
correct directory to PATH, otherwise it'll check a hardcoded default
location and prepend that to PATH if it exists.

We were clearing env for npm subcommands, which meant that volta and co.
failed to locate the install root, and because they were installed via
scoop they don't use the default install path either so it simply
doesn't prepend anything to PATH (winget on the other hand installs
volta to the right place, which is why it worked when using that instead
of scoop to install volta @IllusionaryX).

So volta's npm wrapper executes a subcommand `npm`, but when that
doesn't prepend a different directory to PATH the first `npm` found in
PATH is that same wrapper itself, which horrifyingly causes itself to
re-exec continuously. I think they might have some logic to try to
prevent this using, you'll never guess, another env var that they set
whenever a volta wrapper execs something. Of course since we clear the
env that var also fails to propagate.

Removing env clearing (but keeping the prepending of npm path from your
settings) fixes these issues.

Release Notes:

- Fixed issues with scoop installations of mise/volta

Co-authored-by: John Tur <john-tur@outlook.com>

Change summary

crates/node_runtime/src/node_runtime.rs | 1 -
1 file changed, 1 deletion(-)

Detailed changes

crates/node_runtime/src/node_runtime.rs 🔗

@@ -557,7 +557,6 @@ impl NodeRuntimeTrait for ManagedNodeRuntime {
             let node_ca_certs = env::var(NODE_CA_CERTS_ENV_VAR).unwrap_or_else(|_| String::new());
 
             let mut command = util::command::new_smol_command(node_binary);
-            command.env_clear();
             command.env("PATH", env_path);
             command.env(NODE_CA_CERTS_ENV_VAR, node_ca_certs);
             command.arg(npm_file).arg(subcommand);