From 53679da34cd7fe84aaac2a15f936e1450de7c125 Mon Sep 17 00:00:00 2001 From: lukeflo Date: Fri, 22 Nov 2024 17:35:09 +0100 Subject: rewrite cli parsing, allow multiple files and dir as args --- Cargo.lock | 7 ----- Cargo.toml | 1 - src/bibiman.rs | 2 +- src/cliargs.rs | 80 ++++++++++++++++++++++++++++++++-------------------------- src/main.rs | 6 +---- 5 files changed, 46 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c194d8..3609d77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,6 @@ dependencies = [ "lexopt", "nucleo-matcher", "ratatui", - "sarge", "signal-hook", "tokio", "tokio-util", @@ -1097,12 +1096,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "sarge" -version = "7.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2096e40214337b2293fa4c3eb63c5376b57f4247cbbaf6d0af477f1d36ac21d9" - [[package]] name = "scoped-tls" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index dac2dd6..ccec50b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ itertools = "0.13.0" lexopt = "0.3.0" nucleo-matcher = "0.3.1" ratatui = { version = "0.29.0", features = ["unstable-rendered-line-info"]} -sarge = "7.2.5" signal-hook = "0.3.17" tokio = { version = "1.39.3", features = ["full"] } tokio-util = "0.7.12" diff --git a/src/bibiman.rs b/src/bibiman.rs index 4d0aa60..3ae0520 100644 --- a/src/bibiman.rs +++ b/src/bibiman.rs @@ -77,7 +77,7 @@ pub struct Bibiman { impl Bibiman { // Constructs a new instance of [`App`]. pub fn new(args: CLIArgs) -> Result { - let main_bibfiles = args.bibfilearg; + let main_bibfiles = args.pos_args; let main_biblio = BibiSetup::new(&main_bibfiles); let tag_list = TagList::new(main_biblio.keyword_list.clone()); let search_struct = BibiSearch::default(); diff --git a/src/cliargs.rs b/src/cliargs.rs index a298f65..1b03019 100644 --- a/src/cliargs.rs +++ b/src/cliargs.rs @@ -15,57 +15,65 @@ // along with this program. If not, see . ///// -use sarge::prelude::*; +use color_eyre::eyre::Result; +use color_eyre::owo_colors::OwoColorize; +use lexopt::prelude::*; use std::env; +use std::ffi::OsString; use std::path::PathBuf; - -sarge! { - // Name of the struct - ArgumentsCLI, - - // Show help and exit. - 'h' help: bool, - - // Show version and exit. - 'v' version: bool, -} +use walkdir::WalkDir; // struct for CLIArgs +#[derive(Debug, Default)] pub struct CLIArgs { pub helparg: bool, pub versionarg: bool, - pub bibfilearg: Vec, -} - -impl Default for CLIArgs { - fn default() -> Self { - Self::new() - } + pub pos_args: Vec, } impl CLIArgs { - pub fn new() -> Self { - let (cli_args, pos_args) = ArgumentsCLI::parse().expect("Could not parse CLI arguments"); - let bibfilearg = if pos_args.len() > 1 { - parse_files(pos_args) - } else { - panic!("No bibfile provided") - }; - Self { - helparg: cli_args.help, - versionarg: cli_args.version, - bibfilearg, + pub fn parse_args() -> Result { + let mut args = CLIArgs::default(); + let mut parser = lexopt::Parser::from_env(); + + while let Some(arg) = parser.next()? { + match arg { + Short('h') | Long("help") => args.helparg = true, + Short('v') | Long("version") => args.versionarg = true, + Value(pos_arg) => parse_files(&mut args, pos_arg), + _ => return Err(arg.unexpected()), + } } + Ok(args) } } -pub fn parse_files(args: Vec) -> Vec { - let mut files: Vec = Vec::new(); - for f in args { - files.push(PathBuf::from(f)) +pub fn parse_files(args: &mut CLIArgs, pos_arg: OsString) { + // convert to PathBuf to use methods for testing the path + let path = PathBuf::from(pos_arg); + // If pos arg is file, just push it to path vec + if path.is_file() { + args.pos_args.push(path); + // If pos arg is dir, walk dir and collect bibfiles + } else if path.is_dir() { + for file in WalkDir::new(path) { + let f = file.unwrap().into_path(); + if f.is_file() && f.extension().unwrap() == "bib" { + args.pos_args.push(f) + } + } + } else { + println!( + "{} {}", + "The positional argument is neither a valid file, nor a path:" + .red() + .bold(), + path.as_os_str().to_string_lossy().bright_red().italic() + ); + println!(); + println!("{}", help_func()); + std::process::exit(1) } - files.remove(0); - files } pub fn help_func() -> String { diff --git a/src/main.rs b/src/main.rs index 95bf16a..747a8f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,7 @@ const TEXT_FG_COLOR_INDEX: u8 = 250; #[tokio::main] async fn main() -> Result<()> { // Parse CLI arguments - let parsed_args = CLIArgs::new(); + let parsed_args = CLIArgs::parse_args().unwrap(); // Print help if -h/--help flag is passed and exit if parsed_args.helparg { @@ -52,10 +52,6 @@ async fn main() -> Result<()> { std::process::exit(0); } - // if !parsed_args.bibfilearg.is_file() { - // panic!("No \'.bib\' file passed, aborting") - // } - init_error_hooks()?; // Create an application. -- cgit v1.2.3 ='n88' href='#n88'>88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164