diff --git a/CHANGELOG.md b/CHANGELOG.md index c3b72478..630cfa17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,8 @@ Bug fixes: Upgrade `grep` crate to `regex-syntax 0.5.0`. * [BUG #893](https://github.com/BurntSushi/ripgrep/issues/893): Improve support for git submodules. +* [BUG #900](https://github.com/BurntSushi/ripgrep/issues/900): + When no patterns are given, ripgrep should never match anything. * [BUG #907](https://github.com/BurntSushi/ripgrep/issues/907): ripgrep will now stop traversing after the first file when `--quiet --files` is used. diff --git a/src/args.rs b/src/args.rs index 1d7d1a8e..10b9e557 100644 --- a/src/args.rs +++ b/src/args.rs @@ -36,6 +36,7 @@ pub struct Args { after_context: usize, before_context: usize, byte_offset: bool, + can_match: bool, color_choice: termcolor::ColorChoice, colors: ColorSpecs, column: bool, @@ -220,10 +221,9 @@ impl Args { /// Returns true if the given arguments are known to never produce a match. pub fn never_match(&self) -> bool { - self.max_count == Some(0) + !self.can_match || self.max_count == Some(0) } - /// Returns whether ripgrep should track stats for this run pub fn stats(&self) -> bool { self.stats @@ -385,11 +385,13 @@ impl<'a> ArgMatches<'a> { let (before_context, after_context) = self.contexts()?; let (count, count_matches) = self.counts(); let quiet = self.is_present("quiet"); + let (grep, can_match) = self.grep()?; let args = Args { paths: paths, after_context: after_context, before_context: before_context, byte_offset: self.is_present("byte-offset"), + can_match: can_match, color_choice: self.color_choice(), colors: self.color_specs()?, column: self.column(), @@ -403,7 +405,7 @@ impl<'a> ArgMatches<'a> { files: self.is_present("files"), follow: self.is_present("follow"), glob_overrides: self.overrides()?, - grep: self.grep()?, + grep: grep, heading: self.heading(), hidden: self.hidden(), ignore_files: self.ignore_files(), @@ -491,17 +493,6 @@ impl<'a> ArgMatches<'a> { } } - /// Return the pattern that should be used for searching. - /// - /// If multiple -e/--regexp flags are given, then they are all collapsed - /// into one pattern. - /// - /// If any part of the pattern isn't valid UTF-8, then an error is - /// returned. - fn pattern(&self) -> Result { - Ok(self.patterns()?.join("|")) - } - /// Get a sequence of all available patterns from the command line. /// This includes reading the -e/--regexp and -f/--file flags. /// @@ -551,8 +542,6 @@ impl<'a> ArgMatches<'a> { // match first, and we wouldn't get colours in the output if self.is_present("passthru") && !self.is_present("count") { pats.push("^".to_string()) - } else if pats.is_empty() { - pats.push(self.empty_pattern()) } Ok(pats) } @@ -901,7 +890,10 @@ impl<'a> ArgMatches<'a> { /// /// If there was a problem extracting the pattern from the command line /// flags, then an error is returned. - fn grep(&self) -> Result { + /// + /// If no match can ever occur, then `false` is returned. Otherwise, + /// `true` is returned. + fn grep(&self) -> Result<(Grep, bool)> { let smart = self.is_present("smart-case") && !self.is_present("ignore-case") @@ -909,7 +901,9 @@ impl<'a> ArgMatches<'a> { let casei = self.is_present("ignore-case") && !self.is_present("case-sensitive"); - let mut gb = GrepBuilder::new(&self.pattern()?) + let pats = self.patterns()?; + let ok = !pats.is_empty(); + let mut gb = GrepBuilder::new(&pats.join("|")) .case_smart(smart) .case_insensitive(casei) .line_terminator(b'\n'); @@ -920,7 +914,7 @@ impl<'a> ArgMatches<'a> { if let Some(limit) = self.regex_size_limit()? { gb = gb.size_limit(limit); } - Ok(gb.build()?) + Ok((gb.build()?, ok)) } /// Builds the set of glob overrides from the command line flags. diff --git a/tests/tests.rs b/tests/tests.rs index 8a38f545..e6cc1534 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1320,6 +1320,12 @@ clean!(regression_807, "test", ".", |wd: WorkDir, mut cmd: Command| { assert_eq!(lines, format!("{}:test\n", path(".a/c/file"))); }); +// See: https://github.com/BurntSushi/ripgrep/issues/900 +sherlock!(regression_900, "-fpat", "sherlock", |wd: WorkDir, mut cmd: Command| { + wd.create("pat", ""); + wd.assert_err(&mut cmd); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/1 clean!(feature_1_sjis, "Шерлок Холмс", ".", |wd: WorkDir, mut cmd: Command| { let sherlock =