Compare commits

..

67 Commits

Author SHA1 Message Date
Andrew Gallant
c9bb78ceba grep-cli-0.1.5 2020-05-29 09:14:18 -04:00
Andrew Gallant
72bdde6771 ignore-0.4.16 2020-05-29 09:13:02 -04:00
Andrew Gallant
d66712a452 deps: update all dependencies 2020-05-29 09:11:50 -04:00
Andy Salerno
e8822ce97a ignore/doc: update misleading documentation
This likely originated from a bad copy/paste.

PR #1596
2020-05-24 23:12:53 -04:00
Andrew Gallant
a700b75843 doc: clarify capture group indices
And in particular, note the special $0 index, which corresponds to the
entire match.

Fixes #1591
2020-05-21 22:22:51 -04:00
Gerion Entrup
b72ad8f8aa ignore/types: add meson filetype
Closes #1586, PR #1587
2020-05-18 14:01:35 -04:00
Andrew Gallant
1980630f17 doc: fix egregious markup output
We use '+++' syntax to output a literal '**' for a '--glob' example.
This '+++' syntax is pretty ugly when rendered literally via --help. We
fix this by hackily inserting the '+++' syntax for its one specific case
that we need it during man page generation.

Not ideal but it works. And --help still has some '*foo*' markup, but we
live with that for now.

Fixes #1581
2020-05-13 08:13:05 -04:00
Andrew Gallant
1e9a481a66 doc: more release checklist updates 2020-05-09 11:43:37 -04:00
Andrew Gallant
bacfca174e pkg: update brew tap to version 12.1.0
This also removes Fish shell completions. See #1577 for more details.
2020-05-09 11:42:39 -04:00
Andrew Gallant
6162b000a3 changelog: 12.1.0 2020-05-09 11:36:44 -04:00
Andrew Gallant
2658bd4e46 12.1.0 2020-05-09 11:13:33 -04:00
Andrew Gallant
4b8e1f030e doc: add more detail to release checklist
Getting the crate order right is important, so document it.
2020-05-09 11:12:51 -04:00
Andrew Gallant
72807462e8 deps: update minimal versions for dependencies 2020-05-09 10:39:43 -04:00
Andrew Gallant
08dee094dd grep-0.2.6 2020-05-09 10:37:29 -04:00
Andrew Gallant
caa53b7b09 grep: update minimal dependency versions 2020-05-09 10:37:08 -04:00
Andrew Gallant
c5d6141562 grep-printer-0.1.5 2020-05-09 10:33:02 -04:00
Andrew Gallant
c0f0492b98 grep-regex-0.1.8 2020-05-09 10:31:29 -04:00
Andrew Gallant
568018386b ignore-0.4.15 2020-05-09 10:27:19 -04:00
Andrew Gallant
6219d29c24 doc: add 'cargo outdated' step to release checklist
It's just good sense to make sure everything is updated if possible.
2020-05-09 10:26:00 -04:00
Andrew Gallant
b458cf39f2 deps: update to base64 0.12
No code changes were necessary.
2020-05-09 10:25:37 -04:00
Andrew Gallant
3fd2694fbc deps: update all dependencies
Everything looks pretty minor.
2020-05-09 09:05:51 -04:00
Andrew Gallant
b56315ea84 changelog: add #1550 to CHANGELOG 2020-05-08 23:37:17 -04:00
Andrew Gallant
fac47906e6 doc: add a release checklist
The steps are numerous, subtle and complex enough that it's worth
writing them down. In particular, getting the order correct is
important. (i.e., If we released to crates.io first and the GitHub
release infrastructure failed, then we'd be in a pickle.)
2020-05-08 23:24:40 -04:00
Andrew Gallant
e02bb6b99a changelog: add downstream notices 2020-05-08 23:24:40 -04:00
Chayoung You
16a1221fc7 doc: use asciidoctor instead of a2x
AsciiDoc development is continued under asciidoctor. See
https://github.com/asciidoc/asciidoc.

We do however fallback to a2x if asciidoctor is not present. This is to
ease migration, but at some point, it's likely that support for a2x will
be dropped.

Originally reported downstream:
https://github.com/Homebrew/linuxbrew-core/issues/19885

Closes #1544
2020-05-08 23:24:40 -04:00
Casey Rodarmor
793c1179cc ignore: allow filtering with predicate
Adds `WalkBuilder::filter_entry` that takes a predicate to be applied to
all entries. If the predicate returns `false` on a given entry, that
entry and all children will be skipped.

Fixes #1555, Closes #1557
2020-05-08 23:24:40 -04:00
Wieland Hoffmann
df7a3bfc7f grep-cli: support files compressed by compress(1)
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-08 23:24:40 -04:00
Andrew Gallant
28f2a93cae doc: shorten -h/--help prelude
It has grown quite long. It would be nice if we could shorten this only
when -h is used and keep it long for --help, but it seems clap doesn't
let this happen. (It does have `about` and `long_about` options, but
they don't work, even when I disable the use of the template.)

The longer prelude is now only available in the man page.

This addresses #189.
2020-05-08 23:24:40 -04:00
Andrew Gallant
0eb2501b6e doc: add a section about --pre to the GUIDE
Fixes #1252
2020-05-08 23:24:40 -04:00
Andrew Gallant
184c15882e doc: add -U/--multiline to common options 2020-05-08 23:24:40 -04:00
Andrew Gallant
64a4dee495 cli: improve invalid UTF-8 pattern error message
When a pattern with invalid UTF-8 is given, the error message suggests
unqualified use of hex escape sequences to match arbitrary bytes. But
you *also* need to disable Unicode mode. So include that in the error
message.

Fixes #1339
2020-05-08 23:24:40 -04:00
Andrew Gallant
50840ea43b doc: note how to escape a '$' in --replace
Fixes #1524
2020-05-08 23:24:40 -04:00
Andrew Gallant
17dcc2bf51 doc: clarify that *files* override gitignores
This attempts to fix some mild confusion that came up as part of #1574.
Specifically:
https://github.com/BurntSushi/ripgrep/issues/1574#issuecomment-625780436
2020-05-08 23:24:40 -04:00
Andrew Gallant
9a858e4909 doc: add config file note for --type-{add,clear}
This clarifies that persistence is possible via a configuration file.

Fixes #1571
2020-05-08 23:24:40 -04:00
Andrew Gallant
cbfbe9312f snap: remove snapcraft configuration
This hasn't been updated in ages and it's not clear what purpose it's
serving.
2020-05-08 23:24:40 -04:00
Andrew Gallant
7ed9a31819 printer: fix --count-matches output
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-05-08 23:24:40 -04:00
Andrew Gallant
a2e6aec7a4 tests: add new regression test for fixed inner literal bug
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-23 08:37:04 -04:00
Andrew Gallant
73103df6d9 deps: small dependency updates 2020-04-18 11:33:27 -04:00
Andrew Gallant
139f186e57 crates/ignore: switch to depth first traversal
This replaces the use of channels in the parallel directory traversal
with a simple stack. The primary motivation for this change is to reduce
peak memory usage. In particular, when using a channel (which is a
queue), we wind up visiting files in a breadth first fashion. Using a
stack switches us to a depth first traversal. While there are no real
intrinsic differences, depth first traversal generally tends to use less
memory because directory trees are more commonly wide than they are
deep.

In particular, the queue/stack size itself is not the only concern. In
one recent case documented in #1550, a user wanted to search all Rust
crates. The directory structure was shallow but extremely wide, with a
single directory containing all crates. This in turn results is in
descending into each of those directories and building a gitignore
matcher for each (since most crates have `.gitignore` files) before ever
searching a single file. This means that ripgrep has all such matchers
in memory simultaneously, which winds up using quite a bit of memory.

In a depth first traversal, peak memory usage is much lower because
gitignore matches are built and discarded more quickly. In the case of
searching all crates, the peak memory usage decrease is dramatic. On my
system, it shrinks by an order magnitude, from almost 1GB to 50MB. The
decline in peak memory usage is consistent across other use cases as
well, but is typically more modest. For example, searching the Linux
repo has a 50% decrease in peak memory usage and searching the Chromium
repo has a 25% decrease in peak memory usage.

Search times generally remain unchanged, although some ad hoc benchmarks
that I typically run have gotten a bit slower. As far as I can tell,
this appears to be result of scheduling changes. Namely, the depth first
traversal seems to result in searching some very large files towards the
end of the search, which reduces the effectiveness of parallelism and
makes the overall search take longer. This seems to suggest that a stack
isn't optimal. It would instead perhaps be better to prioritize
searching larger files first, but it's not quite clear how to do this
without introducing more overhead (getting the file size for each file
requires a stat call).

Fixes #1550
2020-04-18 11:33:03 -04:00
Andrew Gallant
afb325f733 readme: fix ordering of benchmarks
Results remain the same. I just didn't order them correctly.
2020-04-16 12:03:46 -04:00
Andrew Gallant
40af352d74 github: add necessary metadata 2020-04-14 16:28:09 -04:00
Andrew Gallant
3f1d4b397d github: switch to new issue template format
And also point folks toward Discussions.
2020-04-14 16:23:47 -04:00
Andrew Gallant
a75b4d122a doc: fix newline escape
Fixes #1551
2020-04-13 08:49:27 -04:00
Simon Robin
f51b762c6d pkg: fix brew tap version
It wasn't updated after the 12.0.1 release, even though the
SHA values were.

PR #1545
2020-04-07 19:45:53 -04:00
Andrew Gallant
49de7b119c ci: disable man page check
It appears to be intermittently failing. Specifically, a2x seems to be
failing occasionally with no apparent reason why. The error message it
gives is inscrutable. Sigh.
2020-04-01 21:18:04 -04:00
Andrew Gallant
1c4b5adb7b regex: fix another inner literal bug
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-04-01 20:37:48 -04:00
Marius Schulz
3d6a58faff doc: fix typo in help description
PR #1536
2020-03-30 17:31:16 -04:00
Andrew Gallant
5b6ca04e39 ci: upgrade to actions/checkout@v2
In particular, this appears to fix an extremely annoying bug that was
causing PR builds to fail if they were re-run.

For more details:
https://github.com/actions/checkout/issues/23#issuecomment-572688577
2020-03-30 17:09:41 -04:00
Andrew Gallant
47f20c2661 pkg: update brew tap to 12.0.1 2020-03-29 19:18:57 -04:00
Andrew Gallant
1d5b1011e5 12.0.1 2020-03-29 18:59:40 -04:00
Andrew Gallant
1bb30b72fc changelog: prepare for 12.0.1 release, redux 2020-03-29 18:50:31 -04:00
Andrew Gallant
09a4b75baf ignore-0.4.14 2020-03-29 18:49:01 -04:00
Andrew Gallant
58c428827d changelog: prepare for 12.0.1 release 2020-03-29 18:47:46 -04:00
Andrew Gallant
b9bb04b793 deps: minor dependency updates 2020-03-29 18:47:15 -04:00
Zoltan Puskas
4dfea016b9 ignore/types: add ebuild type
Add support for Gentoo's portage package manager spec files:
https://wiki.gentoo.org/wiki/Portage
2020-03-29 18:44:04 -04:00
Andrew Gallant
3193d57ac1 ci: attempt to fix CI
It looks like a2x isn't working, so take a shot at fixing it.
2020-03-28 21:36:29 -04:00
Andrew Gallant
67c0f576b6 ignore-0.4.13 2020-03-22 21:08:37 -04:00
Andrew Gallant
543f99dbf1 grep-regex-0.1.7 2020-03-22 21:08:19 -04:00
Andrew Gallant
0ea65efd6d regex: special case literal extraction
In a prior commit, we fixed a performance problem with the -w flag by
doing a little extra work to extract literals. It turns out that using
literals in this case when the -w flag is NOT used results in a
performance regression. The reasoning is that we end up using a "fast"
regex as a prefilter when the regex engine itself uses its own
equivalent prefilter, so ripgrep ends up redoing a fair amount of work.

Instead, we only do this extra work when we know the -w flag is enabled.
2020-03-22 21:02:51 -04:00
Paul A. Patience
20deae6497 tests: fix typo in test name
PR #1528
2020-03-22 07:43:16 -04:00
Andrew Gallant
655e33219a crates.io: remove badges
... and don't replace them with anything because crates.io does not
support GitHub Actions yet. But it's almost there:
https://github.com/rust-lang/crates.io/pull/1838

Thanks @atouchet for noticing this.
2020-03-17 17:50:37 -04:00
Andrew Gallant
8ba6ccd159 ignore: fix failing test
This fixes fallout from fixing #1520.
2020-03-16 19:16:24 -04:00
Andrew Gallant
34edb8123a ignore: squash noisy error message
We should not assume that the commondir file actually exists. If it
doesn't, then just move on. This otherwise emits an error message when
searching normal submodules, which is not OK.

This regression was introduced in #1446.

Fixes #1520
2020-03-16 18:50:02 -04:00
Andrew Gallant
5b30c2aed6 ci: fix deb build script 2020-03-15 22:11:32 -04:00
Andrew Gallant
bf1027a83e pkg: update brew tap to 12.0.0 2020-03-15 22:10:08 -04:00
Andrew Gallant
031264e5fb ci: tweak release name
This is consistent with prior releases.
2020-03-15 22:07:22 -04:00
Andrew Gallant
b9cd95faf1 release: 12.0.0, take 2 2020-03-15 21:54:11 -04:00
38 changed files with 827 additions and 284 deletions

View File

@@ -1,3 +1,12 @@
---
name: Bug report
about: An issue with ripgrep or any of its crates (ignore, globset, etc.)
title: ''
labels: ''
assignees: ''
---
#### What version of ripgrep are you using?
Replace this text with the output of `rg --version`.
@@ -12,18 +21,11 @@ Github binary releases.
Replace this text with your operating system and version.
#### Describe your question, feature request, or bug.
#### Describe your bug.
If a question, please describe the problem you're trying to solve and give
as much context as possible.
Give a high level description of the bug.
If a feature request, please describe the behavior you want and the motivation.
Please also provide an example of how ripgrep would be used if your feature
request were added.
If a bug, please see below.
#### If this is a bug, what are the steps to reproduce the behavior?
#### What are the steps to reproduce the behavior?
If possible, please include both your search patterns and the corpus on which
you are searching. Unless the bug is very obvious, then it is unlikely that it
@@ -32,7 +34,7 @@ will be fixed if the ripgrep maintainers cannot reproduce it.
If the corpus is too big and you cannot decrease its size, file the bug anyway
and the ripgrep maintainers will help figure out next steps.
#### If this is a bug, what is the actual behavior?
#### What is the actual behavior?
Show the command you ran and the actual output. Include the `--debug` flag in
your invocation of ripgrep.
@@ -48,6 +50,6 @@ goes
here
```
#### If this is a bug, what is the expected behavior?
#### What is the expected behavior?
What do you think ripgrep should have done?

6
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
blank_issues_enabled: true
contact_links:
- name: Ask a question
about: |
You've come to seek help or want to discuss something related to ripgrep.
url: https://github.com/BurntSushi/ripgrep/discussions/new

View File

@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest a new feature for ripgrep
title: ''
labels: ''
assignees: ''
---
#### Describe your feature request
Please describe the behavior you want and the motivation. Please also provide
examples of how ripgrep would be used if your feature request were added.
If you're not sure what to write here, then try imagining what the ideal
documentation of your new feature would look like in ripgrep's man page. Then
try to write it.

View File

@@ -85,7 +85,7 @@ jobs:
rust: nightly-x86_64-gnu
steps:
- name: Checkout repository
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Install packages (Ubuntu)
if: matrix.os == 'ubuntu-18.04'
@@ -163,7 +163,10 @@ jobs:
shell: bash
run: |
outdir="$(ci/cargo-out-dir "${{ env.TARGET_DIR }}")"
for f in rg.bash rg.fish rg.1; do
# TODO: Check for the man page generation here. For whatever reason,
# it seems to be intermittently failing in CI. No idea why.
# for f in rg.bash rg.fish rg.1; do
for f in rg.bash rg.fish; do
# We could use file -E here, but it isn't supported on macOS.
ls "$outdir/$f" && file "$outdir/$f"
done
@@ -182,7 +185,7 @@ jobs:
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:

View File

@@ -22,7 +22,7 @@ jobs:
create-release:
name: create-release
runs-on: ubuntu-latest
env:
# env:
# Set to force version number, e.g., when no tag exists.
# RG_VERSION: TEST-0.0.0
steps:
@@ -45,7 +45,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.RG_VERSION }}
release_name: ripgrep ${{ env.RG_VERSION }}
release_name: ${{ env.RG_VERSION }}
- name: Save release upload URL to artifact
run: echo "${{ steps.release.outputs.upload_url }}" > artifacts/release-upload-url
@@ -106,7 +106,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v1
uses: actions/checkout@v2
with:
fetch-depth: 1

View File

@@ -1,3 +1,69 @@
TBD
===
Unreleased changes. Release notes have not yet been written.
Bug fixes:
* [BUG #1581](https://github.com/BurntSushi/ripgrep/issues/1581):
Corrects some egregious markup output in `--help`.
* [BUG #1591](https://github.com/BurntSushi/ripgrep/issues/1591):
Mention the special `$0` capture group in docs for the `-r/--replace` flag.
12.1.0 (2020-05-09)
===================
ripgrep 12.1.0 is a small minor version release that mostly includes bug fixes
and documentation improvements. This release also contains some important
notices for downstream packagers.
**Notices for downstream ripgrep package maintainers:**
* Fish shell completions will be removed in the ripgrep 13 release.
See [#1577](https://github.com/BurntSushi/ripgrep/issues/1577)
for more details.
* ripgrep has switched from `a2x` to `asciidoctor` to generate the man page.
If `asciidoctor` is not present, then ripgrep will currently fall back to
`a2x`. Support for `a2x` will be dropped in the ripgrep 13 release.
See [#1544](https://github.com/BurntSushi/ripgrep/issues/1544)
for more details.
Feature enhancements:
* [FEATURE #1547](https://github.com/BurntSushi/ripgrep/pull/1547):
Support decompressing `.Z` files via `uncompress`.
Bug fixes:
* [BUG #1252](https://github.com/BurntSushi/ripgrep/issues/1252):
Add a section on the `--pre` flag to the GUIDE.
* [BUG #1339](https://github.com/BurntSushi/ripgrep/issues/1339):
Improve error message when a pattern with invalid UTF-8 is provided.
* [BUG #1524](https://github.com/BurntSushi/ripgrep/issues/1524):
Note how to escape a `$` when using `--replace`.
* [BUG #1537](https://github.com/BurntSushi/ripgrep/issues/1537):
Fix match bug caused by inner literal optimization.
* [BUG #1544](https://github.com/BurntSushi/ripgrep/issues/1544):
ripgrep now uses `asciidoctor` instead of `a2x` to generate its man page.
* [BUG #1550](https://github.com/BurntSushi/ripgrep/issues/1550):
Substantially reduce peak memory usage when searching wide directories.
* [BUG #1571](https://github.com/BurntSushi/ripgrep/issues/1571):
Add note about configuration files in `--type-{add,clear}` docs.
* [BUG #1573](https://github.com/BurntSushi/ripgrep/issues/1573):
Fix incorrect `--count-matches` output when using look-around.
12.0.1 (2020-03-29)
===================
ripgrep 12.0.1 is a small patch release that includes a minor bug fix relating
to superfluous error messages when searching git repositories with sub-modules.
This was a regression introduced in the 12.0.0 release.
Bug fixes:
* [BUG #1520](https://github.com/BurntSushi/ripgrep/issues/1520):
Don't emit spurious error messages in git repositories with submodules.
12.0.0 (2020-03-15)
===================
ripgrep 12 is a new major version release of ripgrep that contains many bug

210
Cargo.lock generated
View File

@@ -13,8 +13,8 @@ name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -25,7 +25,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.11.0"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -35,7 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bstr"
version = "0.2.12"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -55,7 +55,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.50"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
version = "2.33.0"
version = "2.33.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -95,7 +95,7 @@ dependencies = [
[[package]]
name = "encoding_rs"
version = "0.8.22"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -107,12 +107,12 @@ name = "encoding_rs_io"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fnv"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -130,25 +130,25 @@ name = "globset"
version = "0.4.5"
dependencies = [
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "grep"
version = "0.2.5"
version = "0.2.6"
dependencies = [
"grep-cli 0.1.4",
"grep-cli 0.1.5",
"grep-matcher 0.1.4",
"grep-pcre2 0.1.4",
"grep-printer 0.1.4",
"grep-regex 0.1.6",
"grep-printer 0.1.5",
"grep-regex 0.1.8",
"grep-searcher 0.1.7",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -156,17 +156,17 @@ dependencies = [
[[package]]
name = "grep-cli"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.4.5",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -174,7 +174,7 @@ name = "grep-matcher"
version = "0.1.4"
dependencies = [
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -187,29 +187,29 @@ dependencies = [
[[package]]
name = "grep-printer"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.4",
"grep-regex 0.1.6",
"grep-regex 0.1.8",
"grep-searcher 0.1.7",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "grep-regex"
version = "0.1.6"
version = "0.1.8"
dependencies = [
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.4",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -217,28 +217,28 @@ dependencies = [
name = "grep-searcher"
version = "0.1.7"
dependencies = [
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"bytecount 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.4",
"grep-regex 0.1.6",
"grep-regex 0.1.8",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.1.8"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ignore"
version = "0.4.12"
version = "0.4.16"
dependencies = [
"crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -246,11 +246,11 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -263,9 +263,9 @@ name = "jemalloc-sys"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -274,7 +274,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -284,7 +284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.67"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -310,17 +310,17 @@ name = "memmap"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.12.0"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -336,7 +336,7 @@ name = "pcre2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pcre2-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -347,8 +347,8 @@ name = "pcre2-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -359,7 +359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "1.0.9"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -367,20 +367,20 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.3"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.3.5"
version = "1.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -394,32 +394,32 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.17"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ripgrep"
version = "12.0.0"
version = "12.1.0"
dependencies = [
"bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"grep 0.2.5",
"ignore 0.4.12",
"bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
"grep 0.2.6",
"ignore 0.4.16",
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ryu"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -427,32 +427,32 @@ name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.104"
version = "1.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.104"
version = "1.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.48"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -462,11 +462,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.16"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -475,7 +475,7 @@ name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -511,7 +511,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -530,7 +530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.3"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -545,48 +545,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
"checksum base64 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
"checksum bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
"checksum bytecount 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
"checksum crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28"
"checksum encoding_rs 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
"checksum encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
"checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
"checksum jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
"checksum jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
"checksum packed_simd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220"
"checksum pcre2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "85b30f2f69903b439dd9dc9e824119b82a55bf113b29af8d70948a03c1b11ab1"
"checksum pcre2-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876c72d05059d23a84bd9fcdc3b1d31c50ea7fe00fe1522b4e68cd3608db8d5b"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
"checksum regex 1.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048"
"checksum proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
"checksum quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
"checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
"checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
"checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
"checksum serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
"checksum serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
"checksum serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
"checksum syn 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "ef781e621ee763a2a40721a8861ec519cb76966aee03bb5d00adb6a31dc1c1de"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
@@ -595,5 +595,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -1,6 +1,6 @@
[package]
name = "ripgrep"
version = "12.0.0" #:version
version = "12.1.0" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
ripgrep is a line-oriented search tool that recursively searches your current
@@ -19,10 +19,6 @@ build = "build.rs"
autotests = false
edition = "2018"
[badges]
travis-ci = { repository = "BurntSushi/ripgrep" }
appveyor = { repository = "BurntSushi/ripgrep" }
[[bin]]
bench = false
path = "crates/core/main.rs"
@@ -47,8 +43,8 @@ members = [
[dependencies]
bstr = "0.2.12"
grep = { version = "0.2.5", path = "crates/grep" }
ignore = { version = "0.4.12", path = "crates/ignore" }
grep = { version = "0.2.6", path = "crates/grep" }
ignore = { version = "0.4.15", path = "crates/ignore" }
lazy_static = "1.1.0"
log = "0.4.5"
num_cpus = "1.8.0"

7
FAQ.md
View File

@@ -60,9 +60,10 @@ patch release out with a fix. However, no promises are made.
Does ripgrep have a man page?
</h3>
Yes! Whenever ripgrep is compiled on a system with `asciidoc` present, then a
man page is generated from ripgrep's argv parser. After compiling ripgrep, you
can find the man page like so from the root of the repository:
Yes! Whenever ripgrep is compiled on a system with `asciidoctor` or `asciidoc`
present, then a man page is generated from ripgrep's argv parser. After
compiling ripgrep, you can find the man page like so from the root of the
repository:
```
$ find ./target -name rg.1 -print0 | xargs -0 ls -t | head -n1

208
GUIDE.md
View File

@@ -19,6 +19,7 @@ translatable to any command line shell environment.
* [Configuration file](#configuration-file)
* [File encoding](#file-encoding)
* [Binary data](#binary-data)
* [Preprocessor](#preprocessor)
* [Common options](#common-options)
@@ -767,6 +768,212 @@ via the `--no-mmap` flag. (The cost will be a small performance regression when
searching very large files on some platforms.)
### Preprocessor
In ripgrep, a preprocessor is any type of command that can be run to transform
the input of every file before ripgrep searches it. This makes it possible to
search virtually any kind of content that can be automatically converted to
text without having to teach ripgrep how to read said content.
One common example is searching PDFs. PDFs are first and foremost meant to be
displayed to users. But PDFs often have text streams in them that can be useful
to search. In our case, we want to search Bruce Watson's excellent
dissertation,
[Taxonomies and Toolkits of Regular Language Algorithms](https://burntsushi.net/stuff/1995-watson.pdf).
After downloading it, let's try searching it:
```
$ rg 'The Commentz-Walter algorithm' 1995-watson.pdf
$
```
Surely, a dissertation on regular language algorithms would mention
Commentz-Walter. Indeed it does, but our search isn't picking it up because
PDFs are a binary format, and the text shown in the PDF may not be encoded as
simple contiguous UTF-8. Namely, even passing the `-a/--text` flag to ripgrep
will not make our search work.
One way to fix this is to convert the PDF to plain text first. This won't work
well for all PDFs, but does great in a lot of cases. (Note that the tool we
use, `pdftotext`, is part of the [poppler](https://poppler.freedesktop.org)
PDF rendering library.)
```
$ pdftotext 1995-watson.pdf > 1995-watson.txt
$ rg 'The Commentz-Walter algorithm' 1995-watson.txt
316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :
7165:4.4 The Commentz-Walter algorithms
10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm
17218:The Commentz-Walter algorithm (and its variants) displayed more interesting behaviour,
17249:Aho-Corasick algorithms are used extensively. The Commentz-Walter algorithms are used
17297: The Commentz-Walter algorithms (CW). In all versions of the CW algorithms, a common program skeleton is used with di erent shift functions. The CW algorithms are
```
But having to explicitly convert every file can be a pain, especially when you
have a directory full of PDF files. Instead, we can use ripgrep's preprocessor
feature to search the PDF. ripgrep's `--pre` flag works by taking a single
command name and then executing that command for every file that it searches.
ripgrep passes the file path as the first and only argument to the command and
also sends the contents of the file to stdin. So let's write a simple shell
script that wraps `pdftotext` in a way that conforms to this interface:
```
$ cat preprocess
#!/bin/sh
exec pdftotext - -
```
With `preprocess` in the same directory as `1995-watson.pdf`, we can now use it
to search the PDF:
```
$ rg --pre ./preprocess 'The Commentz-Walter algorithm' 1995-watson.pdf
316:The Commentz-Walter algorithms : : : : : : : : : : : : : : :
7165:4.4 The Commentz-Walter algorithms
10062:in input string S , we obtain the Boyer-Moore algorithm. The Commentz-Walter algorithm
17218:The Commentz-Walter algorithm (and its variants) displayed more interesting behaviour,
17249:Aho-Corasick algorithms are used extensively. The Commentz-Walter algorithms are used
17297: The Commentz-Walter algorithms (CW). In all versions of the CW algorithms, a common program skeleton is used with di erent shift functions. The CW algorithms are
```
Note that `preprocess` must be resolvable to a command that ripgrep can read.
The simplest way to do this is to put your preprocessor command in a directory
that is in your `PATH` (or equivalent), or otherwise use an absolute path.
As a bonus, this turns out to be quite a bit faster than other specialized PDF
grepping tools:
```
$ time rg --pre ./preprocess 'The Commentz-Walter algorithm' 1995-watson.pdf -c
6
real 0.697
user 0.684
sys 0.007
maxmem 16 MB
faults 0
$ time pdfgrep 'The Commentz-Walter algorithm' 1995-watson.pdf -c
6
real 1.336
user 1.310
sys 0.023
maxmem 16 MB
faults 0
```
If you wind up needing to search a lot of PDFs, then ripgrep's parallelism can
make the speed difference even greater.
#### A more robust preprocessor
One of the problems with the aforementioned preprocessor is that it will fail
if you try to search a file that isn't a PDF:
```
$ echo foo > not-a-pdf
$ rg --pre ./preprocess 'The Commentz-Walter algorithm' not-a-pdf
not-a-pdf: preprocessor command failed: '"./preprocess" "not-a-pdf"':
-------------------------------------------------------------------------------
Syntax Warning: May not be a PDF file (continuing anyway)
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't find trailer dictionary
Syntax Error: Couldn't read xref table
```
To fix this, we can make our preprocessor script a bit more robust by only
running `pdftotext` when we think the input is a non-empty PDF:
```
$ cat preprocessor
#!/bin/sh
case "$1" in
*.pdf)
# The -s flag ensures that the file is non-empty.
if [ -s "$1" ]; then
exec pdftotext - -
else
exec cat
fi
;;
*)
exec cat
;;
esac
```
We can even extend our preprocessor to search other kinds of files. Sometimes
we don't always know the file type from the file name, so we can use the `file`
utility to "sniff" the type of the file based on its contents:
```
$ cat processor
#!/bin/sh
case "$1" in
*.pdf)
# The -s flag ensures that the file is non-empty.
if [ -s "$1" ]; then
exec pdftotext - -
else
exec cat
fi
;;
*)
case $(file "$1") in
*Zstandard*)
exec pzstd -cdq
;;
*)
exec cat
;;
esac
;;
esac
```
#### Reducing preprocessor overhead
There is one more problem with the above approach: it requires running a
preprocessor for every single file that ripgrep searches. If every file needs
a preprocessor, then this is OK. But if most don't, then this can substantially
slow down searches because of the overhead of launching new processors. You
can avoid this by telling ripgrep to only invoke the preprocessor when the file
path matches a glob. For example, consider the performance difference even when
searching a repository as small as ripgrep's:
```
$ time rg --pre pre-rg 'fn is_empty' -c
crates/globset/src/lib.rs:1
crates/matcher/src/lib.rs:2
crates/ignore/src/overrides.rs:1
crates/ignore/src/gitignore.rs:1
crates/ignore/src/types.rs:1
real 0.138
user 0.485
sys 0.209
maxmem 7 MB
faults 0
$ time rg --pre pre-rg --pre-glob '*.pdf' 'fn is_empty' -c
crates/globset/src/lib.rs:1
crates/ignore/src/types.rs:1
crates/ignore/src/gitignore.rs:1
crates/ignore/src/overrides.rs:1
crates/matcher/src/lib.rs:2
real 0.008
user 0.010
sys 0.002
maxmem 7 MB
faults 0
```
### Common options
ripgrep has a lot of flags. Too many to keep in your head at once. This section
@@ -788,6 +995,7 @@ used options that will likely impact how you use ripgrep on a regular basis.
* `--files`: Print the files that ripgrep *would* search, but don't actually
search them.
* `-a/--text`: Search binary files as if they were plain text.
* `-U/--multiline`: Permit matches to span multiple lines.
* `-z/--search-zip`: Search compressed files (gzip, bzip2, lzma, xz, lz4,
brotli, zstd). This is disabled by default.
* `-C/--context`: Show the lines surrounding a match.

View File

@@ -53,8 +53,8 @@ for a very detailed comparison with more benchmarks and analysis.
| ripgrep (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 452 | **0.136s** |
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `git grep -P -n -w '[A-Z]+_SUSPEND'` | 452 | 0.348s |
| [ugrep (Unicode)](https://github.com/Genivia/ugrep) | `ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND'` | 452 | 0.506s |
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 452 | 1.150s |
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 452 | 0.654s |
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 452 | 1.150s |
| [ack](https://github.com/beyondgrep/ack3) | `ack -w '[A-Z]+_SUSPEND'` | 452 | 4.054s |
| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 452 | 4.205s |
@@ -116,9 +116,10 @@ times are unaffected by the presence or absence of `-n`.
specifically specified with the `-E/--encoding` flag.)
* ripgrep supports searching files compressed in a common format (brotli,
bzip2, gzip, lz4, lzma, xz, or zstandard) with the `-z/--search-zip` flag.
* ripgrep supports arbitrary input preprocessing filters which could be PDF
text extraction, less supported decompression, decrypting, automatic encoding
detection and so on.
* ripgrep supports
[arbitrary input preprocessing filters](GUIDE.md#preprocessor)
which could be PDF text extraction, less supported decompression, decrypting,
automatic encoding detection and so on.
In other words, use ripgrep if you like speed, filtering by default, fewer
bugs and Unicode support.

42
RELEASE-CHECKLIST.md Normal file
View File

@@ -0,0 +1,42 @@
Release Checklist
-----------------
* Run `cargo update` and review dependency updates. Commit updated
`Cargo.lock`.
* Run `cargo outdated` and review semver incompatible updates. Unless there is
a strong motivation otherwise, review and update every dependency.
* Review changes for every crate in `crates` since the last ripgrep release.
If the set of changes is non-empty, issue a new release for that crate. Check
crates in the following order. After updating a crate, ensure minimal
versions are updated as appropriate in dependents. If an update is required,
run `cargo-up --no-push crates/{CRATE}/Cargo.toml`.
* crates/globset
* crates/ignore
* crates/cli
* crates/matcher
* crates/regex
* crates/pcre2
* crates/searcher
* crates/printer
* crates/grep (bump minimal versions as necessary)
* crates/core (do **not** bump version, but update dependencies as needed)
* Edit the `Cargo.toml` to set the new ripgrep version. Run
`cargo update -p ripgrep` so that the `Cargo.lock` is updated. Commit the
changes and create a new signed tag. Alternatively, use
`cargo-up --no-push --no-release Cargo.toml {VERSION}` to automate this.
* Wait for CI to finish creating the release. If the release build fails, then
delete the tag from GitHub, make fixes, re-tag, delete the release and push.
* Copy the relevant section of the CHANGELOG to the tagged release notes.
Include this blurb describing what ripgrep is:
> In case you haven't heard of it before, ripgrep is a line-oriented search
> tool that recursively searches your current directory for a regex pattern.
> By default, ripgrep will respect your `.gitignore` and automatically skip
> hidden files/directories and binary files.
* Run `ci/build-deb` locally and manually upload the deb package to the
release.
* Run `cargo publish`.
* Run `ci/sha256-releases {VERSION} >> pkg/brew/ripgrep-bin.rb`. Then edit
`pkg/brew/ripgrep-bin.rb` to update the version number and sha256 hashes.
Remove extraneous stuff added by `ci/sha256-releases`. Commit changes.
Note that
[`cargo-up` can be found in BurntSushi's dotfiles](https://github.com/BurntSushi/dotfiles/blob/master/bin/cargo-up).

View File

@@ -65,6 +65,51 @@ fn git_revision_hash() -> Option<String> {
}
fn generate_man_page<P: AsRef<Path>>(outdir: P) -> io::Result<()> {
// If asciidoctor isn't installed, fallback to asciidoc.
if let Err(err) = process::Command::new("asciidoctor").output() {
eprintln!(
"Could not run 'asciidoctor' binary, falling back to 'a2x'."
);
eprintln!("Error from running 'asciidoctor': {}", err);
return legacy_generate_man_page::<P>(outdir);
}
// 1. Read asciidoctor template.
// 2. Interpolate template with auto-generated docs.
// 3. Save interpolation to disk.
// 4. Use asciidoctor to convert to man page.
let outdir = outdir.as_ref();
let cwd = env::current_dir()?;
let tpl_path = cwd.join("doc").join("rg.1.txt.tpl");
let txt_path = outdir.join("rg.1.txt");
let mut tpl = String::new();
File::open(&tpl_path)?.read_to_string(&mut tpl)?;
let options =
formatted_options()?.replace("&#123;", "{").replace("&#125;", "}");
tpl = tpl.replace("{OPTIONS}", &options);
let githash = git_revision_hash();
let githash = githash.as_ref().map(|x| &**x);
tpl = tpl.replace("{VERSION}", &app::long_version(githash, false));
File::create(&txt_path)?.write_all(tpl.as_bytes())?;
let result = process::Command::new("asciidoctor")
.arg("--doctype")
.arg("manpage")
.arg("--backend")
.arg("manpage")
.arg(&txt_path)
.spawn()?
.wait()?;
if !result.success() {
let msg =
format!("'asciidoctor' failed with exit code {:?}", result.code());
return Err(ioerr(msg));
}
Ok(())
}
fn legacy_generate_man_page<P: AsRef<Path>>(outdir: P) -> io::Result<()> {
// If asciidoc isn't installed, then don't do anything.
if let Err(err) = process::Command::new("a2x").output() {
eprintln!("Could not run 'a2x' binary, skipping man page generation.");
@@ -172,6 +217,10 @@ fn formatted_doc_txt(arg: &RGArg) -> io::Result<String> {
.doc_long
.replace("{", "&#123;")
.replace("}", r"&#125;")
// Hack to render ** literally in man page correctly. We can't put
// these crazy +++ in the help text directly, since that shows
// literally in --help output.
.replace("*-g 'foo/**'*", "*-g +++'foo/**'+++*")
.split("\n\n")
.map(|s| s.to_string())
.collect();

View File

@@ -29,7 +29,8 @@ mkdir -p "$DEPLOY_DIR"
cargo build
# Copy man page and shell completions.
cp "$OUT_DIR"/{rg.1,rg.bash,rg.fish,_rg} "$DEPLOY_DIR/"
cp "$OUT_DIR"/{rg.1,rg.bash,rg.fish} "$DEPLOY_DIR/"
cp complete/_rg "$DEPLOY_DIR/"
# Since we're distributing the dpkg, we don't know whether the user will have
# PCRE2 installed, so just do a static build.

View File

@@ -4,7 +4,7 @@ via the [Cross](https://github.com/rust-embedded/cross) tool.
The Cross tool actually provides its own Docker images, and all Docker images
in this directory are derived from one of them. We provide our own in order
to customize the environment. For example, we need to install some things like
`asciidoc` in order to generate man pages. We also install compression tools
`asciidoctor` in order to generate man pages. We also install compression tools
like `xz` so that tests for the `-z/--search-zip` flag are run.
If you make a change to a Docker image, then you can re-build it. `cd` into the

View File

@@ -1,3 +1,3 @@
#!/bin/sh
brew install asciidoc docbook-xsl
brew install asciidoctor

View File

@@ -2,5 +2,5 @@
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxslt1-dev asciidoc docbook-xsl xsltproc libxml2-utils \
asciidoctor \
zsh xz-utils liblz4-tool musl-tools

View File

@@ -1,6 +1,6 @@
[package]
name = "grep-cli"
version = "0.1.4" #:version
version = "0.1.5" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
Utilities for search oriented command line applications.
@@ -15,7 +15,7 @@ license = "Unlicense/MIT"
[dependencies]
atty = "0.2.11"
bstr = "0.2.0"
globset = { version = "0.4.3", path = "../globset" }
globset = { version = "0.4.5", path = "../globset" }
lazy_static = "1.1.0"
log = "0.4.5"
regex = "1.1"

View File

@@ -348,6 +348,7 @@ fn default_decompression_commands() -> Vec<DecompressionCommand> {
const ARGS_LZMA: &[&str] = &["xz", "--format=lzma", "-d", "-c"];
const ARGS_BROTLI: &[&str] = &["brotli", "-d", "-c"];
const ARGS_ZSTD: &[&str] = &["zstd", "-q", "-d", "-c"];
const ARGS_UNCOMPRESS: &[&str] = &["uncompress", "-c"];
fn cmd(glob: &str, args: &[&str]) -> DecompressionCommand {
DecompressionCommand {
@@ -372,5 +373,6 @@ fn default_decompression_commands() -> Vec<DecompressionCommand> {
cmd("*.br", ARGS_BROTLI),
cmd("*.zst", ARGS_ZSTD),
cmd("*.zstd", ARGS_ZSTD),
cmd("*.Z", ARGS_UNCOMPRESS),
]
}

View File

@@ -38,9 +38,9 @@ impl fmt::Display for InvalidPatternError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"found invalid UTF-8 in pattern at byte offset {} \
(use hex escape sequences to match arbitrary bytes \
in a pattern, e.g., \\xFF): '{}'",
"found invalid UTF-8 in pattern at byte offset {}: {} \
(disable Unicode mode and use hex escape sequences to match \
arbitrary bytes in a pattern, e.g., '(?-u)\\xFF')",
self.valid_up_to, self.original,
)
}
@@ -64,10 +64,7 @@ pub fn pattern_from_os(pattern: &OsStr) -> Result<&str, InvalidPatternError> {
.to_string_lossy()
.find('\u{FFFD}')
.expect("a Unicode replacement codepoint for invalid UTF-8");
InvalidPatternError {
original: escape_os(pattern),
valid_up_to: valid_up_to,
}
InvalidPatternError { original: escape_os(pattern), valid_up_to }
})
}

View File

@@ -17,27 +17,10 @@ ripgrep (rg) recursively searches your current directory for a regex pattern.
By default, ripgrep will respect your .gitignore and automatically skip hidden
files/directories and binary files.
ripgrep's default regex engine uses finite automata and guarantees linear
time searching. Because of this, features like backreferences and arbitrary
look-around are not supported. However, if ripgrep is built with PCRE2, then
the --pcre2 flag can be used to enable backreferences and look-around.
ripgrep supports configuration files. Set RIPGREP_CONFIG_PATH to a
configuration file. The file can specify one shell argument per line. Lines
starting with '#' are ignored. For more details, see the man page or the
README.
ripgrep will automatically detect if stdin exists and search stdin for a regex
pattern, e.g. 'ls | rg foo'. In some environments, stdin may exist when it
shouldn't. To turn off stdin detection explicitly specify the directory to
search, e.g. 'rg foo ./'.
Tip: to disable all smart filtering and make ripgrep behave a bit more like
classical grep, use 'rg -uuu'.
Use -h for short descriptions and --help for more details.
Project home page: https://github.com/BurntSushi/ripgrep
Use -h for short descriptions and --help for more details.";
";
const USAGE: &str = "
rg [OPTIONS] PATTERN [PATH ...]
@@ -693,8 +676,8 @@ fn arg_path(args: &mut Vec<RGArg>) {
const SHORT: &str = "A file or directory to search.";
const LONG: &str = long!(
"\
A file or directory to search. Directories are searched recursively. Paths \
specified on the command line override glob and ignore rules. \
A file or directory to search. Directories are searched recursively. File \
paths specified on the command line override glob and ignore rules. \
"
);
let arg = RGArg::positional("path", "PATH")
@@ -1371,7 +1354,7 @@ command line takes precedence.
When this flag is set, every file and directory is applied to it to test for
a match. So for example, if you only want to search in a particular directory
'foo', then *-g foo* is incorrect because 'foo/bar' does not match the glob
'foo'. Instead, you should use *-g +++'foo/**'+++*.
'foo'. Instead, you should use *-g 'foo/**'*.
"
);
let arg = RGArg::flag("glob", "GLOB")
@@ -2313,7 +2296,7 @@ This flag can be disabled with --no-one-file-system.
}
fn flag_only_matching(args: &mut Vec<RGArg>) {
const SHORT: &str = "Print only matches parts of a line.";
const SHORT: &str = "Print only matched parts of a line.";
const LONG: &str = long!(
"\
Print only the matched (non-empty) parts of a matching line, with each such
@@ -2374,7 +2357,7 @@ Note that PCRE2 is an optional ripgrep feature. If PCRE2 wasn't included in
your build of ripgrep, then using this flag will result in ripgrep printing
an error message and exiting. PCRE2 may also have worse user experience in
some cases, since it has fewer introspection APIs than ripgrep's default regex
engine. For example, if you use a '\n' in a PCRE2 regex without the
engine. For example, if you use a '\\n' in a PCRE2 regex without the
'-U/--multiline' flag, then ripgrep will silently fail to match anything
instead of reporting an error immediately (like it does with the default
regex engine).
@@ -2593,10 +2576,15 @@ Replace every match with the text given when printing results. Neither this
flag nor any other ripgrep flag will modify your files.
Capture group indices (e.g., $5) and names (e.g., $foo) are supported in the
replacement string. In shells such as Bash and zsh, you should wrap the
pattern in single quotes instead of double quotes. Otherwise, capture group
indices will be replaced by expanded shell variables which will most likely
be empty.
replacement string. Capture group indices are numbered based on the position of
the opening paranthesis of the group, where the leftmost such group is $1. The
special $0 group corresponds to the entire match.
In shells such as Bash and zsh, you should wrap the pattern in single quotes
instead of double quotes. Otherwise, capture group indices will be replaced by
expanded shell variables which will most likely be empty.
To write a literal '$', use '$$'.
Note that the replacement by default replaces each match, and NOT the entire
line. To replace the entire line, you should match the entire line.
@@ -2877,7 +2865,7 @@ time. Multiple --type-add flags can be provided. Unless --type-clear is used,
globs are added to any existing globs defined inside of ripgrep.
Note that this MUST be passed to every invocation of ripgrep. Type settings are
NOT persisted.
NOT persisted. See CONFIGURATION FILES for a workaround.
Example:
@@ -2915,7 +2903,7 @@ Clear the file type globs previously defined for TYPE. This only clears the
default type definitions that are found inside of ripgrep.
Note that this MUST be passed to every invocation of ripgrep. Type settings are
NOT persisted.
NOT persisted. See CONFIGURATION FILES for a workaround.
"
);
let arg = RGArg::flag("type-clear", "TYPE")

View File

@@ -346,7 +346,7 @@ impl Args {
Ok(self.matches().walker_builder(self.paths())?.build())
}
/// Return a walker that never uses additional threads.
/// Return a parallel walker that may use additional threads.
pub fn walker_parallel(&self) -> Result<WalkParallel> {
Ok(self.matches().walker_builder(self.paths())?.build_parallel())
}

View File

@@ -1,6 +1,6 @@
[package]
name = "grep"
version = "0.2.5" #:version
version = "0.2.6" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
Fast line oriented regex searching as a library.
@@ -16,8 +16,8 @@ license = "Unlicense/MIT"
grep-cli = { version = "0.1.4", path = "../cli" }
grep-matcher = { version = "0.1.4", path = "../matcher" }
grep-pcre2 = { version = "0.1.4", path = "../pcre2", optional = true }
grep-printer = { version = "0.1.4", path = "../printer" }
grep-regex = { version = "0.1.6", path = "../regex" }
grep-printer = { version = "0.1.5", path = "../printer" }
grep-regex = { version = "0.1.8", path = "../regex" }
grep-searcher = { version = "0.1.7", path = "../searcher" }
[dev-dependencies]

View File

@@ -1,6 +1,6 @@
[package]
name = "ignore"
version = "0.4.12" #:version
version = "0.4.16" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
A fast library for efficiently matching ignore files such as `.gitignore`
@@ -18,9 +18,8 @@ name = "ignore"
bench = false
[dependencies]
crossbeam-channel = "0.4.0"
crossbeam-utils = "0.7.0"
globset = { version = "0.4.3", path = "../globset" }
globset = { version = "0.4.5", path = "../globset" }
lazy_static = "1.1"
log = "0.4.5"
memchr = "2.1"
@@ -32,5 +31,8 @@ walkdir = "2.2.7"
[target.'cfg(windows)'.dependencies.winapi-util]
version = "0.1.2"
[dev-dependencies]
crossbeam-channel = "0.4.0"
[features]
simd-accel = ["globset/simd-accel"]

View File

@@ -52,6 +52,7 @@ pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
("dhall", &["*.dhall"]),
("diff", &["*.patch", "*.diff"]),
("docker", &["*Dockerfile*"]),
("ebuild", &["*.ebuild"]),
("edn", &["*.edn"]),
("elisp", &["*.el"]),
("elixir", &["*.ex", "*.eex", "*.exs"]),
@@ -134,6 +135,7 @@ pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
("markdown", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
("matlab", &["*.m"]),
("md", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
("meson", &["meson.build", "meson_options.txt"]),
("mk", &["mkfile"]),
("ml", &["*.ml"]),
("msbuild", &[
@@ -233,6 +235,7 @@ pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
("xz", &["*.xz", "*.txz"]),
("yacc", &["*.y"]),
("yaml", &["*.yaml", "*.yml"]),
("z", &["*.Z"]),
("zig", &["*.zig"]),
("zsh", &[
".zshenv", "zshenv",

View File

@@ -310,7 +310,7 @@ impl Ignore {
git_global_matcher: self.0.git_global_matcher.clone(),
git_ignore_matcher: gi_matcher,
git_exclude_matcher: gi_exclude_matcher,
has_git: has_git,
has_git,
opts: self.0.opts,
};
(ig, errs.into_error_option())
@@ -817,9 +817,7 @@ fn resolve_git_commondir(
let git_commondir_file = || real_git_dir.join("commondir");
let file = match File::open(git_commondir_file()) {
Ok(file) => io::BufReader::new(file),
Err(err) => {
return Err(Some(Error::Io(err).with_path(git_commondir_file())));
}
Err(_) => return Err(None),
};
let commondir_line = match file.lines().next() {
Some(Ok(line)) => line,
@@ -839,7 +837,7 @@ fn resolve_git_commondir(
#[cfg(test)]
mod tests {
use std::fs::{self, File};
use std::io::{self, Write};
use std::io::Write;
use std::path::Path;
use dir::IgnoreBuilder;
@@ -1172,22 +1170,9 @@ mod tests {
// missing commondir file
assert!(fs::remove_file(commondir_path()).is_ok());
let (_, err) = ib.add_child(td.path().join("linked-worktree"));
assert!(err.is_some());
assert!(match err {
Some(Error::WithPath { path, err }) => {
if path != commondir_path() {
false
} else {
match *err {
Error::Io(ioerr) => {
ioerr.kind() == io::ErrorKind::NotFound
}
_ => false,
}
}
}
_ => false,
});
// We squash the error in this case, because it occurs in repositories
// that are not linked worktrees but have submodules.
assert!(err.is_none());
wfile(td.path().join("linked-worktree/.git"), "garbage");
let (_, err) = ib.add_child(td.path().join("linked-worktree"));
@@ -1195,6 +1180,6 @@ mod tests {
wfile(td.path().join("linked-worktree/.git"), "gitdir: garbage");
let (_, err) = ib.add_child(td.path().join("linked-worktree"));
assert!(err.is_some());
assert!(err.is_none());
}
}

View File

@@ -46,7 +46,6 @@ See the documentation for `WalkBuilder` for many other options.
#![deny(missing_docs)]
extern crate crossbeam_channel as channel;
extern crate globset;
#[macro_use]
extern crate lazy_static;

View File

@@ -5,10 +5,11 @@ use std::fs::{self, FileType, Metadata};
use std::io;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use std::vec;
use channel::{self, TryRecvError};
use same_file::Handle;
use walkdir::{self, WalkDir};
@@ -364,7 +365,8 @@ impl DirEntryRaw {
})
}
// Placeholder implementation to allow compiling on non-standard platforms (e.g. wasm32).
// Placeholder implementation to allow compiling on non-standard platforms
// (e.g. wasm32).
#[cfg(not(any(windows, unix)))]
fn from_entry_os(
depth: usize,
@@ -413,7 +415,8 @@ impl DirEntryRaw {
})
}
// Placeholder implementation to allow compiling on non-standard platforms (e.g. wasm32).
// Placeholder implementation to allow compiling on non-standard platforms
// (e.g. wasm32).
#[cfg(not(any(windows, unix)))]
fn from_path(
depth: usize,
@@ -486,6 +489,7 @@ pub struct WalkBuilder {
sorter: Option<Sorter>,
threads: usize,
skip: Option<Arc<Handle>>,
filter: Option<Filter>,
}
#[derive(Clone)]
@@ -496,6 +500,9 @@ enum Sorter {
ByPath(Arc<dyn Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static>),
}
#[derive(Clone)]
struct Filter(Arc<dyn Fn(&DirEntry) -> bool + Send + Sync + 'static>);
impl fmt::Debug for WalkBuilder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("WalkBuilder")
@@ -528,6 +535,7 @@ impl WalkBuilder {
sorter: None,
threads: 0,
skip: None,
filter: None,
}
}
@@ -576,6 +584,7 @@ impl WalkBuilder {
ig: ig_root.clone(),
max_filesize: self.max_filesize,
skip: self.skip.clone(),
filter: self.filter.clone(),
}
}
@@ -594,6 +603,7 @@ impl WalkBuilder {
same_file_system: self.same_file_system,
threads: self.threads,
skip: self.skip.clone(),
filter: self.filter.clone(),
}
}
@@ -875,6 +885,23 @@ impl WalkBuilder {
}
self
}
/// Yields only entries which satisfy the given predicate and skips
/// descending into directories that do not satisfy the given predicate.
///
/// The predicate is applied to all entries. If the predicate is
/// true, iteration carries on as normal. If the predicate is false, the
/// entry is ignored and if it is a directory, it is not descended into.
///
/// Note that the errors for reading entries that may not satisfy the
/// predicate will still be yielded.
pub fn filter_entry<P>(&mut self, filter: P) -> &mut WalkBuilder
where
P: Fn(&DirEntry) -> bool + Send + Sync + 'static,
{
self.filter = Some(Filter(Arc::new(filter)));
self
}
}
/// Walk is a recursive directory iterator over file paths in one or more
@@ -890,6 +917,7 @@ pub struct Walk {
ig: Ignore,
max_filesize: Option<u64>,
skip: Option<Arc<Handle>>,
filter: Option<Filter>,
}
impl Walk {
@@ -922,6 +950,11 @@ impl Walk {
&ent.metadata().ok(),
));
}
if let Some(Filter(filter)) = &self.filter {
if !filter(ent) {
return Ok(true);
}
}
Ok(false)
}
}
@@ -1154,6 +1187,7 @@ pub struct WalkParallel {
same_file_system: bool,
threads: usize,
skip: Option<Arc<Handle>>,
filter: Option<Filter>,
}
impl WalkParallel {
@@ -1186,16 +1220,9 @@ impl WalkParallel {
/// can be merged together into a single data structure.
pub fn visit(mut self, builder: &mut dyn ParallelVisitorBuilder) {
let threads = self.threads();
// TODO: Figure out how to use a bounded channel here. With an
// unbounded channel, the workers can run away and fill up memory
// with all of the file paths. But a bounded channel doesn't work since
// our producers are also are consumers, so they end up getting stuck.
//
// We probably need to rethink parallel traversal completely to fix
// this. The best case scenario would be finding a way to use rayon
// to do this.
let (tx, rx) = channel::unbounded();
let stack = Arc::new(Mutex::new(vec![]));
{
let mut stack = stack.lock().unwrap();
let mut visitor = builder.build();
let mut paths = Vec::new().into_iter();
std::mem::swap(&mut paths, &mut self.paths);
@@ -1232,39 +1259,37 @@ impl WalkParallel {
}
}
};
tx.send(Message::Work(Work {
stack.push(Message::Work(Work {
dent: dent,
ignore: self.ig_root.clone(),
root_device: root_device,
}))
.unwrap();
}));
}
// ... but there's no need to start workers if we don't need them.
if tx.is_empty() {
if stack.is_empty() {
return;
}
}
// Create the workers and then wait for them to finish.
let quit_now = Arc::new(AtomicBool::new(false));
let num_pending = Arc::new(AtomicUsize::new(tx.len()));
let num_pending =
Arc::new(AtomicUsize::new(stack.lock().unwrap().len()));
crossbeam_utils::thread::scope(|s| {
let mut handles = vec![];
for _ in 0..threads {
let worker = Worker {
visitor: builder.build(),
tx: tx.clone(),
rx: rx.clone(),
stack: stack.clone(),
quit_now: quit_now.clone(),
num_pending: num_pending.clone(),
max_depth: self.max_depth,
max_filesize: self.max_filesize,
follow_links: self.follow_links,
skip: self.skip.clone(),
filter: self.filter.clone(),
};
handles.push(s.spawn(|_| worker.run()));
}
drop(tx);
drop(rx);
for handle in handles {
handle.join().unwrap();
}
@@ -1362,10 +1387,13 @@ impl Work {
struct Worker<'s> {
/// The caller's callback.
visitor: Box<dyn ParallelVisitor + 's>,
/// The push side of our mpmc queue.
tx: channel::Sender<Message>,
/// The receive side of our mpmc queue.
rx: channel::Receiver<Message>,
/// A stack of work to do.
///
/// We use a stack instead of a channel because a stack lets us visit
/// directories in depth first order. This can substantially reduce peak
/// memory usage by keeping both the number of files path and gitignore
/// matchers in memory lower.
stack: Arc<Mutex<Vec<Message>>>,
/// Whether all workers should terminate at the next opportunity. Note
/// that we need this because we don't want other `Work` to be done after
/// we quit. We wouldn't need this if have a priority channel.
@@ -1384,6 +1412,9 @@ struct Worker<'s> {
/// A file handle to skip, currently is either `None` or stdout, if it's
/// a file and it has been requested to skip files identical to stdout.
skip: Option<Arc<Handle>>,
/// A predicate applied to dir entries. If true, the entry and all
/// children will be skipped.
filter: Option<Filter>,
}
impl<'s> Worker<'s> {
@@ -1538,8 +1569,14 @@ impl<'s> Worker<'s> {
} else {
false
};
if !should_skip_path && !should_skip_filesize {
let should_skip_filtered =
if let Some(Filter(predicate)) = &self.filter {
!predicate(&dent)
} else {
false
};
if !should_skip_path && !should_skip_filesize && !should_skip_filtered
{
self.send(Work { dent, ignore: ig.clone(), root_device });
}
WalkState::Continue
@@ -1550,25 +1587,25 @@ impl<'s> Worker<'s> {
/// If all work has been exhausted, then this returns None. The worker
/// should then subsequently quit.
fn get_work(&mut self) -> Option<Work> {
let mut value = self.rx.try_recv();
let mut value = self.recv();
loop {
// Simulate a priority channel: If quit_now flag is set, we can
// receive only quit messages.
if self.is_quit_now() {
value = Ok(Message::Quit)
value = Some(Message::Quit)
}
match value {
Ok(Message::Work(work)) => {
Some(Message::Work(work)) => {
return Some(work);
}
Ok(Message::Quit) => {
Some(Message::Quit) => {
// Repeat quit message to wake up sleeping threads, if
// any. The domino effect will ensure that every thread
// will quit.
self.tx.send(Message::Quit).unwrap();
self.send_quit();
return None;
}
Err(TryRecvError::Empty) => {
None => {
// Once num_pending reaches 0, it is impossible for it to
// ever increase again. Namely, it only reaches 0 once
// all jobs have run such that no jobs have produced more
@@ -1580,17 +1617,21 @@ impl<'s> Worker<'s> {
if self.num_pending() == 0 {
// Every other thread is blocked at the next recv().
// Send the initial quit message and quit.
self.tx.send(Message::Quit).unwrap();
self.send_quit();
return None;
}
// Wait for next `Work` or `Quit` message.
value = Ok(self
.rx
.recv()
.expect("channel disconnected while worker is alive"));
}
Err(TryRecvError::Disconnected) => {
unreachable!("channel disconnected while worker is alive");
loop {
if let Some(v) = self.recv() {
value = Some(v);
break;
}
// Our stack isn't blocking. Instead of burning the
// CPU waiting, we let the thread sleep for a bit. In
// general, this tends to only occur once the search is
// approaching termination.
thread::sleep(Duration::from_millis(1));
}
}
}
}
@@ -1614,7 +1655,20 @@ impl<'s> Worker<'s> {
/// Send work.
fn send(&self, work: Work) {
self.num_pending.fetch_add(1, Ordering::SeqCst);
self.tx.send(Message::Work(work)).unwrap();
let mut stack = self.stack.lock().unwrap();
stack.push(Message::Work(work));
}
/// Send a quit message.
fn send_quit(&self) {
let mut stack = self.stack.lock().unwrap();
stack.push(Message::Quit);
}
/// Receive work.
fn recv(&self) -> Option<Message> {
let mut stack = self.stack.lock().unwrap();
stack.pop()
}
/// Signal that work has been received.
@@ -1780,6 +1834,7 @@ fn device_num<P: AsRef<Path>>(_: P) -> io::Result<u64> {
#[cfg(test)]
mod tests {
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
@@ -2161,4 +2216,26 @@ mod tests {
let builder = WalkBuilder::new(&dir_path);
assert_paths(dir_path.parent().unwrap(), &builder, &["root"]);
}
#[test]
fn filter() {
let td = tmpdir();
mkdirp(td.path().join("a/b/c"));
mkdirp(td.path().join("x/y"));
wfile(td.path().join("a/b/foo"), "");
wfile(td.path().join("x/y/foo"), "");
assert_paths(
td.path(),
&WalkBuilder::new(td.path()),
&["x", "x/y", "x/y/foo", "a", "a/b", "a/b/foo", "a/b/c"],
);
assert_paths(
td.path(),
&WalkBuilder::new(td.path())
.filter_entry(|entry| entry.file_name() != OsStr::new("a")),
&["x", "x/y", "x/y/foo"],
);
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "grep-printer"
version = "0.1.4" #:version
version = "0.1.5" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
An implementation of the grep crate's Sink trait that provides standard
@@ -18,7 +18,7 @@ default = ["serde1"]
serde1 = ["base64", "serde", "serde_derive", "serde_json"]
[dependencies]
base64 = { version = "0.11.0", optional = true }
base64 = { version = "0.12.1", optional = true }
bstr = "0.2.0"
grep-matcher = { version = "0.1.2", path = "../matcher" }
grep-searcher = { version = "0.1.4", path = "../searcher" }

View File

@@ -591,6 +591,19 @@ impl<'p, 's, M: Matcher, W: WriteColor> Sink for SummarySink<'p, 's, M, W> {
true
})
.map_err(io::Error::error_message)?;
if match_count == 0 {
// It is possible for the match count to be zero when
// look-around is used. Since `SinkMatch` won't necessarily
// contain the look-around in its match span, the search here
// could fail to find anything.
//
// It seems likely that setting match_count=1 here is probably
// wrong in some cases, but I don't think we can do any
// better. (Because this printer cannot assume that subsequent
// contents have been loaded into memory, so we have no way of
// increasing the search span here.)
match_count = 1;
}
stats.add_matches(match_count);
stats.add_matched_lines(mat.lines().count() as u64);
} else if self.summary.config.kind.quit_early() {

View File

@@ -1,6 +1,6 @@
[package]
name = "grep-regex"
version = "0.1.6" #:version
version = "0.1.8" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """
Use Rust's regex library with the 'grep' crate.

View File

@@ -141,6 +141,9 @@ impl LiteralSets {
// (Not in theory---it could be better. But the current
// implementation isn't good enough.) ... So we make up for it
// here.
if !word {
return None;
}
let p_min_len = self.prefixes.min_len();
let s_min_len = self.suffixes.min_len();
let lits = match (p_min_len, s_min_len) {
@@ -323,12 +326,12 @@ fn is_simple(expr: &Hir) -> bool {
HirKind::Empty
| HirKind::Literal(_)
| HirKind::Class(_)
| HirKind::Repetition(_)
| HirKind::Concat(_)
| HirKind::Alternation(_) => true,
HirKind::Anchor(_) | HirKind::WordBoundary(_) | HirKind::Group(_) => {
false
}
HirKind::Anchor(_)
| HirKind::WordBoundary(_)
| HirKind::Group(_)
| HirKind::Repetition(_) => false,
}
}
@@ -409,8 +412,17 @@ mod tests {
// https://github.com/BurntSushi/ripgrep/issues/1319
assert_eq!(
one_regex(r"TTGAGTCCAGGAG[ATCG]{2}C"),
pat("TTGAGTCCAGGAGA|TTGAGTCCAGGAGC|\
TTGAGTCCAGGAGG|TTGAGTCCAGGAGT")
pat("TTGAGTCCAGGAG"),
);
}
#[test]
fn regression_1537() {
// Regression from:
// https://github.com/BurntSushi/ripgrep/issues/1537
assert_eq!(one_regex(r";(.*,)"), pat(";"));
assert_eq!(one_regex(r";((.*,))"), pat(";"));
assert_eq!(one_regex(r";(.*,)+"), pat(";"),);
assert_eq!(one_regex(r";(.*,){1}"), pat(";"),);
}
}

View File

@@ -75,8 +75,9 @@ _PATTERN_::
dash, use the -e/--regexp option.
_PATH_::
A file or directory to search. Directories are searched recursively. Paths
specified explicitly on the command line override glob and ignore rules.
A file or directory to search. Directories are searched recursively. File
paths specified explicitly on the command line override glob and ignore
rules.
OPTIONS

View File

@@ -1,14 +1,14 @@
class RipgrepBin < Formula
version '11.0.2'
version '12.1.0'
desc "Recursively search directories for a regex pattern."
homepage "https://github.com/BurntSushi/ripgrep"
if OS.mac?
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
sha256 "0ba26423691deedf2649b12b1abe3d2be294ee1cb17c40b68fe85efe194f4f57"
sha256 "974351ca7d00083ba2fad52e2f2539c8ff114119c139420f592507962ab43b75"
elsif OS.linux?
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
sha256 "2e7978e346553fbc45c0940d9fa11e12f9afbae8213b261aad19b698150e169a"
sha256 "c6bba6d643b1a1f18994683e26d4d2b998b41a7a7360e63cb8ec9db8ffbf793c"
end
conflicts_with "ripgrep"
@@ -18,7 +18,6 @@ class RipgrepBin < Formula
man1.install "doc/rg.1"
bash_completion.install "complete/rg.bash"
fish_completion.install "complete/rg.fish"
zsh_completion.install "complete/_rg"
end
end

View File

@@ -1,15 +0,0 @@
name: ripgrep # you probably want to 'snapcraft register <name>'
version: '0.8.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Fast file searcher # 79 char long summary
description: |
ripgrep combines the usability of The Silver Searcher with the raw speed of grep.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: classic # use 'strict' once you have the right plugs and slots
parts:
ripgrep:
plugin: rust
source: .
apps:
rg:
adapter: none
command: ./bin/rg

BIN
tests/data/sherlock.Z Normal file

Binary file not shown.

View File

@@ -511,7 +511,7 @@ rgtest!(context_line_numbers, |dir: Dir, mut cmd: TestCommand| {
eqnice!(expected, cmd.stdout());
});
rgtest!(max_filesize_parse_errro_length, |_: Dir, mut cmd: TestCommand| {
rgtest!(max_filesize_parse_error_length, |_: Dir, mut cmd: TestCommand| {
cmd.arg("--max-filesize").arg("44444444444444444444");
cmd.assert_non_empty_stderr();
});
@@ -970,6 +970,21 @@ be, to a very large extent, the result of luck. Sherlock Holmes
eqnice!(expected, cmd.stdout());
});
rgtest!(compressed_uncompress, |dir: Dir, mut cmd: TestCommand| {
if !cmd_exists("uncompress") {
return;
}
dir.create_bytes("sherlock.Z", include_bytes!("./data/sherlock.Z"));
cmd.arg("-z").arg("Sherlock").arg("sherlock.Z");
let expected = "\
For the Doctor Watsons of this world, as opposed to the Sherlock
be, to a very large extent, the result of luck. Sherlock Holmes
";
eqnice!(expected, cmd.stdout());
});
rgtest!(compressed_failing_gzip, |dir: Dir, mut cmd: TestCommand| {
if !cmd_exists("gzip") {
return;

View File

@@ -791,3 +791,76 @@ rgtest!(
eqnice!("repotree/not-ignored\n", cmd.stdout());
}
);
// See: https://github.com/BurntSushi/ripgrep/issues/1537
rgtest!(r1537, |dir: Dir, mut cmd: TestCommand| {
dir.create("foo", "abc;de,fg");
let expected = "foo:abc;de,fg\n";
eqnice!(expected, cmd.arg(";(.*,){1}").stdout());
});
// See: https://github.com/BurntSushi/ripgrep/issues/1559
rgtest!(r1559, |dir: Dir, mut cmd: TestCommand| {
dir.create(
"foo",
"\
type A struct {
TaskID int `json:\"taskID\"`
}
type B struct {
ObjectID string `json:\"objectID\"`
TaskID int `json:\"taskID\"`
}
",
);
let expected = "\
foo: TaskID int `json:\"taskID\"`
foo: TaskID int `json:\"taskID\"`
";
eqnice!(expected, cmd.arg("TaskID +int").stdout());
});
// See: https://github.com/BurntSushi/ripgrep/issues/1573
//
// Tests that if look-ahead is used, then --count-matches is correct.
rgtest!(r1573, |dir: Dir, mut cmd: TestCommand| {
// Only PCRE2 supports look-ahead.
if !dir.is_pcre2() {
return;
}
dir.create_bytes("foo", b"\xFF\xFE\x00\x62");
dir.create(
"foo",
"\
def A;
def B;
use A;
use B;
",
);
// Check that normal --count is correct.
cmd.args(&[
"--pcre2",
"--multiline",
"--count",
r"(?s)def (\w+);(?=.*use \w+)",
"foo",
]);
eqnice!("2\n", cmd.stdout());
// Now check --count-matches.
let mut cmd = dir.command();
cmd.args(&[
"--pcre2",
"--multiline",
"--count-matches",
r"(?s)def (\w+);(?=.*use \w+)",
"foo",
]);
eqnice!("2\n", cmd.stdout());
});