summaryrefslogtreecommitdiffstats
path: root/tests
AgeCommit message (Collapse)Author
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.
2020-02-17cli: add --no-require-git flagAndrew Gallant
This flag prevents ripgrep from requiring one to search a git repository in order to respect git-related ignore rules (global, .gitignore and local excludes). This actually corresponds to behavior ripgrep had long ago, but #934 changed that. It turns out that users were relying on this buggy behavior. In most cases, fixing it as simple as converting one's rules to .ignore or .rgignore files. Unfortunately, there are other use cases---like Perforce automatically respecting .gitignore files---that make a strong case for ripgrep to at least support this. The UX of a flag like this is absolutely atrocious. It's so obscure that it's really not worth explicitly calling it out anywhere. Moreover, the error cases that occur when this flag isn't used (but its behavior is desirable) will not be intuitive, do not seem easily detectable and will not guide users to this flag. Nevertheless, the motivation for this is just barely strong enough for me to begrudgingly accept this. Fixes #1414, Closes #1416
2020-02-17grep-regex: fix inner literal extraction bugJakub Wieczorek
This appears to be another transcription bug from copying this code from the prefix literal detection from inside the regex crate. Namely, when it comes to inner literals, we only want to treat counted repetition as two separate cases: the case when the minimum match is 0 and the case when the minimum match is more than 0. In the former case, we treat `e{0,n}` as `e*` and in the latter we treat `e{m,n}` where `m >= 1` as just `e`. We could definitely do better here. e.g., This means regexes like `(foo){10}` will only have `foo` extracted as a literal, where searching for the full literal would likely be faster. The actual bug here was that we were not implementing this logic correctly. Namely, we weren't always "cutting" the literals in the second case to prevent them from being expanded. Fixes #1319, Closes #1367
2020-02-17ignore: use git commondir for sourcing .git/info/excludeJohannes Altmanninger
Git looks for this file in GIT_COMMON_DIR, which is usually the same as GIT_DIR (.git). However, when searching inside a linked worktree, .git is usually a file that contains the path of the actual git dir, which in turn contains a file "commondir" which references the directory where info/exclude may reside, alongside other configuration shared across all worktrees. This directory is usually the git dir of the main worktree. Unlike git this does *not* read environment variables GIT_DIR and GIT_COMMON_DIR, because it is not clear how to interpret them when searching multiple repositories. Fixes #1445, Closes #1446
2020-02-17cli: add --no-ignore-exclude flagNaveen Nathan
This commit adds a new --no-ignore-exclude flag that permits disabling the use of .git/info/exclude filtering. Local exclusions are manual configurations to a repository and are not shared, so it is sometimes useful to disable to get a consistent view of a repository. This also adds a new section to the man page that describes automatic filtering. Closes #1420
2020-02-17cli: add --include-zero flagCollin Styles
This flag, when used in conjunction with --count or --count-matches, will print a result for each file searched even if there were zero matches in that file. This is off by default but can be enabled to make ripgrep behave more like grep. This also clarifies some of the defaults for the grep-printer::SummaryBuilder type. Closes #1370, Closes #1405
2020-02-17cli: add --no-context-separator flagMohammad AlSaleh
--context-separator='' still adds a new line separator, which could still potentially be useful. So we add a new `--no-context-separator` flag that completely disables context separators even when the -A/-B/-C context flags are used. Closes #1390
2020-02-17tests: remove existing test directoryAndrew Gallant
I'm surprised this wasn't caught until now, but if a test directory already exists, then it was reused. This can result in hard to debug problems with tests when, e.g., file names are changed and a recursive search is executed.
2019-08-01ripgrep: fix bug when CWD has directory named `-`Ninan John
Specifically, when searching stdin, if the current directory has a directory named `-`, then the `--with-filename` flag would automatically be turned on. This is because `--with-filename` is automatically enabled when ripgrep is given a single path that is a directory. When ripgrep is given empty arguments, and if it is searching stdin, then its default path list is just simple `["-"]`. The `is_dir` check passes, and `--with-filename` gets enabled. This commit fixes the problem by checking whether the path is `-` first. If so, then we assume it isn't a directory. This is fine, since if it is a directory and one asks to search it explicitly, then ripgrep will interpret `-` as stdin anyway (which is arguably a bug on its own, but probably not one worth fixing). Fixes #1223, Closes #1292
2019-08-01ripgrep: add --glob-case-insensitivedana
This flag forces -g/--glob patterns to be treated case-insensitively, as with --iglob patterns. Fixes #1293
2019-08-01regex: fix -F aho-corasick optimizationAndrew Gallant
It turns out that when the -F flag was used, if any of the patterns contained a regex meta character (such as `.`), then we winded up escaping the pattern first before handing it off to Aho-Corasick, which treats all patterns literally. We continue to apply band-aides here and just avoid Aho-Corasick if there is an escape in any of the literal patterns. This is unfortunate, but making this work better requires more refactoring, and the right solution is to get this optimization pushed down into the regex engine. Fixes #1334
2019-04-19cli: fix bug where last byte was strippedAndrew Gallant
In an effort to strip line terminators, we assumed their existence. But a pattern file may not end with a line terminator, so we shouldn't unconditionally strip them. We fix this by moving to bstr's line handling, which does this for us automatically.
2019-04-15ripgrep: max-column-preview --> max-columns-previewAndrew Gallant
Credit to @okdana for catching this. This naming is a bit more consistent with the existing --max-columns flag.
2019-04-14ripgrep: add --auto-hybrid-regex flagAndrew Gallant
This flag, when set, will automatically dispatch to PCRE2 if the given regex cannot be compiled by Rust's regex engine. If both engines fail to compile the regex, then both errors are surfaced. Closes #1155
2019-04-14printer: support previews for long linesAndrew Gallant
This commit adds support for showing a preview of long lines. While the default still remains as completely suppressing the entire line, this new functionality will show the first N graphemes of a matching line, including the number of matches that are suppressed. This was unfortunately a fairly invasive change to the printer that required a bit of refactoring. On the bright side, the single line and multi-line coloring are now more unified than they were before. Closes #1078
2019-04-14binary: rejigger ripgrep's handling of binary filesAndrew Gallant
This commit attempts to surface binary filtering in a slightly more user friendly way. Namely, before, ripgrep would silently stop searching a file if it detected a NUL byte, even if it had previously printed a match. This can lead to the user quite reasonably assuming that there are no more matches, since a partial search is fairly unintuitive. (ripgrep has this behavior by default because it really wants to NOT search binary files at all, just like it doesn't search gitignored or hidden files.) With this commit, if a match has already been printed and ripgrep detects a NUL byte, then it will print a warning message indicating that the search stopped prematurely. Moreover, this commit adds a new flag, --binary, which causes ripgrep to stop filtering binary files, but in a way that still avoids dumping binary data into terminals. That is, the --binary flag makes ripgrep behave more like grep's default behavior. For files explicitly specified in a search, e.g., `rg foo some-file`, then no binary filtering is applied (just like no gitignore and no hidden file filtering is applied). Instead, ripgrep behaves as if you gave the --binary flag for all explicitly given files. This was a fairly invasive change, and potentially increases the UX complexity of ripgrep around binary files. (Before, there were two binary modes, where as now there are three.) However, ripgrep is now a bit louder with warning messages when binary file detection might otherwise be hiding potential matches, so hopefully this is a net improvement. Finally, the `-uuu` convenience now maps to `--no-ignore --hidden --binary`, since this is closer to the actualy intent of the `--unrestricted` flag, i.e., to reduce ripgrep's smart filtering. As a consequence, `rg -uuu foo` should now search roughly the same number of bytes as `grep -r foo`, and `rg -uuua foo` should search roughly the same number of bytes as `grep -ra foo`. (The "roughly" weasel word is used because grep's and ripgrep's binary file detection might differ somewhat---perhaps based on buffer sizes---which can impact exactly what is and isn't searched.) See the numerous tests in tests/binary.rs for intended behavior. Fixes #306, Fixes #855
2019-04-06searcher: add option to disable BOM sniffinglesnyrumcajs
This commit adds a new encoding feature where the -E/--encoding flag will now accept a value of 'none'. When given this value, all encoding related machinery is disabled and ripgrep will search the raw bytes of the file, including the BOM if it's present. Closes #1207, Closes #1208
2019-02-27regex: bump regex dep to fix match bugAndrew Gallant
See * https://github.com/rust-lang/regex/commit/661bf53d5b2b6dde25549aaad601ad8c59b37bfd * https://github.com/rust-lang/regex/commit/edf45e6f5fa54705298ba14f3216cfb5277c0908 for details on the bug fix, which was in the regex engine. Fixes #1203
2019-02-09tests: use const constructor for atomicsAndrew Gallant
We did this in 05411b2b for core ripgrep, but didn't carry it over to tests.
2019-01-26search: fix -F and -f interaction bugAndrew Gallant
This fixes what appears to be a pretty egregious regression where the `-F/--fixed-strings` flag wasn't be applied to patterns supplied via the `-f/--file` flag. The same bug existed for the `-x/--line-regexp` flag as well, which we fix here. Fixes #1176
2019-01-26exit: tweak exit status logicAndrew Gallant
This changes how ripgrep emit exit status codes. In particular, any error that occurs while searching will now cause ripgrep to emit a `2` exit code, where as it previously would emit either a `0` or a `1` code based on whether it matched or not. That is, ripgrep would only emit a `2` exit code for a catastrophic error. This tweak includes additional logic that GNU grep adheres to, which seems like good sense. Namely, if -q/--quiet is given, and an error occurs and a match occurs, then ripgrep will emit a `0` exit code. Closes #1159
2019-01-26args: prevent panicking in 'rg -h | rg'Andrew Gallant
Previously, we relied on clap to handle printing either an error message, or --help/--version output, in addition to setting the exit status code. Unfortunately, for --help/--version output, clap was panicking if the write failed, which can happen in fairly common scenarios via a broken pipe error. e.g., `rg -h | head`. We fix this by using clap's "safe" API and doing the printing ourselves. We also set the exit code to `2` when an invalid command has been given. Fixes #1125 and partially addresses #1159
2019-01-26config: add --no-ignore-dot flagAndrew Gallant
This flag causes ripgrep to ignore `.ignore` files. Closes #1138