Pretify prints

This commit is contained in:
Sergio Gasquez 2022-08-12 10:34:43 +00:00
parent 0812175a2f
commit d12916109b
5 changed files with 100 additions and 89 deletions

1
Cargo.lock generated
View File

@ -665,6 +665,7 @@ dependencies = [
"anyhow", "anyhow",
"clap 3.2.16", "clap 3.2.16",
"clap-nested", "clap-nested",
"console",
"dirs", "dirs",
"espflash", "espflash",
"flate2", "flate2",

View File

@ -25,6 +25,7 @@ winapi = { version = "*", features = ["setupapi", "handleapi", "processthreadsap
zip = "*" zip = "*"
xz2 = "0.1.6" xz2 = "0.1.6"
espflash = "1.6.0" espflash = "1.6.0"
console = "0.15.1"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winreg = "0.10.1" winreg = "0.10.1"

View File

@ -9,7 +9,7 @@ type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>
// General TODOs: // General TODOs:
// - Prettify prints (add emojis) // - Prettify prints (add emojis)
// - Avoid using shell commands // - Avoid using shell commands
// - Maybe split toolchain into toolchain(espidf, gcc, llvm...) and rust(rust checks, instalaltion and crates) // - Maybe split toolchain into toolchain(espidf, gcc, llvm...) and rust(rust checks, instalaltion and crates)
// - Add subcommand test that downloads a projects and builds it // - Add subcommand test that downloads a projects and builds it
// - Esp-idf version should be contained in an enum with the possible values (see chips in espflash for reference) // - Esp-idf version should be contained in an enum with the possible values (see chips in espflash for reference)
@ -95,13 +95,13 @@ pub struct UninstallOpts {
} }
fn install(args: InstallOpts) -> Result<()> { fn install(args: InstallOpts) -> Result<()> {
println!("{:?}", args); // println!("{:?}", args);
let arch = guess_host_triple::guess_host_triple().unwrap(); let arch = guess_host_triple::guess_host_triple().unwrap();
println!("{}", arch); // println!("{}", arch);
let targets: Vec<Chip> = parse_targets(&args.build_target)?; let targets: Vec<Chip> = parse_targets(&args.build_target)?;
println!("targets: {:?}", targets); // println!("targets: {:?}", targets);
let llvm_version = parse_llvm_version(&args.llvm_version).unwrap(); let llvm_version = parse_llvm_version(&args.llvm_version).unwrap();
println!("llvm_version: {:?}", llvm_version); // println!("llvm_version: {:?}", llvm_version);
let artifact_file_extension = get_artifact_file_extension(arch).to_string(); let artifact_file_extension = get_artifact_file_extension(arch).to_string();
let llvm_arch = get_llvm_arch(arch).to_string(); let llvm_arch = get_llvm_arch(arch).to_string();
@ -135,21 +135,21 @@ fn install(args: InstallOpts) -> Result<()> {
arch arch
); );
let mut exports: Vec<String> = Vec::new(); let mut exports: Vec<String> = Vec::new();
check_rust_installation(&args.nightly_version); check_rust_installation(&args.nightly_version);
if args.toolchain_destination.exists() { if args.toolchain_destination.exists() {
println!( println!(
"Previous installation of Rust Toolchain exist in: {}", "{} Previous installation of Rust Toolchain exist in: {}.\n Please, remove the directory before new installation.",
WARN,
args.toolchain_destination.display() args.toolchain_destination.display()
); );
println!("Please, remove the directory before new installation.");
return Ok(()); return Ok(());
} else { } else {
// install_rust_xtensa_toolchain // install_rust_xtensa_toolchain
// Some platfroms like Windows are available in single bundle rust + src, because install // Some platfroms like Windows are available in single bundle rust + src, because install
// script in dist is not available for the plaform. It's sufficient to extract the toolchain // script in dist is not available for the plaform. It's sufficient to extract the toolchain
println!("Installing Xtensa Rust toolchain"); println!("{} Installing Xtensa Rust toolchain", WRENCH);
if get_rust_installer(arch).to_string().is_empty() { if get_rust_installer(arch).to_string().is_empty() {
// TODO: Check idf_env and adjust // TODO: Check idf_env and adjust
// match prepare_package_strip_prefix(&rust_dist_url, // match prepare_package_strip_prefix(&rust_dist_url,
@ -166,19 +166,14 @@ fn install(args: InstallOpts) -> Result<()> {
&format!("rust-nightly-{}", arch), &format!("rust-nightly-{}", arch),
) { ) {
Ok(_) => { Ok(_) => {
println!("Package rust ready"); println!("{} Package rust ready", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("Unable to prepare rust"); println!("{} Unable to prepare rust", ERROR);
} }
} }
println!("{} Installing rust", WRENCH);
let mut arguments: Vec<String> = [].to_vec(); let mut arguments: Vec<String> = [].to_vec();
println!(
"{}/install.sh --destdir={} --prefix='' --without=rust-docs",
get_tool_path("rust"),
args.toolchain_destination.display()
);
arguments.push("-c".to_string()); arguments.push("-c".to_string());
arguments.push(format!( arguments.push(format!(
"{}/install.sh --destdir={} --prefix='' --without=rust-docs", "{}/install.sh --destdir={} --prefix='' --without=rust-docs",
@ -188,10 +183,10 @@ fn install(args: InstallOpts) -> Result<()> {
match run_command("/bin/bash".to_string(), arguments.clone(), "".to_string()) { match run_command("/bin/bash".to_string(), arguments.clone(), "".to_string()) {
Ok(_) => { Ok(_) => {
println!("rust/install.sh command succeeded"); println!("{} rust/install.sh command succeeded", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("rust/install.sh command failed"); println!("{} rust/install.sh command failed", ERROR);
} }
} }
@ -201,19 +196,15 @@ fn install(args: InstallOpts) -> Result<()> {
"rust-src-nightly", "rust-src-nightly",
) { ) {
Ok(_) => { Ok(_) => {
println!("Package rust-src ready"); println!("{} Package rust-src ready", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("Unable to prepare rust-src"); println!("{} Unable to prepare rust-src", ERROR);
} }
} }
println!("{} Installing rust-src", WRENCH);
let mut arguments: Vec<String> = [].to_vec(); let mut arguments: Vec<String> = [].to_vec();
println!(
"{}/install.sh --destdir={} --prefix='' --without=rust-docs",
get_tool_path("rust-src"),
args.toolchain_destination.display()
);
arguments.push("-c".to_string()); arguments.push("-c".to_string());
arguments.push(format!( arguments.push(format!(
"{}/install.sh --destdir={} --prefix='' --without=rust-docs", "{}/install.sh --destdir={} --prefix='' --without=rust-docs",
@ -222,10 +213,10 @@ fn install(args: InstallOpts) -> Result<()> {
)); ));
match run_command("/bin/bash".to_string(), arguments, "".to_string()) { match run_command("/bin/bash".to_string(), arguments, "".to_string()) {
Ok(_) => { Ok(_) => {
println!("rust-src/install.sh Command succeeded"); println!("{} rust-src/install.sh Command succeeded", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("rust-src/install.sh Command failed"); println!("{} rust-src/install.sh Command failed", ERROR);
} }
} }
} }
@ -235,12 +226,11 @@ fn install(args: InstallOpts) -> Result<()> {
// TODO: move to function // TODO: move to function
if Path::new(idf_tool_xtensa_elf_clang.as_str()).exists() { if Path::new(idf_tool_xtensa_elf_clang.as_str()).exists() {
println!( println!(
"Previous installation of LLVM exist in: {}", "{} Previous installation of LLVM exist in: {}.\n Please, remove the directory before new installation.",
WARN,
idf_tool_xtensa_elf_clang idf_tool_xtensa_elf_clang
); );
println!("Please, remove the directory before new installation.");
} else { } else {
println!("Downloading xtensa-esp32-elf-clang");
match prepare_package_strip_prefix( match prepare_package_strip_prefix(
&llvm_url, &llvm_url,
get_tool_path(&format!( get_tool_path(&format!(
@ -250,10 +240,10 @@ fn install(args: InstallOpts) -> Result<()> {
"", "",
) { ) {
Ok(_) => { Ok(_) => {
println!("Package xtensa-esp32-elf-clang ready"); println!("{} Package xtensa-esp32-elf-clang ready", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("Unable to prepare xtensa-esp32-elf-clang"); println!("{} Unable to prepare xtensa-esp32-elf-clang", ERROR);
} }
} }
} }
@ -262,7 +252,7 @@ fn install(args: InstallOpts) -> Result<()> {
exports.push(format!("export LIBCLANG_PATH=\"{}\"", &libclang_path)); exports.push(format!("export LIBCLANG_PATH=\"{}\"", &libclang_path));
if targets.contains(&Chip::Esp32c3) { if targets.contains(&Chip::Esp32c3) {
println!("Installing riscv target"); println!("{} Installing riscv target", WRENCH);
install_riscv_target(&args.nightly_version); install_riscv_target(&args.nightly_version);
} }
@ -271,21 +261,24 @@ fn install(args: InstallOpts) -> Result<()> {
let mut espidf_targets: String = String::new(); let mut espidf_targets: String = String::new();
for target in targets { for target in targets {
if espidf_targets.is_empty() { if espidf_targets.is_empty() {
espidf_targets = espidf_targets + &target.to_string().to_lowercase().replace("-",""); espidf_targets =
espidf_targets + &target.to_string().to_lowercase().replace("-", "");
} else { } else {
espidf_targets = espidf_targets + "," + &target.to_string().to_lowercase().replace("-",""); espidf_targets =
espidf_targets + "," + &target.to_string().to_lowercase().replace("-", "");
} }
} }
install_espidf(&espidf_targets, &espidf_version)?; install_espidf(&espidf_targets, &espidf_version)?;
exports.push(format!( exports.push(format!(
"export IDF_TOOLS_PATH=\"{}\"", "export IDF_TOOLS_PATH=\"{}\"",
get_espressif_base_path() get_espressif_base_path()
)); ));
exports.push(format!("source {}/export.sh", get_espidf_path(&espidf_version))); exports.push(format!(
"source {}/export.sh",
get_espidf_path(&espidf_version)
));
// TODO: Install ldproxy // TODO: Install ldproxy
} else { } else {
println!("No esp-idf version provided. Installing gcc for targets"); println!("No esp-idf version provided. Installing gcc for targets");
exports.extend(install_gcc_targets(targets)?.iter().cloned()); exports.extend(install_gcc_targets(targets)?.iter().cloned());
@ -318,7 +311,6 @@ fn install(args: InstallOpts) -> Result<()> {
println!("{}", e); println!("{}", e);
} }
Ok(()) Ok(())
} }

View File

@ -10,17 +10,17 @@ pub fn check_rust_installation(nightly_version: &str) {
.output() .output()
{ {
Ok(child_output) => { Ok(child_output) => {
println!("rustup found."); println!("{} rustup found", INFO);
let result = String::from_utf8_lossy(&child_output.stdout); let result = String::from_utf8_lossy(&child_output.stdout);
if !result.contains(nightly_version) { if !result.contains(nightly_version) {
println!("nightly toolchain not found"); println!("nightly toolchain not found");
install_rust_nightly(nightly_version); install_rust_nightly(nightly_version);
} else { } else {
println!("nightly toolchain found."); println!("{} {} toolchain found", INFO, nightly_version);
} }
} }
Err(e) => { Err(e) => {
println!("Error: {}", e); println!("{}Error: {}", ERROR, e);
install_rustup(); install_rustup();
} }
} }
@ -39,12 +39,15 @@ pub fn install_riscv_target(version: &str) {
Ok(child_output) => { Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout); let result = String::from_utf8_lossy(&child_output.stdout);
println!( println!(
"Rust-src for RiscV target installed suscesfully: {}", "{} Rust-src for RiscV target installed suscesfully: {}",
result SPARKLE, result
); );
} }
Err(e) => { Err(e) => {
println!("Rust-src for RiscV target installation failed: {}", e); println!(
"{} Rust-src for RiscV target installation failed: {}",
ERROR, e
);
} }
} }
@ -59,10 +62,10 @@ pub fn install_riscv_target(version: &str) {
{ {
Ok(child_output) => { Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout); let result = String::from_utf8_lossy(&child_output.stdout);
println!("RiscV target installed suscesfully: {}", result); println!("{} RiscV target installed suscesfully: {}", SPARKLE, result);
} }
Err(e) => { Err(e) => {
println!("RiscV target installation failed: {}", e); println!("{} RiscV target installation failed: {}", ERROR, e);
} }
} }
} }
@ -85,16 +88,16 @@ pub fn install_rustup() {
{ {
Ok(child_output) => { Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout); let result = String::from_utf8_lossy(&child_output.stdout);
println!("{}", result); println!("{} {}", SPARKLE, result);
} }
Err(e) => { Err(e) => {
println!("Error: {}", e); println!("{} Error: {}", ERROR, e);
} }
} }
} }
pub fn install_rust_nightly(version: &str) { pub fn install_rust_nightly(version: &str) {
println!("installing nightly toolchain"); println!("{} Installing {} toolchain", WRENCH, version);
match std::process::Command::new("rustup") match std::process::Command::new("rustup")
.arg("toolchain") .arg("toolchain")
.arg("install") .arg("install")
@ -106,10 +109,10 @@ pub fn install_rust_nightly(version: &str) {
{ {
Ok(child_output) => { Ok(child_output) => {
let result = String::from_utf8_lossy(&child_output.stdout); let result = String::from_utf8_lossy(&child_output.stdout);
println!("Result: {}", result); println!("{} Result: {}", SPARKLE, result);
} }
Err(e) => { Err(e) => {
println!("Error: {}", e); println!("{} Error: {}", ERROR, e);
} }
} }
} }
@ -147,7 +150,7 @@ pub fn install_gcc_targets(targets: Vec<Chip>) -> Result<Vec<String>, String> {
)); ));
} }
_ => { _ => {
println!("Unknown target") println!("{} Unknown target", ERROR)
} }
} }
} }
@ -177,9 +180,8 @@ pub fn install_gcc(gcc_target: &str) {
} }
pub fn install_espidf(targets: &str, version: &str) -> Result<(), String> { pub fn install_espidf(targets: &str, version: &str) -> Result<(), String> {
let espidf_path = get_espidf_path(version); let espidf_path = get_espidf_path(version);
println!("ESP-IDF Path: {}", espidf_path); println!("{} ESP-IDF Path: {}", INFO, espidf_path);
#[cfg(windows)] #[cfg(windows)]
match prepare_package( match prepare_package(
@ -236,29 +238,29 @@ pub fn install_espidf(targets: &str, version: &str) -> Result<(), String> {
arguments.push("--recursive".to_string()); arguments.push("--recursive".to_string());
arguments.push("https://github.com/espressif/esp-idf.git".to_string()); arguments.push("https://github.com/espressif/esp-idf.git".to_string());
arguments.push(espidf_path.clone()); arguments.push(espidf_path.clone());
println!("Cloning: {} {:?}", git_path, arguments); println!("{} Dowloading esp-idf {}", DOWNLOAD, version);
match run_command(git_path, arguments, "".to_string()) { match run_command(git_path, arguments, "".to_string()) {
Ok(_) => { Ok(_) => {
println!("Cloned esp-idf suscessfuly"); println!("{} Cloned esp-idf suscessfuly", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("Cloned esp-idf failed"); println!("{} Cloned esp-idf failed", ERROR);
} }
} }
} }
println!( println!(
"Installing esp-idf for {} with {}/install.sh", "{} Installing esp-idf for {} with {}/install.sh",
targets, espidf_path WRENCH, targets, espidf_path
); );
let install_script_path = format!("{}/install.sh", espidf_path); let install_script_path = format!("{}/install.sh", espidf_path);
let mut arguments: Vec<String> = [].to_vec(); let mut arguments: Vec<String> = [].to_vec();
arguments.push(targets.to_string()); arguments.push(targets.to_string());
match run_command(install_script_path, arguments, "".to_string()) { match run_command(install_script_path, arguments, "".to_string()) {
Ok(_) => { Ok(_) => {
println!("ESP-IDF installation succeeded"); println!("{} ESP-IDF installation succeeded", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("ESP-IDF installation failed"); println!("{} ESP-IDF installation failed", ERROR);
} }
} }
// match std::process::Command::new(install_script_path) // match std::process::Command::new(install_script_path)
@ -283,10 +285,10 @@ pub fn install_espidf(targets: &str, version: &str) -> Result<(), String> {
arguments.push("cmake".to_string()); arguments.push("cmake".to_string());
match run_command(python_path, arguments, "".to_string()) { match run_command(python_path, arguments, "".to_string()) {
Ok(_) => { Ok(_) => {
println!("CMake installation succeeded"); println!("{} CMake installation succeeded", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("CMake installation failed"); println!("{} CMake installation failed", ERROR);
} }
} }

View File

@ -1,3 +1,4 @@
use console::Emoji;
use dirs::home_dir; use dirs::home_dir;
use espflash::Chip; use espflash::Chip;
use flate2::bufread::GzDecoder; use flate2::bufread::GzDecoder;
@ -11,8 +12,16 @@ use tar::Archive;
use tokio::runtime::Handle; use tokio::runtime::Handle;
use xz2::read::XzDecoder; use xz2::read::XzDecoder;
pub static ERROR: Emoji<'_, '_> = Emoji("", "");
pub static SPARKLE: Emoji<'_, '_> = Emoji("", "");
pub static WARN: Emoji<'_, '_> = Emoji("⚠️ ", "");
pub static WRENCH: Emoji<'_, '_> = Emoji("🔧 ", "");
pub static DOWNLOAD: Emoji<'_, '_> = Emoji("📥 ", "");
pub static INFO: Emoji<'_, '_> = Emoji("💡 ", "");
// pub static DIAMOND: Emoji<'_, '_> = Emoji("🔸 ", "");
pub fn parse_targets(build_target: &str) -> Result<Vec<Chip>, String> { pub fn parse_targets(build_target: &str) -> Result<Vec<Chip>, String> {
println!("Parsing targets: {}", build_target); // println!("Parsing targets: {}", build_target);
let mut chips: Vec<Chip> = Vec::new(); let mut chips: Vec<Chip> = Vec::new();
if build_target.contains("all") { if build_target.contains("all") {
chips.push(Chip::Esp32); chips.push(Chip::Esp32);
@ -109,12 +118,18 @@ pub fn get_tool_path(tool_name: &str) -> String {
} }
pub fn get_espidf_path(version: &str) -> String { pub fn get_espidf_path(version: &str) -> String {
let parsed_version: String = version.chars() let parsed_version: String = version
.map(|x| match x { .chars()
'/' => '-', .map(|x| match x {
_ => x '/' => '-',
}).collect(); _ => x,
format!("{}frameworks/esp-idf-{}", get_espressif_base_path(), parsed_version) })
.collect();
format!(
"{}frameworks/esp-idf-{}",
get_espressif_base_path(),
parsed_version
)
} }
pub fn prepare_package_strip_prefix( pub fn prepare_package_strip_prefix(
@ -123,26 +138,23 @@ pub fn prepare_package_strip_prefix(
strip_prefix: &str, strip_prefix: &str,
) -> Result<(), String> { ) -> Result<(), String> {
println!( println!(
"prepare_package_strip_prefix: "{} Dowloading and uncompressing {} to {}",
-pacakge_url: {} DOWNLOAD, &package_url, &output_directory
-output dir: {}
-strip_prefix: {}",
&package_url, &output_directory, &strip_prefix
); );
if Path::new(&output_directory).exists() { if Path::new(&output_directory).exists() {
println!("Using cached directory: {}", output_directory); println!("{} Using cached directory: {}", WARN, output_directory);
return Ok(()); return Ok(());
} }
let tools_path = get_tool_path(""); let tools_path = get_tool_path("");
if !Path::new(&tools_path).exists() { if !Path::new(&tools_path).exists() {
println!("Creating tools directory: {}", tools_path); println!("{} Creating tools directory: {}", WRENCH, tools_path);
match fs::create_dir_all(&tools_path) { match fs::create_dir_all(&tools_path) {
Ok(_) => { Ok(_) => {
println!("tools_path created"); println!("{} Directory tools_path created", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("tools_path creating failed"); println!("{} Directory tools_path creation failed", ERROR);
} }
} }
} }
@ -159,7 +171,10 @@ pub fn prepare_package_strip_prefix(
} }
if !strip_prefix.is_empty() { if !strip_prefix.is_empty() {
let extracted_folder = format!("{}{}", &tools_path, strip_prefix); let extracted_folder = format!("{}{}", &tools_path, strip_prefix);
println!("Renaming: {} to {}", &extracted_folder, &output_directory); println!(
"{} Renaming: {} to {}",
INFO, &extracted_folder, &output_directory
);
fs::rename(extracted_folder, output_directory).unwrap(); fs::rename(extracted_folder, output_directory).unwrap();
} }
Ok(()) Ok(())
@ -226,12 +241,12 @@ pub fn prepare_single_binary(
let binary_path = format!("{}/{}", tool_path, binary_name); let binary_path = format!("{}/{}", tool_path, binary_name);
if Path::new(&binary_path).exists() { if Path::new(&binary_path).exists() {
println!("Using cached tool: {}", binary_path); println!("{} Using cached tool: {}", WARN, binary_path);
return binary_path; return binary_path;
} }
if !Path::new(&tool_path).exists() { if !Path::new(&tool_path).exists() {
println!("Creating tool directory: {}", tool_path); println!("{} Creating tool directory: {}", WRENCH, tool_path);
match fs::create_dir_all(&tool_path) { match fs::create_dir_all(&tool_path) {
Ok(_) => { Ok(_) => {
println!("Ok"); println!("Ok");
@ -244,10 +259,10 @@ pub fn prepare_single_binary(
match download_package(package_url.to_string(), binary_path.to_string()) { match download_package(package_url.to_string(), binary_path.to_string()) {
Ok(_) => { Ok(_) => {
println!("Ok"); println!("{} Succeded", SPARKLE);
} }
Err(_e) => { Err(_e) => {
println!("Failed"); println!("{} Failed", ERROR);
} }
} }
binary_path binary_path
@ -277,10 +292,10 @@ pub fn download_package(package_url: String, package_archive: String) -> Result<
async fn download_file(url: String, output: String) -> Result<(), String> { async fn download_file(url: String, output: String) -> Result<(), String> {
if Path::new(&output).exists() { if Path::new(&output).exists() {
println!("Using cached archive: {}", output); println!("{} Using cached archive: {}", WRENCH, output);
return Ok(()); return Ok(());
} }
println!("Downloading {} to {}", url, output); println!("{} Downloading {} to {}", DOWNLOAD, url, output);
fetch_url(url, output).await fetch_url(url, output).await
} }
@ -294,7 +309,7 @@ async fn fetch_url(url: String, output: String) -> Result<(), String> {
return Ok(()); return Ok(());
} }
_ => { _ => {
println!("Download of {} failed", url); println!("{} Download of {} failed", ERROR, url);
// Exit code is 0, there is temporal issue with Windows Installer which does not recover from error exit code // Exit code is 0, there is temporal issue with Windows Installer which does not recover from error exit code
#[cfg(windows)] #[cfg(windows)]
std::process::exit(0); std::process::exit(0);