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`.
This commit is contained in:
Ivar Scholten 2024-08-27 13:59:01 +02:00
parent 0f7f68dad2
commit 7d9e4fcc07

View file

@ -126,27 +126,31 @@ impl fmt::Display for Location {
} }
} }
fn ensure_rustfmt(sh: &Shell) { fn rustfmt_executable(sh: &Shell) -> &str {
let version = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap_or_default(); // First try explicitly requesting the stable channel via rustup in case nightly is being used by default,
if !version.contains("stable") { // then plain rustfmt in case rustup isn't being used to manage the compiler (e.g. when using Nix).
panic!( for executable in ["rustup run stable rustfmt", "rustfmt"] {
"Failed to run rustfmt from toolchain 'stable'. \ let version = cmd!(sh, "{executable} --version").read().unwrap_or_default();
Please run `rustup component add rustfmt --toolchain stable` to install it.", 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 { fn reformat(text: String) -> String {
let sh = Shell::new().unwrap(); let sh = Shell::new().unwrap();
ensure_rustfmt(&sh); let rustfmt_exe = rustfmt_executable(&sh);
let rustfmt_toml = project_root().join("rustfmt.toml"); let rustfmt_toml = project_root().join("rustfmt.toml");
let mut stdout = cmd!( let mut stdout =
sh, cmd!(sh, "{rustfmt_exe} --config-path {rustfmt_toml} --config fn_single_line=true")
"rustup run stable rustfmt --config-path {rustfmt_toml} --config fn_single_line=true" .stdin(text)
) .read()
.stdin(text) .unwrap();
.read()
.unwrap();
if !stdout.ends_with('\n') { if !stdout.ends_with('\n') {
stdout.push('\n'); stdout.push('\n');
} }