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 <mrnugget@gmail.com>
This commit is contained in:
张小白 2024-05-22 12:14:44 +08:00 committed by GitHub
parent 71a94c775b
commit b451af4906
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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::<Vec<_>>();
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"));
}