Release Notes: - Fixed a case where system NPM configuration could effect Node based language server installation.
Unified · Split
| @@ -2,7 +2,7 @@ use anyhow::{anyhow, bail, Context, Result}; · 1 unmodified line | |||
| 2 | use async_compression::futures::bufread::GzipDecoder; | 2 | use async_compression::futures::bufread::GzipDecoder; |
| 3 | use async_tar::Archive; | 3 | use async_tar::Archive; |
| 4 | use serde::Deserialize; | 4 | use serde::Deserialize; |
| 5 | use smol::{fs, io::BufReader, process::Command}; | 5 | use smol::{fs, io::BufReader, lock::Mutex, process::Command}; |
| 6 | use std::process::{Output, Stdio}; | 6 | use std::process::{Output, Stdio}; |
| 7 | use std::{ | 7 | use std::{ |
| 8 | env::consts, | 8 | env::consts, |
| @@ -45,14 +45,19 @@ pub trait NodeRuntime: Send + Sync { · 36 unmodified lines | |||
| 45 | 45 | ||
| 46 | pub struct RealNodeRuntime { | 46 | pub struct RealNodeRuntime { |
| 47 | http: Arc<dyn HttpClient>, | 47 | http: Arc<dyn HttpClient>, |
| 48 | installation_lock: Mutex<()>, | ||
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | impl RealNodeRuntime { | 51 | impl RealNodeRuntime { |
| 51 | pub fn new(http: Arc<dyn HttpClient>) -> Arc<dyn NodeRuntime> { | 52 | pub fn new(http: Arc<dyn HttpClient>) -> Arc<dyn NodeRuntime> { |
| 52 | Arc::new(RealNodeRuntime { http }) | 53 | Arc::new(RealNodeRuntime { |
| 54 | http, | ||
| 55 | installation_lock: Mutex::new(()), | ||
| 56 | }) | ||
| 53 | } | 57 | } |
| 54 | 58 | ||
| 55 | async fn install_if_needed(&self) -> Result<PathBuf> { | 59 | async fn install_if_needed(&self) -> Result<PathBuf> { |
| 60 | let _lock = self.installation_lock.lock().await; | ||
| 56 | log::info!("Node runtime install_if_needed"); | 61 | log::info!("Node runtime install_if_needed"); |
| 57 | 62 | ||
| 58 | let arch = match consts::ARCH { | 63 | let arch = match consts::ARCH { |
| @@ -73,6 +78,9 @@ impl RealNodeRuntime { · 14 unmodified lines | |||
| 73 | .stdin(Stdio::null()) | 78 | .stdin(Stdio::null()) |
| 74 | .stdout(Stdio::null()) | 79 | .stdout(Stdio::null()) |
| 75 | .stderr(Stdio::null()) | 80 | .stderr(Stdio::null()) |
| 81 | .args(["--cache".into(), node_dir.join("cache")]) | ||
| 82 | .args(["--userconfig".into(), node_dir.join("blank_user_npmrc")]) | ||
| 83 | .args(["--globalconfig".into(), node_dir.join("blank_global_npmrc")]) | ||
| 76 | .status() | 84 | .status() |
| 77 | .await; | 85 | .await; |
| 78 | let valid = matches!(result, Ok(status) if status.success()); | 86 | let valid = matches!(result, Ok(status) if status.success()); |
| @@ -96,6 +104,11 @@ impl RealNodeRuntime { · 17 unmodified lines | |||
| 96 | archive.unpack(&node_containing_dir).await?; | 104 | archive.unpack(&node_containing_dir).await?; |
| 97 | } | 105 | } |
| 98 | 106 | ||
| 107 | // Note: Not in the `if !valid {}` so we can populate these for existing installations | ||
| 108 | _ = fs::create_dir(node_dir.join("cache")).await; | ||
| 109 | _ = fs::write(node_dir.join("blank_user_npmrc"), []).await; | ||
| 110 | _ = fs::write(node_dir.join("blank_global_npmrc"), []).await; | ||
| 111 | |||
| 99 | anyhow::Ok(node_dir) | 112 | anyhow::Ok(node_dir) |
| 100 | } | 113 | } |
| 101 | } | 114 | } |
| @@ -137,7 +150,17 @@ impl NodeRuntime for RealNodeRuntime { · 35 unmodified lines | |||
| 137 | 150 | ||
| 138 | let mut command = Command::new(node_binary); | 151 | let mut command = Command::new(node_binary); |
| 139 | command.env("PATH", env_path); | 152 | command.env("PATH", env_path); |
| 140 | command.arg(npm_file).arg(subcommand).args(args); | 153 | command.arg(npm_file).arg(subcommand); |
| 154 | command.args(["--cache".into(), installation_path.join("cache")]); | ||
| 155 | command.args([ | ||
| 156 | "--userconfig".into(), | ||
| 157 | installation_path.join("blank_user_npmrc"), | ||
| 158 | ]); | ||
| 159 | command.args([ | ||
| 160 | "--globalconfig".into(), | ||
| 161 | installation_path.join("blank_global_npmrc"), | ||
| 162 | ]); | ||
| 163 | command.args(args); | ||
| 141 | 164 | ||
| 142 | if let Some(directory) = directory { | 165 | if let Some(directory) = directory { |
| 143 | command.current_dir(directory); | 166 | command.current_dir(directory); |