use std::process::exit; use clap::{Parser, Subcommand}; use log::{debug, error, info, trace, warn}; use colored::Colorize; use crate::CONFIG; use crate::package::identifier::PackageIdentifier; use crate::package::Package; use crate::process::Process; use crate::types::fetch::TryFetch; #[derive(Parser, Debug)] #[clap(name = "pkgr", version)] pub struct Cli { #[command(subcommand)] pub command: Command, } #[derive(Subcommand, Debug)] pub enum Command { /// Install a package Install { #[arg(short, long, default_value_t = false)] build: bool, package_identifier: PackageIdentifier, }, /// Remove a package from the system Remove { /// Remove the package from index too #[arg(short, long, default_value_t = false)] index: bool, package_identifier: PackageIdentifier, }, /// List packages List { /// List installed packages #[arg(short, long, default_value_t = true)] installed: bool, }, /// Update packages on the system Update, /// Get info about pkgr Info { #[arg(short, long, default_value_t = false)] detailed: bool }, #[cfg(debug_assertions)] Debug, #[command(hide = true)] None, } impl Command { pub fn execute(&self) { match self { Command::Install { build, package_identifier, } => { warn!("Installer does not run in isolation."); let start = std::time::Instant::now(); let _unix_start = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap(); info!("Parsing package..."); trace!("Fetching package: {:?}", package_identifier); let mut pkg = Package::try_fetch(package_identifier.clone()).unwrap(); debug!("manifest size: {}kb", pkg.pkgfile.manifest.len() / 1024); debug!("files size: {}kb", pkg.pkgfile.data.len() / 1024); trace!("Checking if package is installed..."); if pkg.is_installed() { error!("Package is already installed."); exit(1); } trace!("Starting install..."); match pkg.install(CONFIG.with(|c| if !*build { c.build_by_default } else { *build })) { Ok(_) => (), Err(e) => { error!("Install failed: {}", e.to_string()); exit(1); } } let end = std::time::Instant::now(); let _unix_end = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap(); let duration = end.duration_since(start); info!("Install complete."); info!("Install took {}ms.", duration.as_nanos() as f64 / 1000000.0); } Command::Remove { package_identifier, index, } => { if let PackageIdentifier::URI(_) = package_identifier { error!("URI is unsupported when removing applications."); exit(1); } info!("Index: {}", index); info!("Package identifier: {}", package_identifier); } Command::List { installed: _ } => { error!("List is not yet implemented."); } Command::Update => { error!("Update is not yet implemented."); } Command::Info { detailed } => { info!("Welcome to pkgr!\n\ {}\n\ To get help please run \"{} -h\"", env!("CARGO_PKG_DESCRIPTION"), std::env::args().nth(0).unwrap()); if *detailed { info!(""); info!("version: {}", env!("CARGO_PKG_VERSION")); info!("authors: {}", env!("CARGO_PKG_AUTHORS")); info!(""); info!("If you can't seem to figure something out, use environment variable: PKGR_LOG_LEVEL=debug"); trace!("{}", "The trace log level should really only be used by PKGR devs.".red()); } } #[cfg(debug_assertions)] Command::Debug => { trace!("Trace message.\nWith newline."); debug!("Debug message.\nWith newline."); info!("Info message.\nWith newline."); warn!("Warning message.\nWith newline."); error!("Error message.\nWith newline."); info!(""); Process::command(vec!["sh", "-c", "echo whoami: $(whoami)"]) .spawn() .unwrap(); if let Ok(_user) = std::env::var("SUDO_USER") { Process::command(vec!["sh", "-c", "echo sudo_user: $SUDO_USER"]) .spawn() .unwrap(); } info!(""); info!( "PKGR_LOG_LEVEL: {}", std::env::var("PKGR_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()) ); } Command::None => { error!("No command was specified."); } } } }