about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIvar Scholten <ivar.scholten@protonmail.com>2024-08-27 13:59:01 +0200
committerIvar Scholten <ivar.scholten@protonmail.com>2024-08-27 14:25:13 +0200
commit6e387a3fb1a1ab68410fc00b6a981d76b42bcbaa (patch)
treece5dbe82313ef3fbe72e734a67851b7f79eb5d94
parentf0bfd43b323b2def975379616f34ecfe57048dfd (diff)
downloadrust-6e387a3fb1a1ab68410fc00b6a981d76b42bcbaa.tar.gz
rust-6e387a3fb1a1ab68410fc00b6a981d76b42bcbaa.zip
fix: do not assume rustup is installed in xtask codegen
When formatting generated code the xtask crate attempts to run `rustup run stable rustfmt`,
which fails if `rustup` is not installed. This results in test failures when another source manages
the compiler toolchain, for example when using Nix (or any other distro-specific packaging solution):

* xtask::codegen::grammar::test
* xtask::codegen::assists_doc_tests::test

With this commit xtask will first attempt to run `rustup run stable rustfmt`, and if that fails just
plain `rustfmt`. It still validates a stable version is being used.

This allows `cargo test` to pass on systems that do not use `rustup`.
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen.rs34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs
index aeb0c00ae6a..09bfed19b0e 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen.rs
@@ -126,27 +126,31 @@ impl fmt::Display for Location {
     }
 }
 
-fn ensure_rustfmt(sh: &Shell) {
-    let version = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap_or_default();
-    if !version.contains("stable") {
-        panic!(
-            "Failed to run rustfmt from toolchain 'stable'. \
-                 Please run `rustup component add rustfmt --toolchain stable` to install it.",
-        );
+fn rustfmt_executable(sh: &Shell) -> &str {
+    // First try explicitly requesting the stable channel via rustup in case nightly is being used by default,
+    // then plain rustfmt in case rustup isn't being used to manage the compiler (e.g. when using Nix).
+    for executable in ["rustup run stable rustfmt", "rustfmt"] {
+        let version = cmd!(sh, "{executable} --version").read().unwrap_or_default();
+        if version.contains("stable") {
+            return executable;
+        }
     }
+
+    panic!(
+        "Failed to run rustfmt from toolchain 'stable'. \
+                 Please run `rustup component add rustfmt --toolchain stable` to install it.",
+    );
 }
 
 fn reformat(text: String) -> String {
     let sh = Shell::new().unwrap();
-    ensure_rustfmt(&sh);
+    let rustfmt_exe = rustfmt_executable(&sh);
     let rustfmt_toml = project_root().join("rustfmt.toml");
-    let mut stdout = cmd!(
-        sh,
-        "rustup run stable rustfmt --config-path {rustfmt_toml} --config fn_single_line=true"
-    )
-    .stdin(text)
-    .read()
-    .unwrap();
+    let mut stdout =
+        cmd!(sh, "{rustfmt_exe} --config-path {rustfmt_toml} --config fn_single_line=true")
+            .stdin(text)
+            .read()
+            .unwrap();
     if !stdout.ends_with('\n') {
         stdout.push('\n');
     }