diff --git a/README.md b/README.md index d0a8afc..6edf92d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ developing applications in Rust for Espressif SoC's. To better understand what `espup` installs, see [`Rust on ESP targets` chapter of `The Rust on ESP Book`](https://esp-rs.github.io/book/installation/index.html) ## Requirements -Before running or installing `espup`, make sure that [`rustup`](https://www.rust-lang.org/tools/install) and the following dependencies are installed. +Before running or installing `espup`, make sure that the following dependencies are installed. ### Windows - [git](https://git-scm.com/download/win). diff --git a/src/toolchain/rust.rs b/src/toolchain/rust.rs index 92b6ae8..cb1c764 100644 --- a/src/toolchain/rust.rs +++ b/src/toolchain/rust.rs @@ -253,23 +253,97 @@ pub fn get_rustup_home() -> PathBuf { pub fn check_rust_installation(nightly_version: &str) -> Result<()> { info!("{} Checking existing Rust installation", emoji::WRENCH); - if let Ok(child_output) = cmd!("rustup", "toolchain", "list") + match cmd!("rustup", "toolchain", "list") .into_inner() .stdout(Stdio::piped()) .output() { - let result = String::from_utf8_lossy(&child_output.stdout); - if !result.contains("nightly") { - warn!("{} Rust nightly toolchain not found", emoji::WARN); - install_rust_nightly(nightly_version)?; + Ok(child_output) => { + let result = String::from_utf8_lossy(&child_output.stdout); + if !result.contains("nightly") { + warn!("{} Rust nightly toolchain not found", emoji::WARN); + install_rust_nightly(nightly_version)?; + } + } + Err(e) => { + if let std::io::ErrorKind::NotFound = e.kind() { + warn!("{} rustup was not found.", emoji::WARN); + install_rustup(nightly_version)?; + } else { + bail!("{} Error detecting rustup: {}", emoji::ERROR, e); + } } - } else { - bail!("{} rustup was not found. Please, install rustup: https://www.rust-lang.org/tools/install", emoji::ERROR); } Ok(()) } +/// Installs rustup +fn install_rustup(nightly_version: &str) -> Result<()> { + #[cfg(windows)] + let rustup_init_path = download_file( + "https://win.rustup.rs/x86_64".to_string(), + "rustup-init.exe", + &get_dist_path("rustup"), + false, + )?; + #[cfg(unix)] + let rustup_init_path = download_file( + "https://sh.rustup.rs".to_string(), + "rustup-init.sh", + &get_dist_path("rustup"), + false, + )?; + info!( + "{} Installing rustup with {} toolchain", + emoji::WRENCH, + nightly_version + ); + + #[cfg(windows)] + cmd!( + rustup_init_path, + "--default-toolchain", + nightly_version, + "--profile", + "minimal", + "-y" + ) + .run()?; + #[cfg(not(windows))] + cmd!( + "/bin/bash", + rustup_init_path, + "--default-toolchain", + nightly_version, + "--profile", + "minimal", + "-y" + ) + .run()?; + + #[cfg(windows)] + let path = format!( + "{};{}", + std::env::var("PATH").unwrap(), + get_cargo_home().join("bin").display() + ); + #[cfg(unix)] + let path = format!( + "{}:{}", + std::env::var("PATH").unwrap(), + get_cargo_home().join("bin").display() + ); + + std::env::set_var("PATH", path); + warn!( + "{} Please restart your terminal after the installation for the changes to take effect.", + emoji::WARN + ); + + Ok(()) +} + /// Installs the RiscV target. pub fn install_riscv_target(nightly_version: &str) -> Result<()> { info!("{} Installing Riscv target", emoji::WRENCH);