From 19acf19d171bdf1ae905aee4be39ed93428f7a55 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 21 Oct 2022 09:45:35 +0000 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E2=9C=A8=20Initial=20suppor=20fo?= =?UTF-8?q?r=20config=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 65 +++++++++++++++++++++++++-- Cargo.toml | 9 +++- src/config.rs | 76 +++++++++++++++++++++++++++++++ src/host_triple.rs | 6 ++- src/lib.rs | 1 + src/main.rs | 79 +++++++++++++++++++++------------ src/targets.rs | 3 +- src/toolchain/espidf.rs | 3 +- src/toolchain/llvm_toolchain.rs | 3 +- src/toolchain/rust_toolchain.rs | 5 ++- 10 files changed, 210 insertions(+), 40 deletions(-) create mode 100644 src/config.rs diff --git a/Cargo.lock b/Cargo.lock index 758640e..e02e003 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs" version = "4.0.0" @@ -317,6 +327,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "either" version = "1.8.0" @@ -400,18 +421,22 @@ dependencies = [ "anyhow", "clap", "console", + "directories-next", "dirs", "embuild", "env_logger", "flate2", "guess_host_triple", "log", + "miette", "openssl", "reqwest", + "serde", "strum", "strum_macros", "tar", "tempfile", + "toml", "xz2", "zip", ] @@ -790,6 +815,29 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miette" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28d6092d7e94a90bb9ea8e6c26c99d5d112d49dda2afdb4f7ea8cf09e1a5a6d" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2485ed7d1fe80704928e3eb86387439609bd0c6bb96db8208daa364cfd1e09" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "mime" version = "0.3.16" @@ -1195,18 +1243,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.145" +version = "1.0.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "6df50b7a60a0ad48e1b42eb38373eac8ff785d619fb14db917b4e63d5439361f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "a714fd32ba1d66047ce7d53dabd809e9922d538f9047de13cc4cffca47b36205" dependencies = [ "proc-macro2", "quote", @@ -1466,6 +1514,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + [[package]] name = "tower-service" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index f2f69c4..4e32b8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,15 +29,22 @@ env_logger = "0.9.0" embuild = { version = "0.30.4", features = ["espidf", "git"] } strum = { version = "0.24", features = ["derive"] } strum_macros = "0.24.3" +toml = "0.5.9" +directories-next = "2.0.0" +serde = { version = "1.0.146", features = ["derive"] } +miette = "5.3.0" [target.aarch64-unknown-linux-gnu.dependencies] openssl = { version = "0.10", features = ["vendored"] } +[target.x86_64-unknown-linux-gnu.dependencies] +openssl = { version = "0.10", features = ["vendored"] } + [package.metadata.binstall] pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }.{ archive-format }" bin-dir = "{ bin }{ binary-ext }" pkg-fmt = "zip" [profile.release] -lto = "thin" +lto = "thin" strip = true diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..df3602d --- /dev/null +++ b/src/config.rs @@ -0,0 +1,76 @@ +use crate::{ + host_triple::HostTriple, + targets::Target, + toolchain::espidf::EspIdfRepo, + toolchain::llvm_toolchain::LlvmToolchain, + toolchain::rust_toolchain::{RustCrate, RustToolchain}, +}; +use directories_next::ProjectDirs; +use miette::{IntoDiagnostic, Result, WrapErr}; +use serde::{Deserialize, Serialize}; +use std::{ + collections::HashSet, + fs::{create_dir_all, read, write}, + path::PathBuf, +}; + +/// Deserialized contents of a configuration file +#[derive(Debug, Deserialize, Serialize, Default, Clone)] +pub struct Config { + /// ESP-IDF version + pub espidf_version: Option, + // /// ESP-IDF + // pub espidf: EspIdfRepo, + /// Destination of the generated export file. + pub export_file: PathBuf, + /// Extra crates to installed. + // pub extra_crates: HashSet, + /// GCC toolchain. + // pub gcc_toolchain: GccToolchain, + /// Host triple + pub host_triple: HostTriple, + /// LLVM toolchain. + // pub llvm_toolchain: LlvmToolchain, + /// Nightly Rust toolchain version. + pub nightly_version: String, + /// Minifies the installation. + pub profile_minimal: bool, + // /// List of targets [esp32,esp32s2,esp32s3,esp32c3,all]. + pub targets: HashSet, + /// Xtensa Rust toolchain. + pub xtensa_toolchain: RustToolchain, +} + +impl Config { + /// Load the config from config file + pub fn load() -> Result { + let dirs = ProjectDirs::from("rs", "esp", "espup").unwrap(); + let file = dirs.config_dir().join("espup.toml"); + + let mut config = if let Ok(data) = read(&file) { + toml::from_slice(&data).into_diagnostic()? + } else { + Self::default() + }; + // config.save_path = file; + Ok(config) + } + + pub fn save_with(&self) -> Result<()> { + // pub fn save_with(&self, modify_fn: F) -> Result<()> { + // let mut copy = self.clone(); + // modify_fn(&mut copy); + let dirs = ProjectDirs::from("rs", "esp", "espup").unwrap(); + let file = dirs.config_dir().join("espup.toml"); + + let serialized = toml::to_string(&self.clone()) + .into_diagnostic() + .wrap_err("Failed to serialize config")?; + create_dir_all(file.parent().unwrap()) + .into_diagnostic() + .wrap_err("Failed to create config directory")?; + write(&file, serialized) + .into_diagnostic() + .wrap_err_with(|| format!("Failed to write config to {}", file.display())) + } +} diff --git a/src/host_triple.rs b/src/host_triple.rs index 44e533f..5f16ccd 100644 --- a/src/host_triple.rs +++ b/src/host_triple.rs @@ -1,15 +1,17 @@ use crate::emoji; use anyhow::{Context, Result}; use guess_host_triple::guess_host_triple; +use serde::{Deserialize, Serialize}; use std::str::FromStr; use strum::Display; use strum_macros::EnumString; -#[derive(Display, Debug, Clone, EnumString)] +#[derive(Display, Debug, Clone, EnumString, Deserialize, Serialize, Default)] pub enum HostTriple { /// 64-bit Linux #[strum(serialize = "x86_64-unknown-linux-gnu")] - X86_64UnknownLinuxGnu = 0, + #[default] + X86_64UnknownLinuxGnu, /// ARM64 Linux #[strum(serialize = "aarch64-unknown-linux-gnu")] Aarch64UnknownLinuxGnu, diff --git a/src/lib.rs b/src/lib.rs index 106ebee..c319d8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod config; pub mod emoji; pub mod host_triple; pub mod targets; diff --git a/src/main.rs b/src/main.rs index d65b0f3..59e4057 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use anyhow::Result; use clap::Parser; use embuild::espidf::{parse_esp_idf_git_ref, EspIdfRemote}; use espup::{ + config::Config, emoji, host_triple::get_host_triple, logging::initialize_logger, @@ -180,44 +181,66 @@ fn install(args: InstallOpts) -> Result<()> { #[cfg(windows)] check_arguments(&targets, &args.espidf_version)?; - check_rust_installation(&args.nightly_version)?; + // check_rust_installation(&args.nightly_version)?; - rust_toolchain.install_xtensa_rust()?; + // rust_toolchain.install_xtensa_rust()?; - exports.extend(llvm.install()?); + // exports.extend(llvm.install()?); - if targets.contains(&Target::ESP32C3) { - install_riscv_target(&args.nightly_version)?; - } + // if targets.contains(&Target::ESP32C3) { + // install_riscv_target(&args.nightly_version)?; + // } - if let Some(espidf_version) = &args.espidf_version { - let repo = EspIdfRepo::new(espidf_version, args.profile_minimal, targets); - exports.extend(repo.install()?); - extra_crates.insert(RustCrate::new("ldproxy")); - } else { - exports.extend(install_gcc_targets(targets, &host_triple)?); - } + // if let Some(espidf_version) = &args.espidf_version { + // let repo = EspIdfRepo::new(espidf_version, args.profile_minimal, targets); + // exports.extend(repo.install()?); + // extra_crates.insert(RustCrate::new("ldproxy")); + // } else { + // exports.extend(install_gcc_targets(targets, &host_triple)?); + // } - debug!( + // debug!( + // "{} Installing the following crates: {:#?}", + // emoji::DEBUG, + // extra_crates + // ); + // for extra_crate in extra_crates { + // extra_crate.install()?; + // } + + // if args.profile_minimal { + // clear_dist_folder()?; + // } + + // export_environment(&export_file, &exports)?; + + // info!("{} Installation suscesfully completed!", emoji::CHECK); + // warn!( + // "{} Please, source the export file, as state above, to properly setup the environment!", + // emoji::WARN + // ); + + info!( "{} Installing the following crates: {:#?}", emoji::DEBUG, extra_crates ); - for extra_crate in extra_crates { - extra_crate.install()?; + let config = Config { + espidf_version: args.espidf_version, + // espidf, + export_file, + // extra_crates: extra_crates.clone(), + host_triple, + // llvm_toolchain: llvm, + nightly_version: args.nightly_version, + profile_minimal: args.profile_minimal, + targets, + xtensa_toolchain: rust_toolchain, + }; + + if let Err(e) = config.save_with() { + warn!("Failed to save config {:#}", e); } - - if args.profile_minimal { - clear_dist_folder()?; - } - - export_environment(&export_file, &exports)?; - - info!("{} Installation suscesfully completed!", emoji::CHECK); - warn!( - "{} Please, source the export file, as state above, to properly setup the environment!", - emoji::WARN - ); Ok(()) } diff --git a/src/targets.rs b/src/targets.rs index d1f8434..db27042 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -3,11 +3,12 @@ use crate::emoji; use anyhow::Context; use log::debug; +use serde::{Deserialize, Serialize}; use std::{collections::HashSet, str::FromStr}; use strum::Display; use strum_macros::EnumString; -#[derive(Clone, Copy, EnumString, PartialEq, Hash, Eq, Debug, Display)] +#[derive(Clone, Copy, EnumString, PartialEq, Hash, Eq, Debug, Display, Deserialize, Serialize)] pub enum Target { /// Xtensa LX7 based dual core #[strum(serialize = "esp32")] diff --git a/src/toolchain/espidf.rs b/src/toolchain/espidf.rs index 04e46c4..27a41a9 100644 --- a/src/toolchain/espidf.rs +++ b/src/toolchain/espidf.rs @@ -11,6 +11,7 @@ use crate::{ use anyhow::{Context, Result}; use embuild::{espidf, espidf::EspIdfRemote, git}; use log::{debug, info}; +use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::{ collections::hash_map::DefaultHasher, @@ -48,7 +49,7 @@ pub enum Generator { NMakeMakefilesJOM, WatcomWMake, } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct EspIdfRepo { /// The repository containing GCC sources. pub repository_url: String, diff --git a/src/toolchain/llvm_toolchain.rs b/src/toolchain/llvm_toolchain.rs index 8bcf1eb..4d86ddb 100644 --- a/src/toolchain/llvm_toolchain.rs +++ b/src/toolchain/llvm_toolchain.rs @@ -7,6 +7,7 @@ use crate::{ }; use anyhow::{bail, Ok, Result}; use log::{info, warn}; +use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; const DEFAULT_LLVM_COMPLETE_REPOSITORY: &str = @@ -15,7 +16,7 @@ const DEFAULT_LLVM_MINIFIED_REPOSITORY: &str = "https://github.com/esp-rs/rust-build/releases/download/llvm-project-14.0-minified"; const DEFAULT_LLVM_VERSION: &str = "esp-14.0.0-20220415"; -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize, Clone, Default)] pub struct LlvmToolchain { /// LLVM Toolchain file name. pub file_name: String, diff --git a/src/toolchain/rust_toolchain.rs b/src/toolchain/rust_toolchain.rs index 4689fb9..362ec77 100644 --- a/src/toolchain/rust_toolchain.rs +++ b/src/toolchain/rust_toolchain.rs @@ -8,13 +8,14 @@ use crate::{ use anyhow::{bail, Result}; use embuild::cmd; use log::{info, warn}; +use serde::{Deserialize, Serialize}; use std::fmt::Debug; use std::{env, path::PathBuf, process::Stdio}; const DEFAULT_XTENSA_RUST_REPOSITORY: &str = "https://github.com/esp-rs/rust-build/releases/download"; -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct RustToolchain { /// Path to the cargo home directory. pub cargo_home: PathBuf, @@ -146,7 +147,7 @@ impl RustToolchain { } } -#[derive(Hash, Eq, PartialEq, Debug)] +#[derive(Hash, Eq, PartialEq, Debug, Clone, Serialize, Deserialize, Default)] pub struct RustCrate { /// Crate name. pub name: String, From f405512801eb2c39cba7a4b339b77cbec0f97ba7 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Tue, 25 Oct 2022 15:00:29 +0000 Subject: [PATCH 02/11] =?UTF-8?q?refactor:=20=F0=9F=8E=A8=20Update=20confi?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config.rs | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/config.rs b/src/config.rs index df3602d..403e302 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,12 +1,6 @@ -use crate::{ - host_triple::HostTriple, - targets::Target, - toolchain::espidf::EspIdfRepo, - toolchain::llvm_toolchain::LlvmToolchain, - toolchain::rust_toolchain::{RustCrate, RustToolchain}, -}; +use crate::{host_triple::HostTriple, targets::Target, toolchain::rust_toolchain::RustToolchain}; use directories_next::ProjectDirs; -use miette::{IntoDiagnostic, Result, WrapErr}; +use miette::{ErrReport, IntoDiagnostic, Result, WrapErr}; use serde::{Deserialize, Serialize}; use std::{ collections::HashSet, @@ -17,25 +11,19 @@ use std::{ /// Deserialized contents of a configuration file #[derive(Debug, Deserialize, Serialize, Default, Clone)] pub struct Config { - /// ESP-IDF version + // /// ESP-IDF version pub espidf_version: Option, - // /// ESP-IDF - // pub espidf: EspIdfRepo, /// Destination of the generated export file. pub export_file: PathBuf, /// Extra crates to installed. - // pub extra_crates: HashSet, - /// GCC toolchain. - // pub gcc_toolchain: GccToolchain, + pub extra_crates: HashSet, /// Host triple pub host_triple: HostTriple, - /// LLVM toolchain. - // pub llvm_toolchain: LlvmToolchain, + /// LLVM toolchain path. + pub llvm_path: PathBuf, /// Nightly Rust toolchain version. pub nightly_version: String, - /// Minifies the installation. - pub profile_minimal: bool, - // /// List of targets [esp32,esp32s2,esp32s3,esp32c3,all]. + /// List of targets instaled. pub targets: HashSet, /// Xtensa Rust toolchain. pub xtensa_toolchain: RustToolchain, @@ -47,19 +35,16 @@ impl Config { let dirs = ProjectDirs::from("rs", "esp", "espup").unwrap(); let file = dirs.config_dir().join("espup.toml"); - let mut config = if let Ok(data) = read(&file) { + let config = if let Ok(data) = read(&file) { toml::from_slice(&data).into_diagnostic()? } else { - Self::default() + return Err(ErrReport::msg("No config file found")); }; - // config.save_path = file; Ok(config) } - pub fn save_with(&self) -> Result<()> { - // pub fn save_with(&self, modify_fn: F) -> Result<()> { - // let mut copy = self.clone(); - // modify_fn(&mut copy); + /// Save the config to file + pub fn save(&self) -> Result<()> { let dirs = ProjectDirs::from("rs", "esp", "espup").unwrap(); let file = dirs.config_dir().join("espup.toml"); From 9e39079154418cb6936b3bbf4ad72a6cf9386837 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Tue, 25 Oct 2022 15:02:06 +0000 Subject: [PATCH 03/11] =?UTF-8?q?chore:=20=F0=9F=8E=A8=20Code=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 79 +++++++++++++++------------------ src/toolchain/espidf.rs | 9 ++-- src/toolchain/gcc_toolchain.rs | 8 ++-- src/toolchain/llvm_toolchain.rs | 3 +- 4 files changed, 46 insertions(+), 53 deletions(-) diff --git a/src/main.rs b/src/main.rs index 59e4057..2a5bb9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -146,7 +146,6 @@ fn install(args: InstallOpts) -> Result<()> { let mut exports: Vec = Vec::new(); let export_file = args.export_file.clone(); let rust_toolchain = RustToolchain::new(&args.toolchain_version, &host_triple); - // Complete LLVM is failing for Windows, aarch64 MacOs, and aarch64 Linux, so we are using always minified. #[cfg(all(target_arch = "x86_64", target_os = "linux"))] let llvm = LlvmToolchain::new(args.profile_minimal, &host_triple); @@ -170,7 +169,7 @@ fn install(args: InstallOpts) -> Result<()> { targets, &args.espidf_version, export_file, - extra_crates, + &extra_crates, llvm, &args.nightly_version, rust_toolchain, @@ -181,66 +180,62 @@ fn install(args: InstallOpts) -> Result<()> { #[cfg(windows)] check_arguments(&targets, &args.espidf_version)?; - // check_rust_installation(&args.nightly_version)?; + check_rust_installation(&args.nightly_version)?; - // rust_toolchain.install_xtensa_rust()?; + rust_toolchain.install_xtensa_rust()?; - // exports.extend(llvm.install()?); + exports.extend(llvm.install()?); - // if targets.contains(&Target::ESP32C3) { - // install_riscv_target(&args.nightly_version)?; - // } + if targets.contains(&Target::ESP32C3) { + install_riscv_target(&args.nightly_version)?; + } - // if let Some(espidf_version) = &args.espidf_version { - // let repo = EspIdfRepo::new(espidf_version, args.profile_minimal, targets); - // exports.extend(repo.install()?); - // extra_crates.insert(RustCrate::new("ldproxy")); - // } else { - // exports.extend(install_gcc_targets(targets, &host_triple)?); - // } + if let Some(espidf_version) = &args.espidf_version { + let repo = EspIdfRepo::new(espidf_version, args.profile_minimal, &targets); + exports.extend(repo.install()?); + extra_crates.insert(RustCrate::new("ldproxy")); + } else { + exports.extend(install_gcc_targets(&targets, &host_triple)?); + } - // debug!( - // "{} Installing the following crates: {:#?}", - // emoji::DEBUG, - // extra_crates - // ); - // for extra_crate in extra_crates { - // extra_crate.install()?; - // } - - // if args.profile_minimal { - // clear_dist_folder()?; - // } - - // export_environment(&export_file, &exports)?; - - // info!("{} Installation suscesfully completed!", emoji::CHECK); - // warn!( - // "{} Please, source the export file, as state above, to properly setup the environment!", - // emoji::WARN - // ); - - info!( + debug!( "{} Installing the following crates: {:#?}", emoji::DEBUG, extra_crates ); + for extra_crate in &extra_crates { + extra_crate.install()?; + } + + if args.profile_minimal { + clear_dist_folder()?; + } + + export_environment(&export_file, &exports)?; + let config = Config { espidf_version: args.espidf_version, - // espidf, export_file, - // extra_crates: extra_crates.clone(), + extra_crates: extra_crates + .iter() + .map(|x| x.name.clone()) + .collect::>(), host_triple, - // llvm_toolchain: llvm, + llvm_path: llvm.path, nightly_version: args.nightly_version, - profile_minimal: args.profile_minimal, targets, xtensa_toolchain: rust_toolchain, }; - if let Err(e) = config.save_with() { + if let Err(e) = config.save() { warn!("Failed to save config {:#}", e); } + + info!("{} Installation suscesfully completed!", emoji::CHECK); + warn!( + "{} Please, source the export file, as state above, to properly setup the environment!", + emoji::WARN + ); Ok(()) } diff --git a/src/toolchain/espidf.rs b/src/toolchain/espidf.rs index 27a41a9..7302d96 100644 --- a/src/toolchain/espidf.rs +++ b/src/toolchain/espidf.rs @@ -11,7 +11,6 @@ use crate::{ use anyhow::{Context, Result}; use embuild::{espidf, espidf::EspIdfRemote, git}; use log::{debug, info}; -use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::{ collections::hash_map::DefaultHasher, @@ -49,7 +48,7 @@ pub enum Generator { NMakeMakefilesJOM, WatcomWMake, } -#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Default)] pub struct EspIdfRepo { /// The repository containing GCC sources. pub repository_url: String, @@ -83,7 +82,7 @@ impl EspIdfRepo { let mut tools = vec![]; let mut subtools = Vec::new(); for target in self.targets { - let gcc_toolchain_name = get_toolchain_name(target); + let gcc_toolchain_name = get_toolchain_name(&target); subtools.push(gcc_toolchain_name); let ulp_toolchain_name = get_ulp_toolchain_name(target, version.as_ref().ok()); @@ -164,7 +163,7 @@ impl EspIdfRepo { } /// Create a new instance with the proper arguments. - pub fn new(version: &str, minified: bool, targets: HashSet) -> EspIdfRepo { + pub fn new(version: &str, minified: bool, targets: &HashSet) -> EspIdfRepo { let install_path = PathBuf::from(get_tools_path()); debug!( "{} ESP-IDF install path: '{}'", @@ -176,7 +175,7 @@ impl EspIdfRepo { version: version.to_string(), minified, install_path, - targets, + targets: targets.clone(), } } } diff --git a/src/toolchain/gcc_toolchain.rs b/src/toolchain/gcc_toolchain.rs index 29984ab..507702b 100644 --- a/src/toolchain/gcc_toolchain.rs +++ b/src/toolchain/gcc_toolchain.rs @@ -18,7 +18,7 @@ const DEFAULT_GCC_REPOSITORY: &str = "https://github.com/espressif/crosstool-NG/ const DEFAULT_GCC_RELEASE: &str = "esp-2021r2-patch5"; const DEFAULT_GCC_VERSION: &str = "8_4_0"; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct GccToolchain { /// Host triple. pub host_triple: HostTriple, @@ -75,7 +75,7 @@ impl GccToolchain { } /// Create a new instance with default values and proper toolchain name. - pub fn new(target: Target, host_triple: &HostTriple) -> Self { + pub fn new(target: &Target, host_triple: &HostTriple) -> Self { Self { host_triple: host_triple.clone(), release: DEFAULT_GCC_RELEASE.to_string(), @@ -105,7 +105,7 @@ fn get_artifact_extension(host_triple: &HostTriple) -> &str { } /// Gets the toolchain name based on the Target -pub fn get_toolchain_name(target: Target) -> String { +pub fn get_toolchain_name(target: &Target) -> String { match target { Target::ESP32 => "xtensa-esp32-elf".to_string(), Target::ESP32S2 => "xtensa-esp32s2-elf".to_string(), @@ -138,7 +138,7 @@ pub fn get_ulp_toolchain_name(target: Target, version: Option<&EspIdfVersion>) - /// Installs GCC toolchain the selected targets. pub fn install_gcc_targets( - targets: HashSet, + targets: &HashSet, host_triple: &HostTriple, ) -> Result> { info!("{} Installing gcc for build targets", emoji::WRENCH); diff --git a/src/toolchain/llvm_toolchain.rs b/src/toolchain/llvm_toolchain.rs index 4d86ddb..0baf4b5 100644 --- a/src/toolchain/llvm_toolchain.rs +++ b/src/toolchain/llvm_toolchain.rs @@ -7,7 +7,6 @@ use crate::{ }; use anyhow::{bail, Ok, Result}; use log::{info, warn}; -use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; const DEFAULT_LLVM_COMPLETE_REPOSITORY: &str = @@ -16,7 +15,7 @@ const DEFAULT_LLVM_MINIFIED_REPOSITORY: &str = "https://github.com/esp-rs/rust-build/releases/download/llvm-project-14.0-minified"; const DEFAULT_LLVM_VERSION: &str = "esp-14.0.0-20220415"; -#[derive(Debug, Serialize, Deserialize, Clone, Default)] +#[derive(Debug, Clone, Default)] pub struct LlvmToolchain { /// LLVM Toolchain file name. pub file_name: String, From 1bfef0e3dbadba184d6b1168bb6f9da6b26a7a10 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Tue, 25 Oct 2022 15:47:16 +0000 Subject: [PATCH 04/11] =?UTF-8?q?feat:=20=E2=9C=A8=20Update=20uninstall=20?= =?UTF-8?q?subcommand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 76 ++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2a5bb9e..bad7248 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,11 @@ use anyhow::bail; use anyhow::Result; use clap::Parser; -use embuild::espidf::{parse_esp_idf_git_ref, EspIdfRemote}; +use directories_next::ProjectDirs; +use embuild::{ + cmd, + espidf::{parse_esp_idf_git_ref, EspIdfRemote}, +}; use espup::{ config::Config, emoji, @@ -13,7 +17,7 @@ use espup::{ espidf::{ get_dist_path, get_install_path, get_tool_path, EspIdfRepo, DEFAULT_GIT_REPOSITORY, }, - gcc_toolchain::install_gcc_targets, + gcc_toolchain::{get_toolchain_name, install_gcc_targets}, llvm_toolchain::LlvmToolchain, rust_toolchain::{ check_rust_installation, get_rustup_home, install_riscv_target, RustCrate, @@ -24,9 +28,9 @@ use espup::{ use log::{debug, info, warn}; use std::{ collections::HashSet, - fs::{remove_dir_all, File}, + fs::{remove_dir_all, remove_file, File}, io::Write, - path::PathBuf, + path::{Path, PathBuf}, }; #[cfg(windows)] @@ -113,25 +117,9 @@ pub struct UpdateOpts { #[derive(Debug, Parser)] pub struct UninstallOpts { - /// ESP-IDF version to uninstall. If empty, no esp-idf is uninstalled. Version format: - /// - /// - `commit:`: Uses the commit `` of the `esp-idf` repository. - /// - /// - `tag:`: Uses the tag `` of the `esp-idf` repository. - /// - /// - `branch:`: Uses the branch `` of the `esp-idf` repository. - /// - /// - `v.` or `.`: Uses the tag `v.` of the `esp-idf` repository. - /// - /// - ``: Uses the branch `` of the `esp-idf` repository. - #[arg(short = 'e', long, required = false)] - pub espidf_version: Option, /// Verbosity level of the logs. #[arg(short = 'l', long, default_value = "info", value_parser = ["debug", "info", "warn", "error"])] pub log_level: String, - /// Removes clang. - #[arg(short = 'c', long)] - pub remove_clang: bool, } /// Installs esp-rs environment @@ -243,34 +231,50 @@ fn install(args: InstallOpts) -> Result<()> { fn uninstall(args: UninstallOpts) -> Result<()> { initialize_logger(&args.log_level); info!("{} Uninstalling esp-rs", emoji::DISC); + let config = Config::load().unwrap(); debug!( "{} Arguments: - - Remove Clang: {} - - ESP-IDF version: {:#?}", + - Config: {:#?}", emoji::INFO, - &args.remove_clang, - &args.espidf_version, + config ); info!("{} Deleting Xtensa Rust toolchain", emoji::WRENCH); - remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?; + remove_dir_all(config.xtensa_toolchain.toolchain_destination)?; - if args.remove_clang { - info!("{} Deleting Xtensa Clang", emoji::WRENCH); - remove_dir_all(PathBuf::from(get_tool_path("")).join("xtensa-esp32-elf-clang"))?; + info!("{} Deleting Xtensa LLVM", emoji::WRENCH); + remove_dir_all(config.llvm_path)?; + + if let Some(espidf_version) = config.espidf_version { + info!("{} Deleting ESP-IDF {}", emoji::WRENCH, espidf_version); + let repo = EspIdfRemote { + git_ref: parse_esp_idf_git_ref(&espidf_version), + repo_url: Some(DEFAULT_GIT_REPOSITORY.to_string()), + }; + remove_dir_all(get_install_path(repo).parent().unwrap())?; + } else { + info!("{} Deleting GCC targets", emoji::WRENCH); + for target in &config.targets { + let gcc_path = get_tool_path(&get_toolchain_name(target)); + remove_dir_all(gcc_path)?; + } + } + + info!("{} Uninstalling extra crates", emoji::WRENCH); + for extra_crate in &config.extra_crates { + cmd!("cargo", "uninstall", extra_crate).run()?; } clear_dist_folder()?; - if let Some(espidf_version) = &args.espidf_version { - info!("{} Deleting ESP-IDF", emoji::WRENCH); - let repo = EspIdfRemote { - git_ref: parse_esp_idf_git_ref(espidf_version), - repo_url: Some(DEFAULT_GIT_REPOSITORY.to_string()), - }; - remove_dir_all(get_install_path(repo).parent().unwrap())?; - } + info!("{} Deleting export file", emoji::WRENCH); + remove_file(Path::new(&config.export_file))?; + + info!("{} Deleting config file", emoji::WRENCH); + let conf_dirs = ProjectDirs::from("rs", "esp", "espup").unwrap(); + let conf_file = conf_dirs.config_dir().join("espup.toml"); + remove_file(conf_file)?; info!("{} Uninstallation suscesfully completed!", emoji::CHECK); Ok(()) From 7a8b2039f2327b76b2494767bdf800738d692b14 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 08:51:28 +0000 Subject: [PATCH 05/11] =?UTF-8?q?refactor:=20=E2=9A=A1=EF=B8=8F=20Improve?= =?UTF-8?q?=20update=20subcommand=20and=20add=20toolchain=5Fversion=20pars?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index bad7248..900bd89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #[cfg(windows)] use anyhow::bail; -use anyhow::Result; +use anyhow::{bail, Result}; use clap::Parser; use directories_next::ProjectDirs; use embuild::{ @@ -20,12 +20,13 @@ use espup::{ gcc_toolchain::{get_toolchain_name, install_gcc_targets}, llvm_toolchain::LlvmToolchain, rust_toolchain::{ - check_rust_installation, get_rustup_home, install_riscv_target, RustCrate, + self, check_rust_installation, get_rustup_home, install_riscv_target, RustCrate, RustToolchain, }, }, }; use log::{debug, info, warn}; +use regex::Regex; use std::{ collections::HashSet, fs::{remove_dir_all, remove_file, File}, @@ -37,6 +38,11 @@ use std::{ const DEFAULT_EXPORT_FILE: &str = "export-esp.ps1"; #[cfg(not(windows))] const DEFAULT_EXPORT_FILE: &str = "export-esp.sh"; +/// Xtensa Toolchain version regex. +const RE_TOOLCHAIN_VERSION: &str = r"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)?$"; +/// Latest Xtensa Toolchain version. +const LATEST_TOOLCHAIN_VERSION: &str = "1.64.0.0"; + #[derive(Parser)] #[command( name = "espup", @@ -98,7 +104,7 @@ pub struct InstallOpts { #[arg(short = 't', long, default_value = "all")] pub targets: String, /// Xtensa Rust toolchain version. - #[arg(short = 'v', long, default_value = "1.64.0.0")] + #[arg(short = 'v', long, default_value = LATEST_TOOLCHAIN_VERSION, value_parser = parse_version)] pub toolchain_version: String, } @@ -111,8 +117,8 @@ pub struct UpdateOpts { #[arg(short = 'l', long, default_value = "info", value_parser = ["debug", "info", "warn", "error"])] pub log_level: String, /// Xtensa Rust toolchain version. - #[arg(short = 'v', long, default_value = "1.64.0.0")] - pub toolchain_version: String, + #[arg(short = 'v', long, default_value = LATEST_TOOLCHAIN_VERSION, value_parser = parse_version)] + pub toolchain_version: Option, } #[derive(Debug, Parser)] @@ -122,6 +128,17 @@ pub struct UninstallOpts { pub log_level: String, } +fn parse_version(arg: &str) -> Result { + let re = Regex::new(RE_TOOLCHAIN_VERSION).unwrap(); + if !re.is_match(arg) { + bail!( + "{} Invalid toolchain version, must be in the form of '...'", + emoji::ERROR + ); + } + Ok(arg.to_string()) +} + /// Installs esp-rs environment fn install(args: InstallOpts) -> Result<()> { initialize_logger(&args.log_level); @@ -216,7 +233,7 @@ fn install(args: InstallOpts) -> Result<()> { }; if let Err(e) = config.save() { - warn!("Failed to save config {:#}", e); + bail!("{} Failed to save config {:#}", emoji::ERROR, e); } info!("{} Installation suscesfully completed!", emoji::CHECK); @@ -285,22 +302,44 @@ fn update(args: UpdateOpts) -> Result<()> { initialize_logger(&args.log_level); info!("{} Updating Xtensa Rust toolchain", emoji::DISC); let host_triple = get_host_triple(args.default_host)?; + let mut config = Config::load().unwrap(); + let rust_toolchain: RustToolchain; + if let Some(toolchain_version) = args.toolchain_version { + rust_toolchain = RustToolchain::new(&toolchain_version, &host_triple); + } else { + rust_toolchain = RustToolchain::new(LATEST_TOOLCHAIN_VERSION, &host_triple); + } debug!( "{} Arguments: - Host triple: {} - - Toolchain version: {}", + - Toolchain version: {:#?} + - Config: {:#?}", emoji::INFO, host_triple, - &args.toolchain_version, + rust_toolchain, + config ); + if rust_toolchain.version == config.xtensa_toolchain.version { + info!( + "{} Toolchain '{}' is already up to date", + emoji::CHECK, + rust_toolchain.version + ); + return Ok(()); + } info!("{} Deleting previous Xtensa Rust toolchain", emoji::WRENCH); - remove_dir_all(get_rustup_home().join("toolchains").join("esp"))?; + remove_dir_all(&config.xtensa_toolchain.toolchain_destination)?; - let rust_toolchain = RustToolchain::new(&args.toolchain_version, &host_triple); rust_toolchain.install_xtensa_rust()?; + config.xtensa_toolchain = rust_toolchain; + + if let Err(e) = config.save() { + bail!("{} Failed to save config {:#}", emoji::ERROR, e); + } + info!("{} Update suscesfully completed!", emoji::CHECK); Ok(()) } From 0da0745ea1364a309de286e0754fa1d9d0a3ed3e Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 08:51:48 +0000 Subject: [PATCH 06/11] =?UTF-8?q?build:=20=E2=9E=95=20Add=20regex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 1 + Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index e02e003..a6efb70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,6 +430,7 @@ dependencies = [ "log", "miette", "openssl", + "regex", "reqwest", "serde", "strum", diff --git a/Cargo.toml b/Cargo.toml index 4e32b8d..ed48867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ toml = "0.5.9" directories-next = "2.0.0" serde = { version = "1.0.146", features = ["derive"] } miette = "5.3.0" +regex = "1.6.0" [target.aarch64-unknown-linux-gnu.dependencies] openssl = { version = "0.10", features = ["vendored"] } From b69e7c81ea63583bfdef5f6e7f59733cbec6f7b2 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 09:03:54 +0000 Subject: [PATCH 07/11] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Add/improve=20fn?= =?UTF-8?q?=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 900bd89..35da5d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,6 +128,7 @@ pub struct UninstallOpts { pub log_level: String, } +/// Parses the version of the Xtensa toolchain. fn parse_version(arg: &str) -> Result { let re = Regex::new(RE_TOOLCHAIN_VERSION).unwrap(); if !re.is_match(arg) { @@ -139,7 +140,7 @@ fn parse_version(arg: &str) -> Result { Ok(arg.to_string()) } -/// Installs esp-rs environment +/// Installs the Rust for ESP chips environment fn install(args: InstallOpts) -> Result<()> { initialize_logger(&args.log_level); @@ -244,7 +245,7 @@ fn install(args: InstallOpts) -> Result<()> { Ok(()) } -/// Uninstalls esp-rs environment +/// Uninstalls the Rust for ESP chips environment fn uninstall(args: UninstallOpts) -> Result<()> { initialize_logger(&args.log_level); info!("{} Uninstalling esp-rs", emoji::DISC); @@ -297,7 +298,7 @@ fn uninstall(args: UninstallOpts) -> Result<()> { Ok(()) } -/// Updates Xtensa Rust toolchain +/// Updates Xtensa Rust toolchain. fn update(args: UpdateOpts) -> Result<()> { initialize_logger(&args.log_level); info!("{} Updating Xtensa Rust toolchain", emoji::DISC); From 80b5f1bc3fd64e9de8010b45ce3d6f488bdfd400 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 09:08:53 +0000 Subject: [PATCH 08/11] =?UTF-8?q?chore:=20=E2=9A=A1=EF=B8=8F=20Fix=20clipp?= =?UTF-8?q?y=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 35da5d7..8604615 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,10 +19,7 @@ use espup::{ }, gcc_toolchain::{get_toolchain_name, install_gcc_targets}, llvm_toolchain::LlvmToolchain, - rust_toolchain::{ - self, check_rust_installation, get_rustup_home, install_riscv_target, RustCrate, - RustToolchain, - }, + rust_toolchain::{check_rust_installation, install_riscv_target, RustCrate, RustToolchain}, }, }; use log::{debug, info, warn}; From 329f8bdb6af0026bd60dff1de49896fce7c9eb8a Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 09:14:50 +0000 Subject: [PATCH 09/11] =?UTF-8?q?chore:=20=E2=9A=A1=EF=B8=8F=20Fix=20clipp?= =?UTF-8?q?y=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8604615..0781f19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -#[cfg(windows)] -use anyhow::bail; use anyhow::{bail, Result}; use clap::Parser; use directories_next::ProjectDirs; From 34a4b19cc97bcf41743c55c2e0254f3627c27865 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 09:31:41 +0000 Subject: [PATCH 10/11] =?UTF-8?q?build:=20=E2=8F=AA=EF=B8=8F=20Revert=20ca?= =?UTF-8?q?rgo.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ed48867..a493529 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,9 +38,6 @@ regex = "1.6.0" [target.aarch64-unknown-linux-gnu.dependencies] openssl = { version = "0.10", features = ["vendored"] } -[target.x86_64-unknown-linux-gnu.dependencies] -openssl = { version = "0.10", features = ["vendored"] } - [package.metadata.binstall] pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }.{ archive-format }" bin-dir = "{ bin }{ binary-ext }" From da8f8b45db0415bff350722ad5ab2a09032e7632 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Wed, 26 Oct 2022 16:44:57 +0200 Subject: [PATCH 11/11] =?UTF-8?q?chore:=20=F0=9F=93=8C=20Add=20MSRV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index a493529..ac5dddb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ Tool for installing and maintaining ESP Rust environment. """ keywords = ["esp", "esp-rs", "embedded", "cli", "xtensa", "espidf"] categories = ["command-line-utilities", "development-tools", "embedded"] +rust-version = "1.62" [dependencies] anyhow = "*"