History

Avoid user NPM config/cache & put NodeRuntime installation behind a lock (#3324)

Release Notes: - Fixed a case where system NPM configuration could effect Node based language server installation.

Julia committed 3 years ago

Commit 75490fe2 parents 5c8db99 59ec9e51 file · +26 −3Browse files

Unified · Split

crates/node_runtime/src/node_runtime.rs+26−3
@@ -2,7 +2,7 @@ use anyhow::{anyhow, bail, Context, Result}; · 1 unmodified line
22 use async_compression::futures::bufread::GzipDecoder;
33 use async_tar::Archive;
44 use serde::Deserialize;
5−use smol::{fs, io::BufReader, process::Command};
5+use smol::{fs, io::BufReader, lock::Mutex, process::Command};
66 use std::process::{Output, Stdio};
77 use std::{
88 env::consts,
@@ -45,14 +45,19 @@ pub trait NodeRuntime: Send + Sync { · 36 unmodified lines
4545
4646 pub struct RealNodeRuntime {
4747 http: Arc<dyn HttpClient>,
48+ installation_lock: Mutex<()>,
4849 }
4950
5051 impl RealNodeRuntime {
5152 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+ })
5357 }
5458
5559 async fn install_if_needed(&self) -> Result<PathBuf> {
60+ let _lock = self.installation_lock.lock().await;
5661 log::info!("Node runtime install_if_needed");
5762
5863 let arch = match consts::ARCH {
@@ -73,6 +78,9 @@ impl RealNodeRuntime { · 14 unmodified lines
7378 .stdin(Stdio::null())
7479 .stdout(Stdio::null())
7580 .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")])
7684 .status()
7785 .await;
7886 let valid = matches!(result, Ok(status) if status.success());
@@ -96,6 +104,11 @@ impl RealNodeRuntime { · 17 unmodified lines
96104 archive.unpack(&node_containing_dir).await?;
97105 }
98106
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+
99112 anyhow::Ok(node_dir)
100113 }
101114 }
@@ -137,7 +150,17 @@ impl NodeRuntime for RealNodeRuntime { · 35 unmodified lines
137150
138151 let mut command = Command::new(node_binary);
139152 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);
141164
142165 if let Some(directory) = directory {
143166 command.current_dir(directory);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t