windows: Fix extensions couldn't start if the path contained spaces (#15489)
张小白
created 1 year ago
Closes #15441 .
Fixed the issue where extensions couldn't start if the path contained
spaces. Additionally, this PR introduces the `node_environment_path`
function to obtain the PATH environment variable which includes the node
path.
Release Notes:
- N/A
Change summary
crates/languages/src/tailwind.rs | 21 +++++----------
crates/node_runtime/src/node_runtime.rs | 36 +++++++++++++++++---------
2 files changed, 30 insertions(+), 27 deletions(-)
Detailed changes
@@ -23,10 +23,16 @@ const SERVER_PATH: &str = "node_modules/.bin/tailwindcss-language-server.ps1";
#[cfg(not(target_os = "windows"))]
const SERVER_PATH: &str = "node_modules/.bin/tailwindcss-language-server";
+#[cfg(not(target_os = "windows"))]
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
vec![server_path.into(), "--stdio".into()]
}
+#[cfg(target_os = "windows")]
+fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
+ vec!["-File".into(), server_path.into(), "--stdio".into()]
+}
+
pub struct TailwindLspAdapter {
node: Arc<dyn NodeRuntime>,
}
@@ -113,20 +119,7 @@ impl LspAdapter for TailwindLspAdapter {
#[cfg(target_os = "windows")]
{
- let mut env_path = vec![self
- .node
- .binary_path()
- .await?
- .parent()
- .expect("invalid node binary path")
- .to_path_buf()];
-
- if let Some(existing_path) = std::env::var_os("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)?;
+ let env_path = self.node.node_environment_path().await?;
let mut env = HashMap::default();
env.insert("PATH".to_string(), env_path.to_string_lossy().to_string());
@@ -10,6 +10,7 @@ use semver::Version;
use serde::Deserialize;
use smol::io::BufReader;
use smol::{fs, lock::Mutex, process::Command};
+use std::ffi::OsString;
use std::io;
use std::process::{Output, Stdio};
use std::{
@@ -55,6 +56,7 @@ pub struct NpmInfoDistTags {
#[async_trait::async_trait]
pub trait NodeRuntime: Send + Sync {
async fn binary_path(&self) -> Result<PathBuf>;
+ async fn node_environment_path(&self) -> Result<OsString>;
async fn run_npm_subcommand(
&self,
@@ -216,6 +218,22 @@ impl NodeRuntime for RealNodeRuntime {
Ok(installation_path.join(NODE_PATH))
}
+ async fn node_environment_path(&self) -> Result<OsString> {
+ let installation_path = self.install_if_needed().await?;
+ let node_binary = installation_path.join(NODE_PATH);
+ let mut env_path = vec![node_binary
+ .parent()
+ .expect("invalid node binary path")
+ .to_path_buf()];
+
+ if let Some(existing_path) = std::env::var_os("PATH") {
+ let mut paths = std::env::split_paths(&existing_path).collect::<Vec<_>>();
+ env_path.append(&mut paths);
+ }
+
+ Ok(std::env::join_paths(env_path).context("failed to create PATH env variable")?)
+ }
+
async fn run_npm_subcommand(
&self,
directory: Option<&Path>,
@@ -224,21 +242,9 @@ impl NodeRuntime for RealNodeRuntime {
) -> Result<Output> {
let attempt = || async move {
let installation_path = self.install_if_needed().await?;
-
let node_binary = installation_path.join(NODE_PATH);
let npm_file = installation_path.join(NPM_PATH);
- let mut env_path = vec![node_binary
- .parent()
- .expect("invalid node binary path")
- .to_path_buf()];
-
- if let Some(existing_path) = std::env::var_os("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")?;
+ let env_path = self.node_environment_path().await?;
if smol::fs::metadata(&node_binary).await.is_err() {
return Err(anyhow!("missing node binary file"));
@@ -423,6 +429,10 @@ impl NodeRuntime for FakeNodeRuntime {
unreachable!()
}
+ async fn node_environment_path(&self) -> anyhow::Result<OsString> {
+ unreachable!()
+ }
+
async fn run_npm_subcommand(
&self,
_: Option<&Path>,