use clap::{CommandFactory, Parser};
#[cfg(windows)]
use espup::env::set_environment_variable;
use espup::{
cli::{CompletionsOpts, InstallOpts, UninstallOpts},
error::Error,
logging::initialize_logger,
toolchain::{
gcc::uninstall_gcc_toolchains, install as toolchain_install, llvm::Llvm,
rust::get_rustup_home, InstallMode,
},
update::check_for_update,
};
use log::info;
use miette::Result;
use std::{env, fs::remove_dir_all};
#[derive(Parser)]
#[command(about, version)]
struct Cli {
#[command(subcommand)]
subcommand: SubCommand,
}
#[derive(Parser)]
pub enum SubCommand {
Completions(CompletionsOpts),
Install(Box<InstallOpts>),
Uninstall(UninstallOpts),
Update(Box<InstallOpts>),
}
async fn completions(args: CompletionsOpts) -> Result<()> {
initialize_logger(&args.log_level);
check_for_update(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
info!("Generating completions for {} shell", args.shell);
clap_complete::generate(
args.shell,
&mut Cli::command(),
"espup",
&mut std::io::stdout(),
);
info!("Completions successfully generated!");
Ok(())
}
async fn install(args: InstallOpts, install_mode: InstallMode) -> Result<()> {
initialize_logger(&args.log_level);
check_for_update(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
toolchain_install(args, install_mode).await?;
Ok(())
}
async fn uninstall(args: UninstallOpts) -> Result<()> {
initialize_logger(&args.log_level);
check_for_update(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
info!("Uninstalling the Espressif Rust ecosystem");
let install_path = get_rustup_home().join("toolchains").join(args.name);
Llvm::uninstall(&install_path)?;
uninstall_gcc_toolchains(&install_path)?;
info!(
"Deleting the Xtensa Rust toolchain located in '{}'",
&install_path.display()
);
remove_dir_all(&install_path)
.map_err(|_| Error::RemoveDirectory(install_path.display().to_string()))?;
#[cfg(windows)]
set_environment_variable("PATH", &env::var("PATH").unwrap())?;
info!("Uninstallation successfully completed!");
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
match Cli::parse().subcommand {
SubCommand::Completions(args) => completions(args).await,
SubCommand::Install(args) => install(*args, InstallMode::Install).await,
SubCommand::Update(args) => install(*args, InstallMode::Update).await,
SubCommand::Uninstall(args) => uninstall(args).await,
}
}