mirror of
https://github.com/esp-rs/espup.git
synced 2025-10-02 15:14:56 +00:00
refactor: ♻️ Refactor main and add logs
This commit is contained in:
parent
f0a8f7cd4e
commit
780e0f515a
@ -16,9 +16,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
use strum::{Display, EnumIter, EnumString, IntoStaticStr};
|
use strum::{Display, EnumIter, EnumString, IntoStaticStr};
|
||||||
|
|
||||||
const DEFAULT_GIT_REPOSITORY: &str = "https://github.com/espressif/esp-idf";
|
pub const DEFAULT_GIT_REPOSITORY: &str = "https://github.com/espressif/esp-idf";
|
||||||
|
|
||||||
pub const DEFAULT_CMAKE_GENERATOR: Generator = {
|
const DEFAULT_CMAKE_GENERATOR: Generator = {
|
||||||
// No Ninja builds for linux=aarch64 from Espressif yet
|
// No Ninja builds for linux=aarch64 from Espressif yet
|
||||||
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
|
||||||
{
|
{
|
||||||
@ -149,6 +149,11 @@ impl EspIdfRepo {
|
|||||||
remove_dir_all(espidf_dir.join("tools").join("test_idf_size"))?;
|
remove_dir_all(espidf_dir.join("tools").join("test_idf_size"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
exports.push(format!("$Env:IDF_TOOLS_PATH=\"{}\"", get_tools_path()));
|
||||||
|
#[cfg(unix)]
|
||||||
|
exports.push(format!("export IDF_TOOLS_PATH=\"{}\"", get_tools_path()));
|
||||||
|
|
||||||
Ok(exports)
|
Ok(exports)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +185,7 @@ pub fn get_install_path(repo: EspIdfRemote) -> PathBuf {
|
|||||||
};
|
};
|
||||||
// Replace all directory separators with a dash `-`, so that we don't create
|
// Replace all directory separators with a dash `-`, so that we don't create
|
||||||
// subfolders for tag or branch names that contain such characters.
|
// subfolders for tag or branch names that contain such characters.
|
||||||
let repo_dir = repo_dir.replace(&['/', '\\'], "-");
|
let repo_dir = repo_dir.replace(['/', '\\'], "-");
|
||||||
|
|
||||||
let mut install_path = PathBuf::from(get_tools_path());
|
let mut install_path = PathBuf::from(get_tools_path());
|
||||||
install_path = install_path.join(PathBuf::from(format!("esp-idf-{}", repo_url_hash)));
|
install_path = install_path.join(PathBuf::from(format!("esp-idf-{}", repo_url_hash)));
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use crate::emoji;
|
use crate::emoji;
|
||||||
use crate::espidf::get_tool_path;
|
use crate::espidf::get_tool_path;
|
||||||
use crate::utils::download_file;
|
use crate::utils::download_file;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Ok, Result};
|
||||||
use log::info;
|
use log::info;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
@ -27,15 +27,16 @@ pub struct LlvmToolchain {
|
|||||||
|
|
||||||
impl LlvmToolchain {
|
impl LlvmToolchain {
|
||||||
/// Gets the name of the LLVM arch based on the host triple.
|
/// Gets the name of the LLVM arch based on the host triple.
|
||||||
fn get_arch(host_triple: &str) -> Result<String, String> {
|
fn get_arch(host_triple: &str) -> Result<String> {
|
||||||
match host_triple {
|
match host_triple {
|
||||||
"aarch64-apple-darwin" | "x86_64-apple-darwin" => Ok("macos".to_string()),
|
"aarch64-apple-darwin" | "x86_64-apple-darwin" => Ok("macos".to_string()),
|
||||||
"x86_64-unknown-linux-gnu" => Ok("linux-amd64".to_string()),
|
"x86_64-unknown-linux-gnu" => Ok("linux-amd64".to_string()),
|
||||||
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => Ok("win64".to_string()),
|
"x86_64-pc-windows-msvc" | "x86_64-pc-windows-gnu" => Ok("win64".to_string()),
|
||||||
_ => Err(format!(
|
_ => bail!(
|
||||||
"No LLVM arch found for the host triple: {}",
|
"{} No LLVM arch found for the host triple: {}",
|
||||||
|
emoji::ERROR,
|
||||||
host_triple
|
host_triple
|
||||||
)),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ impl LlvmToolchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the binary path.
|
/// Gets the binary path.
|
||||||
pub fn get_lib_path(&self) -> String {
|
fn get_lib_path(&self) -> String {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let lib_path = format!("{}/bin", get_tool_path("xtensa-esp32-elf-clang"));
|
let lib_path = format!("{}/bin", get_tool_path("xtensa-esp32-elf-clang"));
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -64,7 +65,9 @@ impl LlvmToolchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Installs the LLVM toolchain.
|
/// Installs the LLVM toolchain.
|
||||||
pub fn install(&self) -> Result<()> {
|
pub fn install(&self) -> Result<Vec<String>> {
|
||||||
|
let mut exports: Vec<String> = Vec::new();
|
||||||
|
|
||||||
if Path::new(&self.path).exists() {
|
if Path::new(&self.path).exists() {
|
||||||
bail!(
|
bail!(
|
||||||
"{} Previous installation of LLVM exist in: {}.\n Please, remove the directory before new installation.",
|
"{} Previous installation of LLVM exist in: {}.\n Please, remove the directory before new installation.",
|
||||||
@ -83,7 +86,18 @@ impl LlvmToolchain {
|
|||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
// Set environment variables.
|
||||||
|
#[cfg(windows)]
|
||||||
|
exports.push(format!(
|
||||||
|
"$Env:LIBCLANG_PATH=\"{}/libclang.dll\"",
|
||||||
|
self.get_lib_path()
|
||||||
|
));
|
||||||
|
#[cfg(windows)]
|
||||||
|
exports.push(format!("$Env:PATH+=\";{}\"", self.get_lib_path()));
|
||||||
|
#[cfg(unix)]
|
||||||
|
exports.push(format!("export LIBCLANG_PATH=\"{}\"", self.get_lib_path()));
|
||||||
|
|
||||||
|
Ok(exports)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new instance with default values and proper toolchain version.
|
/// Create a new instance with default values and proper toolchain version.
|
||||||
|
76
src/main.rs
76
src/main.rs
@ -1,10 +1,9 @@
|
|||||||
use crate::chip::Chip;
|
use crate::chip::Chip;
|
||||||
use crate::espidf::{get_install_path, get_tool_path, get_tools_path, EspIdfRepo};
|
use crate::espidf::{get_install_path, get_tool_path, EspIdfRepo};
|
||||||
use crate::gcc_toolchain::install_gcc_targets;
|
use crate::gcc_toolchain::install_gcc_targets;
|
||||||
use crate::llvm_toolchain::LlvmToolchain;
|
use crate::llvm_toolchain::LlvmToolchain;
|
||||||
use crate::rust_toolchain::{
|
use crate::rust_toolchain::{
|
||||||
check_rust_installation, get_rust_crate, get_rustup_home, install_riscv_target, RustCrate,
|
check_rust_installation, get_rustup_home, install_riscv_target, RustCrate, RustToolchain,
|
||||||
RustToolchain,
|
|
||||||
};
|
};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
clear_dist_folder, export_environment, logging::initialize_logger, parse_targets,
|
clear_dist_folder, export_environment, logging::initialize_logger, parse_targets,
|
||||||
@ -13,7 +12,7 @@ use anyhow::Result;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use embuild::espidf::{parse_esp_idf_git_ref, EspIdfRemote};
|
use embuild::espidf::{parse_esp_idf_git_ref, EspIdfRemote};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use std::{fs::remove_dir_all, path::PathBuf};
|
use std::{collections::HashSet, fs::remove_dir_all, path::PathBuf};
|
||||||
|
|
||||||
mod chip;
|
mod chip;
|
||||||
mod emoji;
|
mod emoji;
|
||||||
@ -128,8 +127,8 @@ fn install(args: InstallOpts) -> Result<()> {
|
|||||||
|
|
||||||
info!("{} Installing esp-rs", emoji::DISC);
|
info!("{} Installing esp-rs", emoji::DISC);
|
||||||
let targets: Vec<Chip> = parse_targets(&args.targets).unwrap();
|
let targets: Vec<Chip> = parse_targets(&args.targets).unwrap();
|
||||||
let mut extra_crates: Vec<RustCrate> =
|
let mut extra_crates: HashSet<RustCrate> =
|
||||||
args.extra_crates.split(',').map(get_rust_crate).collect();
|
args.extra_crates.split(',').map(RustCrate::new).collect();
|
||||||
let mut exports: Vec<String> = Vec::new();
|
let mut exports: Vec<String> = Vec::new();
|
||||||
let export_file = args.export_file.clone();
|
let export_file = args.export_file.clone();
|
||||||
let rust_toolchain = RustToolchain::new(args.toolchain_version.clone());
|
let rust_toolchain = RustToolchain::new(args.toolchain_version.clone());
|
||||||
@ -167,36 +166,25 @@ fn install(args: InstallOpts) -> Result<()> {
|
|||||||
|
|
||||||
rust_toolchain.install_xtensa_rust()?;
|
rust_toolchain.install_xtensa_rust()?;
|
||||||
|
|
||||||
llvm.install()?;
|
exports.extend(llvm.install()?);
|
||||||
#[cfg(windows)]
|
|
||||||
exports.push(format!(
|
|
||||||
"$Env:LIBCLANG_PATH=\"{}/libclang.dll\"",
|
|
||||||
&llvm.get_lib_path()
|
|
||||||
));
|
|
||||||
#[cfg(windows)]
|
|
||||||
exports.push(format!("$Env:PATH+=\";{}\"", &llvm.get_lib_path()));
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
exports.push(format!("export LIBCLANG_PATH=\"{}\"", &llvm.get_lib_path()));
|
|
||||||
|
|
||||||
if targets.contains(&Chip::ESP32C3) {
|
if targets.contains(&Chip::ESP32C3) {
|
||||||
install_riscv_target(&args.nightly_version)?;
|
install_riscv_target(&args.nightly_version)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.espidf_version.is_some() {
|
if let Some(espidf_version) = &args.espidf_version {
|
||||||
let espidf_version = args.espidf_version.unwrap();
|
let repo = EspIdfRepo::new(espidf_version, args.profile_minimal, targets);
|
||||||
let repo = EspIdfRepo::new(&espidf_version, args.profile_minimal, targets);
|
exports.extend(repo.install()?);
|
||||||
exports.extend(repo.install().unwrap().iter().cloned());
|
extra_crates.insert(RustCrate::new("ldproxy"));
|
||||||
#[cfg(windows)]
|
|
||||||
exports.push(format!("$Env:IDF_TOOLS_PATH=\"{}\"", get_tools_path()));
|
|
||||||
#[cfg(unix)]
|
|
||||||
exports.push(format!("export IDF_TOOLS_PATH=\"{}\"", get_tools_path()));
|
|
||||||
|
|
||||||
extra_crates.push(get_rust_crate("ldproxy"));
|
|
||||||
} else {
|
} else {
|
||||||
exports.extend(install_gcc_targets(targets).unwrap().iter().cloned());
|
exports.extend(install_gcc_targets(targets).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"{} Installing the following crates: {:#?}",
|
||||||
|
emoji::DEBUG,
|
||||||
|
extra_crates
|
||||||
|
);
|
||||||
for extra_crate in extra_crates {
|
for extra_crate in extra_crates {
|
||||||
extra_crate.install()?;
|
extra_crate.install()?;
|
||||||
}
|
}
|
||||||
@ -207,15 +195,24 @@ fn install(args: InstallOpts) -> Result<()> {
|
|||||||
|
|
||||||
export_environment(&export_file, &exports)?;
|
export_environment(&export_file, &exports)?;
|
||||||
|
|
||||||
info!("{} Installation completed!", emoji::CHECK);
|
info!("{} Installation suscesfully completed!", emoji::CHECK);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Uninstalls esp-rs environment
|
/// Uninstalls esp-rs environment
|
||||||
fn uninstall(args: UninstallOpts) -> Result<()> {
|
fn uninstall(args: UninstallOpts) -> Result<()> {
|
||||||
initialize_logger(&args.log_level);
|
initialize_logger(&args.log_level);
|
||||||
|
|
||||||
info!("{} Uninstalling esp-rs", emoji::DISC);
|
info!("{} Uninstalling esp-rs", emoji::DISC);
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"{} Arguments:
|
||||||
|
- Remove Clang: {}
|
||||||
|
- ESP-IDF version: {:#?}",
|
||||||
|
emoji::INFO,
|
||||||
|
&args.remove_clang,
|
||||||
|
&args.espidf_version,
|
||||||
|
);
|
||||||
|
|
||||||
info!("{} Deleting Xtensa Rust toolchain", emoji::WRENCH);
|
info!("{} Deleting Xtensa Rust toolchain", emoji::WRENCH);
|
||||||
remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?;
|
remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?;
|
||||||
|
|
||||||
@ -226,31 +223,38 @@ fn uninstall(args: UninstallOpts) -> Result<()> {
|
|||||||
|
|
||||||
clear_dist_folder()?;
|
clear_dist_folder()?;
|
||||||
|
|
||||||
if args.espidf_version.is_some() {
|
if let Some(espidf_version) = &args.espidf_version {
|
||||||
info!("{} Deleting ESP-IDF", emoji::WRENCH);
|
info!("{} Deleting ESP-IDF", emoji::WRENCH);
|
||||||
let repo = EspIdfRemote {
|
let repo = EspIdfRemote {
|
||||||
git_ref: parse_esp_idf_git_ref(&args.espidf_version.unwrap()),
|
git_ref: parse_esp_idf_git_ref(espidf_version),
|
||||||
repo_url: Some("https://github.com/espressif/esp-idf".to_string()),
|
repo_url: Some(espidf::DEFAULT_GIT_REPOSITORY.to_string()),
|
||||||
};
|
};
|
||||||
remove_dir_all(get_install_path(repo).parent().unwrap())?;
|
remove_dir_all(get_install_path(repo).parent().unwrap())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("{} Uninstallation completed!", emoji::CHECK);
|
info!("{} Uninstallation suscesfully completed!", emoji::CHECK);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates Xtensa Rust toolchain
|
/// Updates Xtensa Rust toolchain
|
||||||
fn update(args: UpdateOpts) -> Result<()> {
|
fn update(args: UpdateOpts) -> Result<()> {
|
||||||
initialize_logger(&args.log_level);
|
initialize_logger(&args.log_level);
|
||||||
|
info!("{} Updating Xtensa Rust toolchain", emoji::DISC);
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"{} Arguments:
|
||||||
|
- Toolchain version: {}",
|
||||||
|
emoji::INFO,
|
||||||
|
&args.toolchain_version,
|
||||||
|
);
|
||||||
|
|
||||||
info!("{} Uninstalling esp-rs", emoji::DISC);
|
|
||||||
info!("{} Deleting previous Xtensa Rust toolchain", emoji::WRENCH);
|
info!("{} Deleting previous Xtensa Rust toolchain", emoji::WRENCH);
|
||||||
remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?;
|
remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?;
|
||||||
|
|
||||||
let rust_toolchain = RustToolchain::new(args.toolchain_version);
|
let rust_toolchain = RustToolchain::new(args.toolchain_version);
|
||||||
rust_toolchain.install_xtensa_rust()?;
|
rust_toolchain.install_xtensa_rust()?;
|
||||||
|
|
||||||
info!("{} Update completed!", emoji::CHECK);
|
info!("{} Update suscesfully completed!", emoji::CHECK);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ impl RustToolchain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Hash, Eq, PartialEq, Debug)]
|
||||||
pub struct BinstallCrate {
|
pub struct BinstallCrate {
|
||||||
/// Crate version.
|
/// Crate version.
|
||||||
pub url: String,
|
pub url: String,
|
||||||
@ -143,7 +143,7 @@ pub struct BinstallCrate {
|
|||||||
pub fmt: String,
|
pub fmt: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Hash, Eq, PartialEq, Debug)]
|
||||||
pub struct RustCrate {
|
pub struct RustCrate {
|
||||||
/// Crate name.
|
/// Crate name.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -152,7 +152,7 @@ pub struct RustCrate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RustCrate {
|
impl RustCrate {
|
||||||
/// Installs an extra crate.
|
/// Installs a crate.
|
||||||
pub fn install(&self) -> Result<()> {
|
pub fn install(&self) -> Result<()> {
|
||||||
cmd!("cargo", "install", "cargo-binstall").run()?;
|
cmd!("cargo", "install", "cargo-binstall").run()?;
|
||||||
info!("{} Installing {} crate", emoji::WRENCH, self.name);
|
info!("{} Installing {} crate", emoji::WRENCH, self.name);
|
||||||
@ -175,6 +175,52 @@ impl RustCrate {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a crate instance.
|
||||||
|
pub fn new(name: &str) -> Self {
|
||||||
|
match name {
|
||||||
|
// "ldproxy" => {
|
||||||
|
// RustCrate {
|
||||||
|
// name: name.to_string(),
|
||||||
|
// binstall: Some(BinstallCrate {
|
||||||
|
// url: "{ repo }/releases/download/{ name }-v{ version }/{ name }-{ target }.{ archive-format }".to_string(),
|
||||||
|
// bin: "{ bin }{ binary-ext }".to_string(),
|
||||||
|
// fmt: "zip".to_string(),
|
||||||
|
// }),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// "espflash" => {
|
||||||
|
// RustCrate {
|
||||||
|
// name: name.to_string(),
|
||||||
|
// binstall: Some(BinstallCrate {
|
||||||
|
// url: "{ repo }/releases/download/{ name }-v{ version }/{ name }-{ target }.{ archive-format }".to_string(),
|
||||||
|
// bin: "{ bin }{ binary-ext }".to_string(),
|
||||||
|
// fmt: "zip".to_string(),
|
||||||
|
// }),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
"cargo-generate" => {
|
||||||
|
RustCrate {
|
||||||
|
name: name.to_string() + "@0.15.2",
|
||||||
|
binstall: Some(BinstallCrate {
|
||||||
|
url: "{ repo }/releases/download/v{ version }/{ name}-{ version }-{ target }.{ archive-format }".to_string(),
|
||||||
|
bin: "{ bin }{ binary-ext }".to_string(),
|
||||||
|
fmt: "tgz".to_string(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// "wokwi-server" => {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// "web-flash" => {
|
||||||
|
|
||||||
|
// },
|
||||||
|
_ => RustCrate {
|
||||||
|
name: name.to_string(),
|
||||||
|
binstall: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the artifact extension based on the host architecture.
|
/// Gets the artifact extension based on the host architecture.
|
||||||
@ -232,52 +278,6 @@ pub fn check_rust_installation(nightly_version: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retuns the RustCrate from a given name.
|
|
||||||
pub fn get_rust_crate(name: &str) -> RustCrate {
|
|
||||||
match name {
|
|
||||||
// "ldproxy" => {
|
|
||||||
// RustCrate {
|
|
||||||
// name: name.to_string(),
|
|
||||||
// binstall: Some(BinstallCrate {
|
|
||||||
// url: "{ repo }/releases/download/{ name }-v{ version }/{ name }-{ target }.{ archive-format }".to_string(),
|
|
||||||
// bin: "{ bin }{ binary-ext }".to_string(),
|
|
||||||
// fmt: "zip".to_string(),
|
|
||||||
// }),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// "espflash" => {
|
|
||||||
// RustCrate {
|
|
||||||
// name: name.to_string(),
|
|
||||||
// binstall: Some(BinstallCrate {
|
|
||||||
// url: "{ repo }/releases/download/{ name }-v{ version }/{ name }-{ target }.{ archive-format }".to_string(),
|
|
||||||
// bin: "{ bin }{ binary-ext }".to_string(),
|
|
||||||
// fmt: "zip".to_string(),
|
|
||||||
// }),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
"cargo-generate" => {
|
|
||||||
RustCrate {
|
|
||||||
name: name.to_string() + "@0.15.2",
|
|
||||||
binstall: Some(BinstallCrate {
|
|
||||||
url: "{ repo }/releases/download/v{ version }/{ name}-{ version }-{ target }.{ archive-format }".to_string(),
|
|
||||||
bin: "{ bin }{ binary-ext }".to_string(),
|
|
||||||
fmt: "tgz".to_string(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// "wokwi-server" => {
|
|
||||||
|
|
||||||
// },
|
|
||||||
// "web-flash" => {
|
|
||||||
|
|
||||||
// },
|
|
||||||
_ => RustCrate {
|
|
||||||
name: name.to_string(),
|
|
||||||
binstall: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Installs rustup
|
/// Installs rustup
|
||||||
fn install_rustup(nightly_version: &str) -> Result<()> {
|
fn install_rustup(nightly_version: &str) -> Result<()> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user