summaryrefslogtreecommitdiffstats
path: root/tests
AgeCommit message (Collapse)Author
2024-01-06cli: prefix all non-fatal error messages with 'rg: 'Andrew Gallant
Fixes #2694
2024-01-06ci: add more ARM build configurations to CI and release workflowsYounes El-karama
... it turns out that rustembedded/cross:armv7-unknown-linux-musleabi doesn't exist. And looking more closely, it looks like the Cross project has decided to shake things up and publish images to ghcr instead. So we migrate everything over to that.
2023-11-28core: actually implement --sortr=pathAndrew Gallant
This is an embarrassing oversight. A `todo!()` actually made its way into a release! Oof. This was working in ripgrep 13, but I had redone some aspects of sorting and this just got left undone. Fixes #2664
2023-11-27searcher: work around NUL line terminator bugAndrew Gallant
As the FIXME comment says, ripgrep is not yet using the new line terminator option in regex-automata exposed for exactly this purpose. Because of that, line anchors like `(?m:^)` and `(?m:$)` will only match `\n` as a line terminator. This means that when --null-data is used in combination with --line-regexp, the anchors inserted by --line-regexp will not match correctly. This is only a big deal in the "fast" path, which requires the regex engine to deal with line terminators itself correctly. The slow path strips line terminators regardless of what they are, and so the line anchors can match (begin/end of haystack). Fixes #2658
2023-11-25cli: error when searching for NULAndrew Gallant
Basically, unless the -a/--text flag is given, it is generally always an error to search for an explicit NUL byte because the binary detection will prevent it from matching. Fixes #1838
2023-11-25log: add message when a binary file is skippedAndrew Gallant
The way we do this is a little hokey but I believe it is correct. Fixes #2246
2023-11-25printer: trim before applying max column windowingAndrew Gallant
Previously, we were applying the -M/--max-columns flag *before* triming prefix ASCII whitespace. But this doesn't make a whole lot of sense. We should be trimming first, but the result of trimming is ultimately what we'll be printing and that's what -M/--max-columns should be applied to. Fixes #2458
2023-11-20cli: replace clap with lexopt and supporting codeAndrew Gallant
ripgrep began it's life with docopt for argument parsing. Then it moved to Clap and stayed there for a number of years. Clap has served ripgrep well, and it probably could continue to serve ripgrep well, but I ended up deciding to move off of it. Why? The first time I had the thought of moving off of Clap was during the 2->3->4 transition. I thought the 3.x and 4.x releases were great, but for me, it ended up moving a little too quickly. Since the release of 4.x was telegraphed around when 3.x came out, I decided to just hold off and wait to migrate to 4.x instead of doing a 3.x migration followed shortly by another 4.x migration. Of course, I just never ended up doing the migration at all. I never got around to it and there just wasn't a compelling reason for me to upgrade. While I never investigated it, I saw an upgrade as a non-trivial amount of work in part because I didn't encapsulate the usage of Clap enough. The above is just what got me started thinking about it. It wasn't enough to get me to move off of it on its own. What ended up pushing me over the edge was a combination of factors: * As mentioned above, I didn't want to run on the migration treadmill. This has proven to not be much of an issue, but at the time of the 2->3->4 releases, I didn't know how long Clap 4.x would be out before a 5.x would come out. * The release of lexopt[1] caught my eye. IMO, that crate demonstrates exactly how something new can arrive on the scene and just thoroughly solve a problem minimalistically. It has the docs, the reasoning, the simple API, the tests and good judgment. It gets all the weird corner cases right that Clap also gets right (and is part of why I was originally attracted to Clap). * I have an overall desire to reduce the size of my dependency tree. In part because a smaller dependency tree tends to correlate with better compile times, but also in part because it reduces my reliance and trust on others. It lets me be the "master" of ripgrep's destiny by reducing the amount of behavior that is the result of someone else's decision (whether good or bad). * I perceived that Clap solves a more general problem than what I actually need solved. Despite the vast number of flags that ripgrep has, its requirements are actually pretty simple. We just need simple switches and flags that support one value. No multi-value flags. No sub-commands. And probably a lot of other functionality that Clap has that makes it so flexible for so many different use cases. (I'm being hand wavy on the last point.) With all that said, perhaps most importantly, the future of ripgrep possibly demands a more flexible CLI argument parser. In today's world, I would really like, for example, flags like `--type` and `--type-not` to be able to accumulate their repeated values into a single sequence while respecting the order they appear on the CLI. For example, prior to this migration, `rg regex-automata -Tlock -ttoml` would not return results in `Cargo.lock` in this repository because the `-Tlock` always took priority even though `-ttoml` appeared after it. But with this migration, `-ttoml` now correctly overrides `-Tlock`. We would like to do similar things for `-g/--glob` and `--iglob` and potentially even now introduce a `-G/--glob-not` flag instead of requiring users to use `!` to negate a glob. (Which I had done originally to work-around this problem.) And some day, I'd like to add some kind of boolean matching to ripgrep perhaps similar to how `git grep` does it. (Although I haven't thought too carefully on a design yet.) In order to do that, I perceive it would be difficult to implement correctly in Clap. I believe that this last point is possible to implement correctly in Clap 2.x, although it is awkward to do so. I have not looked closely enough at the Clap 4.x API to know whether it's still possible there. In any case, these were enough reasons to move off of Clap and own more of the argument parsing process myself. This did require a few things: * I had to write my own logic for how arguments are combined into one single state object. Of course, I wanted this. This was part of the upside. But it's still code I didn't have to write for Clap. * I had to write my own shell completion generator. * I had to write my own `-h/--help` output generator. * I also had to write my own man page generator. Well, I had to do this with Clap 2.x too, although my understanding is that Clap 4.x supports this. With that said, without having tried it, my guess is that I probably wouldn't have liked the output it generated because I ultimately had to write most of the roff by hand myself to get the man page I wanted. (This also had the benefit of dropping the build dependency on asciidoc/asciidoctor.) While this is definitely a fair bit of extra work, it overall only cost me a couple days. IMO, that's a good trade off given that this code is unlikely to change again in any substantial way. And it should also allow for more flexible semantics going forward. Fixes #884, Fixes #1648, Fixes #1701, Fixes #1814, Fixes #1966 [1]: https://docs.rs/lexopt/0.3.0/lexopt/index.html
2023-10-09progressAndrew Gallant
2023-09-25printer: add hyperlinksLucas Trzesniewski
This commit represents the initial work to get hyperlinks working and was submitted as part of PR #2483. Subsequent commits largely retain the functionality and structure of the hyperlink support added here, but rejigger some things around.
2023-09-20ignore: fix filtering when searching subdirectoriesThilo Uttendorfer
When searching subdirectories the path was not correctly built and included duplicate parts. This fix will remove the duplicate part if possible. Fixes #1757, Closes #2295
2023-08-28ci: replace mips with powerpc64, aarch64 and s390xAndrew Gallant
We drop our MIPS target because it no longer works.[1] We were previously using it as a means of testing ripgrep in a big endian environment. So to achieve that without MIPS, we test on powerpc64 and s390x. (No particular reason to do both, but why not.) We also add aarch64 as a proxy for at least ensuring everything works for the same architecture as Apple silicon. It's not a guarantee that everything works, but it seems better than nothing until we can actually test Apple silicon in CI. [1]: https://github.com/rust-lang/regex/commit/c788378d6fe407f4774df98a78436cea5d98525b
2023-07-31regex: fix fast path for -w/--word-regexp flag (#2576)Andrew Gallant
It turns out our fast path for -w/--word-regexp wasn't quite correct in some cases. Namely, we use `(?m:^|\W)(<original-regex>)(?m:\W|$)` as the implementation of -w/--word-regexp since `\b(<original-regex>)\b` has some unintuitive results in certain cases, specifically when <original-regex> matches non-word characters at match boundaries. The problem is that using this formulation means that you need to extract the capture group around <original-regex> to find the "real" match, since the surrounding (^|\W) and (\W|$) aren't part of the match. This is fine, but the capture group engine is usually slow, so we have a fast path where we try to deduce the correct match boundary after an initial match (before running capture groups). The problem is that doing this is rather tricky because it's hard to know, in general, whether the `^` or the `\W` matched. This still doesn't seem quite right overall, but we at least fix one more case. Fixes #2574
2023-07-09cli: fix non-path sorting behaviornguyenvukhang
Previously, sorting worked by sorting the parents and then sorting the children within each parent. This was done during traversal, but it only works when sorting parents preserves the overall order. This generally only works for '--sort path' in ascending order. This commit fixes the rest of the sorting behavior by collecting all of the paths to search and then sorting them before searching. We only collect all of the paths when sorting was requested. Fixes #2243, Closes #2361
2023-07-08cli: add --stop-on-nonmatch flagEdoardo Pirovano
This causes ripgrep to stop searching an individual file after it has found a non-matching line. But this only occurs after it has found a matching line. Fixes #1790, Closes #1930
2023-07-08cli: '--no-ignore-dot' should also '.rgignore'Richard Sternagel
Fixes #2198, Closes #2202
2023-07-08core: don't let context flags override eachotherAndrew Gallant
This matches the behavior of GNU grep which does not ignore before-context and after-context completely if the context flag is also provided. Note that this change wasn't done just to match GNU grep. In this case, GNU grep has the more sensible behavior. Fixes #2288, Closes #2451
2023-07-08test: test that regex inline flags work as intendedGal Ofri
This was originally fixed by using non-capturing groups when joining patterns in crates/core/args.rs, but before that landed, it ended up getting fixed via a refactor in the course of migrating to regex 1.9. Namely, it's now fixed by pushing pattern joining down into the regex layer, so that patterns can be joined in the most effective way possible. Still, #2488 contains a useful test, so we bring that in here. The test actually failed for `rg -e ')('`, since it expected the command to fail with a syntax error. But my refactor actually causes this command to succeed. And indeed, #2488 worked around this by special casing a single pattern. That work-around fixes it for the single pattern case, but doesn't fix it for the -w or -X or multi-pattern case. So for now, we're content to leave well enough alone. The only real way to fix this for real is to parse each regexp individual and verify that each is valid on its own. It's not clear that doing so is worth it. Fixes #2480, Closes #2488
2022-06-14ignore: fix gitignore parsing bug for trailing \/Andrew Gallant
When a glob pattern ended with a \/, and since we permit backslash escapes, the glob parser gave a "dangling escape" error. Which is weird, because the \ is clearly not dangling. The issue is that the layer above the glob parser, the gitignore parser, was stripping the trailing / so that it wouldn't be part of the matching logic. Of course, stripping the trailing / while it is escaped without removing the backslash escape is wrong. So we do that here. Fixes #2236
2022-05-11printer: fix duplicative replacement in multiline modeAndrew Gallant
This furthers our kludge of dealing with PCRE2's look-around in the printer. Because of our bad abstraction boundaries, we added a kludge to deal with PCRE2 look-around by extending the bytes we search by a fixed amount to hopefully permit any look-around to operate. But because of that kludge, we wind up over extending ourselves in some cases and dragging along those extra bytes. We had fixed this for simple searching by simply rejecting any matches past the end point. But we didn't do the same for replacements. So this commit extends our kludge to replacements. Thanks to @sonohgong for diagnosing the problem and proposing a fix. I mostly went with their solution, but adding the new replacement routine as an internal helper rather than a new APIn in the 'grep-matcher' crate. Fixes #2095, Fixes #2208
2021-06-12regex: update regression testAndrew Gallant
Sadly, PCRE2 has different behavior (but doesn't panic). We should look into that, but for now, this is good enough. Also, update the CHANGELOG. Ref #1891
2021-06-12regex: fix -w when regex can match empty stringAndrew Gallant
This is a weird bug where our optimization for handling -w more quickly than we would otherwise failed. In particular, if the original regex can match the empty string, then our word boundary detection would produce invalid indices to the start the next search at. We "fix" it by simply bailing when the indices are known to be incorrect. This wasn't a problem in a previous release since ripgrep 13 tweaked how word boundaries are detected in commit efd9cfb2. Fixes #1891
2021-05-31printer: trim line terminator before doing replacementsAndrew Gallant
This is basically the same bug as #1401, but applied to replacements instead of --only-matching. Fixes #1739
2021-05-31printer: trim line terminator before finding submatchesAndrew Gallant
This fixes a bug where PCRE2 look-around could change the result of a match if it observed a line terminator in the printer. And in particular, this is precisely how the searcher operates: the line is considered unto itself *without* the line terminator. Fixes #1401
2021-05-31grep: fix bugs in handling multi-line look-aroundAndrew Gallant
This commit hacks in a bug fix for handling look-around across multiple lines. The main problem is that by the time the matching lines are sent to the printer, the surrounding context---which some look-behind or look-ahead might have matched---could have been dropped if it wasn't part of the set of matching lines. Therefore, when the printer re-runs the regex engine in some cases (to do replacements, color matches, etc etc), it won't be guaranteed to see the same matches that the searcher found. Overall, this is a giant clusterfuck and suggests that the way I divided the abstraction boundary between the printer and the searcher is just wrong. It's likely that the searcher needs to handle more of the work of matching and pass that info on to the printer. The tricky part is that this additional work isn't always needed. Ultimately, this means a serious re-design of the interface between searching and printing. Sigh. The way this fix works is to smuggle the underlying buffer used by the searcher through into the printer. Since these bugs only impact multi-line search (otherwise, searches are only limited to matches across a single line), and since multi-line search always requires having the entire file contents in a single contiguous slice (memory mapped or on the heap), it follows that the buffer we pass through when we need it is, in fact, the entire haystack. So this commit refactors the printer's regex searching to use that buffer instead of the intended bundle of bytes containing just the relevant matching portions of that same buffer. There is one last little hiccup: PCRE2 doesn't seem to have a way to specify an ending position for a search. So when we re-run the search to find matches, we can't say, "but don't search past here." Since the buffer is likely to contain the entire file, we really cannot do anything here other than specify a fixed upper bound on the number of bytes to search. So if look-ahead goes more than N bytes beyond the match, this code will break by simply being unable to find the match. In practice, this is probably pretty rare. I believe that if we did a better fix for this bug by fixing the interfaces, then we'd probably try to have PCRE2 find the pertinent matches up front so that it never needs to re-discover them. Fixes #1412
2021-05-31printer: fix multi-line replacement bugAndrew Gallant
This commit fixes a subtle bug in multi-line replacement of line terminators. The problem is that even though ripgrep supports multi-line searches, it is *still* line oriented. It still needs to print line numbers, for example. For this reason, there are various parts in the printer that iterate over lines in order to format them into the desired output. This turns out to be problematic in some cases. #1311 documents one of those cases (with line numbers enabled to highlight a point later): $ printf "hello\nworld\n" | rg -n -U "\n" -r "?" 1:hello? 2:world? But the desired output is this: $ printf "hello\nworld\n" | rg -n -U "\n" -r "?" 1:hello?world? At first I had thought that the main problem was that the printer was taking ownership of writing line terminators, even if the input already had them. But it's more subtle than that. If we fix that issue, we get output like this instead: $ printf "hello\nworld\n" | rg -n -U "\n" -r "?" 1:hello?2:world? Notice how '2:' is printed before 'world?'. The reason it works this way is because matches are reported to the printer in a line oriented way. That is, the printer gets a block of lines. The searcher guarantees that all matches that start or end in any of those lines also end or start in another line in that same block. As a result, the printer uses this assumption: once it has processed a block of lines, the next match will begin on a new and distinct line. Thus, things like '2:' are printed. This is generally all fine and good, but an impedance mismatch arises when replacements are used. Because now, the replacement can be used to change the "block of lines" approach. Now, in terms of the output, the subsequent match might actually continue the current line since the replacement might get rid of the concept of lines altogether. We can sometimes work around this. For example: $ printf "hello\nworld\n" | rg -U "\n(.)?" -r '?$1' hello?world? Why does this work? It's because the '(.)' after the '\n' causes the match to overlap between lines. Thus, the searcher guarantees that the block sent to the printer contains every line. And there in lay the solution: all we need to do is tweak the multi-line searcher so that it combines lines with matches that directly adjacent, instead of requiring at least one byte of overlap. Fixing that solves the issue above. It does cause some tests to fail: * The binary3 test in the searcher crate fails because adjacent line matches are now one part of block, and that block is scanned for binary data. To preserve the essence of the test, we insert a couple dummy lines to split up the blocks. * The JSON CRLF test. It was testing that we didn't output any messages with an empty 'submatches' array. That is indeed still the case. The difference is that the messages got combined because of the adjacent line merging behavior. This is a slight change to the output, but is still correct. Fixes #1311
2021-05-31printer: vimgrep now only prints one lineAndrew Gallant
It turns out that the vimgrep format really only wants one line per match, even when that match spans multiple lines. We continue to support the previous behavior (print all lines in a match) in the `grep-printer` crate. We add a new option to enable the "only print the first line" behavior, and unconditionally enable it in ripgrep. We can do that because the option has no effect in single-line mode, since, well, in that case matches are guaranteed to span one line anyway. Fixes #1866
2021-05-31cli: add --field-{context,match}-separator flagsAnthony Huang
These flags permit configuring the bytes used to delimit fields in match or context lines, where "fields" are things like the file path, line number, column number and the match/context itself. Fixes #1842, Closes #1871
2021-05-31printer: fix context bug when --max-count is usedPen Tree
In the case where after-context is requested with a match count limit, we need to be careful not to reset the state tracking the remaining context lines. Fixes #1380, Closes #1642
2021-05-31searcher: do UTF-8 BOM sniffing like UTF-16Alessandro Menezes
Previously, we were only looking for the UTF-16 BOM for determining whether to do transcoding or not. But we should also look for the UTF-8 BOM as well. Fixes #1638, Closes #1697
2021-05-31printer: fix \r\n line terminator handlingAndrew Gallant
This fixes a bug where it was assumed that 'is_suffix' when CRLF handling was enabled mean that '\r\n' was present. But that's not the case, and it is intentional that 'is_suffix' only looks for '\n'. (Which is why #1803 wasn't taken, which tries to fix this by changing 'is_suffix'.) Fixes #1765, Closes #1803
2021-05-31cli: print warning if nothing was searchedgoto-engineering
This was once part of ripgrep, but at some point, was unintentionally removed. The value of this warning is that since ripgrep tries to be "smart" by default, it can be surprising if it doesn't search certain things. This warning covers the case when ripgrep searches *nothing*, which happens somewhat more frequently than you might expect. e.g., If you're searching within an ignore directory. Note that for now, we only print this message when the user has not supplied any explicit paths. It's not clear that we want to print this otherwise, and in particular, it seems that the message shows up too eagerly. e.g., 'rg foo does-not-exist' will both print an error about 'does-not-exist' not existing, *and* the message about no files being searched, which seems annoying in this case. We can always refine this logic later. Fixes #1404, Closes #1762
2021-05-31args: make --passthru and -A/-B/-C override each otherAndrew Gallant
Fixes #1868
2021-05-29impl: fix --multiline anchored match bugAndrew Gallant
This fixes a bug where using \A or (?-m)^ in combination with -U/--multiline would permit matches that aren't anchored to the beginning of the file. The underlying cause was an optimization that occurred when mmaps couldn't be used. Namely, ripgrep tries to still read the input incrementally if it knows the pattern can't match through a new line. But the detection logic was flawed, since it didn't account for line anchors. This commit fixes that. Fixes #1878, Fixes #1879
2021-05-15printer: fix --vimgrep for multi-line modeAndrew Gallant
It turned out that --vimgrep wasn't quite getting the column of each match correctly. Instead of printing column numbers relative to the current line, it was printing column numbers as byte offsets relative to where the match began. To fix this, we simply subtract the offset of the line number from the beginning of the match. If the beginning of the match came before the start of the current line, then there's really nothing sensible we can do other than to use a column number of 1, which we now document. Interestingly, existing tests were checking that the previous behavior was intended. My only defense is that I somehow tricked myself into thinking it was a byte offset instead of a column number. Kudos to @bfrg for calling this out in #1866: https://github.com/BurntSushi/ripgrep/issues/1866#issuecomment-841635553
2021-03-23tests: fix tests for buffer size changeAndrew Gallant
Sadly, there were several tests that are coupled to the size of the buffer used by ripgrep. Making the tests agnostic to the size is difficult. And it's annoying to fix the tests. But we rarely change the buffer size, so ¯\_(ツ)_/¯.
2020-11-02printer: tweak binary detection message formatAndrew Gallant
This roughly matches similar changes made in GNU grep recently.
2020-11-02deps: bring in all semver updatesAndrew Gallant
This brings in all other semver updates. This did require updating some tests, since bstr changed its debug output for NUL bytes to be a bit more idiomatic.
2020-05-08grep-cli: support files compressed by compress(1)Wieland Hoffmann
While Linux distributions (at least Arch Linux, RHEL, Debian) do not support compressing files with compress(1), macOS & AIX do (the utility is part of POSIX). Additionally, gzip is able to uncompress such compressed files and provides an `uncompress` binary. Closes #1547
2020-05-08printer: fix --count-matches outputAndrew Gallant
In order to implement --count-matches, we simply re-execute the regex on the spans reported by the searcher. The spans always correspond to the lines that participated in the match. This is the correct thing to do, except when the regex contains look-ahead (or look-behind). In particular, the look-around permits the regex's match success to depends on an arbitrary point before or after the lines actually reported as participating in the match. Since only the matched lines are reported to the printer, it is possible for subsequent searching on those lines to fail. A true fix for this would somehow make the total span available to the printer. But that seems tricky since it isn't always available. For PCRE2's case in multiline mode, it is available because we force it to be so for correctness. For now, we simply detect this corner case heuristically. If the match count is zero, then it necessarily means there is some kind of look-around that isn't matching. So we set the match count to 1. This is probably incorrect in some cases, although my brain can't quite come up with a concrete example. Nevertheless, this is strictly better than the status quo. Fixes #1573
2020-04-23tests: add new regression test for fixed inner literal bugAndrew Gallant
This adds a new test case for a bug (#1537) that has already been fixed. Or more precisely, a new bug with the same root cause. Closes #1559
2020-04-01regex: fix another inner literal bugAndrew Gallant
It looks like `is_simple` wasn't quite correct. I can't wait until this code is rewritten. It is still not quite clearly correct to me. Fixes #1537
2020-03-22tests: fix typo in test namePaul A. Patience
PR #1528
2020-03-15cli: add --no-ignore-files flagAndrew Gallant
The purpose of this flag is to force ripgrep to ignore all --ignore-file flags (whether they come before or after --no-ignore-files). This flag can be overridden with --ignore-files. Fixes #1466
2020-02-20tests: add debugging outputAndrew Gallant
The transient failures appear to be persisting and they are quite difficult to debug. So include a full directory listing in the output of every test failure.
2020-02-20tests: use std::env::consts::EXE_SUFFIXAndrew Gallant
This avoids a conditional compilation knob and is likely more portable.
2020-02-20tests: make 'cross test' workAndrew Gallant
The reason why it wasn't working was the integration tests. Namely, the integration tests attempted to execute the 'rg' binary directly from inside cross's docker container. But this obviously doesn't work when 'rg' was compiled for a totally different architecture. Cross normally does this by hooking into the Rust test infrastructure and causing tests to run with 'qemu'. But our integration tests didn't do that. This commit fixes our test setup to check for cross's environment variable that points to the 'qemu' binary. Once we have that, we just use 'qemu-foo rg' instead of 'rg'. Piece of cake.
2020-02-17style: rustfmt everythingAndrew Gallant
This is why I was so intent on clearing the PR queue. This will effectively invalidate all existing patches, so I wanted to start from a clean slate. We do make one little tweak: we put the default type definitions in their own file and tell rustfmt to keep its grubby mits off of it. We also sort it lexicographically and hopefully will enforce that from here on.
2020-02-17ignore: treat symbolic links to directories as directoriesAndrew Gallant
Due to how walkdir works if symlinks are not followed, symlinks to directories are seen as simple files by ripgrep. This caused a panic in some cases due to receiving a WalkEvent::Exit event without a corresponding WalkEvent::Dir event. This is fixed by looking at the metadata of the file in the case of a symlink to determine if it's a directory. We are careful to only do this stat check when the depth of the entry is 0, as this bug only impacts us when 1) we aren't following symlinks generally and 2) the user provides a symlinked directory that we do follow as a top-level path to search. Fixes #1389, Closes #1397
2020-02-17cli: add --no-unicode, deprecate --no-pcre2-unicodeAndrew Gallant
This adds a universal --no-unicode flag that is intended to work for all supported regex engines. There is no point in retaining --no-pcre2-unicode, so we make them aliases to the new flags and deprecate them.