use xshell::Shell;
use crate::environment::{is_quiet_mode, quiet_println};
use crate::quiet_cmd;
use crate::toolchain::{get_workspace_msrv, Toolchain};
const COMPONENTS: &str = "rust-src,clippy,rustfmt";
const TARGET: &str = "thumbv7m-none-eabi";
const ENV_NIGHTLY: &str = "RBMT_NIGHTLY";
const ENV_STABLE: &str = "RBMT_STABLE";
const ENV_MSRV: &str = "RBMT_MSRV";
pub fn run(sh: &Shell, update_nightly: bool, update_stable: bool, msrv: bool) -> Result<(), Box<dyn std::error::Error>> {
if msrv {
let msrv = get_workspace_msrv(sh)?;
println!("{}", msrv);
return Ok(());
}
if update_nightly {
install_toolchain(sh, "nightly")?;
let version = resolve_nightly_version(sh)?;
Toolchain::Nightly.write_version(sh, &version)?;
eprintln!("Updated nightly-version: {}", version);
}
if update_stable {
install_toolchain(sh, "stable")?;
let version = resolve_stable_version(sh)?;
Toolchain::Stable.write_version(sh, &version)?;
eprintln!("Updated stable-version: {}", version);
}
let nightly = Toolchain::Nightly.read_version(sh)?;
let stable = Toolchain::Stable.read_version(sh)?;
let msrv = get_workspace_msrv(sh)?;
quiet_println(&format!(
"Installing toolchains: nightly={}, stable={}, msrv={}",
nightly, stable, msrv
));
install_toolchain(sh, &nightly)?;
install_toolchain(sh, &stable)?;
install_toolchain(sh, &msrv)?;
println!("export {}={}", ENV_NIGHTLY, nightly);
println!("export {}={}", ENV_STABLE, stable);
println!("export {}={}", ENV_MSRV, msrv);
Ok(())
}
fn resolve_nightly_version(sh: &Shell) -> Result<String, Box<dyn std::error::Error>> {
let output = quiet_cmd!(sh, "rustc +nightly --verbose --version").read()?;
let date = output
.lines()
.find_map(|line| line.strip_prefix("commit-date: "))
.ok_or("Could not find commit-date in `rustc +nightly --verbose --version` output")?;
Ok(format!("nightly-{}", date))
}
fn resolve_stable_version(sh: &Shell) -> Result<String, Box<dyn std::error::Error>> {
let output = quiet_cmd!(sh, "rustc +stable --version").read()?;
let version = output
.strip_prefix("rustc ")
.and_then(|s| s.split_whitespace().next())
.ok_or("Could not parse version from `rustc +stable --version` output")?;
Ok(version.to_string())
}
fn install_toolchain(sh: &Shell, toolchain: &str) -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = quiet_cmd!(
sh,
"rustup toolchain install {toolchain} --component {COMPONENTS} --target {TARGET} --no-self-update"
);
if is_quiet_mode() {
cmd = cmd.ignore_stderr();
}
cmd.ignore_stdout().run()?;
Ok(())
}