From 92c81b122548ab42586314ea535bb46ea41f1b10 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Thu, 12 Oct 2023 12:16:42 -0400 Subject: [PATCH] core: switch to anyhow This commit adds `anyhow` as a dependency and switches over to it from Box. It actually looks like I've kept all of my errors rather shallow, such that we don't get a huge benefit from anyhow at present. But now that anyhow is in use, I expect to use its "context" feature more going forward. --- Cargo.lock | 7 ++ Cargo.toml | 1 + crates/core/args.rs | 162 ++++++++++++++++++++---------------------- crates/core/config.rs | 8 +-- crates/core/main.rs | 29 ++++---- crates/core/search.rs | 2 +- 6 files changed, 105 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13fc7c99..472b5618 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "autocfg" version = "1.1.0" @@ -426,6 +432,7 @@ checksum = "56d84fdd47036b038fc80dd333d10b6aab10d5d31f4a366e20014def75328d33" name = "ripgrep" version = "13.0.0" dependencies = [ + "anyhow", "bstr", "clap", "grep", diff --git a/Cargo.toml b/Cargo.toml index 3a905569..14bb7c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ members = [ ] [dependencies] +anyhow = "1.0.75" bstr = "1.6.0" grep = { version = "0.2.12", path = "crates/grep" } ignore = { version = "0.4.19", path = "crates/ignore" } diff --git a/crates/core/args.rs b/crates/core/args.rs index 6125f5e8..1e781b46 100644 --- a/crates/core/args.rs +++ b/crates/core/args.rs @@ -46,7 +46,6 @@ use crate::{ messages::{set_ignore_messages, set_messages}, search::{PatternMatcher, Printer, SearchWorker, SearchWorkerBuilder}, subject::{Subject, SubjectBuilder}, - Result, }; /// The command that ripgrep should execute based on the command line @@ -129,7 +128,7 @@ impl Args { /// ripgrep, then print the version and exit. /// /// Also, initialize a global logger. - pub fn parse() -> Result { + pub fn parse() -> anyhow::Result { // We parse the args given on CLI. This does not include args from // the config. We use the CLI args as an initial configuration while // trying to parse config files. If a config file exists and has @@ -140,7 +139,7 @@ impl Args { set_ignore_messages(!early_matches.is_present("no-ignore-messages")); if let Err(err) = Logger::init() { - return Err(format!("failed to initialize logger: {}", err).into()); + anyhow::bail!("failed to initialize logger: {err}"); } if early_matches.is_present("trace") { log::set_max_level(log::LevelFilter::Trace); @@ -194,7 +193,7 @@ impl Args { /// search results. /// /// The returned printer will write results to the given writer. - fn printer(&self, wtr: W) -> Result> { + fn printer(&self, wtr: W) -> anyhow::Result> { match self.matches().output_kind() { OutputKind::Standard => { let separator_search = self.command() == Command::Search; @@ -218,7 +217,7 @@ impl Args { impl Args { /// Create a new buffer writer for multi-threaded printing with color /// support. - pub fn buffer_writer(&self) -> Result { + pub fn buffer_writer(&self) -> anyhow::Result { let mut wtr = BufferWriter::stdout(self.matches().color_choice()); wtr.separator(self.matches().file_separator()?); Ok(wtr) @@ -236,7 +235,7 @@ impl Args { pub fn path_printer( &self, wtr: W, - ) -> Result> { + ) -> anyhow::Result> { let mut builder = PathPrinterBuilder::new(); builder .color_specs(self.matches().color_specs()?) @@ -253,7 +252,7 @@ impl Args { /// Returns true if and only if the search should quit after finding the /// first match. - pub fn quit_after_match(&self) -> Result { + pub fn quit_after_match(&self) -> anyhow::Result { Ok(self.matches().is_present("quiet") && self.stats()?.is_none()) } @@ -263,7 +262,7 @@ impl Args { pub fn search_worker( &self, wtr: W, - ) -> Result> { + ) -> anyhow::Result> { let matches = self.matches(); let matcher = self.matcher().clone(); let printer = self.printer(wtr)?; @@ -284,7 +283,7 @@ impl Args { /// /// When this returns a `Stats` value, then it is guaranteed that the /// search worker will be configured to track statistics as well. - pub fn stats(&self) -> Result> { + pub fn stats(&self) -> anyhow::Result> { Ok(if self.command().is_search() && self.matches().stats() { Some(Stats::new()) } else { @@ -318,12 +317,12 @@ impl Args { /// /// If there was a problem reading and parsing the type definitions, then /// this returns an error. - pub fn type_defs(&self) -> Result> { + pub fn type_defs(&self) -> anyhow::Result> { Ok(self.matches().types()?.definitions().to_vec()) } /// Return a walker that never uses additional threads. - pub fn walker(&self) -> Result { + pub fn walker(&self) -> anyhow::Result { Ok(self .matches() .walker_builder(self.paths(), self.0.threads)? @@ -371,7 +370,7 @@ impl Args { } /// Return a parallel walker that may use additional threads. - pub fn walker_parallel(&self) -> Result { + pub fn walker_parallel(&self) -> anyhow::Result { Ok(self .matches() .walker_builder(self.paths(), self.0.threads)? @@ -434,7 +433,7 @@ impl SortBy { /// Try to check that the sorting criteria selected is actually supported. /// If it isn't, then an error is returned. - fn check(&self) -> Result<()> { + fn check(&self) -> anyhow::Result<()> { match self.kind { SortByKind::None | SortByKind::Path => {} SortByKind::LastModified => { @@ -509,7 +508,7 @@ impl ArgMatches { /// /// If there are no additional arguments from the environment (e.g., a /// config file), then the given matches are returned as is. - fn reconfigure(self) -> Result { + fn reconfigure(self) -> anyhow::Result { // If the end user says no config, then respect it. if self.is_present("no-config") { log::debug!( @@ -534,7 +533,7 @@ impl ArgMatches { /// Convert the result of parsing CLI arguments into ripgrep's higher level /// configuration structure. - fn to_args(self) -> Result { + fn to_args(self) -> anyhow::Result { // We compute these once since they could be large. let patterns = self.patterns()?; let matcher = self.matcher(&patterns)?; @@ -591,7 +590,7 @@ impl ArgMatches { /// /// If there was a problem building the matcher (e.g., a syntax error), /// then this returns an error. - fn matcher(&self, patterns: &[String]) -> Result { + fn matcher(&self, patterns: &[String]) -> anyhow::Result { if self.is_present("pcre2") { self.matcher_engine("pcre2", patterns) } else if self.is_present("auto-hybrid-regex") { @@ -611,13 +610,13 @@ impl ArgMatches { &self, engine: &str, patterns: &[String], - ) -> Result { + ) -> anyhow::Result { match engine { "default" => { let matcher = match self.matcher_rust(patterns) { Ok(matcher) => matcher, Err(err) => { - return Err(From::from(suggest(err.to_string()))); + anyhow::bail!(suggest(err.to_string())); } }; Ok(PatternMatcher::RustRegex(matcher)) @@ -628,9 +627,9 @@ impl ArgMatches { Ok(PatternMatcher::PCRE2(matcher)) } #[cfg(not(feature = "pcre2"))] - "pcre2" => Err(From::from( + "pcre2" => anyhow::bail!( "PCRE2 is not available in this build of ripgrep", - )), + ), "auto" => { let rust_err = match self.matcher_rust(patterns) { Ok(matcher) => { @@ -647,21 +646,18 @@ impl ArgMatches { Ok(matcher) => return Ok(matcher), Err(err) => err, }; - Err(From::from(format!( + let divider = "~".repeat(79); + anyhow::bail!( "regex could not be compiled with either the default \ regex engine or with PCRE2.\n\n\ - default regex engine error:\n{}\n{}\n{}\n\n\ - PCRE2 regex engine error:\n{}", - "~".repeat(79), - rust_err, - "~".repeat(79), - pcre_err, - ))) + default regex engine error:\n\ + {divider}\n\ + {rust_err}\n\ + {divider}\n\n\ + PCRE2 regex engine error:\n{pcre_err}", + ); } - _ => Err(From::from(format!( - "unrecognized regex engine '{}'", - engine - ))), + _ => anyhow::bail!("unrecognized regex engine '{engine}'"), } } @@ -669,7 +665,10 @@ impl ArgMatches { /// /// If there was a problem building the matcher (such as a regex syntax /// error), then an error is returned. - fn matcher_rust(&self, patterns: &[String]) -> Result { + fn matcher_rust( + &self, + patterns: &[String], + ) -> anyhow::Result { let mut builder = RustRegexMatcherBuilder::new(); builder .case_smart(self.case_smart()) @@ -707,7 +706,7 @@ impl ArgMatches { } match builder.build_many(patterns) { Ok(m) => Ok(m), - Err(err) => Err(From::from(suggest_multiline(err.to_string()))), + Err(err) => anyhow::bail!(suggest_multiline(err.to_string())), } } @@ -716,7 +715,10 @@ impl ArgMatches { /// If there was a problem building the matcher (such as a regex syntax /// error), then an error is returned. #[cfg(feature = "pcre2")] - fn matcher_pcre2(&self, patterns: &[String]) -> Result { + fn matcher_pcre2( + &self, + patterns: &[String], + ) -> anyhow::Result { let mut builder = PCRE2RegexMatcherBuilder::new(); builder .case_smart(self.case_smart()) @@ -748,7 +750,7 @@ impl ArgMatches { } /// Build a JSON printer that writes results to the given writer. - fn printer_json(&self, wtr: W) -> Result> { + fn printer_json(&self, wtr: W) -> anyhow::Result> { let mut builder = JSONBuilder::new(); builder .pretty(false) @@ -774,7 +776,7 @@ impl ArgMatches { paths: &[PathBuf], wtr: W, separator_search: bool, - ) -> Result> { + ) -> anyhow::Result> { let mut builder = StandardBuilder::new(); builder .color_specs(self.color_specs()?) @@ -813,7 +815,7 @@ impl ArgMatches { &self, paths: &[PathBuf], wtr: W, - ) -> Result> { + ) -> anyhow::Result> { let mut builder = SummaryBuilder::new(); builder .kind(self.summary_kind().expect("summary format")) @@ -830,7 +832,7 @@ impl ArgMatches { } /// Build a searcher from the command line parameters. - fn searcher(&self, paths: &[PathBuf]) -> Result { + fn searcher(&self, paths: &[PathBuf]) -> anyhow::Result { let (ctx_before, ctx_after) = self.contexts()?; let line_term = if self.is_present("crlf") { LineTerminator::crlf() @@ -871,7 +873,7 @@ impl ArgMatches { &self, paths: &[PathBuf], threads: usize, - ) -> Result { + ) -> anyhow::Result { let mut builder = WalkBuilder::new(&paths[0]); for path in &paths[1..] { builder.add(path); @@ -994,7 +996,7 @@ impl ArgMatches { /// /// If the was a problem parsing any of the provided specs, then an error /// is returned. - fn color_specs(&self) -> Result { + fn color_specs(&self) -> anyhow::Result { // Start with a default set of color specs. let mut specs = default_color_specs(); for spec_str in self.values_of_lossy_vec("colors") { @@ -1017,7 +1019,7 @@ impl ArgMatches { /// /// If there was a problem parsing the values from the user as an integer, /// then an error is returned. - fn contexts(&self) -> Result<(usize, usize)> { + fn contexts(&self) -> anyhow::Result<(usize, usize)> { let both = self.usize_of("context")?.unwrap_or(0); let after = self.usize_of("after-context")?.unwrap_or(both); let before = self.usize_of("before-context")?.unwrap_or(both); @@ -1061,7 +1063,7 @@ impl ArgMatches { } /// Parse the dfa-size-limit argument option into a byte count. - fn dfa_size_limit(&self) -> Result> { + fn dfa_size_limit(&self) -> anyhow::Result> { let r = self.parse_human_readable_size("dfa-size-limit")?; u64_to_usize("dfa-size-limit", r) } @@ -1072,7 +1074,7 @@ impl ArgMatches { /// if set to automatic, the Searcher will do BOM sniffing for UTF-16 /// and transcode seamlessly. If disabled, no BOM sniffing nor transcoding /// will occur. - fn encoding(&self) -> Result { + fn encoding(&self) -> anyhow::Result { if self.is_present("no-encoding") { return Ok(EncodingMode::Auto); } @@ -1092,7 +1094,7 @@ impl ArgMatches { } /// Return the file separator to use based on the CLI configuration. - fn file_separator(&self) -> Result>> { + fn file_separator(&self) -> anyhow::Result>> { // File separators are only used for the standard grep-line format. if self.output_kind() != OutputKind::Standard { return Ok(None); @@ -1130,7 +1132,7 @@ impl ArgMatches { /// for the current system is used if the value is not set. /// /// If an invalid pattern is provided, then an error is returned. - fn hyperlink_config(&self) -> Result { + fn hyperlink_config(&self) -> anyhow::Result { let mut env = HyperlinkEnvironment::new(); env.host(hostname(self.value_of_os("hostname-bin"))) .wsl_prefix(wsl_prefix()); @@ -1140,8 +1142,7 @@ impl ArgMatches { Some(format) => match format.parse() { Ok(format) => format, Err(err) => { - let msg = format!("invalid hyperlink format: {err}"); - return Err(msg.into()); + anyhow::bail!("invalid hyperlink format: {err}"); } }, }; @@ -1204,7 +1205,7 @@ impl ArgMatches { /// The maximum number of columns allowed on each line. /// /// If `0` is provided, then this returns `None`. - fn max_columns(&self) -> Result> { + fn max_columns(&self) -> anyhow::Result> { Ok(self.usize_of_nonzero("max-columns")?.map(|n| n as u64)) } @@ -1215,12 +1216,12 @@ impl ArgMatches { } /// The maximum number of matches permitted. - fn max_count(&self) -> Result> { + fn max_count(&self) -> anyhow::Result> { Ok(self.usize_of("max-count")?.map(|n| n as u64)) } /// Parses the max-filesize argument option into a byte count. - fn max_file_size(&self) -> Result> { + fn max_file_size(&self) -> anyhow::Result> { self.parse_human_readable_size("max-filesize") } @@ -1311,7 +1312,7 @@ impl ArgMatches { } /// Builds the set of glob overrides from the command line flags. - fn overrides(&self) -> Result { + fn overrides(&self) -> anyhow::Result { let globs = self.values_of_lossy_vec("glob"); let iglobs = self.values_of_lossy_vec("iglob"); if globs.is_empty() && iglobs.is_empty() { @@ -1378,7 +1379,7 @@ impl ArgMatches { /// /// If the provided path separator is more than a single byte, then an /// error is returned. - fn path_separator(&self) -> Result> { + fn path_separator(&self) -> anyhow::Result> { let sep = match self.value_of_os("path-separator") { None => return Ok(None), Some(sep) => cli::unescape_os(&sep), @@ -1386,14 +1387,14 @@ impl ArgMatches { if sep.is_empty() { Ok(None) } else if sep.len() > 1 { - Err(From::from(format!( + anyhow::bail!( "A path separator must be exactly one byte, but \ the given separator is {} bytes: {}\n\ In some shells on Windows '/' is automatically \ expanded. Use '//' instead.", sep.len(), cli::escape(&sep), - ))) + ) } else { Ok(Some(sep[0])) } @@ -1433,7 +1434,7 @@ impl ArgMatches { /// This includes reading the -e/--regexp and -f/--file flags. /// /// If any pattern is invalid UTF-8, then an error is returned. - fn patterns(&self) -> Result> { + fn patterns(&self) -> anyhow::Result> { if self.is_present("files") || self.is_present("type-list") { return Ok(vec![]); } @@ -1485,7 +1486,7 @@ impl ArgMatches { /// if -F/--fixed-strings is set. /// /// If the pattern is not valid UTF-8, then an error is returned. - fn pattern_from_os_str(&self, pat: &OsStr) -> Result { + fn pattern_from_os_str(&self, pat: &OsStr) -> anyhow::Result { let s = cli::pattern_from_os(pat)?; Ok(self.pattern_from_str(s)) } @@ -1525,7 +1526,7 @@ impl ArgMatches { /// Builds the set of globs for filtering files to apply to the --pre /// flag. If no --pre-globs are available, then this always returns an /// empty set of globs. - fn preprocessor_globs(&self) -> Result { + fn preprocessor_globs(&self) -> anyhow::Result { let globs = self.values_of_lossy_vec("pre-glob"); if globs.is_empty() { return Ok(Override::empty()); @@ -1538,7 +1539,7 @@ impl ArgMatches { } /// Parse the regex-size-limit argument option into a byte count. - fn regex_size_limit(&self) -> Result> { + fn regex_size_limit(&self) -> anyhow::Result> { let r = self.parse_human_readable_size("regex-size-limit")?; u64_to_usize("regex-size-limit", r) } @@ -1549,7 +1550,7 @@ impl ArgMatches { } /// Returns the sorting criteria based on command line parameters. - fn sort_by(&self) -> Result { + fn sort_by(&self) -> anyhow::Result { // For backcompat, continue supporting deprecated --sort-files flag. if self.is_present("sort-files") { return Ok(SortBy::asc(SortByKind::Path)); @@ -1596,7 +1597,7 @@ impl ArgMatches { } /// Return the number of threads that should be used for parallelism. - fn threads(&self) -> Result { + fn threads(&self) -> anyhow::Result { if self.sort_by()?.kind != SortByKind::None { return Ok(1); } @@ -1607,7 +1608,7 @@ impl ArgMatches { } /// Builds a file type matcher from the command line flags. - fn types(&self) -> Result { + fn types(&self) -> anyhow::Result { let mut builder = TypesBuilder::new(); builder.add_defaults(); for ty in self.values_of_lossy_vec("type-clear") { @@ -1667,7 +1668,7 @@ impl ArgMatches { /// /// If the number is zero, then it is considered absent and `None` is /// returned. - fn usize_of_nonzero(&self, name: &str) -> Result> { + fn usize_of_nonzero(&self, name: &str) -> anyhow::Result> { let n = match self.usize_of(name)? { None => return Ok(None), Some(n) => n, @@ -1677,7 +1678,7 @@ impl ArgMatches { /// Safely reads an arg value with the given name, and if it's present, /// tries to parse it as a usize value. - fn usize_of(&self, name: &str) -> Result> { + fn usize_of(&self, name: &str) -> anyhow::Result> { match self.value_of_lossy(name) { None => Ok(None), Some(v) => v.parse().map(Some).map_err(From::from), @@ -1691,7 +1692,7 @@ impl ArgMatches { fn parse_human_readable_size( &self, arg_name: &str, - ) -> Result> { + ) -> anyhow::Result> { let size = match self.value_of_lossy(arg_name) { None => return Ok(None), Some(size) => size, @@ -1770,11 +1771,10 @@ and look-around.", fn suggest_multiline(msg: String) -> String { if msg.contains("the literal") && msg.contains("not allowed") { format!( - "{} + "{msg} Consider enabling multiline mode with the --multiline flag (or -U for short). When multiline mode is enabled, new line characters can be matched.", - msg ) } else { msg @@ -1783,18 +1783,16 @@ When multiline mode is enabled, new line characters can be matched.", /// Convert the result of parsing a human readable file size to a `usize`, /// failing if the type does not fit. -fn u64_to_usize(arg_name: &str, value: Option) -> Result> { +fn u64_to_usize( + arg_name: &str, + value: Option, +) -> anyhow::Result> { use std::usize; - let value = match value { - None => return Ok(None), - Some(value) => value, - }; - if value <= usize::MAX as u64 { - Ok(Some(value as usize)) - } else { - Err(From::from(format!("number too large for {}", arg_name))) - } + let Some(value) = value else { return Ok(None) }; + usize::try_from(value) + .map_err(|_| anyhow::anyhow!("number too large for {arg_name}")) + .map(Some) } /// Sorts by an optional parameter. @@ -1818,7 +1816,7 @@ fn sort_by_option( /// corresponds to a `--help` or `--version` request. In which case, the /// corresponding output is printed and the current process is exited /// successfully. -fn clap_matches(args: I) -> Result> +fn clap_matches(args: I) -> anyhow::Result> where I: IntoIterator, T: Into + Clone, @@ -1845,7 +1843,7 @@ where /// a directory that no longer exists. We attempt some fallback mechanisms, /// such as querying the PWD environment variable, but otherwise return an /// error. -fn current_dir() -> Result { +fn current_dir() -> anyhow::Result { let err = match env::current_dir() { Err(err) => err, Ok(cwd) => return Ok(cwd), @@ -1855,12 +1853,10 @@ fn current_dir() -> Result { return Ok(PathBuf::from(cwd)); } } - Err(format!( - "failed to get current working directory: {} \ + anyhow::bail!( + "failed to get current working directory: {err} \ --- did your CWD get deleted?", - err, ) - .into()) } /// Retrieves the hostname that ripgrep should use wherever a hostname is diff --git a/crates/core/config.rs b/crates/core/config.rs index a0b3e9b3..fadcbd37 100644 --- a/crates/core/config.rs +++ b/crates/core/config.rs @@ -53,11 +53,11 @@ pub fn args() -> Vec { /// for each line in addition to successfully parsed arguments. fn parse>( path: P, -) -> crate::Result<(Vec, Vec>)> { +) -> anyhow::Result<(Vec, Vec)> { let path = path.as_ref(); match std::fs::File::open(&path) { Ok(file) => parse_reader(file), - Err(err) => Err(From::from(format!("{}: {}", path.display(), err))), + Err(err) => anyhow::bail!("{}: {}", path.display(), err), } } @@ -74,7 +74,7 @@ fn parse>( /// in addition to successfully parsed arguments. fn parse_reader( rdr: R, -) -> crate::Result<(Vec, Vec>)> { +) -> anyhow::Result<(Vec, Vec)> { let mut bufrdr = std::io::BufReader::new(rdr); let (mut args, mut errs) = (vec![], vec![]); let mut line_number = 0; @@ -90,7 +90,7 @@ fn parse_reader( args.push(osstr.to_os_string()); } Err(err) => { - errs.push(format!("{}: {}", line_number, err).into()); + errs.push(anyhow::anyhow!("{line_number}: {err}")); } } Ok(true) diff --git a/crates/core/main.rs b/crates/core/main.rs index 8cb49435..7cc59dd9 100644 --- a/crates/core/main.rs +++ b/crates/core/main.rs @@ -40,16 +40,14 @@ mod subject; #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; -type Result = std::result::Result>; - fn main() { if let Err(err) = Args::parse().and_then(try_main) { - eprintln_locked!("{}", err); + eprintln_locked!("{:#}", err); std::process::exit(2); } } -fn try_main(args: Args) -> Result<()> { +fn try_main(args: Args) -> anyhow::Result<()> { use args::Command::*; let matched = match args.command() { @@ -73,7 +71,7 @@ fn try_main(args: Args) -> Result<()> { /// The top-level entry point for single-threaded search. This recursively /// steps through the file list (current directory by default) and searches /// each file sequentially. -fn search(args: &Args) -> Result { +fn search(args: &Args) -> anyhow::Result { /// The meat of the routine is here. This lets us call the same iteration /// code over each file regardless of whether we stream over the files /// as they're produced by the underlying directory traversal or whether @@ -82,7 +80,7 @@ fn search(args: &Args) -> Result { args: &Args, subjects: impl Iterator, started_at: std::time::Instant, - ) -> Result { + ) -> anyhow::Result { let quit_after_match = args.quit_after_match()?; let mut stats = args.stats()?; let mut searcher = args.search_worker(args.stdout())?; @@ -138,9 +136,8 @@ fn search(args: &Args) -> Result { /// /// Requesting a sorted output from ripgrep (such as with `--sort path`) will /// automatically disable parallelism and hence sorting is not handled here. -fn search_parallel(args: &Args) -> Result { - use std::sync::atomic::AtomicBool; - use std::sync::atomic::Ordering::SeqCst; +fn search_parallel(args: &Args) -> anyhow::Result { + use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; let quit_after_match = args.quit_after_match()?; let started_at = Instant::now(); @@ -227,7 +224,7 @@ fn eprint_nothing_searched() { /// The top-level entry point for listing files without searching them. This /// recursively steps through the file list (current directory by default) and /// prints each path sequentially using a single thread. -fn files(args: &Args) -> Result { +fn files(args: &Args) -> anyhow::Result { /// The meat of the routine is here. This lets us call the same iteration /// code over each file regardless of whether we stream over the files /// as they're produced by the underlying directory traversal or whether @@ -235,7 +232,7 @@ fn files(args: &Args) -> Result { fn iter( args: &Args, subjects: impl Iterator, - ) -> Result { + ) -> anyhow::Result { let quit_after_match = args.quit_after_match()?; let mut matched = false; let mut path_printer = args.path_printer(args.stdout())?; @@ -276,7 +273,7 @@ fn files(args: &Args) -> Result { /// /// Requesting a sorted output from ripgrep (such as with `--sort path`) will /// automatically disable parallelism and hence sorting is not handled here. -fn files_parallel(args: &Args) -> Result { +fn files_parallel(args: &Args) -> anyhow::Result { use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::SeqCst; use std::sync::mpsc; @@ -328,7 +325,7 @@ fn files_parallel(args: &Args) -> Result { } /// The top-level entry point for --type-list. -fn types(args: &Args) -> Result { +fn types(args: &Args) -> anyhow::Result { let mut count = 0; let mut stdout = args.stdout(); for def in args.type_defs()? { @@ -350,9 +347,9 @@ fn types(args: &Args) -> Result { } /// The top-level entry point for --pcre2-version. -fn pcre2_version(args: &Args) -> Result { +fn pcre2_version(args: &Args) -> anyhow::Result { #[cfg(feature = "pcre2")] - fn imp(args: &Args) -> Result { + fn imp(args: &Args) -> anyhow::Result { use grep::pcre2; let mut stdout = args.stdout(); @@ -367,7 +364,7 @@ fn pcre2_version(args: &Args) -> Result { } #[cfg(not(feature = "pcre2"))] - fn imp(args: &Args) -> Result { + fn imp(args: &Args) -> anyhow::Result { let mut stdout = args.stdout(); writeln!(stdout, "PCRE2 is not available in this build of ripgrep.")?; Ok(false) diff --git a/crates/core/search.rs b/crates/core/search.rs index 23d9ed2f..a6ceaeaa 100644 --- a/crates/core/search.rs +++ b/crates/core/search.rs @@ -119,7 +119,7 @@ impl SearchWorkerBuilder { pub fn preprocessor( &mut self, cmd: Option, - ) -> crate::Result<&mut SearchWorkerBuilder> { + ) -> anyhow::Result<&mut SearchWorkerBuilder> { if let Some(ref prog) = cmd { let bin = cli::resolve_binary(prog)?; self.config.preprocessor = Some(bin);