Compare commits

..

19 Commits

Author SHA1 Message Date
Andrew Gallant
535cd0d312 ci: switch to GitHub Actions 2019-08-31 09:04:09 -04:00
Andrew Gallant
5011dba2fd ignore: remove unused parameter 2019-08-28 20:21:34 -04:00
Andrew Gallant
e14f9195e5 deps: update everything 2019-08-28 20:18:47 -04:00
Andrew Gallant
ef0e7af56a deps: update bstr to 0.2.7
The new bstr release contains a small performance bug fix where some
trivial methods weren't being inlined.
2019-08-11 10:41:05 -04:00
Todd Walton
b266818aa5 doc: use XDG_CONFIG_HOME in comments
XDG_CONFIG_DIR does not actually exist.

PR #1347
2019-08-09 13:37:37 -04:00
LawAbidingCactus
81415ae52d doc: update to reflect glob matching behavior change
Specifically, paths contains a `/` are not allowed to match any
other slash in the path, even as a prefix. So `!.git` is the correct
incantation for ignoring a `.git` directory that occurs anywhere 
in the path.
2019-08-07 13:47:18 -04:00
Andrew Gallant
5c4584aa7c grep-regex-0.1.5 2019-08-06 09:51:13 -04:00
Andrew Gallant
0972c6e7c7 grep-searcher-0.1.6 2019-08-06 09:50:52 -04:00
Andrew Gallant
0a372bf2e4 deps: update ignore 2019-08-06 09:50:35 -04:00
Andrew Gallant
345124a7fa ignore-0.4.10 2019-08-06 09:47:45 -04:00
Andrew Gallant
31807f805a deps: drop tempfile
We were only using it to create temporary directories for `ignore`
tests, but it pulls in a bunch of dependencies and we don't really need
randomness. So just use our own simple wrapper instead.
2019-08-06 09:46:05 -04:00
Andrew Gallant
4de227fd9a deps: update everything
Mostly this just updates regex and its assorted dependencies. This does
drop utf8-ranges and ucd-util, in accordance with changes to
regex-syntax and regex.
2019-08-05 13:50:55 -04:00
jimbo1qaz
d7ce274722 readme: Debian Buster is stable now
PR #1338
2019-08-04 08:06:10 -04:00
Andrew Gallant
5b10328f41 changelog: update with bug fix 2019-08-02 07:37:27 -04:00
Andrew Gallant
813c676eca searcher: fix roll buffer bug
This commit fixes a subtle bug in how the line buffer was rolling its
contents. Specifically, when ripgrep searches without memory maps,
it uses a "roll" buffer for incremental line oriented search without
needing to read the entire file into memory at once. The roll buffer
works by reading a chunk of bytes from the file into memory, and then
searching everything in that buffer up to the last `\n` byte. The bytes
*after* the last `\n` byte are preserved, since they likely correspond
to *part* of the next line. Once ripgrep is done searching the buffer,
it "rolls" the buffer such that the start of the next line is at the
beginning of the buffer, and then ripgrep reads more data into the
buffer starting at the (possibly) partial end of that line.

The implication of this strategy, necessarily so, is that a buffer must
be big enough to fit a single line in memory. This is because the regex
engine needs a contiguous block of memory to search, so there is no way
to search anything smaller than a single line. So if a file contains a
single line with 7.5 million bytes, then the buffer will grow to be at
least that size. (Many files have super long lines like this, but they
tend to be *binary* files, which ripgrep will detect and stop searching
unless the user forces it with the `-a/--text` flag. So in practice,
they aren't usually a problem. However, in this case, #1335 found a case
where a plain text file had a line with 7.5 million bytes.)

Now, for performance reasons, ripgrep reuses these buffers across its
search. Typically, it will create `N` of these line buffers when it
starts (where `N` is the number of threads it is using), and then reuse
them without creating any new ones as it searches through files.

This means that if you search a file with a very long line, that buffer
will expand to be big enough to store that line. ripgrep never contracts
these buffers, so once it searches the next file, ripgrep will continue
to use this large buffer. While it might be prudent to contract these
buffers in some circumstances, this isn't otherwise inherently a
problem. The memory has already been allocated, and there isn't much
cost to using it, other than the fact that ripgrep hangs on to it and
never gives it back to the OS.

However, the `roll` implementation described above had a really
important bug in it that was impacted by the size of the buffer.
Specifically, it used the following to "roll" the partial line at the
end of the buffer to the beginning:

    self.buf.copy_within_str(self.pos.., 0);

Which means that if the buffer is very large, ripgrep will copy
*everything* from `self.pos` (which might be very small, e.g., for small
files) to the end of the buffer, and move it to the beginning of the
buffer. This will happen repeatedly each time the buffer is used to
search small files, which winds up being quite a large slow down if the
line was exceptionally large (say, megabytes).

It turns out that copying everything is completely unnecessary. We only
need to copy the remainder of the last read to the beginning of the
buffer. Everything *after* the last read in the buffer is just free
space that can be filled for the next read. So, all we need to do is
copy just those bytes:

    self.buf.copy_within_str(self.pos..self.end, 0);

... which is typically much much smaller than the rest of the buffer.

This was likely also causing small performance losses in other cases as
well. For example, when searching a lot of small files, ripgrep would
likely do a lot more copying than necessary. Although, given that the
default buffer size is 8KB, this extra copying was likely pretty small,
and was thus harder to observe.

Fixes #1335
2019-08-02 07:23:27 -04:00
Andrew Gallant
f625d72b6f pkg: update brew tap to 11.0.2 2019-08-01 19:39:53 -04:00
Andrew Gallant
3de31f7527 ci: fix musl deployment
The docker image that the Linux binary is now built in does not have
ASCII doc installed, so setup Cross to point to my own image with those
tools installed.
2019-08-01 18:41:44 -04:00
Andrew Gallant
e402d6c260 ripgrep: release 11.0.2 2019-08-01 18:02:15 -04:00
Andrew Gallant
48b5bdc441 src: remove old directories
termcolor has had its own repository for a while now. No need for these
redirects any more.
2019-08-01 17:49:28 -04:00
21 changed files with 667 additions and 632 deletions

98
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,98 @@
name: ci
on:
pull_request:
push:
branches:
- master
schedule:
cron: '00 01 * * *'
jobs:
test:
name: test
runs-on: ${{ matrix.os }}
strategy:
matrix:
# The docs seem to suggest that we can have a matrix with just an
# include directive, but it result in a "matrix must define at least
# one vector" error in the CI system.
build:
- pinned-glibc
- pinned-musl
- stable
- beta
# We test musl with nightly because every once in a while, this will
# catch an upstream regression.
- nightly-glibc
- nightly-musl
- macos
- win-msvc-32
- win-msvc-64
- win-gnu-32
- win-gnu-64
include:
# - build: pinned-glibc
# os: ubuntu-18.04
# rust: 1.34.0
# target: x86_64-unknown-linux-gnu
- build: pinned-musl
os: ubuntu-18.04
rust: 1.34.0
target: x86_64-unknown-linux-musl
- build: stable
os: ubuntu-18.04
rust: stable
target: x86_64-unknown-linux-gnu
# - build: beta
# os: ubuntu-18.04
# rust: beta
# target: x86_64-unknown-linux-gnu
# - build: nightly-glibc
# os: ubuntu-18.04
# rust: nightly
# target: x86_64-unknown-linux-gnu
# - build: nightly-musl
# os: ubuntu-18.04
# rust: nightly
# target: x86_64-unknown-linux-musl
# - build: macos
# os: macOS-10.14
# rust: stable
# target: x86_64-apple-darwin
# - build: win-msvc-32
# os: windows-2019
# rust: stable
# target: i686-pc-windows-msvc
# - build: win-msvc-64
# os: windows-2019
# rust: stable
# target: x86_64-pc-windows-msvc
# - build: win-gnu-32
# os: windows-2019
# rust: stable-i686-gnu
# target: i686-pc-windows-gnu
# - build: win-gnu-64
# os: windows-2019
# rust: stable-x86_64-gnu
# target: x86_64-pc-windows-gnu
steps:
- name: Checkout repository
uses: actions/checkout@v1
with:
fetch-depth: 1
- name: Install Rust
uses: hecrj/setup-rust-action@v1
with:
rust-version: ${{ matrix.rust }}
- name: Install Rust Target
run: rustup target add ${{ matrix.target }}
- name: Install musl-gcc
if: contains(matrix.target, 'musl')
run: |
apt-get install musl-tools
- name: Build everything
run: cargo build --verbose --target ${{ matrix.target }} --all --features pcre2
- name: Test zsh auto-completions
if: matrix.build == 'stable'
run: ./ci/test_complete.sh
- name: Run tests
run: cargo test --verbose --target ${{ matrix.target }} --all --features pcre2

View File

@@ -1,3 +1,13 @@
TBD
===
TODO
Bug fixes:
* [BUG #1335](https://github.com/BurntSushi/ripgrep/issues/1335):
Fixes a performance bug when searching plain text files with very long lines.
11.0.2 (2019-08-01) 11.0.2 (2019-08-01)
=================== ===================
ripgrep 11.0.2 is a new patch release that fixes a few bugs, including a ripgrep 11.0.2 is a new patch release that fixes a few bugs, including a

304
Cargo.lock generated
View File

@@ -2,7 +2,7 @@
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.4" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -13,8 +13,8 @@ name = "atty"
version = "0.2.13" version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -32,10 +32,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "0.2.6" version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.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)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -50,18 +50,9 @@ name = "byteorder"
version = "1.3.2" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "c2-chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.38" version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@@ -77,7 +68,7 @@ dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -94,7 +85,7 @@ version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.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)",
] ]
[[package]] [[package]]
@@ -124,15 +115,6 @@ name = "fs_extra"
version = "1.1.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getrandom"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.0" version = "0.3.0"
@@ -142,12 +124,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "globset" name = "globset"
version = "0.4.4" version = "0.4.4"
dependencies = [ dependencies = [
"aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -158,8 +140,8 @@ dependencies = [
"grep-matcher 0.1.3", "grep-matcher 0.1.3",
"grep-pcre2 0.1.3", "grep-pcre2 0.1.3",
"grep-printer 0.1.3", "grep-printer 0.1.3",
"grep-regex 0.1.4", "grep-regex 0.1.5",
"grep-searcher 0.1.5", "grep-searcher 0.1.6",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -169,11 +151,11 @@ name = "grep-cli"
version = "0.1.3" version = "0.1.3"
dependencies = [ dependencies = [
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.4.4", "globset 0.4.4",
"lazy_static 1.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)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -184,7 +166,7 @@ name = "grep-matcher"
version = "0.1.3" version = "0.1.3"
dependencies = [ dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -200,56 +182,54 @@ name = "grep-printer"
version = "0.1.3" version = "0.1.3"
dependencies = [ dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.3", "grep-matcher 0.1.3",
"grep-regex 0.1.4", "grep-regex 0.1.5",
"grep-searcher 0.1.5", "grep-searcher 0.1.6",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "grep-regex" name = "grep-regex"
version = "0.1.4" version = "0.1.5"
dependencies = [ dependencies = [
"aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.3", "grep-matcher 0.1.3",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "grep-searcher" name = "grep-searcher"
version = "0.1.5" version = "0.1.6"
dependencies = [ dependencies = [
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding_rs_io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs_io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"grep-matcher 0.1.3", "grep-matcher 0.1.3",
"grep-regex 0.1.4", "grep-regex 0.1.5",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "ignore" name = "ignore"
version = "0.4.9" version = "0.4.10"
dependencies = [ dependencies = [
"crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.4.4", "globset 0.4.4",
"lazy_static 1.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)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -265,9 +245,9 @@ name = "jemalloc-sys"
version = "0.3.2" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (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.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -276,17 +256,17 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.3.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.60" version = "0.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@@ -307,8 +287,8 @@ name = "memmap"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -316,7 +296,7 @@ name = "num_cpus"
version = "1.10.1" version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -332,7 +312,7 @@ name = "pcre2"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (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)", "pcre2-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -343,8 +323,8 @@ name = "pcre2-sys"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -353,79 +333,31 @@ name = "pkg-config"
version = "0.3.15" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "0.4.30" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "0.6.13" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "rand"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.2.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -438,35 +370,24 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.10" version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ripgrep" name = "ripgrep"
version = "11.0.1" version = "11.0.2"
dependencies = [ dependencies = [
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (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.4", "grep 0.2.4",
"ignore 0.4.9", "ignore 0.4.10",
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.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)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@@ -486,17 +407,17 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.98" version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.98" version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -506,7 +427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -516,25 +437,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.42" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -542,7 +450,7 @@ name = "termcolor"
version = "1.0.5" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -550,7 +458,7 @@ name = "textwrap"
version = "0.11.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -558,27 +466,17 @@ name = "thread_local"
version = "0.3.6" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.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)",
] ]
[[package]]
name = "ucd-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.5" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.1.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "utf8-ranges"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@@ -587,13 +485,13 @@ version = "2.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.7" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -610,7 +508,7 @@ name = "winapi-util"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -620,23 +518,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "wincolor" name = "wincolor"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"winapi 0.3.7 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[metadata] [metadata]
"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a" "checksum bstr 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94cdf78eb7e94c566c1f5dbe2abf8fc70a548fc902942a48c4b3a98b48ca9ade"
"checksum bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be0fdd54b507df8f22012890aadd099979befdba27713c767993f8380112ca7c" "checksum bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be0fdd54b507df8f22012890aadd099979befdba27713c767993f8380112ca7c"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa"
@@ -645,13 +542,12 @@ dependencies = [
"checksum encoding_rs_io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9619ee7a2bf4e777e020b95c1439abaf008f8ea8041b78a0552c4f1bcf4df32c" "checksum encoding_rs_io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9619ee7a2bf4e777e020b95c1439abaf008f8ea8041b78a0552c4f1bcf4df32c"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "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 fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
"checksum getrandom 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8e190892c840661957ba9f32dacfb3eb405e657f9f9f60485605f0bb37d6f8"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum jemalloc-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45" "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 jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
@@ -660,36 +556,26 @@ dependencies = [
"checksum pcre2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "603da5e101220b9b306bf28e4f1f8703458ce2f64d2787b374e1a19494317180" "checksum pcre2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "603da5e101220b9b306bf28e4f1f8703458ce2f64d2787b374e1a19494317180"
"checksum pcre2-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876c72d05059d23a84bd9fcdc3b1d31c50ea7fe00fe1522b4e68cd3608db8d5b" "checksum pcre2-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876c72d05059d23a84bd9fcdc3b1d31c50ea7fe00fe1522b4e68cd3608db8d5b"
"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" "checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26"
"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" "checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113" "checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c" "checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "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-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9"

View File

@@ -1,11 +1,11 @@
[package] [package]
name = "ripgrep" name = "ripgrep"
version = "11.0.1" #:version version = "11.0.2" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
ripgrep is a line-oriented search tool that recursively searches your current ripgrep is a line-oriented search tool that recursively searches your current
directory for a regex pattern while respecting your gitignore rules. ripgrep directory for a regex pattern while respecting your gitignore rules. ripgrep
has first class support on Windows, macOS and Linux has first class support on Windows, macOS and Linux.
""" """
documentation = "https://github.com/BurntSushi/ripgrep" documentation = "https://github.com/BurntSushi/ripgrep"
homepage = "https://github.com/BurntSushi/ripgrep" homepage = "https://github.com/BurntSushi/ripgrep"

2
Cross.toml Normal file
View File

@@ -0,0 +1,2 @@
[target.x86_64-unknown-linux-musl]
image = "burntsushi/x86_64-unknown-linux-musl:v0.1.14"

View File

@@ -288,11 +288,11 @@ then ripgrep can be installed using a binary `.deb` file provided in each
[ripgrep release](https://github.com/BurntSushi/ripgrep/releases). [ripgrep release](https://github.com/BurntSushi/ripgrep/releases).
``` ```
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/11.0.1/ripgrep_11.0.1_amd64.deb $ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/11.0.2/ripgrep_11.0.2_amd64.deb
$ sudo dpkg -i ripgrep_11.0.1_amd64.deb $ sudo dpkg -i ripgrep_11.0.2_amd64.deb
``` ```
If you run Debian Buster (currently Debian testing) or Debian sid, ripgrep is If you run Debian Buster (currently Debian stable) or Debian sid, ripgrep is
[officially maintained by Debian](https://tracker.debian.org/pkg/rust-ripgrep). [officially maintained by Debian](https://tracker.debian.org/pkg/rust-ripgrep).
``` ```
$ sudo apt-get install ripgrep $ sudo apt-get install ripgrep

View File

@@ -0,0 +1,5 @@
FROM japaric/x86_64-unknown-linux-musl:v0.1.14
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libxslt1-dev asciidoc docbook-xsl xsltproc libxml2-utils

View File

@@ -143,16 +143,16 @@ would behave identically to the following command
same with using globs same with using globs
--glob=!git/* --glob=!.git
or or
--glob --glob
!git/* !.git
would behave identically to the following command would behave identically to the following command
rg --glob '!git/*' foo rg --glob '!.git' foo
ripgrep also provides a flag, *--no-config*, that when present will suppress ripgrep also provides a flag, *--no-config*, that when present will suppress
any and all support for configuration. This includes any future support any and all support for configuration. This includes any future support

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "grep-regex" name = "grep-regex"
version = "0.1.4" #:version version = "0.1.5" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
Use Rust's regex library with the 'grep' crate. Use Rust's regex library with the 'grep' crate.
@@ -19,4 +19,3 @@ log = "0.4.5"
regex = "1.1" regex = "1.1"
regex-syntax = "0.6.5" regex-syntax = "0.6.5"
thread_local = "0.3.6" thread_local = "0.3.6"
utf8-ranges = "1.0.1"

View File

@@ -11,7 +11,6 @@ extern crate log;
extern crate regex; extern crate regex;
extern crate regex_syntax; extern crate regex_syntax;
extern crate thread_local; extern crate thread_local;
extern crate utf8_ranges;
pub use error::{Error, ErrorKind}; pub use error::{Error, ErrorKind};
pub use matcher::{RegexCaptures, RegexMatcher, RegexMatcherBuilder}; pub use matcher::{RegexCaptures, RegexMatcher, RegexMatcherBuilder};

View File

@@ -1,6 +1,6 @@
use grep_matcher::ByteSet; use grep_matcher::ByteSet;
use regex_syntax::hir::{self, Hir, HirKind}; use regex_syntax::hir::{self, Hir, HirKind};
use utf8_ranges::Utf8Sequences; use regex_syntax::utf8::Utf8Sequences;
/// Return a confirmed set of non-matching bytes from the given expression. /// Return a confirmed set of non-matching bytes from the given expression.
pub fn non_matching_bytes(expr: &Hir) -> ByteSet { pub fn non_matching_bytes(expr: &Hir) -> ByteSet {

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "grep-searcher" name = "grep-searcher"
version = "0.1.5" #:version version = "0.1.6" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
Fast line oriented regex searching as a library. Fast line oriented regex searching as a library.

View File

@@ -482,7 +482,7 @@ impl LineBuffer {
} }
let roll_len = self.end - self.pos; let roll_len = self.end - self.pos;
self.buf.copy_within_str(self.pos.., 0); self.buf.copy_within_str(self.pos..self.end, 0);
self.pos = 0; self.pos = 0;
self.last_lineterm = roll_len; self.last_lineterm = roll_len;
self.end = roll_len; self.end = roll_len;

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "ignore" name = "ignore"
version = "0.4.9" #:version version = "0.4.10" #:version
authors = ["Andrew Gallant <jamslam@gmail.com>"] authors = ["Andrew Gallant <jamslam@gmail.com>"]
description = """ description = """
A fast library for efficiently matching ignore files such as `.gitignore` A fast library for efficiently matching ignore files such as `.gitignore`
@@ -31,8 +31,5 @@ walkdir = "2.2.7"
[target.'cfg(windows)'.dependencies.winapi-util] [target.'cfg(windows)'.dependencies.winapi-util]
version = "0.1.2" version = "0.1.2"
[dev-dependencies]
tempfile = "3.0.5"
[features] [features]
simd-accel = ["globset/simd-accel"] simd-accel = ["globset/simd-accel"]

View File

@@ -14,13 +14,13 @@
// well. // well.
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::{OsString, OsStr}; use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use gitignore::{self, Gitignore, GitignoreBuilder}; use gitignore::{self, Gitignore, GitignoreBuilder};
use pathutil::{is_hidden, strip_prefix};
use overrides::{self, Override}; use overrides::{self, Override};
use pathutil::{is_hidden, strip_prefix};
use types::{self, Types}; use types::{self, Types};
use walk::DirEntry; use walk::DirEntry;
use {Error, Match, PartialErrorBuilder}; use {Error, Match, PartialErrorBuilder};
@@ -152,10 +152,7 @@ impl Ignore {
/// ///
/// Note that this can only be called on an `Ignore` matcher with no /// Note that this can only be called on an `Ignore` matcher with no
/// parents (i.e., `is_root` returns `true`). This will panic otherwise. /// parents (i.e., `is_root` returns `true`). This will panic otherwise.
pub fn add_parents<P: AsRef<Path>>( pub fn add_parents<P: AsRef<Path>>(&self, path: P) -> (Ignore, Option<Error>) {
&self,
path: P,
) -> (Ignore, Option<Error>) {
if !self.0.opts.parents if !self.0.opts.parents
&& !self.0.opts.git_ignore && !self.0.opts.git_ignore
&& !self.0.opts.git_exclude && !self.0.opts.git_exclude
@@ -197,12 +194,11 @@ impl Ignore {
errs.maybe_push(err); errs.maybe_push(err);
igtmp.is_absolute_parent = true; igtmp.is_absolute_parent = true;
igtmp.absolute_base = Some(absolute_base.clone()); igtmp.absolute_base = Some(absolute_base.clone());
igtmp.has_git = igtmp.has_git = if self.0.opts.git_ignore {
if self.0.opts.git_ignore { parent.join(".git").exists()
parent.join(".git").exists() } else {
} else { false
false };
};
ig = Ignore(Arc::new(igtmp)); ig = Ignore(Arc::new(igtmp));
compiled.insert(parent.as_os_str().to_os_string(), ig.clone()); compiled.insert(parent.as_os_str().to_os_string(), ig.clone());
} }
@@ -217,10 +213,7 @@ impl Ignore {
/// returned if it exists. /// returned if it exists.
/// ///
/// Note that all I/O errors are completely ignored. /// Note that all I/O errors are completely ignored.
pub fn add_child<P: AsRef<Path>>( pub fn add_child<P: AsRef<Path>>(&self, dir: P) -> (Ignore, Option<Error>) {
&self,
dir: P,
) -> (Ignore, Option<Error>) {
let (ig, err) = self.add_child_path(dir.as_ref()); let (ig, err) = self.add_child_path(dir.as_ref());
(Ignore(Arc::new(ig)), err) (Ignore(Arc::new(ig)), err)
} }
@@ -228,64 +221,49 @@ impl Ignore {
/// Like add_child, but takes a full path and returns an IgnoreInner. /// Like add_child, but takes a full path and returns an IgnoreInner.
fn add_child_path(&self, dir: &Path) -> (IgnoreInner, Option<Error>) { fn add_child_path(&self, dir: &Path) -> (IgnoreInner, Option<Error>) {
let mut errs = PartialErrorBuilder::default(); let mut errs = PartialErrorBuilder::default();
let custom_ig_matcher = let custom_ig_matcher = if self.0.custom_ignore_filenames.is_empty() {
if self.0.custom_ignore_filenames.is_empty() { Gitignore::empty()
Gitignore::empty() } else {
} else { let (m, err) = create_gitignore(
let (m, err) = &dir,
create_gitignore( &self.0.custom_ignore_filenames,
&dir, self.0.opts.ignore_case_insensitive,
&self.0.custom_ignore_filenames, );
self.0.opts.ignore_case_insensitive, errs.maybe_push(err);
); m
errs.maybe_push(err); };
m let ig_matcher = if !self.0.opts.ignore {
}; Gitignore::empty()
let ig_matcher = } else {
if !self.0.opts.ignore { let (m, err) =
Gitignore::empty() create_gitignore(&dir, &[".ignore"], self.0.opts.ignore_case_insensitive);
} else { errs.maybe_push(err);
let (m, err) = m
create_gitignore( };
&dir, let gi_matcher = if !self.0.opts.git_ignore {
&[".ignore"], Gitignore::empty()
self.0.opts.ignore_case_insensitive, } else {
); let (m, err) =
errs.maybe_push(err); create_gitignore(&dir, &[".gitignore"], self.0.opts.ignore_case_insensitive);
m errs.maybe_push(err);
}; m
let gi_matcher = };
if !self.0.opts.git_ignore { let gi_exclude_matcher = if !self.0.opts.git_exclude {
Gitignore::empty() Gitignore::empty()
} else { } else {
let (m, err) = let (m, err) = create_gitignore(
create_gitignore( &dir,
&dir, &[".git/info/exclude"],
&[".gitignore"], self.0.opts.ignore_case_insensitive,
self.0.opts.ignore_case_insensitive, );
); errs.maybe_push(err);
errs.maybe_push(err); m
m };
}; let has_git = if self.0.opts.git_ignore {
let gi_exclude_matcher = dir.join(".git").exists()
if !self.0.opts.git_exclude { } else {
Gitignore::empty() false
} else { };
let (m, err) =
create_gitignore(
&dir,
&[".git/info/exclude"],
self.0.opts.ignore_case_insensitive,
);
errs.maybe_push(err);
m
};
let has_git =
if self.0.opts.git_ignore {
dir.join(".git").exists()
} else {
false
};
let ig = IgnoreInner { let ig = IgnoreInner {
compiled: self.0.compiled.clone(), compiled: self.0.compiled.clone(),
dir: dir.to_path_buf(), dir: dir.to_path_buf(),
@@ -313,16 +291,16 @@ impl Ignore {
let has_custom_ignore_files = !self.0.custom_ignore_filenames.is_empty(); let has_custom_ignore_files = !self.0.custom_ignore_filenames.is_empty();
let has_explicit_ignores = !self.0.explicit_ignores.is_empty(); let has_explicit_ignores = !self.0.explicit_ignores.is_empty();
opts.ignore || opts.git_global || opts.git_ignore opts.ignore
|| opts.git_exclude || has_custom_ignore_files || opts.git_global
|| has_explicit_ignores || opts.git_ignore
|| opts.git_exclude
|| has_custom_ignore_files
|| has_explicit_ignores
} }
/// Like `matched`, but works with a directory entry instead. /// Like `matched`, but works with a directory entry instead.
pub fn matched_dir_entry<'a>( pub fn matched_dir_entry<'a>(&'a self, dent: &DirEntry) -> Match<IgnoreMatch<'a>> {
&'a self,
dent: &DirEntry,
) -> Match<IgnoreMatch<'a>> {
let m = self.matched(dent.path(), dent.is_dir()); let m = self.matched(dent.path(), dent.is_dir());
if m.is_none() && self.0.opts.hidden && is_hidden(dent) { if m.is_none() && self.0.opts.hidden && is_hidden(dent) {
return Match::Ignore(IgnoreMatch::hidden()); return Match::Ignore(IgnoreMatch::hidden());
@@ -334,11 +312,7 @@ impl Ignore {
/// ignored or not. /// ignored or not.
/// ///
/// The match contains information about its origin. /// The match contains information about its origin.
fn matched<'a, P: AsRef<Path>>( fn matched<'a, P: AsRef<Path>>(&'a self, path: P, is_dir: bool) -> Match<IgnoreMatch<'a>> {
&'a self,
path: P,
is_dir: bool,
) -> Match<IgnoreMatch<'a>> {
// We need to be careful with our path. If it has a leading ./, then // We need to be careful with our path. If it has a leading ./, then
// strip it because it causes nothing but trouble. // strip it because it causes nothing but trouble.
let mut path = path.as_ref(); let mut path = path.as_ref();
@@ -350,9 +324,11 @@ impl Ignore {
// return that result immediately. Overrides have the highest // return that result immediately. Overrides have the highest
// precedence. // precedence.
if !self.0.overrides.is_empty() { if !self.0.overrides.is_empty() {
let mat = let mat = self
self.0.overrides.matched(path, is_dir) .0
.map(IgnoreMatch::overrides); .overrides
.matched(path, is_dir)
.map(IgnoreMatch::overrides);
if !mat.is_none() { if !mat.is_none() {
return mat; return mat;
} }
@@ -367,8 +343,7 @@ impl Ignore {
} }
} }
if !self.0.types.is_empty() { if !self.0.types.is_empty() {
let mat = let mat = self.0.types.matched(path, is_dir).map(IgnoreMatch::types);
self.0.types.matched(path, is_dir).map(IgnoreMatch::types);
if mat.is_ignore() { if mat.is_ignore() {
return mat; return mat;
} else if mat.is_whitelist() { } else if mat.is_whitelist() {
@@ -380,61 +355,70 @@ impl Ignore {
/// Performs matching only on the ignore files for this directory and /// Performs matching only on the ignore files for this directory and
/// all parent directories. /// all parent directories.
fn matched_ignore<'a>( fn matched_ignore<'a>(&'a self, path: &Path, is_dir: bool) -> Match<IgnoreMatch<'a>> {
&'a self, let (mut m_custom_ignore, mut m_ignore, mut m_gi, mut m_gi_exclude, mut m_explicit) = (
path: &Path, Match::None,
is_dir: bool, Match::None,
) -> Match<IgnoreMatch<'a>> { Match::None,
let (mut m_custom_ignore, mut m_ignore, mut m_gi, mut m_gi_exclude, mut m_explicit) = Match::None,
(Match::None, Match::None, Match::None, Match::None, Match::None); Match::None,
);
let any_git = self.parents().any(|ig| ig.0.has_git); let any_git = self.parents().any(|ig| ig.0.has_git);
let mut saw_git = false; let mut saw_git = false;
for ig in self.parents().take_while(|ig| !ig.0.is_absolute_parent) { for ig in self.parents().take_while(|ig| !ig.0.is_absolute_parent) {
if m_custom_ignore.is_none() { if m_custom_ignore.is_none() {
m_custom_ignore = m_custom_ignore =
ig.0.custom_ignore_matcher.matched(path, is_dir) ig.0.custom_ignore_matcher
.map(IgnoreMatch::gitignore); .matched(path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if m_ignore.is_none() { if m_ignore.is_none() {
m_ignore = m_ignore =
ig.0.ignore_matcher.matched(path, is_dir) ig.0.ignore_matcher
.map(IgnoreMatch::gitignore); .matched(path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if any_git && !saw_git && m_gi.is_none() { if any_git && !saw_git && m_gi.is_none() {
m_gi = m_gi =
ig.0.git_ignore_matcher.matched(path, is_dir) ig.0.git_ignore_matcher
.map(IgnoreMatch::gitignore); .matched(path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if any_git && !saw_git && m_gi_exclude.is_none() { if any_git && !saw_git && m_gi_exclude.is_none() {
m_gi_exclude = m_gi_exclude =
ig.0.git_exclude_matcher.matched(path, is_dir) ig.0.git_exclude_matcher
.map(IgnoreMatch::gitignore); .matched(path, is_dir)
.map(IgnoreMatch::gitignore);
} }
saw_git = saw_git || ig.0.has_git; saw_git = saw_git || ig.0.has_git;
} }
if self.0.opts.parents { if self.0.opts.parents {
if let Some(abs_parent_path) = self.absolute_base() { if let Some(abs_parent_path) = self.absolute_base() {
let path = abs_parent_path.join(path); let path = abs_parent_path.join(path);
for ig in self.parents().skip_while(|ig|!ig.0.is_absolute_parent) { for ig in self.parents().skip_while(|ig| !ig.0.is_absolute_parent) {
if m_custom_ignore.is_none() { if m_custom_ignore.is_none() {
m_custom_ignore = m_custom_ignore =
ig.0.custom_ignore_matcher.matched(&path, is_dir) ig.0.custom_ignore_matcher
.map(IgnoreMatch::gitignore); .matched(&path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if m_ignore.is_none() { if m_ignore.is_none() {
m_ignore = m_ignore =
ig.0.ignore_matcher.matched(&path, is_dir) ig.0.ignore_matcher
.map(IgnoreMatch::gitignore); .matched(&path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if any_git && !saw_git && m_gi.is_none() { if any_git && !saw_git && m_gi.is_none() {
m_gi = m_gi =
ig.0.git_ignore_matcher.matched(&path, is_dir) ig.0.git_ignore_matcher
.map(IgnoreMatch::gitignore); .matched(&path, is_dir)
.map(IgnoreMatch::gitignore);
} }
if any_git && !saw_git && m_gi_exclude.is_none() { if any_git && !saw_git && m_gi_exclude.is_none() {
m_gi_exclude = m_gi_exclude =
ig.0.git_exclude_matcher.matched(&path, is_dir) ig.0.git_exclude_matcher
.map(IgnoreMatch::gitignore); .matched(&path, is_dir)
.map(IgnoreMatch::gitignore);
} }
saw_git = saw_git || ig.0.has_git; saw_git = saw_git || ig.0.has_git;
} }
@@ -446,16 +430,21 @@ impl Ignore {
} }
m_explicit = gi.matched(&path, is_dir).map(IgnoreMatch::gitignore); m_explicit = gi.matched(&path, is_dir).map(IgnoreMatch::gitignore);
} }
let m_global = let m_global = if any_git {
if any_git { self.0
self.0.git_global_matcher .git_global_matcher
.matched(&path, is_dir) .matched(&path, is_dir)
.map(IgnoreMatch::gitignore) .map(IgnoreMatch::gitignore)
} else { } else {
Match::None Match::None
}; };
m_custom_ignore.or(m_ignore).or(m_gi).or(m_gi_exclude).or(m_global).or(m_explicit) m_custom_ignore
.or(m_ignore)
.or(m_gi)
.or(m_gi_exclude)
.or(m_global)
.or(m_explicit)
} }
/// Returns an iterator over parent ignore matchers, including this one. /// Returns an iterator over parent ignore matchers, including this one.
@@ -535,20 +524,19 @@ impl IgnoreBuilder {
/// The matcher returned won't match anything until ignore rules from /// The matcher returned won't match anything until ignore rules from
/// directories are added to it. /// directories are added to it.
pub fn build(&self) -> Ignore { pub fn build(&self) -> Ignore {
let git_global_matcher = let git_global_matcher = if !self.opts.git_global {
if !self.opts.git_global { Gitignore::empty()
Gitignore::empty() } else {
} else { let mut builder = GitignoreBuilder::new("");
let mut builder = GitignoreBuilder::new(""); builder
builder .case_insensitive(self.opts.ignore_case_insensitive)
.case_insensitive(self.opts.ignore_case_insensitive) .unwrap();
.unwrap(); let (gi, err) = builder.build_global();
let (gi, err) = builder.build_global(); if let Some(err) = err {
if let Some(err) = err { debug!("{}", err);
debug!("{}", err); }
} gi
gi };
};
Ignore(Arc::new(IgnoreInner { Ignore(Arc::new(IgnoreInner {
compiled: Arc::new(RwLock::new(HashMap::new())), compiled: Arc::new(RwLock::new(HashMap::new())),
@@ -604,9 +592,10 @@ impl IgnoreBuilder {
/// later names. /// later names.
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>( pub fn add_custom_ignore_filename<S: AsRef<OsStr>>(
&mut self, &mut self,
file_name: S file_name: S,
) -> &mut IgnoreBuilder { ) -> &mut IgnoreBuilder {
self.custom_ignore_filenames.push(file_name.as_ref().to_os_string()); self.custom_ignore_filenames
.push(file_name.as_ref().to_os_string());
self self
} }
@@ -678,10 +667,7 @@ impl IgnoreBuilder {
/// Process ignore files case insensitively /// Process ignore files case insensitively
/// ///
/// This is disabled by default. /// This is disabled by default.
pub fn ignore_case_insensitive( pub fn ignore_case_insensitive(&mut self, yes: bool) -> &mut IgnoreBuilder {
&mut self,
yes: bool,
) -> &mut IgnoreBuilder {
self.opts.ignore_case_insensitive = yes; self.opts.ignore_case_insensitive = yes;
self self
} }
@@ -721,10 +707,9 @@ mod tests {
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use tempfile::{self, TempDir};
use dir::IgnoreBuilder; use dir::IgnoreBuilder;
use gitignore::Gitignore; use gitignore::Gitignore;
use tests::TempDir;
use Error; use Error;
fn wfile<P: AsRef<Path>>(path: P, contents: &str) { fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
@@ -743,19 +728,21 @@ mod tests {
} }
} }
fn tmpdir(prefix: &str) -> TempDir { fn tmpdir() -> TempDir {
tempfile::Builder::new().prefix(prefix).tempdir().unwrap() TempDir::new().unwrap()
} }
#[test] #[test]
fn explicit_ignore() { fn explicit_ignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join("not-an-ignore"), "foo\n!bar"); wfile(td.path().join("not-an-ignore"), "foo\n!bar");
let (gi, err) = Gitignore::new(td.path().join("not-an-ignore")); let (gi, err) = Gitignore::new(td.path().join("not-an-ignore"));
assert!(err.is_none()); assert!(err.is_none());
let (ig, err) = IgnoreBuilder::new() let (ig, err) = IgnoreBuilder::new()
.add_ignore(gi).build().add_child(td.path()); .add_ignore(gi)
.build()
.add_child(td.path());
assert!(err.is_none()); assert!(err.is_none());
assert!(ig.matched("foo", false).is_ignore()); assert!(ig.matched("foo", false).is_ignore());
assert!(ig.matched("bar", false).is_whitelist()); assert!(ig.matched("bar", false).is_whitelist());
@@ -764,7 +751,7 @@ mod tests {
#[test] #[test]
fn git_exclude() { fn git_exclude() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git/info")); mkdirp(td.path().join(".git/info"));
wfile(td.path().join(".git/info/exclude"), "foo\n!bar"); wfile(td.path().join(".git/info/exclude"), "foo\n!bar");
@@ -777,7 +764,7 @@ mod tests {
#[test] #[test]
fn gitignore() { fn gitignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
wfile(td.path().join(".gitignore"), "foo\n!bar"); wfile(td.path().join(".gitignore"), "foo\n!bar");
@@ -790,7 +777,7 @@ mod tests {
#[test] #[test]
fn gitignore_no_git() { fn gitignore_no_git() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "foo\n!bar"); wfile(td.path().join(".gitignore"), "foo\n!bar");
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path()); let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
@@ -802,7 +789,7 @@ mod tests {
#[test] #[test]
fn ignore() { fn ignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".ignore"), "foo\n!bar"); wfile(td.path().join(".ignore"), "foo\n!bar");
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path()); let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
@@ -814,13 +801,14 @@ mod tests {
#[test] #[test]
fn custom_ignore() { fn custom_ignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
let custom_ignore = ".customignore"; let custom_ignore = ".customignore";
wfile(td.path().join(custom_ignore), "foo\n!bar"); wfile(td.path().join(custom_ignore), "foo\n!bar");
let (ig, err) = IgnoreBuilder::new() let (ig, err) = IgnoreBuilder::new()
.add_custom_ignore_filename(custom_ignore) .add_custom_ignore_filename(custom_ignore)
.build().add_child(td.path()); .build()
.add_child(td.path());
assert!(err.is_none()); assert!(err.is_none());
assert!(ig.matched("foo", false).is_ignore()); assert!(ig.matched("foo", false).is_ignore());
assert!(ig.matched("bar", false).is_whitelist()); assert!(ig.matched("bar", false).is_whitelist());
@@ -830,14 +818,15 @@ mod tests {
// Tests that a custom ignore file will override an .ignore. // Tests that a custom ignore file will override an .ignore.
#[test] #[test]
fn custom_ignore_over_ignore() { fn custom_ignore_over_ignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
let custom_ignore = ".customignore"; let custom_ignore = ".customignore";
wfile(td.path().join(".ignore"), "foo"); wfile(td.path().join(".ignore"), "foo");
wfile(td.path().join(custom_ignore), "!foo"); wfile(td.path().join(custom_ignore), "!foo");
let (ig, err) = IgnoreBuilder::new() let (ig, err) = IgnoreBuilder::new()
.add_custom_ignore_filename(custom_ignore) .add_custom_ignore_filename(custom_ignore)
.build().add_child(td.path()); .build()
.add_child(td.path());
assert!(err.is_none()); assert!(err.is_none());
assert!(ig.matched("foo", false).is_whitelist()); assert!(ig.matched("foo", false).is_whitelist());
} }
@@ -845,7 +834,7 @@ mod tests {
// Tests that earlier custom ignore files have lower precedence than later. // Tests that earlier custom ignore files have lower precedence than later.
#[test] #[test]
fn custom_ignore_precedence() { fn custom_ignore_precedence() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
let custom_ignore1 = ".customignore1"; let custom_ignore1 = ".customignore1";
let custom_ignore2 = ".customignore2"; let custom_ignore2 = ".customignore2";
wfile(td.path().join(custom_ignore1), "foo"); wfile(td.path().join(custom_ignore1), "foo");
@@ -854,7 +843,8 @@ mod tests {
let (ig, err) = IgnoreBuilder::new() let (ig, err) = IgnoreBuilder::new()
.add_custom_ignore_filename(custom_ignore1) .add_custom_ignore_filename(custom_ignore1)
.add_custom_ignore_filename(custom_ignore2) .add_custom_ignore_filename(custom_ignore2)
.build().add_child(td.path()); .build()
.add_child(td.path());
assert!(err.is_none()); assert!(err.is_none());
assert!(ig.matched("foo", false).is_whitelist()); assert!(ig.matched("foo", false).is_whitelist());
} }
@@ -862,7 +852,7 @@ mod tests {
// Tests that an .ignore will override a .gitignore. // Tests that an .ignore will override a .gitignore.
#[test] #[test]
fn ignore_over_gitignore() { fn ignore_over_gitignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "foo"); wfile(td.path().join(".gitignore"), "foo");
wfile(td.path().join(".ignore"), "!foo"); wfile(td.path().join(".ignore"), "!foo");
@@ -874,7 +864,7 @@ mod tests {
// Tests that exclude has lower precedent than both .ignore and .gitignore. // Tests that exclude has lower precedent than both .ignore and .gitignore.
#[test] #[test]
fn exclude_lowest() { fn exclude_lowest() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "!foo"); wfile(td.path().join(".gitignore"), "!foo");
wfile(td.path().join(".ignore"), "!bar"); wfile(td.path().join(".ignore"), "!bar");
mkdirp(td.path().join(".git/info")); mkdirp(td.path().join(".git/info"));
@@ -889,7 +879,7 @@ mod tests {
#[test] #[test]
fn errored() { fn errored() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "{foo"); wfile(td.path().join(".gitignore"), "{foo");
let (_, err) = IgnoreBuilder::new().build().add_child(td.path()); let (_, err) = IgnoreBuilder::new().build().add_child(td.path());
@@ -898,7 +888,7 @@ mod tests {
#[test] #[test]
fn errored_both() { fn errored_both() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "{foo"); wfile(td.path().join(".gitignore"), "{foo");
wfile(td.path().join(".ignore"), "{bar"); wfile(td.path().join(".ignore"), "{bar");
@@ -908,7 +898,7 @@ mod tests {
#[test] #[test]
fn errored_partial() { fn errored_partial() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
wfile(td.path().join(".gitignore"), "{foo\nbar"); wfile(td.path().join(".gitignore"), "{foo\nbar");
@@ -919,7 +909,7 @@ mod tests {
#[test] #[test]
fn errored_partial_and_ignore() { fn errored_partial_and_ignore() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
wfile(td.path().join(".gitignore"), "{foo\nbar"); wfile(td.path().join(".gitignore"), "{foo\nbar");
wfile(td.path().join(".ignore"), "!bar"); wfile(td.path().join(".ignore"), "!bar");
@@ -930,7 +920,7 @@ mod tests {
#[test] #[test]
fn not_present_empty() { fn not_present_empty() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
let (_, err) = IgnoreBuilder::new().build().add_child(td.path()); let (_, err) = IgnoreBuilder::new().build().add_child(td.path());
assert!(err.is_none()); assert!(err.is_none());
@@ -940,7 +930,7 @@ mod tests {
fn stops_at_git_dir() { fn stops_at_git_dir() {
// This tests that .gitignore files beyond a .git barrier aren't // This tests that .gitignore files beyond a .git barrier aren't
// matched, but .ignore files are. // matched, but .ignore files are.
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
mkdirp(td.path().join("foo/.git")); mkdirp(td.path().join("foo/.git"));
wfile(td.path().join(".gitignore"), "foo"); wfile(td.path().join(".gitignore"), "foo");
@@ -961,7 +951,7 @@ mod tests {
#[test] #[test]
fn absolute_parent() { fn absolute_parent() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
mkdirp(td.path().join("foo")); mkdirp(td.path().join("foo"));
wfile(td.path().join(".gitignore"), "bar"); wfile(td.path().join(".gitignore"), "bar");
@@ -984,7 +974,7 @@ mod tests {
#[test] #[test]
fn absolute_parent_anchored() { fn absolute_parent_anchored() {
let td = tmpdir("ignore-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
mkdirp(td.path().join("src/llvm")); mkdirp(td.path().join("src/llvm"));
wfile(td.path().join(".gitignore"), "/llvm/\nfoo"); wfile(td.path().join(".gitignore"), "/llvm/\nfoo");

View File

@@ -537,7 +537,7 @@ impl GitignoreBuilder {
/// ///
/// Note that the file path returned may not exist. /// Note that the file path returned may not exist.
fn gitconfig_excludes_path() -> Option<PathBuf> { fn gitconfig_excludes_path() -> Option<PathBuf> {
// git supports $HOME/.gitconfig and $XDG_CONFIG_DIR/git/config. Notably, // git supports $HOME/.gitconfig and $XDG_CONFIG_HOME/git/config. Notably,
// both can be active at the same time, where $HOME/.gitconfig takes // both can be active at the same time, where $HOME/.gitconfig takes
// precedent. So if $HOME/.gitconfig defines a `core.excludesFile`, then // precedent. So if $HOME/.gitconfig defines a `core.excludesFile`, then
// we're done. // we're done.
@@ -568,7 +568,7 @@ fn gitconfig_home_contents() -> Option<Vec<u8>> {
} }
/// Returns the file contents of git's global config file, if one exists, in /// Returns the file contents of git's global config file, if one exists, in
/// the user's XDG_CONFIG_DIR directory. /// the user's XDG_CONFIG_HOME directory.
fn gitconfig_xdg_contents() -> Option<Vec<u8>> { fn gitconfig_xdg_contents() -> Option<Vec<u8>> {
let path = env::var_os("XDG_CONFIG_HOME") let path = env::var_os("XDG_CONFIG_HOME")
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) }) .and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })

View File

@@ -55,8 +55,6 @@ extern crate log;
extern crate memchr; extern crate memchr;
extern crate regex; extern crate regex;
extern crate same_file; extern crate same_file;
#[cfg(test)]
extern crate tempfile;
extern crate thread_local; extern crate thread_local;
extern crate walkdir; extern crate walkdir;
#[cfg(windows)] #[cfg(windows)]
@@ -442,3 +440,66 @@ impl<T> Match<T> {
} }
} }
} }
#[cfg(test)]
mod tests {
use std::env;
use std::error;
use std::fs;
use std::path::{Path, PathBuf};
use std::result;
/// A convenient result type alias.
pub type Result<T> =
result::Result<T, Box<dyn error::Error + Send + Sync>>;
macro_rules! err {
($($tt:tt)*) => {
Box::<dyn error::Error + Send + Sync>::from(format!($($tt)*))
}
}
/// A simple wrapper for creating a temporary directory that is
/// automatically deleted when it's dropped.
///
/// We use this in lieu of tempfile because tempfile brings in too many
/// dependencies.
#[derive(Debug)]
pub struct TempDir(PathBuf);
impl Drop for TempDir {
fn drop(&mut self) {
fs::remove_dir_all(&self.0).unwrap();
}
}
impl TempDir {
/// Create a new empty temporary directory under the system's configured
/// temporary directory.
pub fn new() -> Result<TempDir> {
use std::sync::atomic::{AtomicUsize, Ordering};
static TRIES: usize = 100;
static COUNTER: AtomicUsize = AtomicUsize::new(0);
let tmpdir = env::temp_dir();
for _ in 0..TRIES {
let count = COUNTER.fetch_add(1, Ordering::SeqCst);
let path = tmpdir.join("rust-ignore").join(count.to_string());
if path.is_dir() {
continue;
}
fs::create_dir_all(&path).map_err(|e| {
err!("failed to create {}: {}", path.display(), e)
})?;
return Ok(TempDir(path));
}
Err(err!("failed to create temp dir after {} tries", TRIES))
}
/// Return the underlying path to this temporary directory.
pub fn path(&self) -> &Path {
&self.0
}
}
}

View File

@@ -4,8 +4,8 @@ use std::fmt;
use std::fs::{self, FileType, Metadata}; use std::fs::{self, FileType, Metadata};
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use std::vec; use std::vec;
@@ -182,14 +182,14 @@ impl DirEntryInner {
match *self { match *self {
Stdin => { Stdin => {
let err = Error::Io(io::Error::new( let err = Error::Io(io::Error::new(
io::ErrorKind::Other, "<stdin> has no metadata")); io::ErrorKind::Other,
"<stdin> has no metadata",
));
Err(err.with_path("<stdin>")) Err(err.with_path("<stdin>"))
} }
Walkdir(ref x) => { Walkdir(ref x) => x
x.metadata().map_err(|err| { .metadata()
Error::Io(io::Error::from(err)).with_path(x.path()) .map_err(|err| Error::Io(io::Error::from(err)).with_path(x.path())),
})
}
Raw(ref x) => x.metadata(), Raw(ref x) => x.metadata(),
} }
} }
@@ -223,8 +223,8 @@ impl DirEntryInner {
#[cfg(unix)] #[cfg(unix)]
fn ino(&self) -> Option<u64> { fn ino(&self) -> Option<u64> {
use walkdir::DirEntryExt;
use self::DirEntryInner::*; use self::DirEntryInner::*;
use walkdir::DirEntryExt;
match *self { match *self {
Stdin => None, Stdin => None,
Walkdir(ref x) => Some(x.ino()), Walkdir(ref x) => Some(x.ino()),
@@ -297,7 +297,8 @@ impl DirEntryRaw {
fs::metadata(&self.path) fs::metadata(&self.path)
} else { } else {
Ok(self.metadata.clone()) Ok(self.metadata.clone())
}.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path)) }
.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path))
} }
#[cfg(not(windows))] #[cfg(not(windows))]
@@ -306,7 +307,8 @@ impl DirEntryRaw {
fs::metadata(&self.path) fs::metadata(&self.path)
} else { } else {
fs::symlink_metadata(&self.path) fs::symlink_metadata(&self.path)
}.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path)) }
.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path))
} }
fn file_type(&self) -> FileType { fn file_type(&self) -> FileType {
@@ -314,7 +316,9 @@ impl DirEntryRaw {
} }
fn file_name(&self) -> &OsStr { fn file_name(&self) -> &OsStr {
self.path.file_name().unwrap_or_else(|| self.path.as_os_str()) self.path
.file_name()
.unwrap_or_else(|| self.path.as_os_str())
} }
fn depth(&self) -> usize { fn depth(&self) -> usize {
@@ -326,10 +330,7 @@ impl DirEntryRaw {
self.ino self.ino
} }
fn from_entry( fn from_entry(depth: usize, ent: &fs::DirEntry) -> Result<DirEntryRaw, Error> {
depth: usize,
ent: &fs::DirEntry,
) -> Result<DirEntryRaw, Error> {
let ty = ent.file_type().map_err(|err| { let ty = ent.file_type().map_err(|err| {
let err = Error::Io(io::Error::from(err)).with_path(ent.path()); let err = Error::Io(io::Error::from(err)).with_path(ent.path());
Error::WithDepth { Error::WithDepth {
@@ -387,18 +388,14 @@ impl DirEntryRaw {
ty: fs::FileType, ty: fs::FileType,
) -> Result<DirEntryRaw, Error> { ) -> Result<DirEntryRaw, Error> {
Err(Error::Io(io::Error::new( Err(Error::Io(io::Error::new(
io::ErrorKind::Other, "unsupported platform"))) io::ErrorKind::Other,
"unsupported platform",
)))
} }
#[cfg(windows)] #[cfg(windows)]
fn from_path( fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntryRaw, Error> {
depth: usize, let md = fs::metadata(&pb).map_err(|err| Error::Io(err).with_path(&pb))?;
pb: PathBuf,
link: bool,
) -> Result<DirEntryRaw, Error> {
let md = fs::metadata(&pb).map_err(|err| {
Error::Io(err).with_path(&pb)
})?;
Ok(DirEntryRaw { Ok(DirEntryRaw {
path: pb, path: pb,
ty: md.file_type(), ty: md.file_type(),
@@ -409,16 +406,10 @@ impl DirEntryRaw {
} }
#[cfg(unix)] #[cfg(unix)]
fn from_path( fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntryRaw, Error> {
depth: usize,
pb: PathBuf,
link: bool,
) -> Result<DirEntryRaw, Error> {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
let md = fs::metadata(&pb).map_err(|err| { let md = fs::metadata(&pb).map_err(|err| Error::Io(err).with_path(&pb))?;
Error::Io(err).with_path(&pb)
})?;
Ok(DirEntryRaw { Ok(DirEntryRaw {
path: pb, path: pb,
ty: md.file_type(), ty: md.file_type(),
@@ -430,13 +421,11 @@ 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)))] #[cfg(not(any(windows, unix)))]
fn from_path( fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntryRaw, Error> {
depth: usize,
pb: PathBuf,
link: bool,
) -> Result<DirEntryRaw, Error> {
Err(Error::Io(io::Error::new( Err(Error::Io(io::Error::new(
io::ErrorKind::Other, "unsupported platform"))) io::ErrorKind::Other,
"unsupported platform",
)))
} }
} }
@@ -547,33 +536,34 @@ impl WalkBuilder {
let follow_links = self.follow_links; let follow_links = self.follow_links;
let max_depth = self.max_depth; let max_depth = self.max_depth;
let sorter = self.sorter.clone(); let sorter = self.sorter.clone();
let its = self.paths.iter().map(move |p| { let its = self
if p == Path::new("-") { .paths
(p.to_path_buf(), None) .iter()
} else { .map(move |p| {
let mut wd = WalkDir::new(p); if p == Path::new("-") {
wd = wd.follow_links(follow_links || p.is_file()); (p.to_path_buf(), None)
wd = wd.same_file_system(self.same_file_system); } else {
if let Some(max_depth) = max_depth { let mut wd = WalkDir::new(p);
wd = wd.max_depth(max_depth); wd = wd.follow_links(follow_links || p.is_file());
} wd = wd.same_file_system(self.same_file_system);
if let Some(ref sorter) = sorter { if let Some(max_depth) = max_depth {
match sorter.clone() { wd = wd.max_depth(max_depth);
Sorter::ByName(cmp) => { }
wd = wd.sort_by(move |a, b| { if let Some(ref sorter) = sorter {
cmp(a.file_name(), b.file_name()) match sorter.clone() {
}); Sorter::ByName(cmp) => {
} wd = wd.sort_by(move |a, b| cmp(a.file_name(), b.file_name()));
Sorter::ByPath(cmp) => { }
wd = wd.sort_by(move |a, b| { Sorter::ByPath(cmp) => {
cmp(a.path(), b.path()) wd = wd.sort_by(move |a, b| cmp(a.path(), b.path()));
}); }
} }
} }
(p.to_path_buf(), Some(WalkEventIter::from(wd)))
} }
(p.to_path_buf(), Some(WalkEventIter::from(wd))) })
} .collect::<Vec<_>>()
}).collect::<Vec<_>>().into_iter(); .into_iter();
let ig_root = self.ig_builder.build(); let ig_root = self.ig_builder.build();
Walk { Walk {
its: its, its: its,
@@ -657,8 +647,12 @@ impl WalkBuilder {
let mut errs = PartialErrorBuilder::default(); let mut errs = PartialErrorBuilder::default();
errs.maybe_push(builder.add(path)); errs.maybe_push(builder.add(path));
match builder.build() { match builder.build() {
Ok(gi) => { self.ig_builder.add_ignore(gi); } Ok(gi) => {
Err(err) => { errs.push(err); } self.ig_builder.add_ignore(gi);
}
Err(err) => {
errs.push(err);
}
} }
errs.into_error_option() errs.into_error_option()
} }
@@ -671,7 +665,7 @@ impl WalkBuilder {
/// later names. /// later names.
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>( pub fn add_custom_ignore_filename<S: AsRef<OsStr>>(
&mut self, &mut self,
file_name: S file_name: S,
) -> &mut WalkBuilder { ) -> &mut WalkBuilder {
self.ig_builder.add_custom_ignore_filename(file_name); self.ig_builder.add_custom_ignore_filename(file_name);
self self
@@ -808,11 +802,9 @@ impl WalkBuilder {
/// by `sort_by_file_name`. /// by `sort_by_file_name`.
/// ///
/// Note that this is not used in the parallel iterator. /// Note that this is not used in the parallel iterator.
pub fn sort_by_file_path<F>( pub fn sort_by_file_path<F>(&mut self, cmp: F) -> &mut WalkBuilder
&mut self, where
cmp: F, F: Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static,
) -> &mut WalkBuilder
where F: Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static
{ {
self.sorter = Some(Sorter::ByPath(Arc::new(cmp))); self.sorter = Some(Sorter::ByPath(Arc::new(cmp)));
self self
@@ -830,7 +822,8 @@ impl WalkBuilder {
/// ///
/// Note that this is not used in the parallel iterator. /// Note that this is not used in the parallel iterator.
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
where F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static where
F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static,
{ {
self.sorter = Some(Sorter::ByName(Arc::new(cmp))); self.sorter = Some(Sorter::ByName(Arc::new(cmp)));
self self
@@ -1011,7 +1004,11 @@ enum WalkEvent {
impl From<WalkDir> for WalkEventIter { impl From<WalkDir> for WalkEventIter {
fn from(it: WalkDir) -> WalkEventIter { fn from(it: WalkDir) -> WalkEventIter {
WalkEventIter { depth: 0, it: it.into_iter(), next: None } WalkEventIter {
depth: 0,
it: it.into_iter(),
next: None,
}
} }
} }
@@ -1094,10 +1091,10 @@ impl WalkParallel {
/// Execute the parallel recursive directory iterator. `mkf` is called /// Execute the parallel recursive directory iterator. `mkf` is called
/// for each thread used for iteration. The function produced by `mkf` /// for each thread used for iteration. The function produced by `mkf`
/// is then in turn called for each visited file path. /// is then in turn called for each visited file path.
pub fn run<F>( pub fn run<F>(self, mut mkf: F)
self, where
mut mkf: F, F: FnMut() -> Box<dyn FnMut(Result<DirEntry, Error>) -> WalkState + Send + 'static>,
) where F: FnMut() -> Box<dyn FnMut(Result<DirEntry, Error>) -> WalkState + Send + 'static> { {
let mut f = mkf(); let mut f = mkf();
let threads = self.threads(); let threads = self.threads();
// TODO: Figure out how to use a bounded channel here. With an // TODO: Figure out how to use a bounded channel here. With an
@@ -1114,30 +1111,16 @@ impl WalkParallel {
// Note that we only send directories. For files, we send to them the // Note that we only send directories. For files, we send to them the
// callback directly. // callback directly.
for path in self.paths { for path in self.paths {
let (dent, root_device) = let (dent, root_device) = if path == Path::new("-") {
if path == Path::new("-") { (DirEntry::new_stdin(), None)
(DirEntry::new_stdin(), None) } else {
let root_device = if !self.same_file_system {
None
} else { } else {
let root_device = match device_num(&path) {
if !self.same_file_system { Ok(root_device) => Some(root_device),
None
} else {
match device_num(&path) {
Ok(root_device) => Some(root_device),
Err(err) => {
let err = Error::Io(err).with_path(path);
if f(Err(err)).is_quit() {
return;
}
continue;
}
}
};
match DirEntryRaw::from_path(0, path, false) {
Ok(dent) => {
(DirEntry::new_raw(dent, None), root_device)
}
Err(err) => { Err(err) => {
let err = Error::Io(err).with_path(path);
if f(Err(err)).is_quit() { if f(Err(err)).is_quit() {
return; return;
} }
@@ -1145,11 +1128,22 @@ impl WalkParallel {
} }
} }
}; };
match DirEntryRaw::from_path(0, path, false) {
Ok(dent) => (DirEntry::new_raw(dent, None), root_device),
Err(err) => {
if f(Err(err)).is_quit() {
return;
}
continue;
}
}
};
tx.send(Message::Work(Work { tx.send(Message::Work(Work {
dent: dent, dent: dent,
ignore: self.ig_root.clone(), ignore: self.ig_root.clone(),
root_device: root_device, root_device: root_device,
})).unwrap(); }))
.unwrap();
any_work = true; any_work = true;
} }
// ... but there's no need to start workers if we don't need them. // ... but there's no need to start workers if we don't need them.
@@ -1341,22 +1335,21 @@ impl Worker {
continue; continue;
} }
}; };
let descend = let descend = if let Some(root_device) = work.root_device {
if let Some(root_device) = work.root_device { match is_same_file_system(root_device, work.dent.path()) {
match is_same_file_system(root_device, work.dent.path()) { Ok(true) => true,
Ok(true) => true, Ok(false) => false,
Ok(false) => false, Err(err) => {
Err(err) => { if (self.f)(Err(err)).is_quit() {
if (self.f)(Err(err)).is_quit() { self.quit_now();
self.quit_now(); return;
return;
}
false
} }
false
} }
} else { }
true } else {
}; true
};
let depth = work.dent.depth(); let depth = work.dent.depth();
match (self.f)(Ok(work.dent)) { match (self.f)(Ok(work.dent)) {
@@ -1374,12 +1367,7 @@ impl Worker {
continue; continue;
} }
for result in readdir { for result in readdir {
let state = self.run_one( let state = self.run_one(&work.ignore, depth + 1, work.root_device, result);
&work.ignore,
depth + 1,
work.root_device,
result,
);
if state.is_quit() { if state.is_quit() {
self.quit_now(); self.quit_now();
return; return;
@@ -1444,23 +1432,24 @@ impl Worker {
} }
} }
let should_skip_path = should_skip_entry(ig, &dent); let should_skip_path = should_skip_entry(ig, &dent);
let should_skip_filesize = let should_skip_filesize = if self.max_filesize.is_some() && !dent.is_dir() {
if self.max_filesize.is_some() && !dent.is_dir() { skip_filesize(
skip_filesize( self.max_filesize.unwrap(),
self.max_filesize.unwrap(), dent.path(),
dent.path(), &dent.metadata().ok(),
&dent.metadata().ok(), )
) } else {
} else { false
false };
};
if !should_skip_path && !should_skip_filesize { if !should_skip_path && !should_skip_filesize {
self.tx.send(Message::Work(Work { self.tx
dent: dent, .send(Message::Work(Work {
ignore: ig.clone(), dent: dent,
root_device: root_device, ignore: ig.clone(),
})).unwrap(); root_device: root_device,
}))
.unwrap();
} }
WalkState::Continue WalkState::Continue
} }
@@ -1590,17 +1579,25 @@ fn check_symlink_loop(
child_depth: usize, child_depth: usize,
) -> Result<(), Error> { ) -> Result<(), Error> {
let hchild = Handle::from_path(child_path).map_err(|err| { let hchild = Handle::from_path(child_path).map_err(|err| {
Error::from(err).with_path(child_path).with_depth(child_depth) Error::from(err)
.with_path(child_path)
.with_depth(child_depth)
})?; })?;
for ig in ig_parent.parents().take_while(|ig| !ig.is_absolute_parent()) { for ig in ig_parent
.parents()
.take_while(|ig| !ig.is_absolute_parent())
{
let h = Handle::from_path(ig.path()).map_err(|err| { let h = Handle::from_path(ig.path()).map_err(|err| {
Error::from(err).with_path(child_path).with_depth(child_depth) Error::from(err)
.with_path(child_path)
.with_depth(child_depth)
})?; })?;
if hchild == h { if hchild == h {
return Err(Error::Loop { return Err(Error::Loop {
ancestor: ig.path().to_path_buf(), ancestor: ig.path().to_path_buf(),
child: child_path.to_path_buf(), child: child_path.to_path_buf(),
}.with_depth(child_depth)); }
.with_depth(child_depth));
} }
} }
Ok(()) Ok(())
@@ -1608,14 +1605,10 @@ fn check_symlink_loop(
// Before calling this function, make sure that you ensure that is really // Before calling this function, make sure that you ensure that is really
// necessary as the arguments imply a file stat. // necessary as the arguments imply a file stat.
fn skip_filesize( fn skip_filesize(max_filesize: u64, path: &Path, ent: &Option<Metadata>) -> bool {
max_filesize: u64,
path: &Path,
ent: &Option<Metadata>
) -> bool {
let filesize = match *ent { let filesize = match *ent {
Some(ref md) => Some(md.len()), Some(ref md) => Some(md.len()),
None => None None => None,
}; };
if let Some(fs) = filesize { if let Some(fs) = filesize {
@@ -1630,10 +1623,7 @@ fn skip_filesize(
} }
} }
fn should_skip_entry( fn should_skip_entry(ig: &Ignore, dent: &DirEntry) -> bool {
ig: &Ignore,
dent: &DirEntry,
) -> bool {
let m = ig.matched_dir_entry(dent); let m = ig.matched_dir_entry(dent);
if m.is_ignore() { if m.is_ignore() {
debug!("ignoring {}: {:?}", dent.path().display(), m); debug!("ignoring {}: {:?}", dent.path().display(), m);
@@ -1695,28 +1685,27 @@ fn path_equals(dent: &DirEntry, handle: &Handle) -> Result<bool, Error> {
/// Returns true if and only if the given path is on the same device as the /// Returns true if and only if the given path is on the same device as the
/// given root device. /// given root device.
fn is_same_file_system(root_device: u64, path: &Path) -> Result<bool, Error> { fn is_same_file_system(root_device: u64, path: &Path) -> Result<bool, Error> {
let dent_device = device_num(path) let dent_device = device_num(path).map_err(|err| Error::Io(err).with_path(path))?;
.map_err(|err| Error::Io(err).with_path(path))?;
Ok(root_device == dent_device) Ok(root_device == dent_device)
} }
#[cfg(unix)] #[cfg(unix)]
fn device_num<P: AsRef<Path>>(path: P)-> io::Result<u64> { fn device_num<P: AsRef<Path>>(path: P) -> io::Result<u64> {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
path.as_ref().metadata().map(|md| md.dev()) path.as_ref().metadata().map(|md| md.dev())
} }
#[cfg(windows)] #[cfg(windows)]
fn device_num<P: AsRef<Path>>(path: P) -> io::Result<u64> { fn device_num<P: AsRef<Path>>(path: P) -> io::Result<u64> {
use winapi_util::{Handle, file}; use winapi_util::{file, Handle};
let h = Handle::from_path_any(path)?; let h = Handle::from_path_any(path)?;
file::information(h).map(|info| info.volume_serial_number()) file::information(h).map(|info| info.volume_serial_number())
} }
#[cfg(not(any(unix, windows)))] #[cfg(not(any(unix, windows)))]
fn device_num<P: AsRef<Path>>(_: P)-> io::Result<u64> { fn device_num<P: AsRef<Path>>(_: P) -> io::Result<u64> {
Err(io::Error::new( Err(io::Error::new(
io::ErrorKind::Other, io::ErrorKind::Other,
"walkdir: same_file_system option not supported on this platform", "walkdir: same_file_system option not supported on this platform",
@@ -1730,9 +1719,8 @@ mod tests {
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tempfile::{self, TempDir};
use super::{DirEntry, WalkBuilder, WalkState}; use super::{DirEntry, WalkBuilder, WalkState};
use tests::TempDir;
fn wfile<P: AsRef<Path>>(path: P, contents: &str) { fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
let mut file = File::create(path).unwrap(); let mut file = File::create(path).unwrap();
@@ -1779,10 +1767,7 @@ mod tests {
paths paths
} }
fn walk_collect_parallel( fn walk_collect_parallel(prefix: &Path, builder: &WalkBuilder) -> Vec<String> {
prefix: &Path,
builder: &WalkBuilder,
) -> Vec<String> {
let mut paths = vec![]; let mut paths = vec![];
for dent in walk_collect_entries_parallel(builder) { for dent in walk_collect_entries_parallel(builder) {
let path = dent.path().strip_prefix(prefix).unwrap(); let path = dent.path().strip_prefix(prefix).unwrap();
@@ -1817,15 +1802,11 @@ mod tests {
paths paths
} }
fn tmpdir(prefix: &str) -> TempDir { fn tmpdir() -> TempDir {
tempfile::Builder::new().prefix(prefix).tempdir().unwrap() TempDir::new().unwrap()
} }
fn assert_paths( fn assert_paths(prefix: &Path, builder: &WalkBuilder, expected: &[&str]) {
prefix: &Path,
builder: &WalkBuilder,
expected: &[&str],
) {
let got = walk_collect(prefix, builder); let got = walk_collect(prefix, builder);
assert_eq!(got, mkpaths(expected), "single threaded"); assert_eq!(got, mkpaths(expected), "single threaded");
let got = walk_collect_parallel(prefix, builder); let got = walk_collect_parallel(prefix, builder);
@@ -1834,20 +1815,22 @@ mod tests {
#[test] #[test]
fn no_ignores() { fn no_ignores() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("a/b/c")); mkdirp(td.path().join("a/b/c"));
mkdirp(td.path().join("x/y")); mkdirp(td.path().join("x/y"));
wfile(td.path().join("a/b/foo"), ""); wfile(td.path().join("a/b/foo"), "");
wfile(td.path().join("x/y/foo"), ""); wfile(td.path().join("x/y/foo"), "");
assert_paths(td.path(), &WalkBuilder::new(td.path()), &[ assert_paths(
"x", "x/y", "x/y/foo", "a", "a/b", "a/b/foo", "a/b/c", td.path(),
]); &WalkBuilder::new(td.path()),
&["x", "x/y", "x/y/foo", "a", "a/b", "a/b/foo", "a/b/c"],
);
} }
#[test] #[test]
fn custom_ignore() { fn custom_ignore() {
let td = tmpdir("walk-test-"); let td = tmpdir();
let custom_ignore = ".customignore"; let custom_ignore = ".customignore";
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(td.path().join(custom_ignore), "foo"); wfile(td.path().join(custom_ignore), "foo");
@@ -1863,7 +1846,7 @@ mod tests {
#[test] #[test]
fn custom_ignore_exclusive_use() { fn custom_ignore_exclusive_use() {
let td = tmpdir("walk-test-"); let td = tmpdir();
let custom_ignore = ".customignore"; let custom_ignore = ".customignore";
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(td.path().join(custom_ignore), "foo"); wfile(td.path().join(custom_ignore), "foo");
@@ -1883,7 +1866,7 @@ mod tests {
#[test] #[test]
fn gitignore() { fn gitignore() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(td.path().join(".gitignore"), "foo"); wfile(td.path().join(".gitignore"), "foo");
@@ -1892,14 +1875,16 @@ mod tests {
wfile(td.path().join("bar"), ""); wfile(td.path().join("bar"), "");
wfile(td.path().join("a/bar"), ""); wfile(td.path().join("a/bar"), "");
assert_paths(td.path(), &WalkBuilder::new(td.path()), &[ assert_paths(
"bar", "a", "a/bar", td.path(),
]); &WalkBuilder::new(td.path()),
&["bar", "a", "a/bar"],
);
} }
#[test] #[test]
fn explicit_ignore() { fn explicit_ignore() {
let td = tmpdir("walk-test-"); let td = tmpdir();
let igpath = td.path().join(".not-an-ignore"); let igpath = td.path().join(".not-an-ignore");
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(&igpath, "foo"); wfile(&igpath, "foo");
@@ -1915,7 +1900,7 @@ mod tests {
#[test] #[test]
fn explicit_ignore_exclusive_use() { fn explicit_ignore_exclusive_use() {
let td = tmpdir("walk-test-"); let td = tmpdir();
let igpath = td.path().join(".not-an-ignore"); let igpath = td.path().join(".not-an-ignore");
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(&igpath, "foo"); wfile(&igpath, "foo");
@@ -1927,13 +1912,16 @@ mod tests {
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
builder.standard_filters(false); builder.standard_filters(false);
assert!(builder.add_ignore(&igpath).is_none()); assert!(builder.add_ignore(&igpath).is_none());
assert_paths(td.path(), &builder, assert_paths(
&[".not-an-ignore", "bar", "a", "a/bar"]); td.path(),
&builder,
&[".not-an-ignore", "bar", "a", "a/bar"],
);
} }
#[test] #[test]
fn gitignore_parent() { fn gitignore_parent() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join(".git")); mkdirp(td.path().join(".git"));
mkdirp(td.path().join("a")); mkdirp(td.path().join("a"));
wfile(td.path().join(".gitignore"), "foo"); wfile(td.path().join(".gitignore"), "foo");
@@ -1946,7 +1934,7 @@ mod tests {
#[test] #[test]
fn max_depth() { fn max_depth() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("a/b/c")); mkdirp(td.path().join("a/b/c"));
wfile(td.path().join("foo"), ""); wfile(td.path().join("foo"), "");
wfile(td.path().join("a/foo"), ""); wfile(td.path().join("a/foo"), "");
@@ -1954,19 +1942,23 @@ mod tests {
wfile(td.path().join("a/b/c/foo"), ""); wfile(td.path().join("a/b/c/foo"), "");
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
assert_paths(td.path(), &builder, &[ assert_paths(
"a", "a/b", "a/b/c", "foo", "a/foo", "a/b/foo", "a/b/c/foo", td.path(),
]); &builder,
&["a", "a/b", "a/b/c", "foo", "a/foo", "a/b/foo", "a/b/c/foo"],
);
assert_paths(td.path(), builder.max_depth(Some(0)), &[]); assert_paths(td.path(), builder.max_depth(Some(0)), &[]);
assert_paths(td.path(), builder.max_depth(Some(1)), &["a", "foo"]); assert_paths(td.path(), builder.max_depth(Some(1)), &["a", "foo"]);
assert_paths(td.path(), builder.max_depth(Some(2)), &[ assert_paths(
"a", "a/b", "foo", "a/foo", td.path(),
]); builder.max_depth(Some(2)),
&["a", "a/b", "foo", "a/foo"],
);
} }
#[test] #[test]
fn max_filesize() { fn max_filesize() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("a/b")); mkdirp(td.path().join("a/b"));
wfile_size(td.path().join("foo"), 0); wfile_size(td.path().join("foo"), 0);
wfile_size(td.path().join("bar"), 400); wfile_size(td.path().join("bar"), 400);
@@ -1976,41 +1968,49 @@ mod tests {
wfile_size(td.path().join("a/baz"), 200); wfile_size(td.path().join("a/baz"), 200);
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
assert_paths(td.path(), &builder, &[ assert_paths(
"a", "a/b", "foo", "bar", "baz", "a/foo", "a/bar", "a/baz", td.path(),
]); &builder,
assert_paths(td.path(), builder.max_filesize(Some(0)), &[ &["a", "a/b", "foo", "bar", "baz", "a/foo", "a/bar", "a/baz"],
"a", "a/b", "foo" );
]); assert_paths(
assert_paths(td.path(), builder.max_filesize(Some(500)), &[ td.path(),
"a", "a/b", "foo", "bar", "a/bar", "a/baz" builder.max_filesize(Some(0)),
]); &["a", "a/b", "foo"],
assert_paths(td.path(), builder.max_filesize(Some(50000)), &[ );
"a", "a/b", "foo", "bar", "baz", "a/foo", "a/bar", "a/baz", assert_paths(
]); td.path(),
builder.max_filesize(Some(500)),
&["a", "a/b", "foo", "bar", "a/bar", "a/baz"],
);
assert_paths(
td.path(),
builder.max_filesize(Some(50000)),
&["a", "a/b", "foo", "bar", "baz", "a/foo", "a/bar", "a/baz"],
);
} }
#[cfg(unix)] // because symlinks on windows are weird #[cfg(unix)] // because symlinks on windows are weird
#[test] #[test]
fn symlinks() { fn symlinks() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("a/b")); mkdirp(td.path().join("a/b"));
symlink(td.path().join("a/b"), td.path().join("z")); symlink(td.path().join("a/b"), td.path().join("z"));
wfile(td.path().join("a/b/foo"), ""); wfile(td.path().join("a/b/foo"), "");
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
assert_paths(td.path(), &builder, &[ assert_paths(td.path(), &builder, &["a", "a/b", "a/b/foo", "z"]);
"a", "a/b", "a/b/foo", "z", assert_paths(
]); td.path(),
assert_paths(td.path(), &builder.follow_links(true), &[ &builder.follow_links(true),
"a", "a/b", "a/b/foo", "z", "z/foo", &["a", "a/b", "a/b/foo", "z", "z/foo"],
]); );
} }
#[cfg(unix)] // because symlinks on windows are weird #[cfg(unix)] // because symlinks on windows are weird
#[test] #[test]
fn first_path_not_symlink() { fn first_path_not_symlink() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("foo")); mkdirp(td.path().join("foo"));
let dents = WalkBuilder::new(td.path().join("foo")) let dents = WalkBuilder::new(td.path().join("foo"))
@@ -2021,9 +2021,7 @@ mod tests {
assert_eq!(1, dents.len()); assert_eq!(1, dents.len());
assert!(!dents[0].path_is_symlink()); assert!(!dents[0].path_is_symlink());
let dents = walk_collect_entries_parallel( let dents = walk_collect_entries_parallel(&WalkBuilder::new(td.path().join("foo")));
&WalkBuilder::new(td.path().join("foo")),
);
assert_eq!(1, dents.len()); assert_eq!(1, dents.len());
assert!(!dents[0].path_is_symlink()); assert!(!dents[0].path_is_symlink());
} }
@@ -2031,17 +2029,13 @@ mod tests {
#[cfg(unix)] // because symlinks on windows are weird #[cfg(unix)] // because symlinks on windows are weird
#[test] #[test]
fn symlink_loop() { fn symlink_loop() {
let td = tmpdir("walk-test-"); let td = tmpdir();
mkdirp(td.path().join("a/b")); mkdirp(td.path().join("a/b"));
symlink(td.path().join("a"), td.path().join("a/b/c")); symlink(td.path().join("a"), td.path().join("a/b/c"));
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
assert_paths(td.path(), &builder, &[ assert_paths(td.path(), &builder, &["a", "a/b", "a/b/c"]);
"a", "a/b", "a/b/c", assert_paths(td.path(), &builder.follow_links(true), &["a", "a/b"]);
]);
assert_paths(td.path(), &builder.follow_links(true), &[
"a", "a/b",
]);
} }
// It's a little tricky to test the 'same_file_system' option since // It's a little tricky to test the 'same_file_system' option since
@@ -2061,7 +2055,7 @@ mod tests {
// If our test directory actually isn't a different volume from /sys, // If our test directory actually isn't a different volume from /sys,
// then this test is meaningless and we shouldn't run it. // then this test is meaningless and we shouldn't run it.
let td = tmpdir("walk-test-"); let td = tmpdir();
if device_num(td.path()).unwrap() == device_num("/sys").unwrap() { if device_num(td.path()).unwrap() == device_num("/sys").unwrap() {
return; return;
} }
@@ -2075,8 +2069,6 @@ mod tests {
// completely. // completely.
let mut builder = WalkBuilder::new(td.path()); let mut builder = WalkBuilder::new(td.path());
builder.follow_links(true).same_file_system(true); builder.follow_links(true).same_file_system(true);
assert_paths(td.path(), &builder, &[ assert_paths(td.path(), &builder, &["same_file", "same_file/alink"]);
"same_file", "same_file/alink",
]);
} }
} }

View File

@@ -1,14 +1,14 @@
class RipgrepBin < Formula class RipgrepBin < Formula
version '11.0.1' version '11.0.2'
desc "Recursively search directories for a regex pattern." desc "Recursively search directories for a regex pattern."
homepage "https://github.com/BurntSushi/ripgrep" homepage "https://github.com/BurntSushi/ripgrep"
if OS.mac? if OS.mac?
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz" url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
sha256 "92446c6b28b6c726f91ad66a03bcd533fc6e1a28ef4b44c27bfe2d49a0f88531" sha256 "0ba26423691deedf2649b12b1abe3d2be294ee1cb17c40b68fe85efe194f4f57"
elsif OS.linux? elsif OS.linux?
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz" url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
sha256 "ce74cabac9b39b1ad55837ec01e2c670fa7e965772ac2647b209e31ead19008c" sha256 "2e7978e346553fbc45c0940d9fa11e12f9afbae8213b261aad19b698150e169a"
end end
conflicts_with "ripgrep" conflicts_with "ripgrep"

View File

@@ -1,2 +0,0 @@
termcolor has moved to its own repository:
https://github.com/BurntSushi/termcolor

View File

@@ -1,2 +0,0 @@
wincolor has moved to the termcolor repository:
https://github.com/BurntSushi/termcolor