diff options
| author | bors <bors@rust-lang.org> | 2023-10-06 11:33:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-10-06 11:33:52 +0000 |
| commit | b1f89a84ab350091e6c20cfe30c2fab8d76b80e4 (patch) | |
| tree | e1ee6a89037e97acbfd9a2af43d8ee771dff995d | |
| parent | ef58843b9fe5d580fcaf29d8231fa607deea175f (diff) | |
| parent | b3ebc9ab6a0793612d75d3587f9de3522f6a71bb (diff) | |
| download | rust-b1f89a84ab350091e6c20cfe30c2fab8d76b80e4.tar.gz rust-b1f89a84ab350091e6c20cfe30c2fab8d76b80e4.zip | |
Auto merge of #15600 - davidbarsky:davidbarsky/broken-rustfmt-in-ra, r=Veykril
fix: ensure `rustfmt` runs when configured with `./`
(Hopefully) resolves https://github.com/rust-lang/rust-analyzer/issues/15595. This change kinda approaches canonicalization—which I am not a fan of—but only in service of making `./`-configured commands run correctly.
Longer-term, I feel like this code should be removed once `rustfmt` supports recursive searches of configuration files or interpolation of values like `${workspace_folder}` lands in rust-analyzer.
## Testing
I cloned `rustc`, setup rust-analyzer as suggested in the [`rustc` dev guide](https://rustc-dev-guide.rust-lang.org/building/suggested.html#configuring-rust-analyzer-for-rustc), saved and formatted files in `src/tools/miri` and `compiler`, and saw `rustfmt` (seemingly) correctly.
| -rw-r--r-- | crates/rust-analyzer/src/handlers/request.rs | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index b8a1a39be19..6c2f1ec3fed 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,25 @@ fn run_rustfmt( cmd } RustfmtConfig::CustomCommand { command, args } => { - let mut cmd = process::Command::new(command); + let cmd = PathBuf::from(&command); + let workspace = CargoTargetSpec::for_file(&snap, file_id)?; + let mut cmd = match workspace { + Some(spec) => { + // 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), + }; cmd.envs(snap.config.extra_env()); cmd.args(args); @@ -2003,6 +2022,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 |
