mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-07-27 10:11:58 -07:00
Compare commits
51 Commits
ignore-0.4
...
grep-regex
Author | SHA1 | Date | |
---|---|---|---|
|
c0f0492b98 | ||
|
568018386b | ||
|
6219d29c24 | ||
|
b458cf39f2 | ||
|
3fd2694fbc | ||
|
b56315ea84 | ||
|
fac47906e6 | ||
|
e02bb6b99a | ||
|
16a1221fc7 | ||
|
793c1179cc | ||
|
df7a3bfc7f | ||
|
28f2a93cae | ||
|
0eb2501b6e | ||
|
184c15882e | ||
|
64a4dee495 | ||
|
50840ea43b | ||
|
17dcc2bf51 | ||
|
9a858e4909 | ||
|
cbfbe9312f | ||
|
7ed9a31819 | ||
|
a2e6aec7a4 | ||
|
73103df6d9 | ||
|
139f186e57 | ||
|
afb325f733 | ||
|
40af352d74 | ||
|
3f1d4b397d | ||
|
a75b4d122a | ||
|
f51b762c6d | ||
|
49de7b119c | ||
|
1c4b5adb7b | ||
|
3d6a58faff | ||
|
5b6ca04e39 | ||
|
47f20c2661 | ||
|
1d5b1011e5 | ||
|
1bb30b72fc | ||
|
09a4b75baf | ||
|
58c428827d | ||
|
b9bb04b793 | ||
|
4dfea016b9 | ||
|
3193d57ac1 | ||
|
67c0f576b6 | ||
|
543f99dbf1 | ||
|
0ea65efd6d | ||
|
20deae6497 | ||
|
655e33219a | ||
|
8ba6ccd159 | ||
|
34edb8123a | ||
|
5b30c2aed6 | ||
|
bf1027a83e | ||
|
031264e5fb | ||
|
b9cd95faf1 |
@@ -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
6
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal 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
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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.
|
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@@ -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:
|
||||
|
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
|
53
CHANGELOG.md
53
CHANGELOG.md
@@ -1,3 +1,56 @@
|
||||
TBD
|
||||
===
|
||||
ripgrep 12.1.0 is a small minor version release that mostly includes bug fixes
|
||||
and documentation improvements.
|
||||
|
||||
**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
|
||||
|
154
Cargo.lock
generated
154
Cargo.lock
generated
@@ -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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.69 (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]]
|
||||
@@ -55,7 +55,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.50"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -135,9 +135,9 @@ dependencies = [
|
||||
"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.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -148,7 +148,7 @@ dependencies = [
|
||||
"grep-matcher 0.1.4",
|
||||
"grep-pcre2 0.1.4",
|
||||
"grep-printer 0.1.4",
|
||||
"grep-regex 0.1.6",
|
||||
"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)",
|
||||
@@ -163,10 +163,10 @@ dependencies = [
|
||||
"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.7 (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.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -189,26 +189,26 @@ dependencies = [
|
||||
name = "grep-printer"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"base64 0.11.0 (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.12 (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.107 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.52 (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)",
|
||||
"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 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -222,23 +222,23 @@ dependencies = [
|
||||
"encoding_rs 0.8.22 (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.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.8"
|
||||
version = "0.1.12"
|
||||
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.69 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.12"
|
||||
version = "0.4.15"
|
||||
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.7 (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.52 (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.69 (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.69 (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.69"
|
||||
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.69 (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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.69 (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.69 (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.52 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.69 (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.12"
|
||||
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,15 +367,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.3.5"
|
||||
version = "1.3.7"
|
||||
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)",
|
||||
@@ -399,27 +399,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ripgrep"
|
||||
version = "12.0.0"
|
||||
version = "12.0.1"
|
||||
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",
|
||||
"ignore 0.4.15",
|
||||
"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.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.52 (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.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.104"
|
||||
version = "1.0.107"
|
||||
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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.48"
|
||||
version = "1.0.52"
|
||||
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.107 (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.19"
|
||||
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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.4 (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,12 +545,12 @@ 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 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.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
|
||||
"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 crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
|
||||
@@ -560,33 +560,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"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.12 (registry+https://github.com/rust-lang/crates.io-index)" = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
|
||||
"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.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
|
||||
"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.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319"
|
||||
"checksum quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7"
|
||||
"checksum regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
|
||||
"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 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.107 (registry+https://github.com/rust-lang/crates.io-index)" = "eba7550f2cdf88ffc23ab0f1607133486c390a8c0f89b57e589b9654ee15e04d"
|
||||
"checksum serde_derive 1.0.107 (registry+https://github.com/rust-lang/crates.io-index)" = "10be45e22e5597d4b88afcc71f9d7bfadcd604bf0c78a3ab4582b8d2b37f39f3"
|
||||
"checksum serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd"
|
||||
"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.19 (registry+https://github.com/rust-lang/crates.io-index)" = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7"
|
||||
"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"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ripgrep"
|
||||
version = "12.0.0" #:version
|
||||
version = "12.0.1" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
ripgrep is a line-oriented search tool that recursively searches your current
|
||||
@@ -20,8 +20,8 @@ autotests = false
|
||||
edition = "2018"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "BurntSushi/ripgrep" }
|
||||
appveyor = { repository = "BurntSushi/ripgrep" }
|
||||
# I guess crates.io does not support GitHub Action badges yet.
|
||||
# Tracking PR: https://github.com/rust-lang/crates.io/pull/1838
|
||||
|
||||
[[bin]]
|
||||
bench = false
|
||||
|
7
FAQ.md
7
FAQ.md
@@ -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
208
GUIDE.md
@@ -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.
|
||||
|
@@ -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.
|
||||
|
21
RELEASE-CHECKLIST.md
Normal file
21
RELEASE-CHECKLIST.md
Normal file
@@ -0,0 +1,21 @@
|
||||
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.
|
||||
* 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.
|
||||
* Create a new signed tag for the ripgrep release. Push it to GitHub.
|
||||
* 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.
|
||||
* Run `ci/build-deb` locally and manually upload the deb package to the
|
||||
release.
|
||||
* Run `cargo publish`.
|
||||
* Run `ci/sha256-releases >> pkg/brew/ripgrep-bin.rb`. Then edit
|
||||
`pkg/brew/ripgrep-bin.rb` to update the version numbers and sha256 hashes.
|
||||
Remove extraneous stuff added by `ci/sha256-releases`. Commit changes.
|
45
build.rs
45
build.rs
@@ -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("{", "{").replace("}", "}");
|
||||
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.");
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
brew install asciidoc docbook-xsl
|
||||
brew install asciidoctor
|
||||
|
@@ -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
|
||||
|
@@ -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),
|
||||
]
|
||||
}
|
||||
|
@@ -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 }
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -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")
|
||||
@@ -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).
|
||||
@@ -2598,6 +2581,8 @@ 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 +2862,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 +2900,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")
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ignore"
|
||||
version = "0.4.12" #:version
|
||||
version = "0.4.15" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
A fast library for efficiently matching ignore files such as `.gitignore`
|
||||
@@ -18,7 +18,6 @@ name = "ignore"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
crossbeam-channel = "0.4.0"
|
||||
crossbeam-utils = "0.7.0"
|
||||
globset = { version = "0.4.3", path = "../globset" }
|
||||
lazy_static = "1.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"]
|
||||
|
@@ -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"]),
|
||||
@@ -233,6 +234,7 @@ pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
|
||||
("xz", &["*.xz", "*.txz"]),
|
||||
("yacc", &["*.y"]),
|
||||
("yaml", &["*.yaml", "*.yml"]),
|
||||
("z", &["*.Z"]),
|
||||
("zig", &["*.zig"]),
|
||||
("zsh", &[
|
||||
".zshenv", "zshenv",
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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"],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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" }
|
||||
|
@@ -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() {
|
||||
|
@@ -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.
|
||||
|
@@ -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(";"),);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -1,14 +1,14 @@
|
||||
class RipgrepBin < Formula
|
||||
version '11.0.2'
|
||||
version '12.0.1'
|
||||
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 "59e78931a7577e76f40c937cae2782f2bbdcb40f056df5dd84247a671373525d"
|
||||
elsif OS.linux?
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
|
||||
sha256 "2e7978e346553fbc45c0940d9fa11e12f9afbae8213b261aad19b698150e169a"
|
||||
sha256 "2dbd6e0cef8048f26ea9f0d6b5412f117645001c5cec267b3bcd4716a64a7a7a"
|
||||
end
|
||||
|
||||
conflicts_with "ripgrep"
|
||||
|
@@ -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
BIN
tests/data/sherlock.Z
Normal file
Binary file not shown.
@@ -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;
|
||||
|
@@ -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());
|
||||
});
|
||||
|
Reference in New Issue
Block a user