From 2974416a81a64d75e0dc1c394b75fecd96230713 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Tue, 12 Sep 2023 14:35:24 -0400 Subject: [PATCH 1/3] fix: ensure `rustfmt` runs when configured with `./` --- crates/rust-analyzer/src/handlers/request.rs | 41 +++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index b8a1a39be193..ad6319586cfe 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -4,6 +4,7 @@ use std::{ fs, io::Write as _, + path::PathBuf, process::{self, Stdio}, }; @@ -1995,7 +1996,43 @@ fn run_rustfmt( cmd } RustfmtConfig::CustomCommand { command, args } => { - let mut cmd = process::Command::new(command); + let cmd = PathBuf::from(&command); + let mut components = cmd.components(); + + // to support rustc's suggested, default configuration + let mut cmd = match components.next() { + Some(std::path::Component::CurDir) => { + let rest = components.as_path(); + + let roots = snap + .workspaces + .iter() + .flat_map(|ws| ws.workspace_definition_path()) + .collect::>(); + + let abs: Option = roots.into_iter().find_map(|base| { + let abs = base.join(rest); + std::fs::metadata(&abs).ok().map(|_| abs) + }); + + let command = match abs { + Some(cmd) => cmd, + None => { + tracing::error!( + rustfmt = ?command, + "Unable to make the format command an absolute path" + ); + anyhow::bail!( + "Unable to make the format command an absolute path: {}", + command + ); + } + }; + + process::Command::new(&command.as_os_str()) + } + _ => process::Command::new(command), + }; cmd.envs(snap.config.extra_env()); cmd.args(args); @@ -2003,6 +2040,8 @@ fn run_rustfmt( } }; + tracing::debug!(?command, "created format command"); + // try to chdir to the file so we can respect `rustfmt.toml` // FIXME: use `rustfmt --config-path` once // https://github.com/rust-lang/rustfmt/issues/4660 gets fixed From a8ec77dc7e30af115f542e137395e204b0fb5b28 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Tue, 3 Oct 2023 16:44:09 -0400 Subject: [PATCH 2/3] address PR feedback. --- crates/rust-analyzer/src/handlers/request.rs | 40 +++----------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index ad6319586cfe..8dc0c97bc58f 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -1997,41 +1997,13 @@ fn run_rustfmt( } RustfmtConfig::CustomCommand { command, args } => { let cmd = PathBuf::from(&command); - let mut components = cmd.components(); - - // to support rustc's suggested, default configuration - let mut cmd = match components.next() { - Some(std::path::Component::CurDir) => { - let rest = components.as_path(); - - let roots = snap - .workspaces - .iter() - .flat_map(|ws| ws.workspace_definition_path()) - .collect::>(); - - let abs: Option = roots.into_iter().find_map(|base| { - let abs = base.join(rest); - std::fs::metadata(&abs).ok().map(|_| abs) - }); - - let command = match abs { - Some(cmd) => cmd, - None => { - tracing::error!( - rustfmt = ?command, - "Unable to make the format command an absolute path" - ); - anyhow::bail!( - "Unable to make the format command an absolute path: {}", - command - ); - } - }; - - process::Command::new(&command.as_os_str()) + let workspace = CargoTargetSpec::for_file(&snap, file_id)?; + let mut cmd = match workspace { + Some(spec) => { + let cmd = spec.workspace_root.join(cmd); + process::Command::new(cmd.as_os_str()) } - _ => process::Command::new(command), + None => process::Command::new(cmd), }; cmd.envs(snap.config.extra_env()); From b3ebc9ab6a0793612d75d3587f9de3522f6a71bb Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Oct 2023 13:26:36 +0200 Subject: [PATCH 3/3] Check for both path separators on windows --- crates/rust-analyzer/src/handlers/request.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 8dc0c97bc58f..6c2f1ec3fede 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -2000,8 +2000,18 @@ fn run_rustfmt( let workspace = CargoTargetSpec::for_file(&snap, file_id)?; let mut cmd = match workspace { Some(spec) => { - let cmd = spec.workspace_root.join(cmd); - process::Command::new(cmd.as_os_str()) + // approach: if the command name contains a path seperator, join it with the workspace root. + // however, if the path is absolute, joining will result in the absolute path being preserved. + // as a fallback, rely on $PATH-based discovery. + let cmd_path = + if cfg!(windows) && command.contains(&[std::path::MAIN_SEPARATOR, '/']) { + spec.workspace_root.join(cmd).into() + } else if command.contains(std::path::MAIN_SEPARATOR) { + spec.workspace_root.join(cmd).into() + } else { + cmd + }; + process::Command::new(cmd_path) } None => process::Command::new(cmd), };