mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-08-24 08:33:48 -07:00
printer: fix handling of has_match
for summary printer
Previously, `Quiet` mode in the summary printer always acted like "print matching paths," except without the printing. This happened even if we wanted to "print non-matching paths." Since this only afflicted quiet mode, this had the effect of flipping the exit status when `--files-without-match --quiet` was used. Fixes #3108, Ref #3118
This commit is contained in:
@@ -25,6 +25,8 @@ Bug fixes:
|
|||||||
Fix a bug where the "bytes searched" in `--stats` output could be incorrect.
|
Fix a bug where the "bytes searched" in `--stats` output could be incorrect.
|
||||||
* [BUG #2990](https://github.com/BurntSushi/ripgrep/issues/2990):
|
* [BUG #2990](https://github.com/BurntSushi/ripgrep/issues/2990):
|
||||||
Fix a bug where ripgrep would mishandle globs that ended with a `.`.
|
Fix a bug where ripgrep would mishandle globs that ended with a `.`.
|
||||||
|
* [BUG #3108](https://github.com/BurntSushi/ripgrep/issues/3108):
|
||||||
|
Fix a bug where `-q --files-without-match` inverted the exit code.
|
||||||
|
|
||||||
Feature enhancements:
|
Feature enhancements:
|
||||||
|
|
||||||
|
@@ -562,7 +562,16 @@ impl HiArgs {
|
|||||||
wtr: W,
|
wtr: W,
|
||||||
) -> Printer<W> {
|
) -> Printer<W> {
|
||||||
let summary_kind = if self.quiet {
|
let summary_kind = if self.quiet {
|
||||||
SummaryKind::Quiet
|
match search_mode {
|
||||||
|
SearchMode::FilesWithMatches
|
||||||
|
| SearchMode::Count
|
||||||
|
| SearchMode::CountMatches
|
||||||
|
| SearchMode::JSON
|
||||||
|
| SearchMode::Standard => SummaryKind::QuietWithMatch,
|
||||||
|
SearchMode::FilesWithoutMatch => {
|
||||||
|
SummaryKind::QuietWithoutMatch
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
match search_mode {
|
match search_mode {
|
||||||
SearchMode::FilesWithMatches => SummaryKind::PathWithMatch,
|
SearchMode::FilesWithMatches => SummaryKind::PathWithMatch,
|
||||||
|
@@ -87,7 +87,13 @@ pub enum SummaryKind {
|
|||||||
///
|
///
|
||||||
/// Note that if `stats` is enabled, then searching continues in order to
|
/// Note that if `stats` is enabled, then searching continues in order to
|
||||||
/// compute statistics.
|
/// compute statistics.
|
||||||
Quiet,
|
QuietWithMatch,
|
||||||
|
/// Don't show any output and the stop the search once a non-matching file
|
||||||
|
/// is found.
|
||||||
|
///
|
||||||
|
/// Note that if `stats` is enabled, then searching continues in order to
|
||||||
|
/// compute statistics.
|
||||||
|
QuietWithoutMatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SummaryKind {
|
impl SummaryKind {
|
||||||
@@ -101,7 +107,7 @@ impl SummaryKind {
|
|||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
PathWithMatch | PathWithoutMatch => true,
|
PathWithMatch | PathWithoutMatch => true,
|
||||||
Count | CountMatches | Quiet => false,
|
Count | CountMatches | QuietWithMatch | QuietWithoutMatch => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +118,8 @@ impl SummaryKind {
|
|||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
CountMatches => true,
|
CountMatches => true,
|
||||||
Count | PathWithMatch | PathWithoutMatch | Quiet => false,
|
Count | PathWithMatch | PathWithoutMatch | QuietWithMatch
|
||||||
|
| QuietWithoutMatch => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +129,10 @@ impl SummaryKind {
|
|||||||
use self::SummaryKind::*;
|
use self::SummaryKind::*;
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
PathWithMatch | Quiet => true,
|
PathWithMatch | QuietWithMatch => true,
|
||||||
Count | CountMatches | PathWithoutMatch => false,
|
Count | CountMatches | PathWithoutMatch | QuietWithoutMatch => {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,9 +255,9 @@ impl SummaryBuilder {
|
|||||||
///
|
///
|
||||||
/// When this is enabled, this printer may need to do extra work in order
|
/// When this is enabled, this printer may need to do extra work in order
|
||||||
/// to compute certain statistics, which could cause the search to take
|
/// to compute certain statistics, which could cause the search to take
|
||||||
/// longer. For example, in `Quiet` mode, a search can quit after finding
|
/// longer. For example, in `QuietWithMatch` mode, a search can quit after
|
||||||
/// the first match, but if `stats` is enabled, then the search will
|
/// finding the first match, but if `stats` is enabled, then the search
|
||||||
/// continue after the first match in order to compute statistics.
|
/// will continue after the first match in order to compute statistics.
|
||||||
///
|
///
|
||||||
/// For a complete description of available statistics, see [`Stats`].
|
/// For a complete description of available statistics, see [`Stats`].
|
||||||
///
|
///
|
||||||
@@ -505,7 +514,9 @@ impl<'p, 's, M: Matcher, W: WriteColor> SummarySink<'p, 's, M, W> {
|
|||||||
/// search.
|
/// search.
|
||||||
pub fn has_match(&self) -> bool {
|
pub fn has_match(&self) -> bool {
|
||||||
match self.summary.config.kind {
|
match self.summary.config.kind {
|
||||||
SummaryKind::PathWithoutMatch => self.match_count == 0,
|
SummaryKind::PathWithoutMatch | SummaryKind::QuietWithoutMatch => {
|
||||||
|
self.match_count == 0
|
||||||
|
}
|
||||||
_ => self.match_count > 0,
|
_ => self.match_count > 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -749,14 +760,14 @@ impl<'p, 's, M: Matcher, W: WriteColor> Sink for SummarySink<'p, 's, M, W> {
|
|||||||
// don't quit and therefore search the entire contents of the file.
|
// don't quit and therefore search the entire contents of the file.
|
||||||
//
|
//
|
||||||
// There is an unfortunate inconsistency here. Namely, when using
|
// There is an unfortunate inconsistency here. Namely, when using
|
||||||
// Quiet or PathWithMatch, then the printer can quit after the first
|
// QuietWithMatch or PathWithMatch, then the printer can quit after the
|
||||||
// match seen, which could be long before seeing binary data. This
|
// first match seen, which could be long before seeing binary data.
|
||||||
// means that using PathWithMatch can print a path where as using
|
// This means that using PathWithMatch can print a path where as using
|
||||||
// Count might not print it at all because of binary data.
|
// Count might not print it at all because of binary data.
|
||||||
//
|
//
|
||||||
// It's not possible to fix this without also potentially significantly
|
// It's not possible to fix this without also potentially significantly
|
||||||
// impacting the performance of Quiet or PathWithMatch, so we accept
|
// impacting the performance of QuietWithMatch or PathWithMatch, so we
|
||||||
// the bug.
|
// accept the bug.
|
||||||
if self.binary_byte_offset.is_some()
|
if self.binary_byte_offset.is_some()
|
||||||
&& searcher.binary_detection().quit_byte().is_some()
|
&& searcher.binary_detection().quit_byte().is_some()
|
||||||
{
|
{
|
||||||
@@ -798,7 +809,7 @@ impl<'p, 's, M: Matcher, W: WriteColor> Sink for SummarySink<'p, 's, M, W> {
|
|||||||
self.write_path_line(searcher)?;
|
self.write_path_line(searcher)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SummaryKind::Quiet => {}
|
SummaryKind::QuietWithMatch | SummaryKind::QuietWithoutMatch => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1133,7 @@ and exhibited clearly, with a label attached.
|
|||||||
fn quiet() {
|
fn quiet() {
|
||||||
let matcher = RegexMatcher::new(r"Watson|Sherlock").unwrap();
|
let matcher = RegexMatcher::new(r"Watson|Sherlock").unwrap();
|
||||||
let mut printer = SummaryBuilder::new()
|
let mut printer = SummaryBuilder::new()
|
||||||
.kind(SummaryKind::Quiet)
|
.kind(SummaryKind::QuietWithMatch)
|
||||||
.build_no_color(vec![]);
|
.build_no_color(vec![]);
|
||||||
let match_count = {
|
let match_count = {
|
||||||
let mut sink = printer.sink_with_path(&matcher, "sherlock");
|
let mut sink = printer.sink_with_path(&matcher, "sherlock");
|
||||||
@@ -1144,7 +1155,7 @@ and exhibited clearly, with a label attached.
|
|||||||
fn quiet_with_stats() {
|
fn quiet_with_stats() {
|
||||||
let matcher = RegexMatcher::new(r"Watson|Sherlock").unwrap();
|
let matcher = RegexMatcher::new(r"Watson|Sherlock").unwrap();
|
||||||
let mut printer = SummaryBuilder::new()
|
let mut printer = SummaryBuilder::new()
|
||||||
.kind(SummaryKind::Quiet)
|
.kind(SummaryKind::QuietWithMatch)
|
||||||
.stats(true)
|
.stats(true)
|
||||||
.build_no_color(vec![]);
|
.build_no_color(vec![]);
|
||||||
let match_count = {
|
let match_count = {
|
||||||
|
@@ -1476,3 +1476,44 @@ rgtest!(r2990_trip_over_trailing_dot, |dir: Dir, _cmd: TestCommand| {
|
|||||||
let got = dir.command().args(&["--files", "-g", "!asdf./"]).stdout();
|
let got = dir.command().args(&["--files", "-g", "!asdf./"]).stdout();
|
||||||
eqnice!("asdf/foo\n", got);
|
eqnice!("asdf/foo\n", got);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/BurntSushi/ripgrep/issues/3108
|
||||||
|
rgtest!(r3108_files_without_match_quiet_exit, |dir: Dir, _: TestCommand| {
|
||||||
|
dir.create("yes-match", "abc");
|
||||||
|
dir.create("non-match", "xyz");
|
||||||
|
|
||||||
|
dir.command().args(&["-q", "abc", "non-match"]).assert_exit_code(1);
|
||||||
|
dir.command().args(&["-q", "abc", "yes-match"]).assert_exit_code(0);
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-with-matches", "-q", "abc", "non-match"])
|
||||||
|
.assert_exit_code(1);
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-with-matches", "-q", "abc", "yes-match"])
|
||||||
|
.assert_exit_code(0);
|
||||||
|
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-without-match", "abc", "non-match"])
|
||||||
|
.assert_exit_code(0);
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-without-match", "abc", "yes-match"])
|
||||||
|
.assert_exit_code(1);
|
||||||
|
|
||||||
|
let got = dir
|
||||||
|
.command()
|
||||||
|
.args(&["--files-without-match", "abc", "non-match"])
|
||||||
|
.stdout();
|
||||||
|
eqnice!("non-match\n", got);
|
||||||
|
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-without-match", "-q", "abc", "non-match"])
|
||||||
|
.assert_exit_code(0);
|
||||||
|
dir.command()
|
||||||
|
.args(&["--files-without-match", "-q", "abc", "yes-match"])
|
||||||
|
.assert_exit_code(1);
|
||||||
|
|
||||||
|
let got = dir
|
||||||
|
.command()
|
||||||
|
.args(&["--files-without-match", "-q", "abc", "non-match"])
|
||||||
|
.stdout();
|
||||||
|
eqnice!("", got);
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user