diff --git a/Cargo.lock b/Cargo.lock index 116f2c1..00254cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,14 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "humantime" version = "1.2.0" @@ -888,6 +896,7 @@ dependencies = [ "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", "size_format 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "tree_magic_fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "xz2 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1017,6 +1026,26 @@ name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "structopt" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.34" @@ -1132,6 +1161,11 @@ dependencies = [ "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-segmentation" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.5" @@ -1311,6 +1345,7 @@ dependencies = [ "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" @@ -1385,6 +1420,8 @@ dependencies = [ "checksum size_format 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed5f6ab2122c6dec69dca18c72fa4590a27e581ad20d44960fe74c032a0b23b" "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c767a8971f53d7324583085deee2e230903be09e52fb27df9af94c5cb2b43c31" +"checksum structopt-derive 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c57a30c87454ced2186f62f940e981746e8cbbe026d52090c8c4352b636f8235" "checksum syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)" = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" @@ -1398,6 +1435,7 @@ dependencies = [ "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" +"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" diff --git a/Cargo.toml b/Cargo.toml index f4c520b..77e86e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rga" -description = "ripgrep but also search in PDFs, E-Books, Office documents, etc, and also in archives" +description = "ripgrep but search in PDFs, E-Books, Office documents, etc, and also in archives" license = "AGPL-3.0-or-later" version = "0.4.0" repository = "https://github.com/phiresky/rga" @@ -39,3 +39,4 @@ encoding_rs = "0.8.17" encoding_rs_io = "0.1.6" rusqlite = { version = "0.18.0", features=["vtab"] } # "bundled" size_format = "1.0.2" +structopt = "0.2.17" diff --git a/README.md b/README.md index 6aebb35..79300b9 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,10 @@ similar: # considerations - matching on mime (magic bytes) instead of filename + +# Development + +To enable debug logging: + +export RUST_LOG=rga=debug +export RUST_BACKTRACE=1 diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..9dbb57d --- /dev/null +++ b/src/args.rs @@ -0,0 +1,64 @@ +use clap::{crate_version, App, Arg}; +use failure::Fallible; +use log::*; +use serde::{Deserialize, Serialize}; +use std::ffi::OsStr; +use std::ffi::OsString; +use std::iter::IntoIterator; +use std::process::Command; +use structopt::StructOpt; +fn is_default(t: &T) -> bool { + t == &T::default() +} + +#[derive(StructOpt, Debug, Deserialize, Serialize)] +#[structopt(rename_all = "kebab-case")] +pub struct RgaOptions { + #[serde(default, skip_serializing_if = "is_default")] + #[structopt(long, help = "Disable caching of results")] + pub no_cache: bool, + + #[serde(default, skip_serializing_if = "is_default")] + #[structopt( + long, + require_equals = true, + require_delimiter = true, + help = "Change which adapters to use and in which priority order (descending)" + )] + pub adapters: Vec, + + #[serde(skip)] + #[structopt(long, help = "Show help for ripgrep itself")] + pub rg_help: bool, + + #[serde(skip)] + #[structopt(long, help = "Show version of ripgrep itself")] + pub rg_version: bool, + + #[serde(skip)] + #[structopt(long, help = "List all known adapters")] + pub list_adapters: bool, +} + +static RGA_CONFIG: &str = "RGA_CONFIG"; + +pub fn parse_args(args: I) -> Fallible +where + I: IntoIterator, + I::Item: Into + Clone, +{ + match std::env::var(RGA_CONFIG) { + Ok(val) => { + error!("Loading args from env {}={}", RGA_CONFIG, val); + Ok(serde_json::from_str(&val)?) + } + Err(_) => { + let matches = RgaOptions::from_iter(args); + let serialized_config = serde_json::to_string(&matches)?; + std::env::set_var(RGA_CONFIG, &serialized_config); + debug!("{}={}", RGA_CONFIG, serialized_config); + + Ok(matches) + } + } +} diff --git a/src/bin/rga-preproc.rs b/src/bin/rga-preproc.rs index fad5284..a06eb01 100644 --- a/src/bin/rga-preproc.rs +++ b/src/bin/rga-preproc.rs @@ -1,10 +1,17 @@ -use failure::{format_err, Error}; +use clap::{crate_version, App, Arg}; + +use failure::{format_err, Error, Fallible}; +use log::*; use rga::adapters::*; use rga::preproc::*; use std::env; use std::fs::File; use std::io::BufReader; -fn main() -> Result<(), Error> { +fn main() -> Fallible<()> { + env_logger::init(); + let empty: Vec = vec![]; + let args = rga::args::parse_args(empty)?; + //clap::App::new("rga-preproc").arg(Arg::from_usage()) let path = { let filepath = std::env::args_os() .skip(1) @@ -16,9 +23,10 @@ fn main() -> Result<(), Error> { let i = File::open(&path)?; let mut o = std::io::stdout(); - let cache = match env::var("RGA_NO_CACHE") { - Ok(ref s) if s.len() > 0 => None, - Ok(_) | Err(_) => Some(rga::preproc_cache::open()?), + let cache = if args.no_cache { + None + } else { + Some(rga::preproc_cache::open()?) }; let ai = AdaptInfo { inp: &mut BufReader::new(i), diff --git a/src/bin/rga.rs b/src/bin/rga.rs index c134437..81c102b 100644 --- a/src/bin/rga.rs +++ b/src/bin/rga.rs @@ -3,24 +3,18 @@ use failure::Fallible; use log::*; use rga::adapters::spawning::map_exe_error; use rga::adapters::*; +use rga::args::*; +use serde::{Deserialize, Serialize}; use std::ffi::OsString; use std::process::Command; +use structopt::StructOpt; + +fn split_args() -> Fallible<(RgaOptions, Vec)> { + let mut app = RgaOptions::clap(); -fn main() -> Fallible<()> { - env_logger::init(); - let mut app = App::new(env!("CARGO_PKG_NAME")) - .version(crate_version!()) - .about(env!("CARGO_PKG_DESCRIPTION")) - // .setting(clap::AppSettings::ArgRequiredElseHelp) - .arg(Arg::from_usage( - "--list-adapters 'Lists all known adapters'", - )) - .arg(Arg::from_usage("--adapters=[commaseparated] 'Change which adapters to use and in which priority order (descending)'").require_equals(true)) - .arg(Arg::from_usage("--no-cache 'Disable caching of results'")) - .arg(Arg::from_usage("--rg-help 'Show help for ripgrep itself'")) - .arg(Arg::from_usage("--rg-version 'Show version of ripgrep itself'")); app.p.create_help_and_version(); let mut firstarg = true; + // debug!("{:#?}", app.p.flags); let (our_args, mut passthrough_args): (Vec, Vec) = std::env::args_os() .partition(|os_arg| { if firstarg { @@ -45,7 +39,7 @@ fn main() -> Fallible<()> { for opt in app.p.opts() { // only parse --x=... for now if let Some(l) = opt.s.long { - if arg.starts_with(&format!("--{}-", l)) { + if arg.starts_with(&format!("--{}=", l)) { return true; } } @@ -54,18 +48,24 @@ fn main() -> Fallible<()> { false }); debug!("our_args: {:?}", our_args); - let matches = app.get_matches_from(our_args); - if matches.is_present("rg-help") { + let matches = parse_args(our_args)?; + if matches.rg_help { passthrough_args.insert(0, "--help".into()); } - if matches.is_present("rg-version") { + if matches.rg_version { passthrough_args.insert(0, "--version".into()); } debug!("passthrough_args: {:?}", passthrough_args); + Ok((matches, passthrough_args)) +} +fn main() -> Fallible<()> { + env_logger::init(); + + let (args, passthrough_args) = split_args()?; let adapters = get_adapters(); - if matches.is_present("list-adapters") { + if args.list_adapters { println!("Adapters:"); for adapter in adapters { let meta = adapter.metadata(); diff --git a/src/lib.rs b/src/lib.rs index 6bb280c..f9bddac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![warn(clippy::all)] pub mod adapters; +pub mod args; mod caching_writer; pub mod preproc; pub mod preproc_cache;