From b451af49069bcbb88b3eb118a340a5ba1e587933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=B0=8F=E7=99=BD?= <364772080@qq.com> Date: Wed, 22 May 2024 12:14:44 +0800 Subject: [PATCH] Fix `npm install` error with some languages (#12087) If you have already installed `node` using `brew install node`, you are fine. If you did not install `node` on you local machine, it fails. The `node_binary` path is actually not included in environment variable. When run `npm install`, some extensions like `eslint`, may run some commands like `sh -c node .....`. Since `node_binary` path is not included in `PATH` variable, `sh -c node ...` will fail complaining that "command not found". If you have installed `node` before, `node` is already included in `PATH`, so you are fine. If not, it fails. Closes #11890 Release Notes: - Fixed Zed's internal Node runtime not being put in `$PATH` correctly when running language servers and other commands with `node`. ([#11890](https://github.com/zed-industries/zed/issues/11890)) --------- Co-authored-by: Thorsten Ball --- crates/node_runtime/src/node_runtime.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/node_runtime/src/node_runtime.rs b/crates/node_runtime/src/node_runtime.rs index 426b5c4d3c..a00ce6cd23 100644 --- a/crates/node_runtime/src/node_runtime.rs +++ b/crates/node_runtime/src/node_runtime.rs @@ -226,18 +226,19 @@ impl NodeRuntime for RealNodeRuntime { let node_binary = installation_path.join(NODE_PATH); let npm_file = installation_path.join(NPM_PATH); - let mut env_path = node_binary + let mut env_path = vec![node_binary .parent() .expect("invalid node binary path") - .to_path_buf(); + .to_path_buf()]; if let Some(existing_path) = std::env::var_os("PATH") { - if !existing_path.is_empty() { - env_path.push(":"); - env_path.push(&existing_path); - } + let mut paths = std::env::split_paths(&existing_path).collect::>(); + env_path.append(&mut paths); } + let env_path = + std::env::join_paths(env_path).context("failed to create PATH env variable")?; + if smol::fs::metadata(&node_binary).await.is_err() { return Err(anyhow!("missing node binary file")); }