83 Commits

Author SHA1 Message Date
Sylvestre Ledru adda4c1ba5 Update 0.3.0 2022-01-26 23:38:16 +01:00
Sylvestre Ledru 250867d99c Merge pull request #135 from sylvestre/udeps
Move tempfile dep to dev-dep
2022-01-26 23:34:53 +01:00
Sylvestre Ledru c61af2ae0e Move tempfile dep to dev-dep
cargo +nightly udeps
2022-01-26 23:10:33 +01:00
Sylvestre Ledru c616c69854 Merge pull request #132 from refi64/update-uucore
Update uucore to 0.0.12
2022-01-25 22:38:14 +01:00
Sylvestre Ledru bec239f9d6 Merge pull request #133 from refi64/download-correct-workflow
Fix compat tests not using the latest workflow
2022-01-25 13:48:10 +01:00
Ryan Gonzalez ab25ef8d1a Fix compat tests not using the latest workflow
By default, artifacts are only downloaded from the latest successful
workflow, meaning that, if the compat tests regressed, then it is
impossible to compare against the new current state. This isn't a
perfect solution, but I believe it should by far be "good enough" for
these purposes.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-24 11:28:53 -06:00
Ryan Gonzalez 949e76b5b9 Update uucore to 0.0.12
This version includes the needed filesystem type detection fix.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-24 09:32:59 -06:00
Sylvestre Ledru 1e67813594 Merge pull request #121 from refi64/xargs
Add an initial implementation of xargs
2022-01-23 15:59:20 +01:00
Ryan Gonzalez 3a1c42123f Add an initial implementation of xargs
This includes much of the core xargs functionality, with the following
notable exceptions:

- Parallel execution (`-P`): This option currently just does
  nothing, that way anything that passes -P can at least run without a
  notable behavior shift (other than simply being slower).
- Replacement strings (`-I`): This can easily be worked around via an
  intermediate shell invocation (e.g. `xargs -L1 sh -c 'do-things-with
  $@' --`).
- EOF strings (`-E`): I've honestly never seen this actually used,
  though it would not be particularly difficult to implement given the
  current architecture.

Closes #37

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-22 20:22:01 -06:00
Sylvestre Ledru 8fe924cb68 update of the readme 2022-01-23 01:23:53 +01:00
Sylvestre Ledru d432d665d1 Merge pull request #126 from refi64/regex
Add support for regex matching
2022-01-23 01:19:55 +01:00
Sylvestre Ledru 96b353b7f5 Merge pull request #123 from refi64/print02
Add support for -print0
2022-01-23 01:18:09 +01:00
Ryan Gonzalez 4d9ede3c89 Add support for -print0
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-22 09:10:10 -06:00
Ryan Gonzalez 0298d20481 Update proc_macro2
Depending on onig ends up requiring proc_macro2, but the version that
was in the lockfile breaks the build if panic=abort is used (which is
done for coverage checks). This was fixed in 1.0.30+ for Rust 1.57+, so
update to that version.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-22 09:05:20 -06:00
Ryan Gonzalez e52b4f2e46 Add support for regex matching
This adds support for -regextype, -regex, and -iregex, using Oniguruma
to implement support for the Emacs, grep, POSIX basic, and POSIX
extended regex types.

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-22 09:05:20 -06:00
Sylvestre Ledru bdfd492a0a Merge pull request #130 from refi64/compat-tests-2
Add remaining portions of automated compatibility tests
2022-01-22 10:14:58 +01:00
Sylvestre Ledru 79d4bc4b2f Merge pull request #129 from refi64/compat-tests-1
Add initial parts of automated compatibility tests
2022-01-21 23:51:08 +01:00
Ryan Gonzalez 165d72efd2 Add remaining portions of automated compatibility tests
This adds the rest of the compatibility test workflow, in order to
automatically run against the GNU findutils & BFS test suites as part of
standard CI and compare the results to the latest from the 'main'
branch.

Closes #128

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-21 16:18:35 -06:00
Ryan Gonzalez 97ea4ae294 Add initial parts of automated compatibility tests
This is the first half of the needed changes to set up automated
compatibility tests against GNU findutils and bfs, handling the uploads
of the build logs and JSON results. The workflow itself is heavily based
on the one from uutils/coreutils:

https://github.com/uutils/coreutils/blob/main/.github/workflows/GnuTests.yml

but with various cleanups & tweaks to better suit findutils.

This does *not* include the actual regression comparisons, because those
will only pass once archives of these files are up on the main branch.

Ref #128

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2022-01-21 16:15:48 -06:00
Sylvestre Ledru 50d2bde28f Merge pull request #127 from uutils/dependabot/cargo/assert_cmd-2.0.4
Bump assert_cmd from 2.0.2 to 2.0.4
2022-01-14 09:34:57 +01:00
dependabot[bot] 8e3093b4e8 Bump assert_cmd from 2.0.2 to 2.0.4
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 2.0.2 to 2.0.4.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v2.0.2...v2.0.4)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-14 07:18:26 +00:00
Sylvestre Ledru b8b3c32a1c Merge pull request #124 from uutils/dependabot/cargo/predicates-2.1.1
Bump predicates from 2.1.0 to 2.1.1
2022-01-12 09:58:12 +01:00
dependabot[bot] 27e8e4a186 Bump predicates from 2.1.0 to 2.1.1
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v2.1.0...v2.1.1)

---
updated-dependencies:
- dependency-name: predicates
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-12 07:12:56 +00:00
Sylvestre Ledru 81402f3c59 Merge pull request #120 from refi64/printf
Add support for GNU-compatible printf
2022-01-10 10:32:29 +01:00
Sylvestre Ledru dd443b977c Merge branch 'master' into printf 2022-01-10 09:59:52 +01:00
Sylvestre Ledru d38536222f Merge pull request #122 from uutils/dependabot/cargo/tempfile-3.3.0
Bump tempfile from 3.2.0 to 3.3.0
2022-01-10 09:58:45 +01:00
dependabot[bot] fdf0707885 Bump tempfile from 3.2.0 to 3.3.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.2.0 to 3.3.0.
- [Release notes](https://github.com/Stebalien/tempfile/releases)
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.2.0...v3.3.0)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-10 07:10:01 +00:00
Ryan Gonzalez 0ea822cecb Add support for GNU-compatible printf
This adds initial support for GNU find-compatible printf syntax. As far
as I can tell, it should implement all the specifiers, with the
following exceptions:

- Using zero as padding instead of space: GNU find isn't consistent with
  which numeric format specifiers support this.
- Specifying precision (`%x.yz`): I believe sparseness (%S)
  and seconds-since-epoch (`%A@` / `%C@` / `%T@`) are the only ones that
  allow this, making it only partially useful.
- Printing SELinux contexts (`%Z`): requires some extra dependencies and
  isn't within our scope.

uucore is added as a dependency, because it has several utility
functions that we need, the complexity of which is high enough that
using the extra dependency is quite helpful.

This also stubs out many of the specifiers for Windows, simply because I
have no idea how these should work there. (The defaults chosen should be
"good enough" for the moment, though.)

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
2021-12-27 13:44:35 -06:00
Sylvestre Ledru 87ceb10073 Merge pull request #119 from uutils/dependabot/cargo/predicates-2.1.0
Bump predicates from 2.0.2 to 2.1.0
2021-11-23 14:06:03 +01:00
dependabot[bot] a99eae5136 Bump predicates from 2.0.2 to 2.1.0
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 2.0.2 to 2.1.0.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v2.0.2...v2.1.0)

---
updated-dependencies:
- dependency-name: predicates
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-23 07:13:16 +00:00
Sylvestre Ledru aa4713e766 Merge pull request #117 from uutils/dependabot/cargo/assert_cmd-2.0.2
Bump assert_cmd from 2.0.1 to 2.0.2
2021-10-08 09:33:44 +02:00
dependabot[bot] 6078cdc66a Bump assert_cmd from 2.0.1 to 2.0.2
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-08 07:11:12 +00:00
Sylvestre Ledru ab451cf014 Merge pull request #116 from tavianator/bfs-tests
ci: Run the bfs testsuite
2021-09-15 16:09:58 +02:00
Tavian Barnes 8b7bf9e0d1 ci: Run the bfs testsuite 2021-09-15 09:57:18 -04:00
Sylvestre Ledru 1dff91e3c5 Merge pull request #115 from sylvestre/gnu
run the GNU testsuite in the CI
2021-09-08 00:04:55 +02:00
Sylvestre Ledru bf478a140d run the GNU testsuite in the CI 2021-09-07 23:51:15 +02:00
Sylvestre Ledru 4ead9a3c62 document how to run the gnu testsuite 2021-09-07 23:25:08 +02:00
Sylvestre Ledru bcb7fab917 GNU: allow to run a specific arg 2021-09-07 23:23:29 +02:00
Sylvestre Ledru 94c830661b GNU: Don't build it everytime 2021-09-07 23:22:58 +02:00
Sylvestre Ledru 28989171ab add a script to run the tests with the GNU testsuite 2021-09-07 23:01:43 +02:00
Sylvestre Ledru ac576f50b0 add --version to the cli 2021-09-07 22:39:36 +02:00
Sylvestre Ledru 2a39bf143b update of the version to 0.2.0 2021-09-07 22:13:15 +02:00
Sylvestre Ledru 3d65249b4e remove the travis badge 2021-09-07 22:11:53 +02:00
Sylvestre Ledru 40cd5719c2 Merge pull request #111 from sylvestre/cov
Add back coverage with codecov
2021-09-07 12:16:32 +02:00
Sylvestre Ledru 0253f24657 Add back coverage with codecov 2021-09-07 11:53:37 +02:00
Sylvestre Ledru b9b899cb13 Merge pull request #110 from sylvestre/tempfile
replace tempdir by tempfile
2021-09-07 10:52:16 +02:00
Sylvestre Ledru f9e736d194 replace tempdir by tempfile 2021-09-07 10:36:07 +02:00
Sylvestre Ledru 49ee992dcd remove the author file. it hasn't been used 2021-09-07 09:35:33 +02:00
Sylvestre Ledru 1dcd2d5d77 Merge pull request #109 from uutils/dependabot/cargo/assert_cmd-2.0.1
Bump assert_cmd from 2.0.0 to 2.0.1
2021-09-07 09:33:12 +02:00
dependabot[bot] 5336410602 Bump assert_cmd from 2.0.0 to 2.0.1
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-07 07:09:29 +00:00
Sylvestre Ledru 9b319c7474 Merge pull request #108 from uutils/dependabot/cargo/predicates-2.0.2
Bump predicates from 2.0.1 to 2.0.2
2021-08-17 09:35:59 +02:00
dependabot[bot] d7e7c7f7fb Bump predicates from 2.0.1 to 2.0.2
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 2.0.1 to 2.0.2.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: predicates
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-17 07:10:18 +00:00
Sylvestre Ledru d9c68c27c3 Merge pull request #105 from uutils/dependabot/cargo/predicates-2.0.1
Bump predicates from 2.0.0 to 2.0.1
2021-08-06 09:53:29 +02:00
dependabot[bot] 420cbe826b Bump predicates from 2.0.0 to 2.0.1
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: predicates
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-06 07:21:23 +00:00
Sylvestre Ledru 48ca34914f Merge pull request #107 from uutils/dependabot/cargo/assert_cmd-2.0.0
Bump assert_cmd from 1.0.8 to 2.0.0
2021-08-06 09:20:19 +02:00
dependabot[bot] 9127763651 Bump assert_cmd from 1.0.8 to 2.0.0
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 1.0.8 to 2.0.0.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v1.0.8...v2.0.0)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-06 07:11:06 +00:00
Sylvestre Ledru 540842a241 Merge pull request #106 from uutils/dependabot/cargo/assert_cmd-1.0.8
Bump assert_cmd from 1.0.5 to 1.0.8
2021-08-02 09:13:11 +02:00
dependabot[bot] 1f760bc2a5 Bump assert_cmd from 1.0.5 to 1.0.8
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 1.0.5 to 1.0.8.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v1.0.5...v1.0.8)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 07:09:50 +00:00
Sylvestre Ledru 0f05b1e932 Merge pull request #104 from sylvestre/pred
update predicates
2021-07-05 10:00:47 +02:00
Sylvestre Ledru 52adf59b5c Merge pull request #103 from sylvestre/clip
Fix some clippy warnings
2021-07-05 09:50:21 +02:00
Sylvestre Ledru 35ef54a2b3 predicate: adjust the api 2021-07-05 09:50:06 +02:00
dependabot[bot] eedda44ac9 Bump predicates from 1.0.8 to 2.0.0
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 1.0.8 to 2.0.0.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v1.0.8...v2.0.0)
2021-07-05 09:46:33 +02:00
Sylvestre Ledru 8f9334479e Fix another clippy warning
`writing `&PathBuf` instead of `&Path` involves a new object where a slice will do`
2021-07-05 09:44:25 +02:00
Sylvestre Ledru 2b5eca5355 Fix a clippy warning
`struct constructor field order is inconsistent with struct definition field order`
2021-07-05 09:39:47 +02:00
Sylvestre Ledru d7fcd6c1ee Merge pull request #99 from uutils/dependabot/cargo/assert_cmd-1.0.5
Bump assert_cmd from 1.0.4 to 1.0.5
2021-06-03 11:54:18 +02:00
dependabot[bot] 8472a9e982 Bump assert_cmd from 1.0.4 to 1.0.5
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v1.0.4...v1.0.5)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-03 07:46:27 +00:00
Sylvestre Ledru 73593f30ae Merge pull request #95 from uutils/dependabot/cargo/predicates-1.0.8
Bump predicates from 1.0.7 to 1.0.8
2021-05-22 12:50:55 +02:00
Sylvestre Ledru 93be4b7050 Merge pull request #97 from uutils/dependabot/cargo/regex-1.5.4
Bump regex from 1.5.3 to 1.5.4
2021-05-22 12:50:42 +02:00
Sylvestre Ledru b3a2767bcb Merge pull request #98 from uutils/dependabot/cargo/assert_cmd-1.0.4
Bump assert_cmd from 1.0.3 to 1.0.4
2021-05-13 09:58:55 +02:00
dependabot[bot] 80938e1ff3 Bump assert_cmd from 1.0.3 to 1.0.4
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/assert-rs/assert_cmd/releases)
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v1.0.3...v1.0.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-13 07:17:43 +00:00
dependabot[bot] bda0bac489 Bump regex from 1.5.3 to 1.5.4
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.3 to 1.5.4.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.3...1.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-07 08:50:45 +00:00
Sylvestre Ledru aab63c089d Merge pull request #92 from tavianator/execdir-root-chdir
exec: Handle parent directories more carefully
2021-05-03 10:00:38 +02:00
Sylvestre Ledru 0069dd3e71 Merge pull request #94 from uutils/dependabot/add-v2-config-file
Upgrade to GitHub-native Dependabot
2021-05-03 10:00:08 +02:00
Sylvestre Ledru 7cc30e3c07 Merge pull request #96 from uutils/dependabot/cargo/regex-1.5.3
Bump regex from 1.4.5 to 1.5.3
2021-05-03 09:59:19 +02:00
dependabot-preview[bot] 810a2df417 Bump regex from 1.4.5 to 1.5.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.4.5 to 1.5.3.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.4.5...1.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-05-03 07:37:44 +00:00
dependabot-preview[bot] c20333c9dd Bump predicates from 1.0.7 to 1.0.8
Bumps [predicates](https://github.com/assert-rs/predicates-rs) from 1.0.7 to 1.0.8.
- [Release notes](https://github.com/assert-rs/predicates-rs/releases)
- [Changelog](https://github.com/assert-rs/predicates-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/predicates-rs/compare/v1.0.7...v1.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-29 07:15:07 +00:00
dependabot-preview[bot] 03923ae435 Upgrade to GitHub-native Dependabot 2021-04-28 21:37:47 +00:00
Tavian Barnes 88cbbff332 exec: Handle parent directories more carefully
Fixes #23, fixes #28.
2021-03-28 17:47:46 -04:00
Sylvestre Ledru 85e96152f6 Merge pull request #91 from tavianator/calm-exec-plus
Make multi-exec only match {} + with nothing in between
2021-03-28 20:28:56 +02:00
Tavian Barnes 87c5caa779 Make multi-exec only match {} + with nothing in between
Fixes #40.
2021-03-28 13:37:11 -04:00
Sylvestre Ledru 8ecc66fc46 Merge pull request #90 from uutils/dependabot/cargo/walkdir-2.3.2
Bump walkdir from 2.3.1 to 2.3.2
2021-03-23 12:38:25 +01:00
dependabot-preview[bot] 595d832f8f Bump walkdir from 2.3.1 to 2.3.2
Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/BurntSushi/walkdir/releases)
- [Commits](https://github.com/BurntSushi/walkdir/compare/2.3.1...2.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-23 11:10:22 +00:00
Sylvestre Ledru 49d78548b2 README.md: add the crates.io badge 2021-03-15 10:03:28 +01:00
29 changed files with 4351 additions and 160 deletions
+8
View File
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: cargo
directory: "/"
schedule:
interval: daily
time: "07:00"
open-pull-requests-limit: 10
+127
View File
@@ -16,6 +16,16 @@ jobs:
profile: minimal
toolchain: stable
override: true
# For bindgen: https://github.com/rust-lang/rust-bindgen/issues/1797
- uses: KyleMayes/install-llvm-action@v1
if: matrix.os == 'windows-latest'
with:
version: "11.0"
directory: ${{ runner.temp }}/llvm
- run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
if: matrix.os == 'windows-latest'
- uses: actions-rs/cargo@v1
with:
command: check
@@ -33,6 +43,16 @@ jobs:
profile: minimal
toolchain: stable
override: true
# For bindgen: https://github.com/rust-lang/rust-bindgen/issues/1797
- uses: KyleMayes/install-llvm-action@v1
if: matrix.os == 'windows-latest'
with:
version: "11.0"
directory: ${{ runner.temp }}/llvm
- run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
if: matrix.os == 'windows-latest'
- uses: actions-rs/cargo@v1
with:
command: test
@@ -68,3 +88,110 @@ jobs:
with:
command: clippy
args: -- -D warnings
grcov:
name: Code coverage
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
toolchain:
- nightly
cargo_flags:
- "--all-features"
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.toolchain }}
override: true
- name: Install grcov
uses: actions-rs/install@v0.1
with:
crate: grcov
version: latest
use-tool-cache: true
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
args: --all --no-fail-fast ${{ matrix.cargo_flags }}
env:
CARGO_INCREMENTAL: "0"
RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort -Cdebug-assertions=off'
RUSTDOCFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort -Cdebug-assertions=off'
- name: Generate coverage data
id: grcov
# uses: actions-rs/grcov@v0.1
run: |
grcov target/debug/ \
--branch \
--llvm \
--source-dir . \
--output-path lcov.info \
--ignore-not-existing \
--excl-line "#\\[derive\\(" \
--excl-br-line "#\\[derive\\(" \
--excl-start "#\\[cfg\\(test\\)\\]" \
--excl-br-start "#\\[cfg\\(test\\)\\]" \
--commit-sha ${{ github.sha }} \
--service-job-id ${{ github.job }} \
--service-name "GitHub Actions" \
--service-number ${{ github.run_id }}
- name: Upload coverage as artifact
uses: actions/upload-artifact@v2
with:
name: lcov.info
# path: ${{ steps.grcov.outputs.report }}
path: lcov.info
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@v1
with:
# file: ${{ steps.grcov.outputs.report }}
file: lcov.info
fail_ci_if_error: true
external:
name: External testsuites
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
toolchain:
- nightly
cargo_flags:
- "--all-features"
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.toolchain }}
override: true
- name: Run the gnu testsuite
id: gnu
run: |
sudo apt install autopoint
git clone https://git.savannah.gnu.org/git/findutils.git ../findutils.gnu
bash util/build-gnu.sh || true
- name: Run the bfs testsuite
id: bfs
run: |
sudo apt install acl libacl1-dev attr libattr1-dev libcap2-bin libcap-dev
git clone https://github.com/tavianator/bfs.git ../bfs
bash util/build-bfs.sh || true
+217
View File
@@ -0,0 +1,217 @@
on: [push, pull_request]
name: GNU findutils compatibility tests
jobs:
gnu-tests:
name: Run GNU findutils tests
runs-on: ubuntu-latest
steps:
- name: Checkout findutils
uses: actions/checkout@v2
with:
path: findutils
- name: Checkout GNU findutils
uses: actions/checkout@v2
with:
repository: gnu-mirror-unofficial/findutils
path: findutils.gnu
ref: 5768a03ddfb5e18b1682e339d6cdd24ff721c510
submodules: true
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install dependencies
shell: bash
run: |
# Enable sources & install dependencies
sudo find /etc/apt/sources.list* -type f -exec sed -i 'p; s/^deb /deb-src /' '{}' +
sudo apt-get update
sudo apt-get build-dep findutils
- name: Run GNU tests
shell: bash
run: |
cd findutils
bash util/build-gnu.sh ||:
- name: Extract testing info
shell: bash
run: |
LOG_FILE=findutils.gnu/tests/test-suite.log
if test -f "$LOG_FILE"; then
TOTAL=$(sed -n "s/.*# TOTAL: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
PASS=$(sed -n "s/.*# PASS: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
SKIP=$(sed -n "s/.*# SKIP: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
FAIL=$(sed -n "s/.*# FAIL: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
XPASS=$(sed -n "s/.*# XPASS: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
ERROR=$(sed -n "s/.*# ERROR: \(.*\)/\1/p" "$LOG_FILE"|tr -d '\r'|head -n1)
if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then
echo "Error in the execution, failing early"
exit 1
fi
output="GNU tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL / ERROR: $ERROR"
echo "${output}"
if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then echo "::warning ::${output}" ; fi
jq -n \
--arg date "$(date --rfc-email)" \
--arg sha "$GITHUB_SHA" \
--arg total "$TOTAL" \
--arg pass "$PASS" \
--arg skip "$SKIP" \
--arg fail "$FAIL" \
--arg xpass "$XPASS" \
--arg error "$ERROR" \
'{($date): { sha: $sha, total: $total, pass: $pass, skip: $skip, fail: $fail, xpass: $xpass, error: $error, }}' > gnu-result.json
else
echo "::error ::Failed to get summary of test results"
fi
- uses: actions/upload-artifact@v2
with:
name: gnu-test-report
path: findutils.gnu/tests/**/*.log
- uses: actions/upload-artifact@v2
with:
name: gnu-result
path: gnu-result.json
- name: Download the result
uses: dawidd6/action-download-artifact@v2
with:
workflow: compat.yml
workflow_conclusion: completed
name: gnu-result
repo: uutils/findutils
branch: main
path: dl
- name: Download the log
uses: dawidd6/action-download-artifact@v2
with:
workflow: compat.yml
workflow_conclusion: completed
name: gnu-test-report
repo: uutils/findutils
branch: main
path: dl
- name: Compare failing tests against master
shell: bash
run: |
OLD_FAILING=$(sed -n "s/^FAIL: \([[:print:]]\+\).*/\1/p" dl/test-suite.log | sort)
NEW_FAILING=$(sed -n "s/^FAIL: \([[:print:]]\+\).*/\1/p" findutils.gnu/tests/test-suite.log | sort)
for LINE in $OLD_FAILING; do
if ! grep -Fxq $LINE<<<"$NEW_FAILING"; then
echo "::warning ::Congrats! The gnu test $LINE is now passing!"
fi
done
for LINE in $NEW_FAILING; do
if ! grep -Fxq $LINE<<<"$OLD_FAILING"; then
echo "::error ::gnu test failed: $LINE. $LINE is passing on 'main'. Maybe you have to rebase?"
fi
done
- name: Compare against main results
shell: bash
run: |
mv dl/gnu-result.json latest-gnu-result.json
python findutils/util/compare_gnu_result.py
bfs-tests:
name: Run BFS tests
runs-on: ubuntu-latest
steps:
- name: Checkout findutils
uses: actions/checkout@v2
with:
path: findutils
- name: Checkout BFS
uses: actions/checkout@v2
with:
repository: tavianator/bfs
path: bfs
ref: '2.3.1'
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install dependencies
shell: bash
run: |
# Enable sources & install dependencies
sudo find /etc/apt/sources.list* -type f -exec sed -i 'p; s/^deb /deb-src /' '{}' +
sudo apt-get update
sudo apt-get build-dep bfs
- name: Run BFS tests
shell: bash
run: |
cd findutils
bash util/build-bfs.sh ||:
- name: Extract testing info
shell: bash
run: |
LOG_FILE=bfs/tests.log
if test -f "$LOG_FILE"; then
PASS=$(sed -n "s/^tests passed: \(.*\)/\1/p" "$LOG_FILE"|head -n1)
FAIL=$(sed -n "s/^tests failed: \(.*\)/\1/p" "$LOG_FILE"|head -n1)
TOTAL=$(($PASS + $FAIL))
if [[ "$TOTAL" -eq 0 || "$TOTAL" -eq 1 ]]; then
echo "Error in the execution, failing early"
exit 1
fi
output="BFS tests summary = TOTAL: $TOTAL / PASS: $PASS / FAIL: $FAIL"
echo "${output}"
if [[ "$FAIL" -gt 0 || "$ERROR" -gt 0 ]]; then echo "::warning ::${output}" ; fi
jq -n \
--arg date "$(date --rfc-email)" \
--arg sha "$GITHUB_SHA" \
--arg total "$TOTAL" \
--arg pass "$PASS" \
--arg fail "$FAIL" \
'{($date): { sha: $sha, total: $total, pass: $pass, fail: $fail, }}' > bfs-result.json
else
echo "::error ::Failed to get summary of test results"
fi
- uses: actions/upload-artifact@v2
with:
name: bfs-test-report
path: bfs/tests.log
- uses: actions/upload-artifact@v2
with:
name: bfs-result
path: bfs-result.json
- name: Download the result
uses: dawidd6/action-download-artifact@v2
with:
workflow: compat.yml
workflow_conclusion: completed
name: bfs-result
repo: uutils/findutils
branch: main
path: dl
- name: Download the log
uses: dawidd6/action-download-artifact@v2
with:
workflow: compat.yml
workflow_conclusion: completed
name: bfs-test-report
repo: uutils/findutils
branch: main
path: dl
- name: Compare failing tests against main
shell: bash
run: |
OLD_FAILING=$(sed -n "s/^\([[:print:]]\+\) failed\!/\1/p" dl/tests.log | sort)
NEW_FAILING=$(sed -n "s/^\([[:print:]]\+\) failed\!/\1/p" bfs/tests.log | sort)
for LINE in $OLD_FAILING; do
if ! grep -Fxq $LINE<<<"$NEW_FAILING"; then
echo "::warning ::Congrats! The bfs test $LINE is now passing!"
fi
done
for LINE in $NEW_FAILING; do
if ! grep -Fxq $LINE<<<"$OLD_FAILING"; then
echo "::error ::bfs test failed: $LINE. $LINE is passing on 'main'. Maybe you have to rebase?"
fi
done
- name: Compare against main results
shell: bash
run: |
mv dl/bfs-result.json latest-bfs-result.json
python findutils/util/compare_bfs_result.py
+1 -2
View File
@@ -3,5 +3,4 @@ target
.project
.cargo
.settings
test_data/links/link-f
test_data/links/link-d
test_data/links/link-*
-4
View File
@@ -1,4 +0,0 @@
# Names should be added to this file like so:
# # Name or Organization <email address>
#
# Google Inc. <opensource@google.com>
Generated
+487 -70
View File
File diff suppressed because it is too large Load Diff
+15 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "findutils"
version = "0.1.0"
version = "0.3.0"
homepage = "https://github.com/uutils/findutils"
repository = "https://github.com/uutils/findutils"
edition = "2018"
@@ -10,20 +10,30 @@ description = "Rust implementation of GNU findutils"
authors = ["uutils developers"]
[dependencies]
chrono = "0.4"
clap = "2.34"
glob = "0.3"
walkdir = "2.3"
tempdir = "0.3"
regex = "1.4"
regex = "1.5"
once_cell = "1.9"
onig = "6.3"
uucore = { version = "0.0.12", features = ["entries", "fs", "fsext"] }
[dev-dependencies]
assert_cmd = "1"
predicates = "1"
assert_cmd = "2"
filetime = "0.2"
predicates = "2"
serial_test = "0.5"
tempfile = "3"
[[bin]]
name = "find"
path = "src/find/main.rs"
[[bin]]
name = "xargs"
path = "src/xargs/main.rs"
[[bin]]
name = "testing-commandline"
path = "src/testing/commandline/main.rs"
+16 -2
View File
@@ -1,7 +1,21 @@
# findutils
[![Build Status](https://travis-ci.org/uutils/findutils.svg?branch=master)](https://travis-ci.org/uutils/findutils)
[![Build status](https://ci.appveyor.com/api/projects/status/wrmbs03dn6sb721e/branch/master?svg=true)](https://ci.appveyor.com/project/Arcterus/findutils/branch/master)
[![Crates.io](https://img.shields.io/crates/v/findutils.svg)](https://crates.io/crates/findutils)
[![dependency status](https://deps.rs/repo/github/uutils/findutils/status.svg)](https://deps.rs/repo/github/uutils/findutils)
[![codecov](https://codecov.io/gh/uutils/findutils/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/findutils)
Rust implementation of [GNU findutils](https://www.gnu.org/software/findutils/).
## Run the GNU testsuite on rust/findutils:
```
bash util/build-gnu.sh
# To run a specific test:
bash util/build-gnu.sh tests/misc/help-version.sh
```
## Comparing with GNU
![Evolution over time - GNU testsuite](https://github.com/uutils/findutils-tracking/blob/main/gnu-results.png?raw=true)
![Evolution over time - BFS testsuite](https://github.com/uutils/findutils-tracking/blob/main/bfs-results.png?raw=true)
+7 -6
View File
@@ -63,8 +63,8 @@ impl Matcher for DeleteMatcher {
#[cfg(test)]
mod tests {
use std::fs::File;
use tempdir::TempDir;
use std::fs::{create_dir, File};
use tempfile::Builder;
use super::*;
use crate::find::matchers::tests::get_dir_entry_for;
@@ -75,9 +75,11 @@ mod tests {
let matcher = DeleteMatcher::new();
let deps = FakeDependencies::new();
let temp_dir = TempDir::new_in("test_data", "delete_matcher").expect("made temp dir");
let temp_dir = Builder::new().prefix("test_data").tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_string_lossy();
File::create(temp_dir.path().join("test")).expect("created test file");
create_dir(temp_dir.path().join("test_dir")).expect("created test directory");
let test_entry = get_dir_entry_for(&temp_dir_path, "test");
assert!(
matcher.matches(&test_entry, &mut deps.new_matcher_io()),
@@ -88,14 +90,13 @@ mod tests {
"DeleteMatcher should actually delete files it matches",
);
let temp_dir_name = temp_dir.path().file_name().unwrap().to_string_lossy();
let temp_dir_entry = get_dir_entry_for("test_data", &temp_dir_name);
let temp_dir_entry = get_dir_entry_for(&temp_dir_path, "test_dir");
assert!(
matcher.matches(&temp_dir_entry, &mut deps.new_matcher_io()),
"DeleteMatcher should match directories",
);
assert!(
!temp_dir.path().exists(),
!temp_dir.path().join("test_dir").exists(),
"DeleteMatcher should actually delete (empty) directories it matches",
);
}
+11 -4
View File
@@ -78,10 +78,17 @@ impl Matcher for SingleExecMatcher {
});
}
if self.exec_in_parent_dir {
if file_info.path() == Path::new(".") {
command.current_dir(file_info.path());
} else if let Some(parent) = file_info.path().parent() {
command.current_dir(parent);
match file_info.path().parent() {
None => {
// Root paths like "/" have no parent. Run them from the root to match GNU find.
command.current_dir(file_info.path());
}
Some(parent) if parent == Path::new("") => {
// Paths like "foo" have a parent of "". Avoid chdir("").
}
Some(parent) => {
command.current_dir(parent);
}
}
}
match command.status() {
+5 -5
View File
@@ -11,7 +11,7 @@
//! to "-foo -o ( -bar -baz )", not "( -foo -o -bar ) -baz").
use std::error::Error;
use std::iter::Iterator;
use std::path::PathBuf;
use std::path::Path;
use walkdir::DirEntry;
use super::{Matcher, MatcherIO};
@@ -44,7 +44,7 @@ impl Matcher for AndMatcher {
self.submatchers.iter().any(|x| x.has_side_effects())
}
fn finished_dir(&self, dir: &PathBuf) {
fn finished_dir(&self, dir: &Path) {
for m in &self.submatchers {
m.finished_dir(dir);
}
@@ -113,7 +113,7 @@ impl Matcher for OrMatcher {
self.submatchers.iter().any(|x| x.has_side_effects())
}
fn finished_dir(&self, dir: &PathBuf) {
fn finished_dir(&self, dir: &Path) {
for m in &self.submatchers {
m.finished_dir(dir);
}
@@ -204,7 +204,7 @@ impl Matcher for ListMatcher {
self.submatchers.iter().any(|x| x.has_side_effects())
}
fn finished_dir(&self, dir: &PathBuf) {
fn finished_dir(&self, dir: &Path) {
for m in &self.submatchers {
m.finished_dir(dir);
}
@@ -342,7 +342,7 @@ impl Matcher for NotMatcher {
self.submatcher.has_side_effects()
}
fn finished_dir(&self, dir: &PathBuf) {
fn finished_dir(&self, dir: &Path) {
self.submatcher.finished_dir(dir);
}
+60 -8
View File
@@ -10,15 +10,17 @@ mod logical_matchers;
mod name;
mod perm;
mod printer;
mod printf;
mod prune;
mod regex;
mod size;
mod time;
mod type_matcher;
use regex::Regex;
use std::error::Error;
use std::path::PathBuf;
use ::regex::Regex;
use std::path::Path;
use std::time::SystemTime;
use std::{error::Error, str::FromStr};
use walkdir::DirEntry;
use super::{Config, Dependencies};
@@ -70,7 +72,7 @@ pub trait Matcher {
}
/// Notification that find has finished processing a given directory.
fn finished_dir(&self, _finished_directory: &PathBuf) {}
fn finished_dir(&self, _finished_directory: &Path) {}
/// Notification that find has finished processing all directories -
/// allowing for any cleanup that isn't suitable for destructors (e.g.
@@ -115,7 +117,8 @@ pub fn build_top_level_matcher(
if !top_level_matcher.has_side_effects() {
let mut new_and_matcher = logical_matchers::AndMatcherBuilder::new();
new_and_matcher.new_and_condition(top_level_matcher);
new_and_matcher.new_and_condition(printer::Printer::new_box());
new_and_matcher
.new_and_condition(printer::Printer::new_box(printer::PrintDelimiter::Newline));
return Ok(new_and_matcher.build());
}
Ok(top_level_matcher)
@@ -197,6 +200,8 @@ fn build_matcher_tree(
) -> Result<(usize, Box<dyn Matcher>), Box<dyn Error>> {
let mut top_level_matcher = logical_matchers::ListMatcherBuilder::new();
let mut regex_type = regex::RegexType::default();
// can't use getopts for a variety or reasons:
// order of arguments is important
// arguments can start with + as well as -
@@ -205,7 +210,15 @@ fn build_matcher_tree(
let mut invert_next_matcher = false;
while i < args.len() {
let possible_submatcher = match args[i] {
"-print" => Some(printer::Printer::new_box()),
"-print" => Some(printer::Printer::new_box(printer::PrintDelimiter::Newline)),
"-print0" => Some(printer::Printer::new_box(printer::PrintDelimiter::Null)),
"-printf" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
i += 1;
Some(printf::Printf::new_box(args[i])?)
}
"-true" => Some(logical_matchers::TrueMatcher::new_box()),
"-false" => Some(logical_matchers::FalseMatcher::new_box()),
"-name" => {
@@ -222,6 +235,28 @@ fn build_matcher_tree(
i += 1;
Some(name::CaselessNameMatcher::new_box(args[i])?)
}
"-regextype" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
i += 1;
regex_type = regex::RegexType::from_str(args[i])?;
None
}
"-regex" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
i += 1;
Some(regex::RegexMatcher::new_box(regex_type, args[i], false)?)
}
"-iregex" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
i += 1;
Some(regex::RegexMatcher::new_box(regex_type, args[i], true)?)
}
"-type" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
@@ -269,7 +304,7 @@ fn build_matcher_tree(
"-exec" | "-execdir" => {
let mut arg_index = i + 1;
while arg_index < args.len() && args[arg_index] != ";" {
if args[arg_index] == "+" {
if args[arg_index - 1] == "{}" && args[arg_index] == "+" {
// MultiExecMatcher isn't written yet
return Err(From::from(format!(
"{} [args...] + isn't supported yet. \
@@ -382,6 +417,10 @@ fn build_matcher_tree(
config.help_requested = true;
None
}
"-version" | "--version" => {
config.version_requested = true;
None
}
_ => return Err(From::from(format!("Unrecognized flag: '{}'", args[i]))),
};
@@ -419,7 +458,13 @@ mod tests {
pub fn get_dir_entry_for(directory: &str, filename: &str) -> DirEntry {
for wrapped_dir_entry in WalkDir::new(fix_up_slashes(directory)) {
let dir_entry = wrapped_dir_entry.unwrap();
if dir_entry.file_name().to_string_lossy() == filename {
if dir_entry
.path()
.strip_prefix(directory)
.unwrap()
.to_string_lossy()
== fix_up_slashes(filename)
{
return dir_entry;
}
}
@@ -948,6 +993,13 @@ mod tests {
.expect("parsing argument list with exec that takes brackets and -os should work");
}
#[test]
fn build_top_level_exec_plus_semicolon() {
let mut config = Config::default();
build_top_level_matcher(&["-exec", "foo", "{}", "foo", "+", ";"], &mut config)
.expect("only {} + should be considered a multi-exec");
}
#[test]
#[cfg(unix)]
fn build_top_level_matcher_perm() {
+43 -11
View File
@@ -8,27 +8,46 @@ use walkdir::DirEntry;
use super::{Matcher, MatcherIO};
pub enum PrintDelimiter {
Newline,
Null,
}
impl std::fmt::Display for PrintDelimiter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PrintDelimiter::Newline => writeln!(f),
PrintDelimiter::Null => write!(f, "\0"),
}
}
}
/// This matcher just prints the name of the file to stdout.
pub struct Printer;
pub struct Printer {
delimiter: PrintDelimiter,
}
impl Printer {
pub fn new() -> Printer {
Printer {}
pub fn new(delimiter: PrintDelimiter) -> Printer {
Printer { delimiter }
}
pub fn new_box() -> Box<dyn Matcher> {
Box::new(Printer::new())
pub fn new_box(delimiter: PrintDelimiter) -> Box<dyn Matcher> {
Box::new(Printer::new(delimiter))
}
}
impl Matcher for Printer {
fn matches(&self, file_info: &DirEntry, matcher_io: &mut MatcherIO) -> bool {
writeln!(
matcher_io.deps.get_output().borrow_mut(),
"{}",
file_info.path().to_string_lossy()
let mut out = matcher_io.deps.get_output().borrow_mut();
write!(
out,
"{}{}",
file_info.path().to_string_lossy(),
self.delimiter
)
.unwrap();
out.flush().unwrap();
true
}
@@ -47,10 +66,10 @@ mod tests {
use crate::find::tests::FakeDependencies;
#[test]
fn prints() {
fn prints_newline() {
let abbbc = get_dir_entry_for("./test_data/simple", "abbbc");
let matcher = Printer::new();
let matcher = Printer::new(PrintDelimiter::Newline);
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
assert_eq!(
@@ -58,4 +77,17 @@ mod tests {
deps.get_output_as_string()
);
}
#[test]
fn prints_null() {
let abbbc = get_dir_entry_for("./test_data/simple", "abbbc");
let matcher = Printer::new(PrintDelimiter::Null);
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
assert_eq!(
fix_up_slashes("./test_data/simple/abbbc\0"),
deps.get_output_as_string()
);
}
}
File diff suppressed because it is too large Load Diff
+241
View File
@@ -0,0 +1,241 @@
// Copyright 2022 Collabora, Ltd.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
use std::{error::Error, fmt, str::FromStr};
use onig::{Regex, RegexOptions, Syntax};
use super::Matcher;
#[derive(Debug)]
pub struct ParseRegexTypeError(String);
impl Error for ParseRegexTypeError {}
impl fmt::Display for ParseRegexTypeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Invalid regex type: {} (must be one of {})",
self.0,
RegexType::VALUES
.iter()
.map(|t| format!("'{}'", t))
.collect::<Vec<_>>()
.join(", ")
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RegexType {
Emacs,
Grep,
PosixBasic,
PosixExtended,
}
impl RegexType {
pub const VALUES: &'static [RegexType] = &[
RegexType::Emacs,
RegexType::Grep,
RegexType::PosixBasic,
RegexType::PosixExtended,
];
}
impl fmt::Display for RegexType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RegexType::Emacs => write!(f, "emacs"),
RegexType::Grep => write!(f, "grep"),
RegexType::PosixBasic => write!(f, "posix-basic"),
RegexType::PosixExtended => write!(f, "posix-extended"),
}
}
}
impl FromStr for RegexType {
type Err = ParseRegexTypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"emacs" => Ok(RegexType::Emacs),
"grep" => Ok(RegexType::Grep),
"posix-basic" => Ok(RegexType::PosixBasic),
"posix-extended" => Ok(RegexType::PosixExtended),
_ => Err(ParseRegexTypeError(s.to_owned())),
}
}
}
impl Default for RegexType {
fn default() -> Self {
RegexType::Emacs
}
}
pub struct RegexMatcher {
regex: Regex,
}
impl RegexMatcher {
pub fn new(
regex_type: RegexType,
pattern: &str,
ignore_case: bool,
) -> Result<RegexMatcher, Box<dyn Error>> {
let syntax = match regex_type {
RegexType::Emacs => Syntax::emacs(),
RegexType::Grep => Syntax::grep(),
RegexType::PosixBasic => Syntax::posix_basic(),
RegexType::PosixExtended => Syntax::posix_extended(),
};
let regex = Regex::with_options(
pattern,
if ignore_case {
RegexOptions::REGEX_OPTION_IGNORECASE
} else {
RegexOptions::REGEX_OPTION_NONE
},
syntax,
)?;
Ok(RegexMatcher { regex })
}
pub fn new_box(
regex_type: RegexType,
pattern: &str,
ignore_case: bool,
) -> Result<Box<dyn Matcher>, Box<dyn Error>> {
Ok(Box::new(RegexMatcher::new(
regex_type,
pattern,
ignore_case,
)?))
}
}
impl Matcher for RegexMatcher {
fn matches(&self, file_info: &walkdir::DirEntry, _: &mut super::MatcherIO) -> bool {
self.regex
.is_match(file_info.path().to_string_lossy().as_ref())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::find::matchers::tests::get_dir_entry_for;
use crate::find::matchers::Matcher;
use crate::find::tests::FakeDependencies;
const POSIX_BASIC_INTERVALS_RE: &str = r".*/ab\{1,3\}c";
const POSIX_EXTENDED_INTERVALS_RE: &str = r".*/ab{1,3}c";
const EMACS_AND_POSIX_EXTENDED_KLEENE_PLUS: &str = r".*/ab+c";
// Variants of fix_up_slashes that properly escape the forward slashes for
// being in a regex.
#[cfg(windows)]
fn fix_up_regex_slashes(re: &str) -> String {
re.replace("/", "\\\\")
}
#[cfg(not(windows))]
fn fix_up_regex_slashes(re: &str) -> String {
re.to_owned()
}
#[test]
fn case_sensitive_matching() {
let abbbc = get_dir_entry_for("test_data/simple", "abbbc");
let matcher =
RegexMatcher::new(RegexType::Emacs, &fix_up_regex_slashes(".*/ab.BC"), false).unwrap();
let deps = FakeDependencies::new();
assert!(!matcher.matches(&abbbc, &mut deps.new_matcher_io()));
}
#[test]
fn case_insensitive_matching() {
let abbbc = get_dir_entry_for("test_data/simple", "abbbc");
let matcher =
RegexMatcher::new(RegexType::Emacs, &fix_up_regex_slashes(".*/ab.BC"), true).unwrap();
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
}
#[test]
fn emacs_regex() {
// Emacs syntax is mostly the same as POSIX extended but with escaped
// brace intervals.
let abbbc = get_dir_entry_for("test_data/simple", "abbbc");
let matcher = RegexMatcher::new(
RegexType::Emacs,
&fix_up_regex_slashes(EMACS_AND_POSIX_EXTENDED_KLEENE_PLUS),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
let matcher = RegexMatcher::new(
RegexType::Emacs,
&fix_up_regex_slashes(POSIX_EXTENDED_INTERVALS_RE),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(!matcher.matches(&abbbc, &mut deps.new_matcher_io()));
}
#[test]
fn posix_basic_regex() {
let abbbc = get_dir_entry_for("test_data/simple", "abbbc");
let matcher = RegexMatcher::new(
RegexType::PosixBasic,
&fix_up_regex_slashes(POSIX_BASIC_INTERVALS_RE),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
let matcher = RegexMatcher::new(
RegexType::PosixBasic,
&fix_up_regex_slashes(POSIX_EXTENDED_INTERVALS_RE),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(!matcher.matches(&abbbc, &mut deps.new_matcher_io()));
}
#[test]
fn posix_extended_regex() {
let abbbc = get_dir_entry_for("test_data/simple", "abbbc");
let matcher = RegexMatcher::new(
RegexType::PosixExtended,
&fix_up_regex_slashes(POSIX_EXTENDED_INTERVALS_RE),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(matcher.matches(&abbbc, &mut deps.new_matcher_io()));
let matcher = RegexMatcher::new(
RegexType::PosixExtended,
&fix_up_regex_slashes(POSIX_BASIC_INTERVALS_RE),
true,
)
.unwrap();
let deps = FakeDependencies::new();
assert!(!matcher.matches(&abbbc, &mut deps.new_matcher_io()));
}
}
+7 -4
View File
@@ -134,8 +134,8 @@ impl FileTimeMatcher {
pub fn new(file_time_type: FileTimeType, days: ComparableValue) -> FileTimeMatcher {
FileTimeMatcher {
file_time_type,
days,
file_time_type,
}
}
@@ -150,7 +150,7 @@ mod tests {
use std::io::{Read, Write};
use std::thread;
use std::time::{Duration, SystemTime};
use tempdir::TempDir;
use tempfile::Builder;
use walkdir::DirEntry;
use super::*;
@@ -163,7 +163,7 @@ mod tests {
// this file should already exist
let old_file = get_dir_entry_for("test_data", "simple");
let temp_dir = TempDir::new("newer_matcher").unwrap();
let temp_dir = Builder::new().prefix("example").tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_string_lossy();
// this has just been created, so should be newer
let new_file_name = "newFile";
@@ -287,7 +287,10 @@ mod tests {
#[test]
fn file_time_matcher_modified_created_accessed() {
let temp_dir = TempDir::new("file_time_matcher_modified_created_accessed").unwrap();
let temp_dir = Builder::new()
.prefix("file_time_matcher_modified_created_accessed")
.tempdir()
.unwrap();
// No easy way to independently set file times. So create it - setting creation time
let foo_path = temp_dir.path().join("foo");
+18 -2
View File
@@ -19,6 +19,7 @@ pub struct Config {
max_depth: usize,
sorted_output: bool,
help_requested: bool,
version_requested: bool,
}
impl Default for Config {
@@ -29,6 +30,7 @@ impl Default for Config {
max_depth: usize::max_value(),
sorted_output: false,
help_requested: false,
version_requested: false,
}
}
}
@@ -145,6 +147,11 @@ fn do_find<'a>(args: &[&str], deps: &'a dyn Dependencies<'a>) -> Result<u64, Box
print_help();
return Ok(0);
}
if paths_and_matcher.config.version_requested {
print_version();
return Ok(0);
}
let mut found_count: u64 = 0;
for path in paths_and_matcher.paths {
found_count += process_dir(
@@ -165,8 +172,13 @@ If no path is supplied then the current working directory is used by default.
Early alpha implementation. Currently the only expressions supported are
-print
-print0
-printf
-name case-sensitive_filename_pattern
-iname case-insensitive_filename_pattern
-regextype type
-regex pattern
-iregex pattern
-type type_char
currently type_char can only be f (for file) or d (for directory)
-size [+-]N[bcwkMG]
@@ -195,6 +207,10 @@ Early alpha implementation. Currently the only expressions supported are
);
}
fn print_version() {
println!("find (Rust) {}", env!("CARGO_PKG_VERSION"));
}
/// Does all the work for find.
///
/// All main has to do is pass in the command-line args and exit the process
@@ -218,7 +234,7 @@ mod tests {
use std::io::{Cursor, Read, Write};
use std::time::{Duration, SystemTime};
use std::vec::Vec;
use tempdir::TempDir;
use tempfile::Builder;
use crate::find::matchers::MatcherIO;
@@ -525,7 +541,7 @@ mod tests {
fn find_newer() {
// create a temp directory and file that are newer than the static
// files in the source tree.
let new_dir = TempDir::new("find_newer").unwrap();
let new_dir = Builder::new().prefix("find_newer").tempdir().unwrap();
let deps = FakeDependencies::new();
+2 -1
View File
@@ -9,6 +9,7 @@ extern crate regex;
extern crate walkdir;
#[cfg(test)]
extern crate tempdir;
extern crate tempfile;
pub mod find;
pub mod xargs;
+69 -20
View File
@@ -6,7 +6,7 @@
use std::env;
use std::fs::{self, File, OpenOptions};
use std::io::Write;
use std::io::{stdin, stdout, Read, Write};
use std::path::PathBuf;
fn usage() -> ! {
@@ -14,10 +14,19 @@ fn usage() -> ! {
std::process::exit(2);
}
enum ExitWith {
Failure,
UrgentFailure,
#[cfg(unix)]
Signal,
}
#[derive(Default)]
struct Config {
exit_with_failure: bool,
destination_dir: String,
exit_with: Option<ExitWith>,
print_stdin: bool,
no_print_cwd: bool,
destination_dir: Option<String>,
}
fn open_file(destination_dir: &str) -> File {
@@ -39,20 +48,61 @@ fn open_file(destination_dir: &str) -> File {
}
}
fn write_content(mut f: impl Write, config: &Config, args: &[String]) {
if !config.no_print_cwd {
writeln!(f, "cwd={}", env::current_dir().unwrap().to_string_lossy())
.expect("failed to write to file");
}
if config.print_stdin {
let mut s = String::new();
stdin()
.read_to_string(&mut s)
.expect("failed to read from stdin");
writeln!(f, "stdin={}", s.trim()).expect("failed to write to file");
}
writeln!(f, "args=").expect("failed to write to file");
// first two args are going to be the path to this executable and
// the destination_dir we want to write to. Don't write either of those
// as they'll be non-deterministic.
for arg in &args[2..] {
writeln!(f, "{}", arg).expect("failed to write to file");
}
}
fn main() {
let args = env::args().collect::<Vec<String>>();
if args.len() < 2 || args[1] == "-h" || args[1] == "--help" {
usage();
}
let mut config = Config {
destination_dir: args[1].clone(),
destination_dir: if args[1] != "-" {
Some(args[1].clone())
} else {
None
},
..Default::default()
};
for arg in &args[2..] {
if arg.starts_with("--") {
match arg.as_ref() {
"--exit_with_failure" => {
config.exit_with_failure = true;
config.exit_with = Some(ExitWith::Failure);
}
"--exit_with_urgent_failure" => {
config.exit_with = Some(ExitWith::UrgentFailure);
}
#[cfg(unix)]
"--exit_with_signal" => {
config.exit_with = Some(ExitWith::Signal);
}
"--no_print_cwd" => {
config.no_print_cwd = true;
}
"--print_stdin" => {
config.print_stdin = true;
}
_ => {
usage();
@@ -61,20 +111,19 @@ fn main() {
}
}
{
let mut f = open_file(&config.destination_dir);
// first two args are going to be the path to this executable and
// the destination_dir we want to write to. Don't write either of those
// as they'll be non-deterministic.
f.write_fmt(format_args!(
"cwd={}\nargs=\n",
env::current_dir().unwrap().to_string_lossy()
))
.expect("failed to write to file");
for arg in &args[2..] {
f.write_fmt(format_args!("{}\n", arg))
.expect("failed to write to file");
}
if let Some(destination_dir) = &config.destination_dir {
write_content(open_file(destination_dir), &config, &args);
} else {
write_content(stdout(), &config, &args);
}
match config.exit_with {
None => std::process::exit(0),
Some(ExitWith::Failure) => std::process::exit(2),
Some(ExitWith::UrgentFailure) => std::process::exit(255),
#[cfg(unix)]
Some(ExitWith::Signal) => unsafe {
uucore::libc::raise(uucore::libc::SIGINT);
},
}
std::process::exit(if config.exit_with_failure { 2 } else { 0 });
}
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2021 Collabora, Ltd.
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
fn main() {
let args = std::env::args().collect::<Vec<String>>();
std::process::exit(findutils::xargs::xargs_main(
&args.iter().map(|s| s.as_ref()).collect::<Vec<&str>>(),
))
}

Some files were not shown because too many files have changed in this diff Show More