From fb2c3eb89294070091fde9c034119a2358cb275e Mon Sep 17 00:00:00 2001 From: Hasan Ali Date: Sat, 26 Mar 2022 22:29:57 +0000 Subject: [PATCH] Avoid hardcoded distro name --- Cargo.lock | 5 +-- lapce-data/Cargo.toml | 1 + lapce-data/src/proxy.rs | 77 +++++++++++++++++++++++++++++++++-------- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4383d90d..e8cfa01d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,9 +258,9 @@ checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" [[package]] name = "bytemuck" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" +checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" dependencies = [ "bytemuck_derive", ] @@ -1885,6 +1885,7 @@ dependencies = [ "base64", "bit-vec 0.5.1", "bitflags", + "bytemuck", "cc", "chrono", "config", diff --git a/lapce-data/Cargo.toml b/lapce-data/Cargo.toml index b2207bde..62cfd5a5 100644 --- a/lapce-data/Cargo.toml +++ b/lapce-data/Cargo.toml @@ -56,6 +56,7 @@ structdesc = { git = "https://github.com/lapce/structdesc" } lapce-core = { path = "../lapce-core" } lapce-rpc = { path = "../lapce-rpc" } lapce-proxy = { path = "../lapce-proxy" } +bytemuck = "1.8.0" [build-dependencies] cc = "1" diff --git a/lapce-data/src/proxy.rs b/lapce-data/src/proxy.rs index a8d72806..7499165d 100644 --- a/lapce-data/src/proxy.rs +++ b/lapce-data/src/proxy.rs @@ -25,7 +25,6 @@ use lsp_types::Position; use lsp_types::Url; use parking_lot::Mutex; -use serde::{Deserialize, Serialize}; use serde_json::json; use serde_json::Value; use xi_rope::spans::SpansBuilder; @@ -230,7 +229,12 @@ fn start(&self, workspace: LapceWorkspace) -> Result<()> { self.start_remote(SshRemote { user, host }, core_sender)?; } LapceWorkspaceType::RemoteWSL => { - self.start_remote(WslRemote, core_sender)?; + let distro = WslDistro::all()? + .into_iter() + .find(|distro| distro.default) + .ok_or_else(|| anyhow!("no default distro found"))? + .name; + self.start_remote(WslRemote { distro }, core_sender)?; } } @@ -591,6 +595,13 @@ pub fn stop(&self) { } } +fn new_command(program: &str) -> Command { + let mut cmd = Command::new(program); + #[cfg(target_os = "windows")] + cmd.creation_flags(0x08000000); + cmd +} + trait Remote: Sized { fn home_dir(&self) -> Result { let cmd = self @@ -631,9 +642,7 @@ impl SshRemote { ]; fn command_builder(user: &str, host: &str) -> Command { - let mut cmd = Command::new("ssh"); - #[cfg(target_os = "windows")] - cmd.creation_flags(0x08000000); + let mut cmd = new_command("ssh"); cmd.arg(format!("{}@{}", user, host)).args(Self::SSH_ARGS); cmd } @@ -641,10 +650,8 @@ fn command_builder(user: &str, host: &str) -> Command { impl Remote for SshRemote { fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()> { - let mut cmd = Command::new("scp"); - #[cfg(target_os = "windows")] - let cmd = cmd.creation_flags(0x08000000); - cmd.args(Self::SSH_ARGS) + new_command("scp") + .args(Self::SSH_ARGS) .arg(local.as_ref()) .arg(dbg!(format!("{}@{}:{remote}", self.user, self.host))) .status()?; @@ -656,11 +663,53 @@ fn command_builder(&self) -> Command { } } -struct WslRemote; +#[derive(Debug)] +struct WslDistro { + pub name: String, + pub default: bool, +} + +impl WslDistro { + fn all() -> Result> { + let cmd = new_command("wsl") + .arg("-l") + .arg("-v") + .stdout(Stdio::piped()) + .output()?; + + if !cmd.status.success() { + return Err(anyhow!("failed to execute `wsl -l -v`")); + } + + let distros = String::from_utf16(bytemuck::cast_slice(&cmd.stdout))? + .lines() + .skip(1) + .filter_map(|line| { + let line = line.trim_start(); + let default = line.starts_with('*'); + let name = line + .trim_start_matches('*') + .trim_start() + .split(' ') + .next()?; + Some(WslDistro { + name: name.to_string(), + default, + }) + }) + .collect(); + + Ok(distros) + } +} + +struct WslRemote { + distro: String, +} impl Remote for WslRemote { fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()> { - let mut wsl_path = Path::new(r"\\wsl.localhost\").join("Ubuntu"); + let mut wsl_path = Path::new(r"\\wsl.localhost\").join(&self.distro); wsl_path = if remote.starts_with('~') { let home_dir = self.home_dir()?; wsl_path.join(remote.replacen('~', &home_dir, 1)) @@ -672,10 +721,8 @@ fn upload_file(&self, local: impl AsRef, remote: &str) -> Result<()> { } fn command_builder(&self) -> Command { - let mut cmd = Command::new("wsl"); - #[cfg(target_os = "windows")] - cmd.creation_flags(0x08000000); - cmd.arg("--"); + let mut cmd = new_command("wsl"); + cmd.arg("-d").arg(&self.distro).arg("--"); cmd } }