diff --git a/Cargo.lock b/Cargo.lock index a25c32a..e6770aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,326 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "anyhow" version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "clap" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "finr" version = "0.1.2" dependencies = [ "anyhow", + "clap", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", ] + +[[package]] +name = "libc" +version = "0.2.146" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "proc-macro2" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml index 89d377f..ef4f2ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ license = "MIT" [dependencies] anyhow = "1.0.71" +clap = { version = "4.3.2", features = ["derive"]} [profile.release] debug = false diff --git a/src/lib.rs b/src/lib.rs index 826c914..0d81827 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,48 +1,36 @@ use anyhow::{Context, Ok}; -use std::collections::HashSet; use std::fs::read_dir; use std::path::{Path, PathBuf}; -#[derive(Debug)] +use clap::Parser; + +#[derive(Debug, Parser)] +#[command(author, version, about, long_about = None)] pub struct Config { pub target: String, - pub entry_type: EntryType, - pub is_extension: bool, + + #[arg(short = 'r')] + pub dir: bool, + + #[arg(short = 'e')] + pub extension: bool, + + #[arg(short = 'd', default_value = "100")] pub max_depth: usize, - pub ignore_dirs: HashSet, - pub include_dirs: HashSet, -} -impl Default for Config { - fn default() -> Self { - let ignore_dirs: HashSet<_> = [ - "node_modules", - "target", - ".git", - ".cargo", - ".rustup", - ".npm", - ".ssh", - "__pycache__", - ] - .into_iter() - .map(|item| item.to_string()) - .collect(); - - Self { - target: String::new(), - entry_type: EntryType::File, - is_extension: false, - max_depth: 100, - ignore_dirs, - include_dirs: HashSet::default(), - } - } + #[arg(short = 'I')] + pub ignore_dirs: Vec, + + #[arg(short = 'i')] + pub include_dirs: Vec, + + #[arg(short = 'p')] + pub path: Option } impl Config { pub fn is_match(&self, filename: &str) -> bool { - if self.is_extension { + if self.extension { filename.ends_with(&self.target) } else { filename.contains(&self.target) @@ -50,22 +38,6 @@ impl Config { } } -#[derive(Debug, Copy, Clone)] -pub enum EntryType { - File = 0, - Directory = 1, -} - -impl EntryType { - pub fn is_dir(&self) -> bool { - use EntryType::*; - match self { - File => false, - Directory => true, - } - } -} - pub fn find>( root: P, depth: usize, @@ -80,9 +52,9 @@ pub fn find>( for entry in entries.into_iter().filter_map(Result::ok) { let name = entry.file_name().to_string_lossy().to_string(); - let is_dir = entry.file_type().context("File type Error")?.is_dir(); + let is_dir = entry.file_type().context("File Type Error")?.is_dir(); - if config.entry_type.is_dir() == is_dir && config.is_match(&name) { + if config.dir == is_dir && config.is_match(&name) { result.push(entry.path()); } @@ -99,28 +71,3 @@ pub fn find>( Ok(()) } - -pub fn print_help() { - println!("finr [PATTERN] [PATH?] [FLAGS...]"); - println!(); - println!( - "{:<20} Max recursion depth. By default is 100", - "--max-depth | -d" - ); - println!( - "{:<20} Type of entry to search. Possible values: f | file | directory | d", - "--type | -t" - ); - println!( - "{:<20} Directories to ignore. Expects a name not a path", - "--ignore | -i" - ); - println!( - "{:<20} Directories to include. Expects a name not a path", - "--include | -n" - ); - println!( - "{:<20} Use [PATTERN] to match at the end of the file or directory", - "--extension | -e" - ); -} diff --git a/src/main.rs b/src/main.rs index 947f140..3f4d782 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,100 +1,27 @@ -use anyhow::{Context, Ok}; -use finr::{find, print_help, Config, EntryType}; use std::env; -use std::path::PathBuf; -fn main() -> anyhow::Result<()> { - let mut args_iter = env::args().skip(1).peekable(); - let mut config = Config::default(); - - if let Some(target) = args_iter.next() { - if target == "--help" { - print_help(); - return Ok(()); - } - - config.target = target; - } else { - print_help(); - return Ok(()); - } - - let mut path = env::current_dir()?; - - if let Some(arg) = args_iter.peek() { - if !arg.starts_with('-') { - path = PathBuf::from(arg); - } - } - - while let Some(arg) = args_iter.next() { - if arg == "--max-depth" || arg == "-d" { - config.max_depth = args_iter - .next() - .ok_or(anyhow::anyhow!("Missing argument for --max-depth flag"))? - .parse::() - .context("Argument for --max-depth should be a positive integer")?; - } - - if arg == "--type" || arg == "-t" { - let arg = args_iter - .next() - .ok_or(anyhow::anyhow!("Missing Argument for --type flag"))?; - - config.entry_type = match arg.as_str() { - "file" | "f" => Ok(EntryType::File), - "directory" | "d" => Ok(EntryType::Directory), - _ => anyhow::bail!( - "Invalid argument \"{}\" for --type flag. Valid arguments [file | directory]", - arg - ), - }?; - } +use anyhow::Ok; +use finr::{find, Config}; +use clap::Parser; - if arg == "--ignore" || arg == "-i" { - while let Some(current) = args_iter.peek() { - if current.starts_with('-') { - break; - } - - let dir = args_iter.next().unwrap().trim().to_string(); - - if dir.is_empty() { - anyhow::bail!("Invalid value for --ignore argument: \"{}\"", dir); - } - - config.ignore_dirs.insert(dir); - } - } - - if arg == "--include" || arg == "-n" { - while let Some(current) = args_iter.peek() { - if current.starts_with('-') { - break; - } - - let dir = args_iter.next().unwrap().trim().to_string(); - - if dir.is_empty() { - anyhow::bail!("Invalid value for --include argument: \"{}\"", dir); - } - - config.include_dirs.insert(dir); - } - } - - if arg == "--extension" || arg == "-e" { - config.is_extension = true - } - - if arg == "--help" { - print_help(); - return Ok(()); - } +fn main() -> anyhow::Result<()> { + let mut config = Config::parse(); + + if config.ignore_dirs.is_empty() { + config.ignore_dirs = [ + "node_modules", + "target", + ".git", + ".cargo", + ".rustup", + ".npm", + ".ssh", + "__pycache__", + ].into_iter().map(ToString::to_string).collect() } let mut result = Vec::with_capacity(6); - find(path, 0, &config, &mut result)?; + find(config.path.clone().unwrap_or(env::current_dir()?), 0, &config, &mut result)?; for e in result.iter() { println!("{}", e.display());