diff --git a/Cargo.toml b/Cargo.toml index 0b89884..2ede96c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] toml = "0.8.10" serde = {version = "1.0.197", features = ["derive"]} -clap = { version = "4.5.2", features = ["cargo"] } +clap = { version = "4.5.2", features = ["cargo", "derive"] } colored = "2.1.0" once_cell = "1.19.0" walkdir = "2.5.0" diff --git a/src/frontend/command.rs b/src/frontend/command.rs deleted file mode 100644 index 7ea7545..0000000 --- a/src/frontend/command.rs +++ /dev/null @@ -1,27 +0,0 @@ -use clap::{Arg, Command}; -use once_cell::sync::Lazy; - -pub static BUILD_CMD: Lazy = Lazy::new(|| { - Command::new("build") - .about("Build your Java project into a standalone .jar") - .alias("b") -}); - -pub static INIT_CMD: Lazy = Lazy::new(|| { - Command::new("init") - .about("Initialize a new Espresso project") - .alias("i") -}); - -pub static RUN_CMD: Lazy = Lazy::new(|| { - Command::new("run") - .about("Build & run your Java project") - .alias("r") -}); - -pub static ADD_CMD: Lazy = Lazy::new(|| { - Command::new("add") - .about("Add a dependency from Maven Repository to your project") - .alias("a") - .subcommand_value_name(value_name) -}); diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 69c60c7..9bfb725 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -1,3 +1,2 @@ -pub mod command; pub mod service; pub mod terminal; diff --git a/src/frontend/service/mod.rs b/src/frontend/service/mod.rs index d89ff30..4f5ddd1 100644 --- a/src/frontend/service/mod.rs +++ b/src/frontend/service/mod.rs @@ -1,7 +1,9 @@ use crate::backend::context::{AbsoltuePaths, ProjectContext}; +use crate::backend::dependency::resolve::Package; use crate::backend::toolchain::{compile_project, run_jar, ToolchainContext}; use crate::backend::{self, context}; use crate::frontend::terminal::{print_err, print_sameline}; +use crate::util::error::EspressoError; use std::{error, io, result}; use super::terminal::print_general; @@ -116,13 +118,41 @@ pub async fn add( print_general(format!("{}) G:{} | A:{}", elem + 1, package.group_id, package.artifact_id).as_str()); } - // collect the package selection - let mut package_selection = String::new(); - print_sameline(format!("Select a package (1-{}): ", packages.len()).as_str()); - if let Err(_) = io::stdin().read_line(&mut package_selection) { - print_err("Failed to read user package selection") + // collect the package selection if there was more than one returned package + let selected_package: &Package; + if packages.len() == 1 { + selected_package = packages.get(0).expect("At least one package was simultaneously returned & not returned. Schrodinger's package..?"); + } else if packages.len() > 1 { + // get the selected package as a string + let mut package_number_selection = String::new(); + print_sameline(format!("Select a package (1-{}): ", packages.len()).as_str()); + if let Err(_) = io::stdin().read_line(&mut package_number_selection) { + print_err("Failed to read user package selection") + } + + // convert the input into a u64 + let package_number_selection_int: u64 = match package_number_selection.parse::() { + Ok(v) => v, + Err(e) => { + print_err("Failed to parse user input as an unsigned integer."); + panic!("{}", e); + } + }; + + // set the selected package to its corresponding Package struct + selected_package = match packages.get((package_number_selection_int - 1) as usize) { + Some(v) => v, + None => { + print_err("Out of range"); + panic!("Out of range"); + } + }; + } else { + print_err("There were no packages matching that search term"); + panic!() } + println!("You selected: {}", selected_package.artifact_id); // pass ownership back Ok((p_ctx, tc_ctx)) } diff --git a/src/main.rs b/src/main.rs index b596e02..e28c7fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,12 +2,40 @@ use backend::{ context::{get_project_context, ProjectContext}, toolchain::{get_toolchain_context, ToolchainContext}, }; -use clap::Command; +use clap::{Parser, Subcommand, command}; use frontend::terminal::print_err; mod backend; mod frontend; mod util; +#[derive(Parser, Debug)] +#[command(name="espresso")] +#[command(about="Build Java apps without the fuss of antiquated build tools. Drink some Espresso.")] +struct EspressoCli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand, Debug)] +enum Commands { + #[command(about="Build your project")] + Build {}, + + #[command(about="Initialize a new project")] + Init {}, + + #[command(about="Run your project")] + Run {}, + + #[command(arg_required_else_help = true)] + #[command(about="Add a package to your project")] + Add { + #[arg(required = true)] + search_term: String + }, +} + + /// Get runtime contexts required for command service functions /// /// # Returns @@ -26,46 +54,32 @@ fn get_contexts() -> (ProjectContext, ToolchainContext) { #[tokio::main] async fn main() { - let cmd = Command::new("Espresso") - .bin_name("espresso") - .version("1.0.0") - .about("Build Java apps without the fuss of antiquated build tools. Drink some Espresso.") - .subcommand_required(true) - .subcommand((frontend::command::BUILD_CMD).clone()) - .subcommand((frontend::command::INIT_CMD).clone()) - .subcommand((frontend::command::RUN_CMD).clone()) - .subcommand((frontend::command::ADD_CMD).clone()); - - let matches = cmd.get_matches(); + let args = EspressoCli::parse(); - // ensure the espresso_debug directory exists if ESPRESSO_DEBUG=1 - // ensure_debug_directory_exists_if_debug(); - - match matches.subcommand_name() { - Some("build") => { + match args.command { + Commands::Build { } => { let (p_ctx, tc_ctx) = get_contexts(); match frontend::service::build(p_ctx, tc_ctx) { Ok(_) => (), Err(e) => print_err(format!("Error occurred running command: {}", e).as_str()), } - } - Some("init") => { - frontend::service::init(); - } - Some("run") => { + }, + Commands::Init { } => { + frontend::service::init() + }, + Commands::Run { } => { let (p_ctx, tc_ctx) = get_contexts(); match frontend::service::run(p_ctx, tc_ctx) { Ok(_) => (), Err(e) => print_err(format!("Error occurred running command: {}", e).as_str()), } } - Some("add") => { + Commands::Add { search_term } => { let (p_ctx, tc_ctx) = get_contexts(); - match frontend::service::add(p_ctx, tc_ctx).await { + match frontend::service::add(p_ctx, tc_ctx, search_term).await { Ok(_) => (), Err(e) => print_err(format!("Error occurred running command: {}", e).as_str()), } } - _ => print_err("Unknown subcommand"), } }