Compare commits

...

532 Commits

Author SHA1 Message Date
Tavian Barnes 5c0c86c2d5 ci: Use Ubuntu 22.04 runners
Ubuntu 20.04 is now unsupported.

Link: https://github.com/actions/runner-images/issues/11101
2025-04-24 10:03:57 -04:00
Tavian Barnes 3651f86162 Use next_back() instead of last()
Fixes a new Clippy warning.
2025-04-24 10:01:06 -04:00
Thayne McCombs 16b46710ee Merge pull request #1703 from sharkdp/dependabot/cargo/clap_complete-4.5.47
build(deps): bump clap_complete from 4.5.44 to 4.5.47
2025-04-02 08:01:35 -06:00
Tavian Barnes edafedbbc7 Merge pull request #1704 from vp-elitnet/changed_opt_doc_fix
doc: Disambiguate modification time vs timestamp
2025-04-02 07:53:07 -05:00
Vilius Panevėžys 5b29a4c8b3 Disambiguate modification time vs timestamp 2025-04-02 12:37:09 +03:00
Thayne McCombs 5f606ad6e2 Merge pull request #1701 from sharkdp/dependabot/cargo/jiff-0.2.5
build(deps): bump jiff from 0.2.4 to 0.2.5
2025-04-01 23:03:53 -06:00
dependabot[bot] 202615ccf7 build(deps): bump jiff from 0.2.4 to 0.2.5
Bumps [jiff](https://github.com/BurntSushi/jiff) from 0.2.4 to 0.2.5.
- [Release notes](https://github.com/BurntSushi/jiff/releases)
- [Changelog](https://github.com/BurntSushi/jiff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/jiff/compare/jiff-static-0.2.4...jiff-static-0.2.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 04:34:16 +00:00
Thayne McCombs c644330a52 Merge pull request #1702 from sharkdp/dependabot/cargo/anyhow-1.0.97
build(deps): bump anyhow from 1.0.96 to 1.0.97
2025-04-01 22:33:03 -06:00
Thayne McCombs 34acf31e0f Merge pull request #1700 from sharkdp/dependabot/cargo/clap-4.5.35
build(deps): bump clap from 4.5.31 to 4.5.35
2025-04-01 22:32:12 -06:00
Thayne McCombs 7cfd25cbb6 Merge pull request #1699 from sharkdp/dependabot/cargo/tempfile-3.19.1
build(deps): bump tempfile from 3.16.0 to 3.19.1
2025-04-01 22:31:11 -06:00
dependabot[bot] 39a616d6c4 build(deps): bump clap_complete from 4.5.44 to 4.5.47
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.44 to 4.5.47.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.44...clap_complete-v4.5.47)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 17:38:43 +00:00
dependabot[bot] db6eb2959c build(deps): bump anyhow from 1.0.96 to 1.0.97
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.96 to 1.0.97.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.96...1.0.97)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 17:38:38 +00:00
dependabot[bot] 5e8ae1d337 build(deps): bump clap from 4.5.31 to 4.5.35
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.31 to 4.5.35.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.5.31...clap_complete-v4.5.35)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 17:38:29 +00:00
dependabot[bot] e3ce16a7b4 build(deps): bump tempfile from 3.16.0 to 3.19.1
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.16.0 to 3.19.1.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.16.0...v3.19.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 17:38:24 +00:00
Tavian Barnes 045fd2d689 Merge pull request #1695 from Bzero/patch-1
Fix broken Arch Linux link
2025-03-24 12:57:00 -05:00
Bzero 029ce455fd Fix broken Arch Linux link 2025-03-24 18:12:56 +01:00
Thayne McCombs e5b3269d1d Merge pull request #1649 from Its-Just-Nans/add-documentation-key
Add documentation key in Cargo.toml
2025-03-24 01:56:26 -06:00
Thayne McCombs 2b0f609a48 Merge pull request #1692 from tmccombs/jiff-more
Some small improvements to time filter code after switch to jiff
2025-03-22 15:01:46 -06:00
Thayne McCombs f370301a5b Use guard to ensure cleanup of test time 2025-03-22 02:03:15 -06:00
Thayne McCombs f36c7d0be2 refactor: Simplify time filter code 2025-03-19 00:39:46 -06:00
Thayne McCombs e0363fc9f8 refactor: Avoid passing in current time just for tests
Instead use a thread local variable that we can use to set the current
time, and use a separate now function in tests than the actual binary.
2025-03-17 02:22:38 -06:00
Thayne McCombs 9859d5117c docs: More description of jiff change in changelog 2025-03-16 18:50:51 -06:00
Thayne McCombs 803d1fd38b Merge pull request #1690 from sorairolake/replace-humantime-with-jiff
chore(deps): Replace `humantime` and `chrono` with `jiff`
2025-03-13 01:30:39 -06:00
Shun Sakai bbac76747b chore(deps): Replace chrono with jiff 2025-03-13 11:44:36 +09:00
Shun Sakai 7d57f61dfb chore: Change to use jiff::Zoned
Supports when the duration contains calendar units.
2025-03-12 23:50:47 +09:00
Shun Sakai c670a0b366 chore(deps): Replace humantime with jiff 2025-03-12 18:15:37 +09:00
Thayne McCombs a4fdad6ff7 Merge pull request #1683 from sharkdp/dependabot/cargo/clap-4.5.31
build(deps): bump clap from 4.5.27 to 4.5.31
2025-03-03 10:09:04 -07:00
Thayne McCombs da7ccc21d0 Merge pull request #1682 from sharkdp/dependabot/cargo/libc-0.2.170
build(deps): bump libc from 0.2.169 to 0.2.170
2025-03-03 00:31:19 -07:00
Thayne McCombs 595c1af4b6 Merge pull request #1684 from sharkdp/dependabot/cargo/globset-0.4.16
build(deps): bump globset from 0.4.15 to 0.4.16
2025-03-02 17:51:34 -07:00
Thayne McCombs 69e3f1a6e6 Merge pull request #1681 from sharkdp/dependabot/cargo/anyhow-1.0.96
build(deps): bump anyhow from 1.0.95 to 1.0.96
2025-03-02 17:49:26 -07:00
dependabot[bot] df550cce26 build(deps): bump clap from 4.5.27 to 4.5.31
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.27 to 4.5.31.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.27...v4.5.31)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-02 09:09:23 +00:00
dependabot[bot] cc7472d4db build(deps): bump libc from 0.2.169 to 0.2.170
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.169 to 0.2.170.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.170/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.169...0.2.170)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-02 09:09:22 +00:00
dependabot[bot] 0c2b432fd8 build(deps): bump globset from 0.4.15 to 0.4.16
Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.15 to 0.4.16.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/ignore-0.4.15...globset-0.4.16)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-02 09:09:18 +00:00
dependabot[bot] 5803cdb401 build(deps): bump anyhow from 1.0.95 to 1.0.96
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.95 to 1.0.96.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.95...1.0.96)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-02 09:09:16 +00:00
Thayne McCombs fe51550687 Merge pull request #1680 from sharkdp/dependabot/cargo/etcetera-0.9.0
build(deps): bump etcetera from 0.8.0 to 0.9.0
2025-03-02 02:08:20 -07:00
dependabot[bot] 54fca540e8 build(deps): bump etcetera from 0.8.0 to 0.9.0
Bumps [etcetera](https://github.com/lunacookies/etcetera) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/lunacookies/etcetera/releases)
- [Commits](https://github.com/lunacookies/etcetera/compare/v0.8.0...v0.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 17:40:12 +00:00
Thayne McCombs 3a56c32a1c Merge pull request #1671 from tmccombs/update-mac-runner
chore: Use macos-13 instead of 12
2025-02-02 10:52:21 -07:00
Thayne McCombs 34d40443a4 Merge pull request #1668 from sharkdp/dependabot/cargo/clap_complete-4.5.44
build(deps): bump clap_complete from 4.5.38 to 4.5.44
2025-02-02 01:33:06 -07:00
Thayne McCombs 3bbe11169a Merge pull request #1669 from sharkdp/dependabot/cargo/clap-4.5.27
build(deps): bump clap from 4.5.23 to 4.5.27
2025-02-02 01:32:39 -07:00
Thayne McCombs d0e2c3d33b Merge pull request #1670 from sharkdp/dependabot/cargo/tempfile-3.16.0
build(deps): bump tempfile from 3.14.0 to 3.16.0
2025-02-02 01:28:24 -07:00
Thayne McCombs 72a58676c6 chore: Use macos-13 instead of 12
Github actions doesn't suport macos-12 anymore
2025-02-02 01:27:51 -07:00
dependabot[bot] 4e6a47fee5 build(deps): bump tempfile from 3.14.0 to 3.16.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.14.0 to 3.16.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.14.0...v3.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-01 17:25:03 +00:00
dependabot[bot] 29bc3345f1 build(deps): bump clap from 4.5.23 to 4.5.27
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.23 to 4.5.27.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.23...clap_complete-v4.5.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-01 17:24:56 +00:00
dependabot[bot] 9c5b66b6b4 build(deps): bump clap_complete from 4.5.38 to 4.5.44
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.38 to 4.5.44.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.38...clap_complete-v4.5.44)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-01 17:24:52 +00:00
Thayne McCombs 564a61588d Merge pull request #1663 from tmccombs/more-troubleshooting
docs: Mention --full-path in troubleshooting
2025-01-28 09:09:39 -07:00
Thayne McCombs 8c177567a7 chore: Fix clippy lints
Use is_some_and instead of map_or(false
2025-01-28 01:55:21 -07:00
Thayne McCombs 2a66fbab28 docs: Mention --full-path in troubleshooting
See: #1662
2025-01-28 01:35:00 -07:00
Tavian Barnes 86d6e2d45f Merge pull request #1657 from sharkdp/dependabot/cargo/clap-4.5.23
build(deps): bump clap from 4.5.21 to 4.5.23
2025-01-01 15:49:25 -05:00
Tavian Barnes 62e5b11d8c Merge pull request #1656 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.14
build(deps): bump crossbeam-channel from 0.5.13 to 0.5.14
2025-01-01 15:46:50 -05:00
Tavian Barnes 4327c36280 Merge pull request #1655 from sharkdp/dependabot/cargo/chrono-0.4.39
build(deps): bump chrono from 0.4.38 to 0.4.39
2025-01-01 15:46:09 -05:00
Tavian Barnes 31f8eda117 Merge pull request #1654 from sharkdp/dependabot/cargo/anyhow-1.0.95
build(deps): bump anyhow from 1.0.93 to 1.0.95
2025-01-01 15:45:48 -05:00
Tavian Barnes 727a976d6b Merge pull request #1653 from sharkdp/dependabot/cargo/libc-0.2.169
build(deps): bump libc from 0.2.167 to 0.2.169
2025-01-01 15:45:33 -05:00
dependabot[bot] 0f69a1af62 build(deps): bump clap from 4.5.21 to 4.5.23
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.21 to 4.5.23.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.21...clap_complete-v4.5.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 17:34:12 +00:00
dependabot[bot] 5ab7a9b56d build(deps): bump crossbeam-channel from 0.5.13 to 0.5.14
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.13 to 0.5.14.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.13...crossbeam-channel-0.5.14)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 17:34:07 +00:00
dependabot[bot] 1cc4cec3cb build(deps): bump chrono from 0.4.38 to 0.4.39
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.38 to 0.4.39.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.38...v0.4.39)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 17:34:02 +00:00
dependabot[bot] 64b326da79 build(deps): bump anyhow from 1.0.93 to 1.0.95
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.93 to 1.0.95.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.93...1.0.95)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 17:33:57 +00:00
dependabot[bot] ce39d34483 build(deps): bump libc from 0.2.167 to 0.2.169
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.167 to 0.2.169.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.169/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.167...0.2.169)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 17:33:53 +00:00
n4n5 f86a460e48 Update Cargo.toml 2024-12-16 17:45:45 +01:00
n4n5 1785baa372 add documentation 2024-12-16 17:44:41 +01:00
Thayne McCombs 331daf10b8 Merge pull request #1644 from sharkdp/dependabot/cargo/clap_complete-4.5.38
build(deps): bump clap_complete from 4.5.28 to 4.5.38
2024-12-09 11:41:18 -07:00
Thayne McCombs 4d957d3a63 Merge pull request #1642 from sharkdp/dependabot/cargo/tempfile-3.14.0
build(deps): bump tempfile from 3.13.0 to 3.14.0
2024-12-02 09:16:35 -07:00
dependabot[bot] 4104411a1b build(deps): bump clap_complete from 4.5.28 to 4.5.38
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.28 to 4.5.38.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.28...clap_complete-v4.5.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 15:22:24 +00:00
Thayne McCombs 915483bcd0 Merge pull request #1646 from sharkdp/dependabot/cargo/clap-4.5.21
build(deps): bump clap from 4.5.20 to 4.5.21
2024-12-02 08:20:43 -07:00
Thayne McCombs f272180939 Merge pull request #1645 from sharkdp/dependabot/cargo/anyhow-1.0.93
build(deps): bump anyhow from 1.0.89 to 1.0.93
2024-12-02 08:20:18 -07:00
Thayne McCombs 285ff99ce0 Merge pull request #1643 from sharkdp/dependabot/cargo/libc-0.2.167
build(deps): bump libc from 0.2.161 to 0.2.167
2024-12-02 08:19:52 -07:00
dependabot[bot] ff434bb8a0 build(deps): bump clap from 4.5.20 to 4.5.21
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.20 to 4.5.21.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.20...clap_complete-v4.5.21)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 17:47:13 +00:00
dependabot[bot] 54015f3fbe build(deps): bump anyhow from 1.0.89 to 1.0.93
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.89 to 1.0.93.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.89...1.0.93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 17:47:08 +00:00
dependabot[bot] e11180b323 build(deps): bump libc from 0.2.161 to 0.2.167
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.161 to 0.2.167.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.167/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.161...0.2.167)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 17:46:56 +00:00
dependabot[bot] 9547622726 build(deps): bump tempfile from 3.13.0 to 3.14.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.13.0 to 3.14.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.13.0...v3.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 17:46:50 +00:00
Thayne McCombs 7a908a474c Merge pull request #1633 from sharkdp/dependabot/cargo/clap-4.5.20
build(deps): bump clap from 4.5.16 to 4.5.20
2024-11-01 22:49:11 -06:00
Thayne McCombs 71deea6671 Merge pull request #1632 from sharkdp/dependabot/cargo/lscolors-0.20.0
build(deps): bump lscolors from 0.19.0 to 0.20.0
2024-11-01 11:47:25 -06:00
Thayne McCombs bb676df284 Merge pull request #1634 from sharkdp/dependabot/cargo/regex-1.11.1
build(deps): bump regex from 1.10.6 to 1.11.1
2024-11-01 11:47:02 -06:00
Thayne McCombs b517934b42 Merge pull request #1630 from sharkdp/dependabot/cargo/tempfile-3.13.0
build(deps): bump tempfile from 3.12.0 to 3.13.0
2024-11-01 11:46:26 -06:00
dependabot[bot] 06483d1df5 build(deps): bump regex from 1.10.6 to 1.11.1
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.6 to 1.11.1.
- [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.10.6...1.11.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 17:23:36 +00:00
dependabot[bot] 8c93b19883 build(deps): bump clap from 4.5.16 to 4.5.20
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.16 to 4.5.20.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.16...clap_complete-v4.5.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 17:23:31 +00:00
dependabot[bot] 4505da8771 build(deps): bump lscolors from 0.19.0 to 0.20.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.19.0 to 0.20.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/v0.19.0...v0.20.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 17:23:25 +00:00
dependabot[bot] 22b73a0253 build(deps): bump tempfile from 3.12.0 to 3.13.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.12.0 to 3.13.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.12.0...v3.13.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 17:23:14 +00:00
Thayne McCombs 202e32953c Merge pull request #1627 from hamirmahal/style/simplify-string-formatting-for-readability
style: simplify string formatting for readability
2024-10-06 14:25:02 -06:00
Hamir Mahal 87f230a66e fix: formatting in src/ and tests/ 2024-10-06 09:34:41 -07:00
Hamir Mahal 4bdee80afa style: simplify string formatting for readability 2024-10-06 09:33:58 -07:00
Tavian Barnes 3d0d1865c8 Merge pull request #1617 from cstyles/add-mindepth-alias
Add a hidden `--mindepth` alias for `--min-depth`
2024-10-02 12:30:25 -04:00
Collin Styles 0d99badc1b Add a hidden --mindepth alias for --min-depth 2024-10-02 12:22:01 -04:00
Thayne McCombs 3b7b95d081 Merge pull request #1625 from sharkdp/dependabot/cargo/anyhow-1.0.89
build(deps): bump anyhow from 1.0.86 to 1.0.89
2024-10-01 23:51:08 -06:00
dependabot[bot] bd9882d797 build(deps): bump anyhow from 1.0.86 to 1.0.89
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.86 to 1.0.89.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.86...1.0.89)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-02 04:27:23 +00:00
Thayne McCombs 1fed60d5c1 Merge pull request #1623 from sharkdp/dependabot/cargo/libc-0.2.159
build(deps): bump libc from 0.2.158 to 0.2.159
2024-10-01 22:25:13 -06:00
Thayne McCombs f84c1d67c0 Merge pull request #1624 from sharkdp/dependabot/cargo/ignore-0.4.23
build(deps): bump ignore from 0.4.22 to 0.4.23
2024-10-01 22:24:47 -06:00
Thayne McCombs e50cb817e1 Merge pull request #1621 from sharkdp/dependabot/cargo/clap_complete-4.5.28
build(deps): bump clap_complete from 4.5.24 to 4.5.28
2024-10-01 22:23:58 -06:00
Thayne McCombs 8207b3ebae Merge pull request #1622 from sharkdp/dependabot/cargo/globset-0.4.15
build(deps): bump globset from 0.4.14 to 0.4.15
2024-10-01 22:22:30 -06:00
dependabot[bot] aa81800ffa build(deps): bump ignore from 0.4.22 to 0.4.23
Bumps [ignore](https://github.com/BurntSushi/ripgrep) from 0.4.22 to 0.4.23.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 17:18:00 +00:00
dependabot[bot] 5de01fdd7b build(deps): bump libc from 0.2.158 to 0.2.159
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.158 to 0.2.159.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.159/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.158...0.2.159)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 17:17:55 +00:00
dependabot[bot] 85764e28ef build(deps): bump globset from 0.4.14 to 0.4.15
Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.14 to 0.4.15.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/globset-0.4.14...ignore-0.4.15)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 17:17:51 +00:00
dependabot[bot] a4b3bd29aa build(deps): bump clap_complete from 4.5.24 to 4.5.28
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.24 to 4.5.28.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.24...clap_complete-v4.5.28)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 17:17:44 +00:00
Thayne McCombs 27c6b50919 Fix a new clippy warning 2024-09-23 09:42:58 +02:00
Tavian Barnes 8e0bd33af7 Merge pull request #1610 from sharkdp/dependabot/cargo/filetime-0.2.25
build(deps): bump filetime from 0.2.24 to 0.2.25
2024-09-03 10:23:34 -04:00
Thayne McCombs b674b9b820 Merge pull request #1611 from sharkdp/dependabot/cargo/clap_complete-4.5.24
build(deps): bump clap_complete from 4.5.19 to 4.5.24
2024-09-01 12:11:03 -06:00
dependabot[bot] 96ac5fa0a0 build(deps): bump clap_complete from 4.5.19 to 4.5.24
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.19 to 4.5.24.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.19...clap_complete-v4.5.24)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-01 17:23:24 +00:00
dependabot[bot] 9b1017a4d5 build(deps): bump filetime from 0.2.24 to 0.2.25
Bumps [filetime](https://github.com/alexcrichton/filetime) from 0.2.24 to 0.2.25.
- [Commits](https://github.com/alexcrichton/filetime/compare/0.2.24...0.2.25)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-01 17:23:19 +00:00
Tavian Barnes b191368713 Merge pull request #1607 from tmccombs/release-10.2
Prepare for 10.2.0 release
2024-08-22 15:27:40 -04:00
Thayne McCombs e3d4f57e75 Bump dependencies
In particular, lscolors
2024-08-19 23:29:02 -06:00
Thayne McCombs 1ce6906808 Prepare for 10.2.0 release 2024-08-18 22:55:28 -06:00
Thayne McCombs 9cf415ccc7 Merge pull request #1593 from sharkdp/deb-improvements
Deb improvements
2024-08-08 21:02:08 -06:00
Thayne McCombs e9fe337921 Merge pull request #1596 from RossSmyth/WinLints
Fix up some lints on Windows
2024-08-07 23:16:56 -06:00
Thayne McCombs 8958a7bd74 Merge pull request #1602 from JCHacking/readme_last_version_regex
docs: documentation link of regular expressions to the latest version
2024-08-05 14:30:05 -06:00
JCHacking c26c45dba3 docs: documentation link of regular expressions to the latest version 2024-08-05 13:32:20 +02:00
Thayne McCombs 7decd53c70 Merge pull request #1601 from sharkdp/dependabot/cargo/clap-4.5.13
build(deps): bump clap from 4.5.8 to 4.5.13
2024-08-01 19:12:08 -06:00
Thayne McCombs d5253c5372 Merge pull request #1600 from sharkdp/dependabot/cargo/clap_complete-4.5.8
build(deps): bump clap_complete from 4.5.7 to 4.5.8
2024-08-01 19:11:30 -06:00
Thayne McCombs 3e7691ee6e Merge pull request #1599 from sharkdp/dependabot/cargo/nu-ansi-term-0.50.1
build(deps): bump nu-ansi-term from 0.50.0 to 0.50.1
2024-08-01 19:10:55 -06:00
Thayne McCombs 385131765d Merge pull request #1598 from sharkdp/dependabot/cargo/version_check-0.9.5
build(deps): bump version_check from 0.9.4 to 0.9.5
2024-08-01 19:06:36 -06:00
dependabot[bot] adbae9cf54 build(deps): bump clap from 4.5.8 to 4.5.13
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.8 to 4.5.13.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.8...v4.5.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 17:45:49 +00:00
dependabot[bot] b862c11550 build(deps): bump clap_complete from 4.5.7 to 4.5.8
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.7 to 4.5.8.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.7...clap_complete-v4.5.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 17:45:44 +00:00
dependabot[bot] e7b93e6c96 build(deps): bump nu-ansi-term from 0.50.0 to 0.50.1
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.50.0 to 0.50.1.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.50.0...v0.50.1)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 17:45:36 +00:00
dependabot[bot] 2ea5d2a90e build(deps): bump version_check from 0.9.4 to 0.9.5
Bumps [version_check](https://github.com/SergioBenitez/version_check) from 0.9.4 to 0.9.5.
- [Commits](https://github.com/SergioBenitez/version_check/compare/v0.9.4...v0.9.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 17:45:31 +00:00
Ross Smyth 80a73fda49 Fix unused config struct field on Windows 2024-07-22 10:02:08 -04:00
Ross Smyth db9d2fa299 Fix unused OnceLock import lint on Windows 2024-07-22 10:02:05 -04:00
Thayne McCombs 830fed4f82 Fix Conflicts syntax 2024-07-22 01:34:03 -06:00
Thayne McCombs e3b7dcbb7e Create fdfind symlinks in deb package
To be consistent with the offical debian pckage
2024-07-22 00:33:10 -06:00
Thayne McCombs 55d2e78cc1 Refactor creating deb package into separate script
Which I think is cleaner than having it inline in the github actions
yaml
2024-07-22 00:33:10 -06:00
Thayne McCombs 9f0fea6e21 Merge pull request #1594 from sharkdp/deb-readme-update
Note executable name in release debs
2024-07-17 12:54:07 -06:00
Thayne McCombs 3480df88ef Note executable name in release debs
Fixes: #1592
2024-07-17 00:04:36 -06:00
Thayne McCombs cfced9787e Merge pull request #1571 from tmccombs/hyperlink
Add hyperlink support to fd
2024-07-16 15:57:30 -06:00
Thayne McCombs 9cefd79ef4 Merge pull request #1583 from sharkdp/dependabot/cargo/clap_complete-4.5.7
build(deps): bump clap_complete from 4.5.2 to 4.5.7
2024-07-01 16:05:25 -06:00
dependabot[bot] d5525e171b build(deps): bump clap_complete from 4.5.2 to 4.5.7
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.5.2 to 4.5.7.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.2...clap_complete-v4.5.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 21:44:07 +00:00
Thayne McCombs 724275f3ef Merge pull request #1582 from sharkdp/dependabot/cargo/clap-4.5.8
build(deps): bump clap from 4.5.4 to 4.5.8
2024-07-01 15:43:27 -06:00
Thayne McCombs 79d1435c68 Merge pull request #1581 from sharkdp/dependabot/cargo/lscolors-0.18.0
build(deps): bump lscolors from 0.17.0 to 0.18.0
2024-07-01 15:42:50 -06:00
Thayne McCombs 5147fd6aec Merge pull request #1580 from sharkdp/dependabot/cargo/regex-1.10.5
build(deps): bump regex from 1.10.4 to 1.10.5
2024-07-01 15:38:59 -06:00
dependabot[bot] f55708e31d build(deps): bump regex from 1.10.4 to 1.10.5
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.4 to 1.10.5.
- [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.10.4...1.10.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 21:04:01 +00:00
Thayne McCombs b6b16ce959 Merge pull request #1584 from sharkdp/dependabot/cargo/regex-syntax-0.8.4
build(deps): bump regex-syntax from 0.8.3 to 0.8.4
2024-07-01 15:03:19 -06:00
dependabot[bot] e65104e762 build(deps): bump regex-syntax from 0.8.3 to 0.8.4
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.8.3 to 0.8.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/regex-syntax-0.8.3...regex-syntax-0.8.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 17:47:29 +00:00
dependabot[bot] da65108efc build(deps): bump clap from 4.5.4 to 4.5.8
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.4 to 4.5.8.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.4...v4.5.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 17:47:16 +00:00
dependabot[bot] c74fefabb6 build(deps): bump lscolors from 0.17.0 to 0.18.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.17.0 to 0.18.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/v0.17.0...v0.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-01 17:47:08 +00:00
Thayne McCombs 45d6fbb9e2 Fix percent encoding
When the first digit is 0
2024-06-24 00:39:41 -06:00
Bryan Honof 4e9672250b docs: Add flox install 2024-06-23 13:45:22 +02:00
Thayne McCombs f8270a6a44 Merge pull request #1575 from tmccombs/windows-build-updates
Windows build updates
2024-06-14 13:50:14 -06:00
Thayne McCombs 7042dff969 Continue supporting windows 7 with builds
By using an older version of rust to build the artifacts on windows.

Alternatively we could build separate artifacts for windows 7, and
continue using the latest version of rust for later versions of windows
that are more optimized for more recent versions.

Fixes: #1550
2024-06-14 00:06:08 -06:00
Thayne McCombs f477c4f2c9 Update OS versions for github actions 2024-06-14 00:06:03 -06:00
Thayne McCombs b1f7aef00b Change --hyperlink to be an option instead of a flag 2024-06-11 00:38:01 -06:00
Thayne McCombs d8d2c37ec0 Fix test on windows 2024-06-10 00:55:10 -06:00
Thayne McCombs 609f1adf90 Fix unicode encoding of hyperlinks
The problem, is I based the code on the implementation in ripgrep. But
while ripgrep is writing directly to the stream, I am using a Formatter,
which means I have to write characters, not raw bytes.

Thus we need to percent encode all non-ascii bytes (or we could switch
to writing bytes directly, but that would be more complicated, and I
think percent encoding is safer anyway).
2024-06-09 22:57:00 -06:00
Thayne McCombs bd649e2fd7 Add hyperlink support to fd
Fixes: #1295
Fixes: #1563
2024-06-08 23:38:57 -06:00
Thayne McCombs be815c261a Merge pull request #1567 from sharkdp/dependabot/cargo/nix-0.29.0
build(deps): bump nix from 0.28.0 to 0.29.0
2024-06-02 14:29:42 -06:00
Thayne McCombs d8a808c0e3 Merge pull request #1569 from sharkdp/dependabot/cargo/libc-0.2.155
build(deps): bump libc from 0.2.154 to 0.2.155
2024-06-01 23:49:47 -06:00
Thayne McCombs c92290c3d7 Merge pull request #1566 from sharkdp/dependabot/cargo/anyhow-1.0.86
build(deps): bump anyhow from 1.0.82 to 1.0.86
2024-06-01 23:46:33 -06:00
Thayne McCombs 0649c2b379 Merge pull request #1568 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.13
build(deps): bump crossbeam-channel from 0.5.12 to 0.5.13
2024-06-01 23:46:05 -06:00
dependabot[bot] 755970deba build(deps): bump libc from 0.2.154 to 0.2.155
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.154 to 0.2.155.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.154...0.2.155)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 17:56:17 +00:00
dependabot[bot] f897b82d76 build(deps): bump crossbeam-channel from 0.5.12 to 0.5.13
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.12 to 0.5.13.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.12...crossbeam-channel-0.5.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 17:56:11 +00:00
dependabot[bot] dbbabed606 build(deps): bump nix from 0.28.0 to 0.29.0
Bumps [nix](https://github.com/nix-rust/nix) from 0.28.0 to 0.29.0.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.28.0...v0.29.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 17:56:05 +00:00
dependabot[bot] ac178e20af build(deps): bump anyhow from 1.0.82 to 1.0.86
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.82 to 1.0.86.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.82...1.0.86)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-01 17:55:57 +00:00
David Peter 29936f0fba Update sponsors.md 2024-05-16 16:56:22 +02:00
David Peter bfc16a1dee Remove sponsorship message 2024-05-16 16:55:35 +02:00
Thayne McCombs 289a68bac3 Merge pull request #1555 from tmccombs/fmt-readme
Add --format to help in README
2024-05-08 00:40:02 -06:00
Thayne McCombs fcaff0f385 Add --format to help in README 2024-05-08 00:38:45 -06:00
Thayne McCombs 36163f9c3a Merge pull request #1554 from tmccombs/release-10.1.0
Prepare for 10.1.0 release
2024-05-08 00:36:34 -06:00
Thayne McCombs d90ec1758e Prepare for 10.1.0 release 2024-05-08 00:20:43 -06:00
Thayne McCombs ea22cbd712 Merge pull request #1043 from tmccombs/format-option
Implement option for printing custom formats
2024-05-07 23:10:12 -06:00
Thayne McCombs d44badc190 Implement option for printing custom formats 2024-05-07 22:52:49 -06:00
Thayne McCombs 6becb66185 Merge pull request #1445 from tmccombs/cwd-prefix
feat: Add option to always include cwd prefix
2024-05-07 21:27:45 -06:00
Thayne McCombs 1a1f057e5d Merge pull request #1552 from tmccombs/mac-m1-build
Attempt to add aarch64 osx build to CI
2024-05-07 10:41:09 -06:00
Thayne McCombs 10a269bd3f Merge pull request #1553 from tmccombs/changelog-update
Add upcoming to changelog
2024-05-07 00:24:37 -06:00
Thayne McCombs 90d3381814 docs: Make auto option for --strip-cwd-prefix more clear 2024-05-07 00:24:15 -06:00
Thayne McCombs b1f83a0bb0 feat: Add option to always include cwd prefix
Fixes: #1243
Fixes: #1331
2024-05-07 00:24:06 -06:00
Thayne McCombs 3bc70925a9 Add upcoming to changelog 2024-05-07 00:16:56 -06:00
Thayne McCombs f287f08b9f Attempt to add aarch64 osx build to CI
Fixes: #1088
2024-05-07 00:14:52 -06:00
Tavian Barnes 0e4488e9dc Merge pull request #1549 from tavianator/jemalloc-aarch64
Fix #1085 for real
2024-05-06 12:39:49 -04:00
Tavian Barnes d7d63eddbe Fix #1085 for real
cross doesn't pass all environment variables through into the build
container, so JEMALLOC_SYS_WITH_LG_PAGE=16 wasn't being picked up from
the host.  Instead, set it explicitly in Cross.toml.

Link: https://github.com/cross-rs/cross/wiki/Configuration
2024-05-06 12:29:11 -04:00
Thayne McCombs 8acd7722f0 Merge pull request #1548 from tmccombs/release-9.1.0
Release 10.0.0
2024-05-06 00:01:31 -06:00
Thayne McCombs 92fab6e058 Prepare for 10.0.0 release 2024-05-05 23:52:50 -06:00
Thayne McCombs a0ee0856db Add @timestamp to --help 2024-05-05 23:52:50 -06:00
Thayne McCombs b8df500a70 Add script to automate some of release process. 2024-05-05 23:52:50 -06:00
Thayne McCombs cd96ca071d Merge pull request #1547 from tavianator/jemalloc-aarch64
ci: Support large page sizes on AArch64
2024-05-03 21:46:40 -06:00
Tavian Barnes 216472ff9f ci: Support large page sizes on AArch64
Fixes #1085.
2024-05-03 15:23:41 -04:00
Thayne McCombs 3680d10e5c Merge pull request #1544 from sharkdp/dependabot/cargo/libc-0.2.154
build(deps): bump libc from 0.2.153 to 0.2.154
2024-05-01 12:03:31 -06:00
dependabot[bot] abe3b9cd78 build(deps): bump libc from 0.2.153 to 0.2.154
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.153 to 0.2.154.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.153...0.2.154)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-01 17:47:51 +00:00
Thayne McCombs 7aad6c9edf Merge pull request #1543 from sharkdp/dependabot/cargo/chrono-0.4.38
build(deps): bump chrono from 0.4.37 to 0.4.38
2024-05-01 11:47:39 -06:00
Thayne McCombs ddd3aae249 Merge pull request #1542 from sharkdp/dependabot/cargo/nix-0.28.0
build(deps): bump nix from 0.27.1 to 0.28.0
2024-05-01 11:46:53 -06:00
dependabot[bot] 6d3bb68faf build(deps): bump chrono from 0.4.37 to 0.4.38
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.37 to 0.4.38.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.37...v0.4.38)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-01 17:31:34 +00:00
dependabot[bot] 21d50dae8c build(deps): bump nix from 0.27.1 to 0.28.0
Bumps [nix](https://github.com/nix-rust/nix) from 0.27.1 to 0.28.0.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.27.1...v0.28.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-01 17:31:29 +00:00
David Peter 9279b1f0af Fix typo in CHANGELOG 2024-04-30 15:56:12 +02:00
Thayne McCombs 6647085015 Add test for gitignore workaround
And make sure it works for user-supplied path of "."

Also add changelog entry
2024-04-30 15:56:12 +02:00
Thayne McCombs 6af8f092ee Workaround for bug with gitinored files
This is a workaround for
https://github.com/BurntSushi/ripgrep/issues/2711

Fixes: #1461
2024-04-30 15:56:12 +02:00
Thayne McCombs c4094c7a05 Merge pull request #1492 from AlbydST/master
Add installation instructions for more Linux distributions in README
2024-04-29 13:13:38 -06:00
AlbydS 6d58df5f0c Remove unnecessary sudo in front of commands
Removed unnecessary "sudo" in front of all commands, also removed the "replace sudo with doas..." instruction at the end.
2024-04-29 18:04:39 +00:00
AlbydS ffecccf209 Merge branch 'sharkdp:master' into master 2024-04-29 17:58:24 +00:00
Thayne McCombs 31f2839751 Merge pull request #1540 from tmccombs/revert-git-ignore
Stop ignore .git folders by default
2024-04-28 20:33:03 -06:00
Thayne McCombs e10a4eab2b Stop ignore .git folders by default
Fixes: #1457
See: #1396, #1403
2024-04-28 20:23:25 -06:00
Thayne McCombs 8eb047945e Merge pull request #1541 from tavianator/clippy-is-empty
filesystem: Remove a redundant as_str()
2024-04-28 20:22:10 -06:00
Tavian Barnes 1031325cca filesystem: Remove a redundant as_str() 2024-04-28 17:30:44 -04:00
Tavian Barnes 9fc2167cf9 Merge pull request #1505 from leuven65/master
set default path separator to '/' in UCRT64 of MSYS
2024-04-28 17:23:43 -04:00
Tavian Barnes ae1de4de24 Merge pull request #1539 from tmccombs/fix-clippy
Fix deprecation warning.
2024-04-28 17:21:41 -04:00
Thayne McCombs 7e5d14b733 Fix deprecation warning. 2024-04-27 21:58:54 -06:00
Thayne McCombs 85cbea8dcb Merge pull request #1494 from nabellows/master
Add support for @%s time format
2024-04-26 22:37:54 -06:00
Thayne McCombs bc6782624e Merge pull request #1520 from tmccombs/clippy
Add clippy using latest rust version to CI
2024-04-15 00:17:20 -06:00
Thayne McCombs cf6ff87c7d Add clippy using latest rust version to CI
Fixes: #1511
2024-04-14 23:33:40 -06:00
Thayne McCombs 3cd73d7927 Merge pull request #1536 from bin-ly/master
Use 'MAIN_SEPARATOR_STR' instead of '&MAIN_SEPARATOR.to_string()'
2024-04-14 20:58:12 -06:00
binlingyu 7794c4aae5 Use 'MAIN_SEPARATOR_STR' instead of '&MAIN_SEPARATOR.to_string()' 2024-04-15 10:36:10 +08:00
Thayne McCombs 8c7a84ea30 Merge pull request #1534 from tmccombs/msrv-update
Update MSRV to 1.77.2
2024-04-11 23:06:41 -06:00
Thayne McCombs e262ade74e Update MSRV to 1.77.2
Prior to this version, `Command` didn't properly escape command line
arguments on windows.

Although, the risk of attacker controlled arguments passed through fd is
relatively small, I think it is best to upgrade to a version that fixes
this.

The biggest risk for users is probably running fd with `--exec` or
`--exec-batch` on directories that contain files with names controlled
by another party (for example a git repo that you cloned).

See: https://blog.rust-lang.org/2024/04/09/cve-2024-24576.html
Security: CVE-2024-24576
2024-04-11 21:14:11 -06:00
Thayne McCombs 11069e284a Merge pull request #1530 from sharkdp/dependabot/cargo/lscolors-0.17.0
build(deps): bump lscolors from 0.16.0 to 0.17.0
2024-04-01 15:22:35 -06:00
Thayne McCombs 6e2e86decb Merge pull request #1529 from sharkdp/dependabot/cargo/aho-corasick-1.1.3
build(deps): bump aho-corasick from 1.1.2 to 1.1.3
2024-04-01 15:22:15 -06:00
Thayne McCombs 15d3b63ccc Merge pull request #1531 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.12
build(deps): bump crossbeam-channel from 0.5.11 to 0.5.12
2024-04-01 15:21:48 -06:00
dependabot[bot] 453577651e build(deps): bump crossbeam-channel from 0.5.11 to 0.5.12
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.11 to 0.5.12.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.11...crossbeam-channel-0.5.12)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 17:31:12 +00:00
dependabot[bot] 39c07b7b4c build(deps): bump lscolors from 0.16.0 to 0.17.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.16.0 to 0.17.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/0.16.0...v0.17.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 17:31:06 +00:00
dependabot[bot] 5910285db0 build(deps): bump aho-corasick from 1.1.2 to 1.1.3
Bumps [aho-corasick](https://github.com/BurntSushi/aho-corasick) from 1.1.2 to 1.1.3.
- [Commits](https://github.com/BurntSushi/aho-corasick/compare/1.1.2...1.1.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 17:31:00 +00:00
Thayne McCombs 68fe31da3f Merge pull request #1517 from one230six/master
refactor: Optimize code based on cargo clippy suggestions
2024-03-13 22:27:48 -06:00
Jian Wang f875ea9a52 Set default path separator to '/' in MSYS/MSYS2
The environments of MSYS: [[https://www.msys2.org/docs/environments/]]
2024-03-13 19:32:13 +01:00
one230six 138919907b refactor: Optimize code based on cargo clippy suggestions
Signed-off-by: one230six <723682061@qq.com>
2024-03-13 15:37:24 +08:00
Thayne McCombs b8744626e7 Merge pull request #1515 from sharkdp/dependabot/github_actions/softprops/action-gh-release-2
build(deps): bump softprops/action-gh-release from 1 to 2
2024-03-11 11:55:43 -06:00
dependabot[bot] b08d78f6fc build(deps): bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 17:45:08 +00:00
Tavian Barnes 4efc05ef27 Merge pull request #1510 from garlic-hub/clippy
Clean up clippy warnings
2024-03-08 16:23:38 -05:00
garlic-hub 0788c43c3f Clean up clippy warnings 2024-03-08 10:46:24 -08:00
Thayne McCombs 3b2fd158b5 Merge pull request #1502 from sharkdp/dependabot/cargo/tempfile-3.10.1
build(deps): bump tempfile from 3.9.0 to 3.10.1
2024-03-01 11:16:34 -07:00
Thayne McCombs c38dbacbd0 Merge pull request #1500 from sharkdp/dependabot/cargo/libc-0.2.153
build(deps): bump libc from 0.2.151 to 0.2.153
2024-03-01 11:15:55 -07:00
Thayne McCombs 728b3200c0 Merge pull request #1503 from sharkdp/dependabot/cargo/chrono-0.4.34
build(deps): bump chrono from 0.4.31 to 0.4.34
2024-03-01 11:15:23 -07:00
dependabot[bot] 7f74cd9e56 build(deps): bump chrono from 0.4.31 to 0.4.34
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.31 to 0.4.34.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.31...v0.4.34)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 17:42:05 +00:00
dependabot[bot] 6ae8da6a39 build(deps): bump tempfile from 3.9.0 to 3.10.1
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.9.0 to 3.10.1.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.9.0...v3.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 17:41:57 +00:00
dependabot[bot] f699c8bb6a build(deps): bump libc from 0.2.151 to 0.2.153
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.151 to 0.2.153.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.151...0.2.153)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 17:41:45 +00:00
Nathan Bellows ffde94c10e Run formatting 2024-02-12 02:12:58 -08:00
Nathan Bellows b0a8848f68 Add support for @%s time format 2024-02-12 02:05:41 -08:00
AlbydS d651a595d4 Add installation instructions for more Linux distributions in README
Added installation instructions for Arch AUR, ALT Linux and Solus and did a few minor changes
2024-02-11 21:25:33 +01:00
David Peter 969316cc0e More whitespace 2024-02-07 09:32:16 +01:00
David Peter 5b46867507 Add Terminal Trove sponsorship 2024-02-07 09:30:20 +01:00
Thayne McCombs e117a373a7 Merge pull request #1488 from sharkdp/dependabot/cargo/nu-ansi-term-0.50.0
build(deps): bump nu-ansi-term from 0.49.0 to 0.50.0
2024-02-01 15:18:00 -07:00
dependabot[bot] a4aed14337 build(deps): bump nu-ansi-term from 0.49.0 to 0.50.0
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.49.0 to 0.50.0.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.49.0...v0.50.0)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 20:50:41 +00:00
Thayne McCombs 9cde3c12a2 Merge pull request #1490 from sharkdp/dependabot/cargo/clap_complete-4.4.9
build(deps): bump clap_complete from 4.4.6 to 4.4.9
2024-02-01 13:50:25 -07:00
Thayne McCombs 906e7a933e Merge pull request #1489 from sharkdp/dependabot/cargo/ignore-0.4.22
build(deps): bump ignore from 0.4.21 to 0.4.22
2024-02-01 13:50:04 -07:00
dependabot[bot] 077d28d13a build(deps): bump ignore from 0.4.21 to 0.4.22
Bumps [ignore](https://github.com/BurntSushi/ripgrep) from 0.4.21 to 0.4.22.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/ignore-0.4.21...ignore-0.4.22)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 18:34:09 +00:00
dependabot[bot] b55bb1e9be build(deps): bump clap_complete from 4.4.6 to 4.4.9
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.4.6 to 4.4.9.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.4.6...clap_complete-v4.4.9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 18:33:20 +00:00
Thayne McCombs 7a6cc92d6d Merge pull request #1486 from sharkdp/dependabot/cargo/regex-1.10.3
build(deps): bump regex from 1.10.2 to 1.10.3
2024-02-01 11:33:08 -07:00
Thayne McCombs b694c6e673 Merge pull request #1487 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.11
build(deps): bump crossbeam-channel from 0.5.10 to 0.5.11
2024-02-01 11:32:41 -07:00
dependabot[bot] 17895538a0 build(deps): bump crossbeam-channel from 0.5.10 to 0.5.11
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.10 to 0.5.11.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.10...crossbeam-channel-0.5.11)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 17:54:58 +00:00
dependabot[bot] 72ff1f9a87 build(deps): bump regex from 1.10.2 to 1.10.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.10.2 to 1.10.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.10.2...1.10.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 17:54:48 +00:00
Thayne McCombs ef3194a510 Merge pull request #1483 from ognevny/patch-1
Makefile: use `--locked` for build
2024-01-26 00:25:04 -07:00
Maksim Bondarenkov 8773402246 Makefile: use --locked for build
to be ensured that Cargo.lock is up to date. also it's needed for disributions
2024-01-20 17:44:38 +03:00
Rob ff3fc81db4 Add target aarch64-unknown-linux-musl 2024-01-16 20:32:41 +01:00
Tavian Barnes 0dc3342c33 Merge pull request #1472 from tmccombs/clap-update
Update clap version
2024-01-08 10:36:43 -05:00
Thayne McCombs c66fc812ac Update clap version
Fixes: #1407
2024-01-08 02:03:39 -07:00
Thayne McCombs 14ed023875 Merge pull request #1464 from Ato2207/dir_alias
Added alias --type dir
2024-01-07 12:03:24 -07:00
Tavian Barnes 58284b8dbe Merge pull request #1470 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.10
build(deps): bump crossbeam-channel from 0.5.8 to 0.5.10
2024-01-01 23:38:31 -05:00
Tavian Barnes 60889d0b99 Merge pull request #1468 from sharkdp/dependabot/cargo/tempfile-3.9.0
build(deps): bump tempfile from 3.8.1 to 3.9.0
2024-01-01 23:36:01 -05:00
dependabot[bot] 7e19bad0a4 build(deps): bump tempfile from 3.8.1 to 3.9.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.8.1 to 3.9.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.8.1...v3.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 18:07:49 +00:00
Thayne McCombs 4b1d73d39d Merge pull request #1469 from sharkdp/dependabot/cargo/filetime-0.2.23
build(deps): bump filetime from 0.2.22 to 0.2.23
2024-01-01 11:07:14 -07:00
dependabot[bot] 03e19a1ad2 build(deps): bump crossbeam-channel from 0.5.8 to 0.5.10
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.8 to 0.5.10.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.8...crossbeam-channel-0.5.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 18:04:12 +00:00
Thayne McCombs 8fb9499c20 Merge pull request #1466 from sharkdp/dependabot/cargo/libc-0.2.151
build(deps): bump libc from 0.2.150 to 0.2.151
2024-01-01 11:03:48 -07:00
Thayne McCombs 38fb6a5958 Merge pull request #1467 from sharkdp/dependabot/cargo/clap_complete-4.4.5
build(deps): bump clap_complete from 4.4.4 to 4.4.5
2024-01-01 11:03:17 -07:00
dependabot[bot] 49cd62d65e build(deps): bump filetime from 0.2.22 to 0.2.23
Bumps [filetime](https://github.com/alexcrichton/filetime) from 0.2.22 to 0.2.23.
- [Commits](https://github.com/alexcrichton/filetime/compare/0.2.22...0.2.23)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 17:33:54 +00:00
dependabot[bot] 24bb5216bb build(deps): bump clap_complete from 4.4.4 to 4.4.5
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.4.4 to 4.4.5.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.4.4...clap_complete-v4.4.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 17:33:45 +00:00
dependabot[bot] 7f8760fd1f build(deps): bump libc from 0.2.150 to 0.2.151
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.150 to 0.2.151.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.150...0.2.151)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 17:33:39 +00:00
Alexandru-Constantin Atomei 3cb6b9d93a Updated CHANGELOG.md, man page and made alias visible in fd -h too 2024-01-01 17:14:32 +02:00
Atomei Alexandru c591106b86 Merge branch 'master' into dir_alias 2023-12-30 22:58:10 +02:00
Alexandru-Constantin Atomei 9f096737db Added explicit documentation about the possibility of using dir 2023-12-30 22:54:57 +02:00
Alexandru-Constantin Atomei 1bda165b25 Added alias --type dir 2023-12-30 22:14:53 +02:00
Thayne McCombs f48372624d Merge pull request #1463 from Roshanjossey/patch-1
Format notes in Readme
2023-12-27 22:25:00 -07:00
Roshan Jossy 5cd15536b6 Format notes in Readme 2023-12-28 00:50:02 +01:00
Sayan Goswami aeb4a5fdad Fixes typo in README
Fixes a tiny typo: ~defautl~ to default.
2023-12-27 14:32:00 -05:00
Thayne McCombs 9529f30129 fix: Respect NO_COLOR with --list-details option
Fixes: #1455
2023-12-23 21:32:33 +01:00
Thayne McCombs 266311ca33 Merge pull request #1454 from tavianator/thats-a-lot-of-issues
CHANGELOG: Fix issue number typo
2023-12-19 13:37:47 -07:00
Tavian Barnes 954a3900b9 CHANGELOG: Fix issue number typo 2023-12-19 14:04:01 -05:00
David Peter 07343b5baf Update troubleshooting section 2023-12-19 11:45:09 +01:00
David Peter a03ed8b300 Update license information 2023-12-19 11:44:20 +01:00
David Peter 13a93e5cbe Add new unreleased section 2023-12-19 11:42:27 +01:00
David Peter d9c4e6239f Fix names for ARM Debian packages 2023-12-19 11:28:59 +01:00
David Peter 61ebd9be6a Update benchmark results 2023-12-19 11:28:59 +01:00
David Peter e3b40208d5 Preprations for fd 9 release 2023-12-19 11:28:59 +01:00
Tavian Barnes 16c2d1e1d0 walk: Flush stdout in batches
The previous behaviour was designed to mimic the output buffering of
typical UNIX tools: line-buffered if stdout is a TTY, and fully-buffered
otherwise.  More precicely, when printing to a terminal, fd would flush
explicitly after printing any buffered results, then flush after every
single result once streaming mode started.  When not printing to a
terminal, fd never explicitly flushed, so writes would only happen as
the BufWriter filled up.

The new behaviour actually unifies the TTY and non-TTY cases: we flush
after printing the buffered results, then once we start streaming, we
flush after each batch, but *only when the channel is empty*.  This
provides a good balance: if the channel is empty, the receiver thread
might as well flush before it goes to sleep waiting for more results.
If the channel is non-empty, we might as well process those results
before deciding to flush.

For TTYs, this should improve performance by consolidating write() calls
without sacrificing interactivity.  For non-TTYs, we'll be flushing more
often, but only when the receiver would otherwise have nothing to do,
thus improving interactivity without sacrificing performance.  This is
particularly handy when fd is piped into another command (such as head
or grep): with the old behaviour, fd could wait for the whole traversal
to finish before printing anything.  With the new behaviour, fd will
print those results soon after they are received.

Fixes #1313.
2023-12-18 22:01:11 +01:00
Tavian Barnes fea1622724 cli: Tweak default thread count logic 2023-12-18 21:55:18 +01:00
David Peter 00b64f3ccb Suggest to use -u instead of -HI 2023-12-08 13:37:03 +01:00
Thayne McCombs 74b850a642 Merge pull request #1436 from sharkdp/dependabot/cargo/clap-4.4.10
build(deps): bump clap from 4.4.7 to 4.4.10
2023-12-01 11:18:35 -07:00
dependabot[bot] 4202f3939e build(deps): bump test-case from 3.2.1 to 3.3.1
Bumps [test-case](https://github.com/frondeus/test-case) from 3.2.1 to 3.3.1.
- [Release notes](https://github.com/frondeus/test-case/releases)
- [Changelog](https://github.com/frondeus/test-case/blob/master/CHANGELOG.md)
- [Commits](https://github.com/frondeus/test-case/compare/v3.2.1...v3.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 18:39:13 +01:00
dependabot[bot] e1ecba2ce4 build(deps): bump lscolors from 0.15.0 to 0.16.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.15.0 to 0.16.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/v0.15.0...0.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 18:38:29 +01:00
dependabot[bot] 0853e35e1f build(deps): bump libc from 0.2.149 to 0.2.150
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.150.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.149...0.2.150)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 18:37:58 +01:00
dependabot[bot] 4b4a74c988 build(deps): bump clap from 4.4.7 to 4.4.10
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.7 to 4.4.10.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.7...v4.4.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-01 17:25:38 +00:00
Tavian Barnes 84f032eba8 Merge pull request #1422 from tavianator/batch
walk: Send WorkerResults in batches
2023-11-29 10:57:19 -05:00
Tavian Barnes b8a5f95cf2 walk: Limit batch sizes in --exec mode 2023-11-28 15:51:33 -05:00
Tavian Barnes 73260c0e35 walk: Send WorkerResults in batches 2023-11-28 15:51:33 -05:00
Tavian Barnes 5903dec289 Merge pull request #1429 from tavianator/ignore-0.4.21
Bump ignore to 0.4.21
2023-11-26 16:28:55 -05:00
Tavian Barnes 571ebb349b Bump ignore to 0.4.21
This includes all the patches from #1420, so switch back to the official
release.
2023-11-26 14:39:25 -05:00
Tavian Barnes d62bbbbcd1 Merge pull request #1421 from acuteenvy/fix-no-color
fix: display color when `NO_COLOR` is an empty string
2023-11-07 13:29:50 -05:00
Lena ad5fb44ddc fix: display color when NO_COLOR is an empty string 2023-11-04 15:07:10 +01:00
Tavian Barnes 8bbbd7679b walk: New WorkerState struct shared by the worker threads 2023-11-02 17:07:38 +01:00
David Peter cd32a3827d Update lockfile 2023-11-02 08:07:39 +01:00
Tavian Barnes 66c0637c90 Use a patched version of ignore for perf improvements
- https://github.com/BurntSushi/ripgrep/commit/d938e955af7a39ac0245b1ce84924f7f4a2141ac
- https://github.com/BurntSushi/ripgrep/pull/2624
- https://github.com/BurntSushi/ripgrep/pull/2642
2023-11-01 21:20:54 +01:00
Tavian Barnes c9df4296f9 Merge pull request #1419 from sharkdp/dependabot/cargo/clap_complete-4.4.4
build(deps): bump clap_complete from 4.4.3 to 4.4.4
2023-11-01 14:07:43 -04:00
Tavian Barnes 7c5cf28ace Merge pull request #1418 from sharkdp/dependabot/cargo/clap-4.4.7
build(deps): bump clap from 4.4.6 to 4.4.7
2023-11-01 14:07:26 -04:00
Tavian Barnes 51002c842d Merge pull request #1417 from sharkdp/dependabot/cargo/nix-0.27.1
build(deps): bump nix from 0.26.4 to 0.27.1
2023-11-01 13:40:57 -04:00
Tavian Barnes 8e582971fa Merge pull request #1416 from sharkdp/dependabot/cargo/regex-syntax-0.8.2
build(deps): bump regex-syntax from 0.7.5 to 0.8.2
2023-11-01 13:36:58 -04:00
Tavian Barnes 6daa72f929 Merge pull request #1415 from sharkdp/dependabot/cargo/tempfile-3.8.1
build(deps): bump tempfile from 3.8.0 to 3.8.1
2023-11-01 13:36:14 -04:00
dependabot[bot] 8355d78359 build(deps): bump clap_complete from 4.4.3 to 4.4.4
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.4.3 to 4.4.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.4.3...clap_complete-v4.4.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 17:20:14 +00:00
dependabot[bot] dbc1818073 build(deps): bump clap from 4.4.6 to 4.4.7
Bumps [clap](https://github.com/clap-rs/clap) from 4.4.6 to 4.4.7.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.6...v4.4.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 17:20:06 +00:00
dependabot[bot] e57ce7f2a4 build(deps): bump nix from 0.26.4 to 0.27.1
Bumps [nix](https://github.com/nix-rust/nix) from 0.26.4 to 0.27.1.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.26.4...v0.27.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 17:19:59 +00:00
dependabot[bot] d8f89fa59e build(deps): bump regex-syntax from 0.7.5 to 0.8.2
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.7.5 to 0.8.2.
- [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/regex-syntax-0.7.5...regex-syntax-0.8.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 17:19:54 +00:00
dependabot[bot] 350003d8da build(deps): bump tempfile from 3.8.0 to 3.8.1
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.8.0 to 3.8.1.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-01 17:19:49 +00:00
tkb-github 15329f9cfa Update RHEL package info 2023-11-01 16:25:25 +01:00
Thayne McCombs 95b4dff379 Merge pull request #1412 from tmccombs/limit-default-threads
Limit default threads
2023-10-27 23:26:31 -06:00
Thayne McCombs c96b1af3be Merge pull request #1410 from tmccombs/available-parallelism
Replace num_cpus with `std::thread::available_parallelism`
2023-10-27 23:25:51 -06:00
Thayne McCombs 5ee6365510 Set maximum default threads
Set a limit of how many threads fd will use by default. On hosts that
have a large number of cores, using additional threads has diminishing
returns, and having large numbers of threads increases the setup cost.
Thus we don't necessarily want to use the same number of threads as we
have cores.

Fixes: #1203
2023-10-26 00:48:30 -06:00
Thayne McCombs 1d57b3a064 Simplify parsing number of threads. 2023-10-25 23:56:59 -06:00
Thayne McCombs 325d419e39 Replace num_cpus with std::thread::available_parallelism
I think this might help startup time a little bit, since it looks like
on linux at least the std implementation uses syscalls to determine the
parallelism, whereas num_cpus was processing the /proc/cpuinfo file.

It also removes another dependency.
2023-10-25 02:00:31 -06:00
Thayne McCombs 8b5532d8dd Merge pull request #1409 from marcospb19/fix-docs-typo
Fix docs typos
2023-10-23 22:10:05 -06:00
João Marcos P. Bezerra 7263b5e01d Fix docs typos 2023-10-24 00:40:12 -03:00
Thayne McCombs c6fcdbe000 docs: Explicitly warn against relying on result order for exec
Supersedes: #1230
Fixes: #1228
2023-10-23 08:34:15 +02:00
Thayne McCombs 306dacd0b4 tests: Add more tests cases for ignoring .git 2023-10-23 08:34:03 +02:00
Thayne McCombs 08910e4e3f docs: Some tweaks from review 2023-10-23 08:34:03 +02:00
Thayne McCombs 8897659607 tests: Add tests for ignoring .git/ 2023-10-23 08:34:03 +02:00
Thayne McCombs 53fd416c47 docs: Document exclusion of .git/ 2023-10-23 08:34:03 +02:00
Thayne McCombs 5e0018fb1f Merge pull request #1402 from tmccombs/nix-users
maint: Remove use of unmaintained users crate
2023-10-22 01:35:47 -06:00
Thayne McCombs 054bae01ef maint: Remove use of unmaintained users crate
The users crate is no longer maintained. There is a maintained fork
called uzers, but we already have a dependency on nix, and that has the
functionality we need.
2023-10-21 23:37:32 -06:00
David Peter 8f32a758a4 Update lock file 2023-10-21 22:16:15 +02:00
David Peter 0fc8facfb7 Fix --help text 2023-10-21 22:16:15 +02:00
Thayne McCombs 069b181625 Fix documentation for brace escapes 2023-10-21 22:16:15 +02:00
Thayne McCombs d9b69c8405 feat: Add a way to escape { and }in exec templates.
fixes #1303
2023-10-21 22:16:15 +02:00
Thayne McCombs a11f8426d4 Fix deprecation warning from chrono
Also change logic to use the latest time if the local time is ambiguous
(for example due to daylight savings)
2023-10-21 14:07:50 +02:00
Thayne McCombs e6aa8e82f6 Add Upcoming Release to changelog 2023-10-21 14:06:52 +02:00
sitiom 978866d983 Change Winget Releaser job to ubuntu-latest 2023-10-21 14:06:25 +02:00
Christian Göttsche 36bc84041b Support character and block device file types 2023-10-21 13:56:33 +02:00
Thayne McCombs 3ed4ea7538 Merge pull request #1396 from skoriop/default-ignore-git-folder
feat: ignore `.git/` by default
2023-10-20 22:35:22 -06:00
Thayne McCombs 6b5fe1c634 Merge pull request #1399 from tmccombs/8.7.1-release
8.7.1 release
2023-10-20 21:57:38 -06:00
Thayne McCombs 7c39fff969 Prepare for 8.7.1 release 2023-10-18 21:44:34 -06:00
Thayne McCombs b922ca18f0 A couple more updates to the changelog 2023-10-18 21:31:28 -06:00
Thayne McCombs b8e7cbd5e3 Merge pull request #1398 from tmccombs/clap-update
Clap update
2023-10-18 09:09:45 -06:00
Karthik Prakash 9df9a489f0 refactor: replace map_err with expect
Co-authored-by: Thayne McCombs <astrothayne@gmail.com>
2023-10-18 13:06:51 +05:30
Thayne McCombs fa01a280ed Update Changelog
This was missed
2023-10-17 23:12:30 -06:00
Thayne McCombs e6b5a4ef9d bug: Update clap to 4.4.6
This also fixes a couple of problems that are now errors:

- Remove use of unstable-grouped feature flag that no longer exists
- Fix some conflicts rules with non-existant options
  * has_results should have been quiet
  * count doesn't exist. I'm not sure where it came from

Fixes: #1397
2023-10-17 23:12:03 -06:00
Thayne McCombs 19832fcbd3 Merge pull request #1386 from SonkeWohler/fix-readme-as-tree
fix(README.md): as-tree is unmaintained, fixes #1040
2023-10-16 10:17:24 -06:00
sonke d371b10039 fix(README.md): as-tree is unmaintained, fixes #1040 2023-10-16 17:54:15 +03:00
skoriop 8c50bc733d docs: update CHANGELOG.md 2023-10-15 11:25:30 +05:30
skoriop 3f9794cd1a feat: ignore .git/ by default 2023-10-15 11:11:53 +05:30
Thayne McCombs fc240f7b2a Merge pull request #1394 from final-israel/make_max_results_one_conflict_with_exec
Making `-1` conflict with `--exec` and making `max-results` override `-1`
2023-10-05 10:27:43 -06:00
Eden Mikitas dea9110b90 Making -1 conflict with --exec and making max-results override -1 2023-10-05 15:10:37 +03:00
Thayne McCombs 93cdb2628e Merge pull request #1391 from sharkdp/dependabot/cargo/jemallocator-0.5.4
Bump jemallocator from 0.5.0 to 0.5.4
2023-10-01 21:28:57 -06:00
Thayne McCombs 817c0bc512 Merge pull request #1390 from sharkdp/dependabot/cargo/libc-0.2.148
Bump libc from 0.2.147 to 0.2.148
2023-10-01 21:28:12 -06:00
Thayne McCombs e97dec777c Merge pull request #1389 from sharkdp/dependabot/cargo/globset-0.4.13
Bump globset from 0.4.10 to 0.4.13
2023-10-01 21:27:32 -06:00
Thayne McCombs 5f494b0925 Merge pull request #1388 from sharkdp/dependabot/cargo/regex-1.9.6
Bump regex from 1.9.1 to 1.9.6
2023-10-01 21:27:02 -06:00
Thayne McCombs 59feb7d6ab Merge pull request #1392 from sharkdp/dependabot/cargo/anyhow-1.0.75
Bump anyhow from 1.0.72 to 1.0.75
2023-10-01 21:26:25 -06:00
dependabot[bot] 97f5326393 Bump anyhow from 1.0.72 to 1.0.75
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.72 to 1.0.75.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.72...1.0.75)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 17:23:46 +00:00
dependabot[bot] e2a298a84f Bump jemallocator from 0.5.0 to 0.5.4
Bumps [jemallocator](https://github.com/tikv/jemallocator) from 0.5.0 to 0.5.4.
- [Release notes](https://github.com/tikv/jemallocator/releases)
- [Changelog](https://github.com/tikv/jemallocator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tikv/jemallocator/compare/0.5.0...0.5.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 17:23:38 +00:00
dependabot[bot] 3317362e78 Bump libc from 0.2.147 to 0.2.148
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.147 to 0.2.148.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.147...0.2.148)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 17:23:31 +00:00
dependabot[bot] 39d0a3ff3c Bump globset from 0.4.10 to 0.4.13
Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.10 to 0.4.13.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/globset-0.4.10...globset-0.4.13)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 17:23:23 +00:00
dependabot[bot] d36c59920d Bump regex from 1.9.1 to 1.9.6
Bumps [regex](https://github.com/rust-lang/regex) from 1.9.1 to 1.9.6.
- [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.9.1...1.9.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 17:23:14 +00:00
Tavian Barnes 995d2f5e44 Merge pull request #1381 from joshuataylor/bump-proc_macro
Bump proc_macro2 to support building on nightly rust
2023-09-18 20:47:15 -05:00
Tavian Barnes 3884f054f1 Merge pull request #1382 from cstyles/bump-clap_complete
Bump clap_complete to 4.4.1
2023-09-09 18:29:25 -04:00
Collin Styles 32504fa3d5 Bump clap_complete to 4.4.1
This fixes an issue with fish shell completions that was causing
problems for fd.
2023-09-09 12:46:43 -07:00
Josh Taylor afd0efa291 Bump proc_macro2 to support building on nightly rust
cargo update proc-macro2

Otherwise the error "error[E0635]: unknown feature
`proc_macro_span_shrink`" will display and the build will fail.

Seems to be okay as of nightly 62ebe3a2b 2023-09-08
2023-09-09 21:15:39 +08:00
Thayne McCombs 737b5bc42e Merge pull request #1377 from sharkdp/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-04 13:10:44 -06:00
dependabot[bot] 601d2bb13e Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 17:59:00 +00:00
Thayne McCombs 917c56b120 Merge pull request #1374 from sharkdp/dependabot/cargo/libc-0.2.147
Bump libc from 0.2.144 to 0.2.147
2023-09-02 00:24:27 -06:00
Thayne McCombs 9ffd57f4ef Merge pull request #1373 from sharkdp/dependabot/cargo/chrono-0.4.28
Bump chrono from 0.4.26 to 0.4.28
2023-09-01 12:29:15 -06:00
dependabot[bot] 08a8723ee7 Bump libc from 0.2.144 to 0.2.147
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.144 to 0.2.147.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.144...0.2.147)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 18:28:11 +00:00
Thayne McCombs efdba804ac Merge pull request #1372 from sharkdp/dependabot/cargo/clap_complete-4.4.0
Bump clap_complete from 4.3.1 to 4.4.0
2023-09-01 12:27:55 -06:00
Thayne McCombs 6f0632273b Merge pull request #1371 from sharkdp/dependabot/cargo/filetime-0.2.22
Bump filetime from 0.2.20 to 0.2.22
2023-09-01 12:26:57 -06:00
Thayne McCombs c848af33d5 Merge pull request #1375 from sharkdp/dependabot/cargo/regex-syntax-0.7.5
Bump regex-syntax from 0.7.4 to 0.7.5
2023-09-01 12:26:31 -06:00
dependabot[bot] f33de6544f Bump regex-syntax from 0.7.4 to 0.7.5
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.7.4 to 0.7.5.
- [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/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 17:05:34 +00:00
dependabot[bot] d7e5dcf9d2 Bump chrono from 0.4.26 to 0.4.28
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.26 to 0.4.28.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.26...v0.4.28)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 17:05:17 +00:00
dependabot[bot] b38ba68ccc Bump clap_complete from 4.3.1 to 4.4.0
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.3.1 to 4.4.0.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.3.1...clap_complete-v4.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 17:05:08 +00:00
dependabot[bot] e55907dc8b Bump filetime from 0.2.20 to 0.2.22
Bumps [filetime](https://github.com/alexcrichton/filetime) from 0.2.20 to 0.2.22.
- [Commits](https://github.com/alexcrichton/filetime/compare/0.2.20...0.2.22)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-01 17:04:58 +00:00
Thayne McCombs a248607bee Merge pull request #1350 from tmccombs/regex-upgrade
Regex upgrade
2023-08-09 01:16:00 -06:00
dependabot[bot] ed23fb9054 Upgrade regex and regex-syntax
Bump regex from 1.7.3 to 1.9.1

Bumps [regex](https://github.com/rust-lang/regex) from 1.7.3 to 1.8.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

Bump regex-syntax from 0.6.29 to 0.7.2

Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.29 to 0.7.2.
- [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/commits)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: regex-syntax
  dependency-type: direct:production
  update-type: version-update:semver-minor

Supersedes: #1334
Supersedes: #1343
Signed-off-by: dependabot[bot] <support@github.com>
2023-08-09 01:02:55 -06:00
Thayne McCombs 7d357a6cec Merge pull request #1359 from sharkdp/dependabot/cargo/nu-ansi-term-0.49.0
Bump nu-ansi-term from 0.47.0 to 0.49.0
2023-08-09 00:20:45 -06:00
dependabot[bot] 1feed8816a Bump nu-ansi-term from 0.47.0 to 0.49.0
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.47.0 to 0.49.0.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.47.0...v0.49.0)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-02 01:49:31 +00:00
Tavian Barnes 9ce43b2d7b Merge pull request #1357 from sharkdp/dependabot/cargo/lscolors-0.15.0
Bump lscolors from 0.14.0 to 0.15.0
2023-08-01 20:48:37 -05:00
dependabot[bot] a6a78e1c65 Bump lscolors from 0.14.0 to 0.15.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.14.0 to 0.15.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/v0.14.0...v0.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-02 01:10:43 +00:00
Thayne McCombs cd14bb8a2c Merge pull request #1358 from sharkdp/dependabot/cargo/chrono-0.4.26
Bump chrono from 0.4.24 to 0.4.26
2023-08-01 18:09:49 -07:00
Thayne McCombs 7162f28a5b Merge pull request #1360 from sharkdp/dependabot/cargo/anyhow-1.0.72
Bump anyhow from 1.0.71 to 1.0.72
2023-08-01 18:07:10 -07:00
dependabot[bot] 2328e9cd17 Bump anyhow from 1.0.71 to 1.0.72
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.71 to 1.0.72.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.71...1.0.72)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 17:20:32 +00:00
dependabot[bot] 2a6026b25d Bump chrono from 0.4.24 to 0.4.26
Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.24 to 0.4.26.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.24...v0.4.26)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 17:20:18 +00:00
tkb-github c62224d2c3 Update instructions for RHEL8 etc. 2023-07-23 13:12:26 +02:00
Thayne McCombs 9a40d21ceb Merge pull request #1351 from frisoft/master
Update license field following SPDX 2.1 license expression standard
2023-07-20 10:40:48 -06:00
Andrea Frigido d019b02829 Update license field following SPDX 2.1 license expression standard 2023-07-20 08:29:10 +01:00
Thayne McCombs 2f813601aa Merge pull request #1340 from sharkdp/dependabot/cargo/clap_complete-4.3.1
Bump clap_complete from 4.3.0 to 4.3.1
2023-07-01 16:27:30 -06:00
Thayne McCombs aae8519a1d Merge pull request #1341 from sharkdp/dependabot/cargo/tempfile-3.6.0
Bump tempfile from 3.5.0 to 3.6.0
2023-07-01 16:23:56 -06:00
Thayne McCombs 4bfb903b22 Merge pull request #1342 from sharkdp/dependabot/cargo/num_cpus-1.16.0
Bump num_cpus from 1.15.0 to 1.16.0
2023-07-01 14:02:54 -06:00
dependabot[bot] d91b2a202e Bump num_cpus from 1.15.0 to 1.16.0
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.15.0...v1.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 17:25:18 +00:00
dependabot[bot] a74a43987a Bump tempfile from 3.5.0 to 3.6.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.5.0 to 3.6.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.5.0...v3.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 17:25:13 +00:00
dependabot[bot] 2a588a0171 Bump clap_complete from 4.3.0 to 4.3.1
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.3.0...clap_complete-v4.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-01 17:25:09 +00:00
Utkarsh Gupta 3ae04546ea Replace dirs-next crate with etcetera crate 2023-06-14 21:22:28 +02:00
Thayne McCombs a0370aaf25 Merge pull request #1333 from tmccombs/rust-170
Rust 1.70 upgrade
2023-06-12 00:32:06 -06:00
Thayne McCombs 740edeb73f Replace atty with std
std now has a function for testing if stdout is a tty
2023-06-08 00:10:53 -06:00
Thayne McCombs 91e3c3cba5 Replace once_cell with stdlib
LazyLock isn't standardized yet, but OnceLock is good enough for what we
need.
2023-06-08 00:05:00 -06:00
Thayne McCombs d6e9cbfff3 Merge pull request #1327 from sharkdp/dependabot/cargo/clap_complete-4.3.0
Bump clap_complete from 4.2.1 to 4.3.0
2023-06-01 16:38:29 -06:00
dependabot[bot] 8d3172f987 Bump clap_complete from 4.2.1 to 4.3.0
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.2.1...clap_complete-v4.3.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 22:37:51 +00:00
Thayne McCombs 5be58f0f76 Merge pull request #1326 from sharkdp/dependabot/cargo/once_cell-1.17.2
Bump once_cell from 1.17.1 to 1.17.2
2023-06-01 16:37:08 -06:00
Thayne McCombs 8d30d6a4fe Merge pull request #1328 from sharkdp/dependabot/cargo/anyhow-1.0.71
Bump anyhow from 1.0.70 to 1.0.71
2023-06-01 16:36:49 -06:00
Thayne McCombs 5ff866aa26 Merge pull request #1329 from sharkdp/dependabot/cargo/libc-0.2.144
Bump libc from 0.2.140 to 0.2.144
2023-06-01 16:36:33 -06:00
dependabot[bot] 4ecf013527 Bump libc from 0.2.140 to 0.2.144
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.140 to 0.2.144.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.140...0.2.144)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 17:57:32 +00:00
dependabot[bot] 1c3a38b423 Bump anyhow from 1.0.70 to 1.0.71
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.70 to 1.0.71.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.70...1.0.71)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 17:57:21 +00:00
dependabot[bot] a3a4912ced Bump once_cell from 1.17.1 to 1.17.2
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.17.1 to 1.17.2.
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.17.1...v1.17.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 17:56:55 +00:00
Thayne McCombs 0d32bebcc2 Merge pull request #1306 from sharkdp/dependabot/cargo/lscolors-0.14.0
Bump lscolors from 0.13.0 to 0.14.0
2023-05-03 23:34:34 -06:00
Thayne McCombs 0884b837b2 Merge pull request #1310 from sharkdp/dependabot/cargo/clap_complete-4.2.1
Bump clap_complete from 4.2.0 to 4.2.1
2023-05-02 01:15:19 -06:00
dependabot[bot] 11199079c3 Bump clap_complete from 4.2.0 to 4.2.1
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.2.0...clap_complete-v4.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 21:18:42 +00:00
Thayne McCombs 69521a1057 Merge pull request #1307 from sharkdp/dependabot/cargo/crossbeam-channel-0.5.8
Bump crossbeam-channel from 0.5.7 to 0.5.8
2023-05-01 15:17:54 -06:00
Thayne McCombs 59a487b524 Merge pull request #1308 from sharkdp/dependabot/cargo/test-case-3.1.0
Bump test-case from 3.0.0 to 3.1.0
2023-05-01 15:15:14 -06:00
dependabot[bot] 0e2a4bac72 Bump test-case from 3.0.0 to 3.1.0
Bumps [test-case](https://github.com/frondeus/test-case) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/frondeus/test-case/releases)
- [Changelog](https://github.com/frondeus/test-case/blob/master/CHANGELOG.md)
- [Commits](https://github.com/frondeus/test-case/compare/v3.0.0...v3.1.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 17:57:14 +00:00
dependabot[bot] 35aa52538c Bump crossbeam-channel from 0.5.7 to 0.5.8
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.7 to 0.5.8.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.7...crossbeam-channel-0.5.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 17:57:08 +00:00
dependabot[bot] b680a9de9f Bump lscolors from 0.13.0 to 0.14.0
Bumps [lscolors](https://github.com/sharkdp/lscolors) from 0.13.0 to 0.14.0.
- [Release notes](https://github.com/sharkdp/lscolors/releases)
- [Commits](https://github.com/sharkdp/lscolors/compare/v0.13.0...v0.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 17:56:59 +00:00
Nathan Houghton 42244e5f32 Don't use jemalloc on OpenBSD (jemalloc fails to compile) 2023-04-14 21:24:19 +02:00
dependabot[bot] 072c9e56e1 Bump normpath from 1.1.0 to 1.1.1
Bumps [normpath](https://github.com/dylni/normpath) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/dylni/normpath/releases)
- [Commits](https://github.com/dylni/normpath/compare/1.1.0...1.1.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 22:32:09 +02:00
dependabot[bot] f7bb60aba5 Bump clap_complete from 4.1.5 to 4.2.0
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.1.5 to 4.2.0.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.1.5...clap_complete-v4.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 20:38:12 +02:00
dependabot[bot] b019d8f1bf Bump tempfile from 3.4.0 to 3.5.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/Stebalien/tempfile/releases)
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/NEWS)
- [Commits](https://github.com/Stebalien/tempfile/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 20:37:56 +02:00
dependabot[bot] 15c795d2e1 Bump nu-ansi-term from 0.46.0 to 0.47.0
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.46.0 to 0.47.0.
- [Release notes](https://github.com/nushell/nu-ansi-term/releases)
- [Changelog](https://github.com/nushell/nu-ansi-term/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nushell/nu-ansi-term/compare/v0.46.0...v0.47.0)

---
updated-dependencies:
- dependency-name: nu-ansi-term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 22:12:18 +02:00
dependabot[bot] a428f7eb13 Bump test-case from 2.2.2 to 3.0.0
Bumps [test-case](https://github.com/frondeus/test-case) from 2.2.2 to 3.0.0.
- [Release notes](https://github.com/frondeus/test-case/releases)
- [Changelog](https://github.com/frondeus/test-case/blob/master/CHANGELOG.md)
- [Commits](https://github.com/frondeus/test-case/compare/v2.2.2...v3.0.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 22:10:47 +02:00
dependabot[bot] 02c9efba28 Bump regex from 1.7.1 to 1.7.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.7.1 to 1.7.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.7.1...1.7.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 22:01:20 +02:00
dependabot[bot] aebe7537c3 Bump regex-syntax from 0.6.28 to 0.6.29
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.28 to 0.6.29.
- [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/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 21:57:46 +02:00
Ryan Caezar Itang 4356ba3c43 Move Winget Releaser inside CICD workflow 2023-03-27 21:43:06 +02:00
Ryan Caezar Itang c9afbc5b70 Add Winget Releaser workflow 2023-03-27 21:43:06 +02:00
Ryan Caezar Itang e38e3078ac Add GitHub actions to Dependabot 2023-03-27 21:43:06 +02:00
David Peter 5439326aa4 CI updates 2023-03-27 21:39:10 +02:00
Thayne McCombs 35bc1f95fb Specifically set ignore version to 0.4.20 in Cargo.toml 2023-03-24 10:38:59 +01:00
Thayne McCombs 161ee64399 Merge pull request #1285 from tmccombs/doc-update
Add documentation and zsh updates
2023-03-21 18:36:01 -06:00
Thayne McCombs 399bf3a931 Add documentation and zsh updates
- Include --and in man page and zsh completions.
- Include --no-require-git and --changed-after to zsh completions

Fixes: #1282
2023-03-21 00:44:53 -06:00
Tavian Barnes bae0a1bfa6 Merge pull request #1284 from tmccombs/cargo-update
Cargo update
2023-03-20 09:45:28 -04:00
Tavian Barnes e4bca1033c Merge pull request #1283 from tmccombs/new-rust-version
A few changes to take advantage of the new MSRV
2023-03-20 09:44:55 -04:00
Thayne McCombs da40e76aae Run cargo update
To update transient dependencies.

Notably, this removes fs_extras, the current version of which has code
that rustc identifies as not being future compatible.
2023-03-20 01:28:43 -06:00
Thayne McCombs 31ac4a3f5c Bump MSRV to 1.67.0 2023-03-20 01:22:52 -06:00
Thayne McCombs 424d6efcc0 fix: Remove unnecessary collection into a vec. 2023-03-20 01:21:00 -06:00
Thayne McCombs ccf8e69650 fix: clippy warning for unnecessary closure
Now that MSRV is above 1.62, we can use `then_some` instead of a simple
closure.
2023-03-20 01:21:00 -06:00
Thayne McCombs ee44c1ed90 refactor: Use scoped threads from stdlib in spawn_receiver
This makes it so we don't need to use Arc as much.

Fixes #1141
2023-03-20 01:21:00 -06:00
David Peter 3ac2e13a25 Merge pull request #1255 from cha0ran/master
Update Chinese links
2023-03-12 22:41:18 +01:00
Thayne McCombs 06a6a118a1 Merge pull request #1269 from sharkdp/dependabot/cargo/normpath-1.0.1
Bump normpath from 0.3.2 to 1.0.1
2023-03-03 00:27:06 -07:00
Thayne McCombs c095867154 Merge pull request #1268 from sharkdp/dependabot/cargo/clap_complete-4.1.4
Bump clap_complete from 4.0.6 to 4.1.4
2023-03-03 00:26:30 -07:00
Tavian Barnes 324005fb3a Merge pull request #1273 from cyqsimon/rustfmt
Add empty `rustfmt.toml` to enforce default formatting
2023-03-02 09:47:27 -05:00
cyqsimon d8166907e6 Add comment on default in rustfmt.toml 2023-03-02 17:06:47 +08:00
cyqsimon 7cbfb8e29c Add empty rustfmt.toml to enfore default formatting 2023-03-02 17:05:15 +08:00
dependabot[bot] 1c5ce0a661 Bump clap_complete from 4.0.6 to 4.1.4
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.0.6 to 4.1.4.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.0.6...clap_complete-v4.1.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 19:48:23 +00:00
dependabot[bot] f98496abcd Bump normpath from 0.3.2 to 1.0.1
Bumps [normpath](https://github.com/dylni/normpath) from 0.3.2 to 1.0.1.
- [Release notes](https://github.com/dylni/normpath/releases)
- [Commits](https://github.com/dylni/normpath/compare/0.3.2...1.0.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 19:47:08 +00:00
David Peter 82aa17f9fb Merge pull request #1270 from sharkdp/dependabot/cargo/ctrlc-3.2.4
Bump ctrlc from 3.2.3 to 3.2.4
2023-03-01 20:46:05 +01:00
David Peter 9b8457aeb3 Merge pull request #1271 from sharkdp/dependabot/cargo/once_cell-1.17.1
Bump once_cell from 1.17.0 to 1.17.1
2023-03-01 20:45:57 +01:00
dependabot[bot] 535b34e48a Bump once_cell from 1.17.0 to 1.17.1
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.17.0 to 1.17.1.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.17.0...v1.17.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 17:57:40 +00:00
dependabot[bot] 0909d413d0 Bump ctrlc from 3.2.3 to 3.2.4
Bumps [ctrlc](https://github.com/Detegr/rust-ctrlc) from 3.2.3 to 3.2.4.
- [Release notes](https://github.com/Detegr/rust-ctrlc/releases)
- [Commits](https://github.com/Detegr/rust-ctrlc/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 17:57:35 +00:00
Thayne McCombs 284ee3d0c6 Merge pull request #1263 from jpcirrus/patch-1
Add flag `--no-require-git` to man page
2023-02-25 23:41:34 -07:00
John Purnell f3e6536d59 Add flag --no-require-git to man page
#1216 omitted to add the flag to the man page.
2023-02-26 11:41:19 +13:00
Tavian Barnes 002645d7ac Merge pull request #1262 from tmccombs/upcoming-changes
Add upcoming changes to changelog
2023-02-24 08:57:02 -05:00
Thayne McCombs 9f6abded0e Add upcoming changes to changelog 2023-02-24 01:27:15 -07:00
Thayne McCombs 840a565d3a Updates for 8.7.0 2023-02-24 00:14:46 -07:00
David Peter 3cf5ac0b9a Merge pull request #1256 from sitiom/patch-1
Add Winget installation reference
2023-02-04 08:51:38 +01:00
sitiom a217823510 Add Winget installation reference 2023-02-04 10:51:47 +08:00
Frank_Shek f867c28a2c Update Chinese links 2023-02-02 09:36:05 +08:00
David Peter 73a693ef28 Merge pull request #1244 from tmccombs/grouped-occurrences
update: Update to clap 4.1
2023-02-01 21:36:19 +01:00
David Peter 9955e20d01 Merge pull request #1253 from sharkdp/dependabot/cargo/nix-0.26.2
Bump nix from 0.25.0 to 0.26.2
2023-02-01 21:35:47 +01:00
David Peter 03052757a7 Merge pull request #1252 from sharkdp/dependabot/cargo/regex-1.7.1
Bump regex from 1.7.0 to 1.7.1
2023-02-01 21:35:39 +01:00
dependabot[bot] bdcc24ed04 Bump nix from 0.25.0 to 0.26.2
Bumps [nix](https://github.com/nix-rust/nix) from 0.25.0 to 0.26.2.
- [Release notes](https://github.com/nix-rust/nix/releases)
- [Changelog](https://github.com/nix-rust/nix/blob/v0.26.2/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.25.0...v0.26.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 17:02:24 +00:00
dependabot[bot] 8478a2c7eb Bump regex from 1.7.0 to 1.7.1
Bumps [regex](https://github.com/rust-lang/regex) from 1.7.0 to 1.7.1.
- [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.7.0...1.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 17:02:07 +00:00
Thayne McCombs c34bfa30fe chore: Update MSRV to 1.64.0
To match clap 4.1
2023-01-18 23:00:03 -07:00
David Peter af9daff4ee Merge pull request #1216 from vegerot/pr1216
Add flag --no-require-git to always respect gitignore files
2023-01-17 14:37:14 +01:00
Thayne McCombs 10ba34f78b update: Update to clap 4.1
This includes switching to the stable API for getting values grouped by
occurrences, and updating tests to match the new error messages.
2023-01-17 00:17:50 -07:00
Thayne McCombs 503ede7535 Merge pull request #1212 from sharkdp/global-ignore-test
Add tests for global ignore file
2023-01-16 00:55:30 -07:00
Max 👨🏽‍💻 Coplan 08c0d427bf Add flag --no-require-git to always respect gitignore files
Summary: Currently, `--ignore-vcs` only serves to unset `--no-ignore-vcs`.
There is currently no way to tell fd to respect gitignore files when not in a
git repository.  This commit adds the flag `--no-require-git` to make fd always
respect all gitignore files.

This behaves the same as the `--no-require-git` option in [ripgrep](https://github.com/BurntSushi/ripgrep/blob/3bb71b0cb8727ac43237af78ba5c707298de0128/crates/core/app.rs#L2214-L2226)

This commit also contains an unrelated wording fix to CONTRIBUTING.md

Test Plan: `tests/tests.rs`

Background: I am using [Sapling](https://sapling-scm.com/docs/introduction/)
for working with git repositories (including this commit ☺️).  Since Sapling
uses `.sl` instead of `.git`, tools using the `ignore` crate (rg and fd) would show gitignored files.
I made a patch (https://github.com/vegerot/ripgrep/commit/ebf17eef22a04450ca86e9dc790db7cb00e11e52)
to `ignore` to respect gitignores with _either_ `.git` or `.sl`.  However,
@BurntSushi said he did not want to merge that patch and instead suggested I
use `--no-require-git` (https://github.com/BurntSushi/ripgrep/issues/2374).
This works fine, but I couldn't use this workaround for my other favorite tool!
That's what this patch is for 😁

(a follow-up patch will add a similar `FD_CONFIG_PATH` environment variable
like `RG_CONFIG_PATH`)
2023-01-13 13:52:34 -08:00
Thayne McCombs ab7d5eff87 Merge pull request #1220 from sharkdp/dependabot/cargo/regex-syntax-0.6.28
Bump regex-syntax from 0.6.27 to 0.6.28
2023-01-01 23:59:16 -07:00
Thayne McCombs 686318c005 Merge pull request #1221 from sharkdp/dependabot/cargo/nix-0.25.0
Bump nix from 0.24.2 to 0.25.0
2023-01-01 11:04:58 -07:00
Thayne McCombs c04ab74744 Merge pull request #1219 from sharkdp/dependabot/cargo/anyhow-1.0.68
Bump anyhow from 1.0.66 to 1.0.68
2023-01-01 10:50:37 -07:00
Thayne McCombs 8fdfc6c2ef Merge pull request #1222 from sharkdp/dependabot/cargo/once_cell-1.17.0
Bump once_cell from 1.15.0 to 1.17.0
2023-01-01 10:50:06 -07:00
dependabot[bot] 71393fa1be Bump regex-syntax from 0.6.27 to 0.6.28
Bumps [regex-syntax](https://github.com/rust-lang/regex) from 0.6.27 to 0.6.28.
- [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/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-01 17:49:30 +00:00
Thayne McCombs 5e50825af2 Merge pull request #1223 from sharkdp/dependabot/cargo/num_cpus-1.15.0
Bump num_cpus from 1.13.1 to 1.15.0
2023-01-01 10:48:42 -07:00
dependabot[bot] 8fed650de9 Bump num_cpus from 1.13.1 to 1.15.0
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.13.1 to 1.15.0.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.13.1...v1.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-01 17:01:46 +00:00
dependabot[bot] 4d8569ad6b Bump once_cell from 1.15.0 to 1.17.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.15.0 to 1.17.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.15.0...v1.17.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-01 17:01:40 +00:00
dependabot[bot] 2f0677b556 Bump nix from 0.24.2 to 0.25.0
Bumps [nix](https://github.com/nix-rust/nix) from 0.24.2 to 0.25.0.
- [Release notes](https://github.com/nix-rust/nix/releases)
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.24.2...v0.25.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-01 17:01:35 +00:00
dependabot[bot] 0a8a72d4f3 Bump anyhow from 1.0.66 to 1.0.68
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.68.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.68)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-01 17:01:23 +00:00
David Peter de611c8835 Merge pull request #1217 from tmccombs/skip-executable-test-if-root
Skip an executable test if running as root
2022-12-29 14:16:01 +01:00
Thayne McCombs a36f2cf61c Skip an executable test if running as root
Fixes #1214
2022-12-28 23:28:41 -07:00
Thayne McCombs b6c7ebc4f1 Don't test global ignore file on windows
Becase XDG_CONFIG_HOME doesn't work there.
2022-12-18 23:33:32 -07:00
Thayne McCombs fd707b42c2 Add tests for global ignore file 2022-12-18 00:42:54 -07:00
Thayne McCombs 7c86c7d585 Merge pull request #1211 from tmccombs/fix-global-ignore
Fix logic for when to read global ignore file
2022-12-17 11:46:18 -07:00
Thayne McCombs 27013537c9 Fix logic for when to read global ignore file
Fixes #1209
2022-12-17 00:28:47 -07:00
David Peter addf00cb16 Merge pull request #1206 from tmccombs/upstream-changes-pr
Add Upcoming release to changelog
2022-12-09 09:06:39 +01:00
Thayne McCombs 1964e434e6 Add Upcoming release to changelog 2022-12-09 00:19:22 -07:00
Thayne McCombs d5bca085dd Updates for 8.6.0 2022-12-08 23:41:24 -07:00
David Peter 8ecfdfee43 Merge pull request #1171 from tmccombs/clap-derive-comments
Use docstrings for long help in clap derive
2022-12-06 22:40:36 +01:00
Thayne McCombs b7a2f68d59 Mention --changed-after alias in long help 2022-12-06 01:28:15 -07:00
Thayne McCombs e98a6c6755 Use docstrings for long help in clap derive 2022-12-06 01:28:15 -07:00
David Peter 614e637dbc Merge pull request #1200 from tmccombs/more-resilient-full-path-tests
Change full path tests to be more resilient
2022-12-05 09:55:36 +01:00
Thayne McCombs 7ec795cd57 Change full-path tests to work on windows as well 2022-12-03 22:30:32 -07:00
Tavian Barnes 8f510265fc Merge pull request #1191 from sharkdp/chrono-without-time
Remove time from transitive dependencies of chrono
2022-12-03 09:57:44 -05:00
Thayne McCombs 39d80a59b6 Remove time from transitive dependencies of chrono
Because chrono was depending on an older version of time, and we don't
actually need it with recent versions of chrono.

Relates-To: #1188
Alernative-To: #1190
2022-12-03 01:28:17 -07:00
Tavian Barnes 6e3eb26af3 Merge pull request #1192 from tmccombs/ansi-term-deprecated
Use nu-ansi-term instead of ansi-term
2022-12-02 09:07:43 -05:00
Thayne McCombs 4a66d8fcd8 Merge pull request #1195 from sharkdp/dependabot/cargo/clap_complete-4.0.6
Bump clap_complete from 4.0.5 to 4.0.6
2022-12-01 23:58:17 -07:00
Thayne McCombs daa986ea35 Merge pull request #1196 from sharkdp/dependabot/cargo/libc-0.2.137
Bump libc from 0.2.136 to 0.2.137
2022-12-01 23:56:15 -07:00
Thayne McCombs 0a575763a1 Change full path tests to be more resilient
Use patterns that won't conflict with randomly generated portion of
temporary directory

Fixes: #1181
2022-12-01 22:02:19 -07:00
dependabot[bot] 547d08c1ef Bump libc from 0.2.136 to 0.2.137
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.136 to 0.2.137.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.136...0.2.137)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 04:57:40 +00:00
Thayne McCombs bbd66b3240 Merge pull request #1199 from sharkdp/dependabot/cargo/regex-1.7.0
Bump regex from 1.6.0 to 1.7.0
2022-12-01 21:53:19 -07:00
dependabot[bot] 2ddc2f6c18 Bump regex from 1.6.0 to 1.7.0
Bumps [regex](https://github.com/rust-lang/regex) from 1.6.0 to 1.7.0.
- [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.6.0...1.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 17:02:43 +00:00
dependabot[bot] 58a9dde73f Bump clap_complete from 4.0.5 to 4.0.6
Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.0.5 to 4.0.6.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.0.5...clap_complete-v4.0.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 17:01:56 +00:00
Thayne McCombs d441516c9d Use nu-ansi-term instead of ansi-term
Because ansi-term is no longer maintained.

Relates-To: #1188
2022-12-01 00:07:30 -07:00
Thayne McCombs d991beb942 Merge pull request #1189 from tmccombs/tempfile
Use tempfile instead of tempdir
2022-11-30 23:43:38 -07:00
Thayne McCombs 650a511fa4 Use tempfile instead of tempdir
Because tempdir is no longer maintained, because it has been combined
with the tempfile crate.

Relates-To: #1188
2022-11-30 02:26:16 -07:00
Thayne McCombs 2aa966cb3c Merge pull request #1183 from Ptipiak/integration-test-files-permission
Adding a simple test for executable files
2022-11-28 22:14:08 -07:00
Ptipiak cd5fad3cf3 Adding a simple test for executable files 2022-11-26 10:09:40 +01:00
David Peter c9d3968475 Merge pull request #1139 from Uthar/master
add support for matching multiple patterns
2022-11-21 21:19:08 +01:00
David Peter 36e60223eb Use allow_hyphen_values = true for --and <pattern> 2022-11-21 21:08:41 +01:00
David Peter 781bd4bcf2 Add CHANGELOG entry 2022-11-21 21:08:39 +01:00
David Peter 0d9926de40 Move --and option up to other patter-related options 2022-11-21 21:06:48 +01:00
David Peter e147ba901b Minor fixes in help text 2022-11-21 21:06:48 +01:00
Kasper Gałkowski 7e26925933 Added the --and flag for matching multiple patterns 2022-11-21 21:06:48 +01:00
David Peter 8dda499830 Merge pull request #1176 from tmccombs/changed-after
Add --changed-after alias.
2022-11-21 08:36:43 +01:00
Thayne McCombs 317a0c3cd3 Add entry for changed-after alias to CHANGELOG 2022-11-20 23:23:32 -07:00
Thayne McCombs 67cf524287 Add --changed-after alias.
And make some small tweaks to the help text and man page.

Closes: #982
2022-11-20 23:21:53 -07:00
David Peter db2590dca5 Merge pull request #1178 from tmccombs/windows-completion-fix
Use file_stem instead of file_name for command for completions
2022-11-18 08:11:04 +01:00
Thayne McCombs 64e642403e Use file_stem instead of file_name for command for completions
Fixes: #1177
2022-11-17 22:22:02 -07:00
David Peter 38cdeb0413 Merge pull request #1169 from Ptipiak/mention-executable-detection
Using faccess lib to detect executable files
2022-11-15 14:15:35 +01:00
David Peter 5c87ff524e Fix CHANGELOG 2022-11-15 14:15:19 +01:00
Ptipiak 88bebb8aac Using faccess lib to detect executable files
* The detection of executable files was not exactly the same as
the original find
2022-11-15 10:31:44 +01:00
Thayne McCombs d89b5755d9 Merge pull request #1175 from miles170/ci-macos-12
CI: replace macos-latest with macos-12
2022-11-14 21:12:12 -07:00
Miles Liu a3489674bf CI: replace macos-latest with macos-12 2022-11-14 16:15:35 +08:00
Thayne McCombs f6e74407e8 Merge pull request #1174 from sharkdp/v8.5.3-bump
Updates for fd 8.5.3
2022-11-13 23:54:36 -07:00
Thayne McCombs 41d775bedd Updates for fd 8.5.3 2022-11-13 23:23:04 -07:00
David Peter 45cb15d60f Merge pull request #1158 from miles170/ci-update-actions
CI: update actions to run on Node 16
2022-11-14 07:12:19 +01:00
Thayne McCombs ce4e8675ed Merge pull request #1173 from zappolowski/fix-completion-program-name
Use just the file name of the program name for generating completions
2022-11-13 22:11:10 -07:00
Bjoern Hiller 2fcfe7a5b7 Use just the file name of the program name
If passed a full path to the executable (like done in the Makefile) that
value is used in the generated completions. At least for fish this just
doesn't work.

This fixes #1172
2022-11-14 05:57:50 +01:00
Miles Liu fdab5da795 CI: using the bash shell to setup cargo cmd 2022-11-14 09:11:09 +08:00
Thayne McCombs 85e3adaf18 Merge pull request #1170 from tmccombs/clap-improvements-2
Clap improvements 2
2022-11-12 09:09:48 -07:00
Thayne McCombs 38d406876d Fix a couple small clippy warnings
- suppress warning about unused function on windows
- remove extraneous & in test
2022-11-11 02:12:58 -07:00
Thayne McCombs 84bf65e023 Use unit type for negating optins with clap_derive
As now supported by https://github.com/clap-rs/clap/pull/4371  and https://github.com/clap-rs/clap/pull/4459
2022-11-11 02:09:41 -07:00
Thayne McCombs 2c3e40c9d9 Use new Shell::from_env method in clap_complete
Instead of having an fd specific implementation.
2022-11-11 02:09:41 -07:00
Thayne McCombs 9e88f91c22 Merge pull request #1168 from tmccombs/clippy-fixes-2
Fix some warnings from clippy
2022-11-08 11:56:12 -07:00
Thayne McCombs 0773b3067e Fix some warnings from clippy
I'm guessing these are new warnings from the Rust 1.65 release
2022-11-08 01:09:06 -07:00
Thayne McCombs bba7e0acd8 Merge pull request #1167 from hadfl/anyhow
anyhow is not only used for the completions feature
2022-11-07 10:48:22 -07:00
Dominik Hassler 6ebc366146 anyhow is not only used for the completions feature 2022-11-07 17:11:00 +00:00
Miles Liu b389f41cb2 CI: add use of Swatinem/rust-cache 2022-11-04 15:18:34 +08:00
David Peter 56c405d8e6 Updates for fd 8.5.2 2022-11-03 09:13:15 +01:00
David Peter 99d1db8cb3 Merge pull request #1164 from tmccombs/owner-without-panic
Fix panic when using --owner
2022-11-03 09:08:09 +01:00
David Peter fbef976b92 Merge pull request #1159 from tmccombs/silence-large-variant
Silence warning about large enum variant
2022-11-03 08:54:52 +01:00
Thayne McCombs 55aae3a8c0 Silence warning about large enum variant
Because boxing the large variant is probably worse.
2022-11-03 00:56:56 -06:00
Thayne McCombs b04cae2ca0 Only run owner root test on linux
Because macos doesn't have a "root" user
2022-11-02 23:55:31 -06:00
Thayne McCombs c159ea2042 Fix panic when using --owner
Unfortunately, clap_derive can't combine a value_parser of Option<T>
with an optional argument to get a merged Option<T> so we need to do the
check for the nop outside of the value parser.

Also adds some tests for --owner

Fixes: #1163
2022-11-02 23:26:02 -06:00
David Peter 567ce2640f Update CHANGELOG 2022-11-02 13:48:18 +01:00
David Peter 527fe9e262 Updates for fd 8.5.1 2022-11-02 13:46:20 +01:00
David Peter 0a7b51ad42 Merge pull request #1162 from sharkdp/fix-threads-option
Fix --threads/-j option value parsing
2022-11-02 13:45:45 +01:00
David Peter f15be89bff Fix --threads/-j option value parsing 2022-11-02 13:32:22 +01:00
David Peter cbd11d8a45 Try to fix bug issue template 2022-11-02 13:15:55 +01:00
Miles Liu f52eaa92e4 CI: remove use of actions-rs/toolchain
actions-rs is currently inactive and has an issue like actions-rs/toolchain#219
2022-11-02 16:44:15 +08:00
Miles Liu f4c6d55b9d CI: remove use of actions-rs/cargo
actions-rs is currently inactive and has an issue like actions-rs/cargo#216
2022-11-02 16:44:15 +08:00
Miles Liu 5e7a870af6 CI: update actions/checkout to v3 2022-11-02 16:40:59 +08:00
Thayne McCombs 6b7f8da381 Merge pull request #1157 from miles170/ci-migrate-set-output
CI: migrate deprecating set-output commands
2022-11-02 00:50:46 -06:00
Miles Liu 8d1c3631cf CI: migrate deprecating set-output commands 2022-11-02 12:06:43 +08:00
David Peter c85929045e Update CHANGELOG 2022-11-01 21:36:56 +01:00
David Peter 715f0a9e44 Update release checklist 2022-11-01 21:36:30 +01:00
41 changed files with 3478 additions and 2145 deletions
+1
View File
@@ -9,6 +9,7 @@ body:
Please check out the [troubleshooting section](https://github.com/sharkdp/fd#troubleshooting) first.
- type: checkboxes
attributes:
label: Checks
options:
- label: I have read the troubleshooting section and still think this is a bug.
required: true
+4
View File
@@ -4,3 +4,7 @@ updates:
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+118 -218
View File
@@ -1,8 +1,8 @@
name: CICD
env:
MIN_SUPPORTED_RUST_VERSION: "1.60.0"
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
MSRV_FEATURES: "--all-features"
on:
workflow_dispatch:
@@ -14,79 +14,90 @@ on:
- '*'
jobs:
code_quality:
name: Code quality
runs-on: ubuntu-20.04
crate_metadata:
name: Extract crate metadata
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
- uses: actions/checkout@v4
- name: Extract crate information
id: crate_metadata
run: |
echo "name=fd" | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT
outputs:
name: ${{ steps.crate_metadata.outputs.name }}
version: ${{ steps.crate_metadata.outputs.version }}
maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
homepage: ${{ steps.crate_metadata.outputs.homepage }}
msrv: ${{ steps.crate_metadata.outputs.msrv }}
ensure_cargo_fmt:
name: Ensure 'cargo fmt' has been run
runs-on: ubuntu-22.04
steps:
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
default: true
profile: minimal # minimal component installation (ie, no documentation)
components: clippy, rustfmt
- name: Ensure `cargo fmt` has been run
uses: actions-rs/cargo@v1
components: rustfmt
- uses: actions/checkout@v4
- run: cargo fmt -- --check
lint_check:
name: Ensure 'cargo clippy' has no warnings
runs-on: ubuntu-latest
steps:
- uses: dtolnay/rust-toolchain@stable
with:
command: fmt
args: -- --check
- name: Ensure MSRV is set in `clippy.toml`
run: grep "^msrv = \"${{ env.MIN_SUPPORTED_RUST_VERSION }}\"\$" clippy.toml
- name: Run clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --all-features
components: clippy
- uses: actions/checkout@v4
- run: cargo clippy --all-targets --all-features -- -Dwarnings
min_version:
name: Minimum supported rust version
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: crate_metadata
steps:
- name: Checkout source code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }})
uses: actions-rs/toolchain@v1
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
default: true
toolchain: ${{ needs.crate_metadata.outputs.msrv }}
components: clippy
profile: minimal
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --all-features
run: cargo clippy --locked --all-targets ${{ env.MSRV_FEATURES }}
- name: Run tests
uses: actions-rs/cargo@v1
with:
command: test
args: --locked
run: cargo test --locked ${{ env.MSRV_FEATURES }}
build:
name: ${{ matrix.job.os }} (${{ matrix.job.target }})
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
runs-on: ${{ matrix.job.os }}
needs: crate_metadata
strategy:
fail-fast: false
matrix:
job:
- { os: ubuntu-20.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
- { os: ubuntu-20.04, target: arm-unknown-linux-musleabihf, use-cross: true }
- { os: ubuntu-20.04, target: aarch64-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-20.04, target: i686-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-20.04, target: i686-unknown-linux-musl , use-cross: true }
- { os: ubuntu-20.04, target: x86_64-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-20.04, target: x86_64-unknown-linux-musl , use-cross: true }
- { os: macos-latest , target: x86_64-apple-darwin }
# - { os: windows-2019, target: i686-pc-windows-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
- { os: windows-2019, target: i686-pc-windows-msvc }
- { os: windows-2019, target: x86_64-pc-windows-gnu }
- { os: windows-2019, target: x86_64-pc-windows-msvc }
- { target: aarch64-unknown-linux-gnu , os: ubuntu-22.04, use-cross: true }
- { target: aarch64-unknown-linux-musl , os: ubuntu-22.04, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-22.04, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-22.04, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2022 }
- { target: i686-unknown-linux-gnu , os: ubuntu-22.04, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-22.04, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-13 }
- { target: aarch64-apple-darwin , os: macos-14 }
- { target: x86_64-pc-windows-gnu , os: windows-2022 }
- { target: x86_64-pc-windows-msvc , os: windows-2022 }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-22.04, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-22.04, use-cross: true }
env:
BUILD_CMD: cargo
steps:
- name: Checkout source code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Install prerequisites
shell: bash
@@ -96,21 +107,24 @@ jobs:
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Extract crate information
shell: bash
run: |
echo "PROJECT_NAME=fd" >> $GITHUB_ENV
echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV
echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
target: ${{ matrix.job.target }}
override: true
profile: minimal # minimal component installation (ie, no documentation)
targets: ${{ matrix.job.target }}
# On windows, for now build with 1.77.2, so that it works on windows 7.
# When we update the MSRV again, we'll need to revisit this, and probably drop support for Win7
toolchain: "${{ contains(matrix.job.target, 'windows-') && '1.77.2' || 'stable' }}"
- name: Install cross
if: matrix.job.use-cross
uses: taiki-e/install-action@v2
with:
tool: cross
- name: Overwrite build command env variable
if: matrix.job.use-cross
shell: bash
run: echo "BUILD_CMD=cross" >> $GITHUB_ENV
- name: Show version information (Rust, cargo, GCC)
shell: bash
@@ -123,14 +137,11 @@ jobs:
rustc -V
- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: build
args: --locked --release --target=${{ matrix.job.target }}
shell: bash
run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }}
- name: Strip debug information from executable
id: strip
- name: Set binary name & path
id: bin
shell: bash
run: |
# Figure out suffix of binary
@@ -139,31 +150,13 @@ jobs:
*-pc-windows-*) EXE_suffix=".exe" ;;
esac;
# Figure out what strip tool to use if any
STRIP="strip"
case ${{ matrix.job.target }} in
arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;;
*-pc-windows-msvc) STRIP="" ;;
esac;
# Setup paths
BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/"
mkdir -p "${BIN_DIR}"
BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}"
BIN_PATH="${BIN_DIR}/${BIN_NAME}"
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
# Copy the release build binary to the result location
cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}"
# Also strip if possible
if [ -n "${STRIP}" ]; then
"${STRIP}" "${BIN_PATH}"
fi
# Let subsequent steps know where to find the (stripped) bin
echo ::set-output name=BIN_PATH::${BIN_PATH}
echo ::set-output name=BIN_NAME::${BIN_NAME}
# Let subsequent steps know where to find the binary
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
- name: Set testing options
id: test-options
@@ -171,15 +164,12 @@ jobs:
run: |
# test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--bin ${PROJECT_NAME}" ;; esac;
echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
- name: Run tests
uses: actions-rs/cargo@v1
with:
use-cross: ${{ matrix.job.use-cross }}
command: test
args: --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
shell: bash
run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
- name: Generate completions
id: completions
@@ -191,23 +181,23 @@ jobs:
shell: bash
run: |
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
PKG_BASENAME=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }}
PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }}
PKG_NAME=${PKG_BASENAME}${PKG_suffix}
echo ::set-output name=PKG_NAME::${PKG_NAME}
echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT
PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/"
mkdir -p "${ARCHIVE_DIR}"
# Binary
cp "${{ steps.strip.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
# Man page
cp 'doc/${{ env.PROJECT_NAME }}.1' "$ARCHIVE_DIR"
cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
# README, LICENSE and CHANGELOG files
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
# Man page
cp 'doc/${{ needs.crate_metadata.outputs.name }}.1' "$ARCHIVE_DIR"
# Autocompletion files
cp -r autocomplete "${ARCHIVE_DIR}"
@@ -220,119 +210,17 @@ jobs:
popd >/dev/null
# Let subsequent steps know where to find the compressed package
echo ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}"
echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT
- name: Create Debian package
id: debian-package
shell: bash
if: startsWith(matrix.job.os, 'ubuntu')
run: |
COPYRIGHT_YEARS="2018 - "$(date "+%Y")
DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package"
DPKG_DIR="${DPKG_STAGING}/dpkg"
mkdir -p "${DPKG_DIR}"
DPKG_BASENAME=${PROJECT_NAME}
DPKG_CONFLICTS=${PROJECT_NAME}-musl
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
DPKG_VERSION=${PROJECT_VERSION}
unset DPKG_ARCH
case ${{ matrix.job.target }} in
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
i686-*-linux-*) DPKG_ARCH=i686 ;;
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
*) DPKG_ARCH=notset ;;
esac;
DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
echo ::set-output name=DPKG_NAME::${DPKG_NAME}
# Binary
install -Dm755 "${{ steps.strip.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.strip.outputs.BIN_NAME }}"
# Man page
install -Dm644 'doc/${{ env.PROJECT_NAME }}.1' "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
# Autocompletion files
install -Dm644 'autocomplete/fd.bash' "${DPKG_DIR}/usr/share/bash-completion/completions/${{ env.PROJECT_NAME }}"
install -Dm644 'autocomplete/fd.fish' "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish"
install -Dm644 'autocomplete/_fd' "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}"
# README and LICENSE
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT"
install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE"
install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: ${{ env.PROJECT_NAME }}
Source: ${{ env.PROJECT_HOMEPAGE }}
Files: *
Copyright: ${{ env.PROJECT_MAINTAINER }}
Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
License: Apache-2.0 or MIT
License: Apache-2.0
On Debian systems, the complete text of the Apache-2.0 can be found in the
file /usr/share/common-licenses/Apache-2.0.
License: MIT
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
.
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
EOF
chmod 644 "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright"
# control file
mkdir -p "${DPKG_DIR}/DEBIAN"
cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
Package: ${DPKG_BASENAME}
Version: ${DPKG_VERSION}
Section: utils
Priority: optional
Maintainer: ${{ env.PROJECT_MAINTAINER }}
Homepage: ${{ env.PROJECT_HOMEPAGE }}
Architecture: ${DPKG_ARCH}
Provides: ${{ env.PROJECT_NAME }}
Conflicts: ${DPKG_CONFLICTS}
Description: simple, fast and user-friendly alternative to find
fd is a program to find entries in your filesystem.
It is a simple, fast and user-friendly alternative to find.
While it does not aim to support all of finds powerful functionality, it provides
sensible (opinionated) defaults for a majority of use cases.
EOF
DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
echo ::set-output name=DPKG_PATH::${DPKG_PATH}
# build dpkg
fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
run: bash scripts/create-deb.sh
env:
TARGET: ${{ matrix.job.target }}
DPKG_VERSION: ${{ needs.crate_metadata.version }}
BIN_PATH: ${{ steps.bin.outputs.BIN_PATH }}
- name: "Artifact upload: tarball"
uses: actions/upload-artifact@master
@@ -352,10 +240,10 @@ jobs:
shell: bash
run: |
unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi
echo ::set-output name=IS_RELEASE::${IS_RELEASE}
echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT
- name: Publish archives and packages
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
if: steps.is-release.outputs.IS_RELEASE
with:
files: |
@@ -363,3 +251,15 @@ jobs:
${{ steps.debian-package.outputs.DPKG_PATH }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
winget:
name: Publish to Winget
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: sharkdp.fd
installers-regex: '-pc-windows-msvc\.zip$'
token: ${{ secrets.WINGET_TOKEN }}
+183
View File
@@ -1,3 +1,186 @@
# Upcoming release
## Features
- Add a hidden `--mindepth` alias for `--min-depth`. (#1617)
## Bugfixes
## Changes
- Replace `humantime` crate and `chrono` crate with `jiff` crate, see #1690 (@sorairolake). This has some small changes to the
way dates given to options such `--changed-within` and `--changed-before` including:
- 'M' no longer means "month", as that could be confusing with minutes. Use "mo", "mos", "month" or "months" instead.
- month and year now account for variability in the calander rather than being a hard-coded number of seconds. That is probably
what you would expect, but it is a slight change in behavior.
## Other
# 10.2.0
## Features
- Add --hyperlink option to add OSC 8 hyperlinks to output
## Bugfixes
## Changes
- Build windows releases with rust 1.77 so windows 7 is still supported
- Deb packages now include symlink for fdfind to be more consistent with official packages
## Other
# 10.1.0
## Features
- Allow passing an optional argument to `--strip-cwd-prefix` of "always", "never", or "auto". to force whether the cwd prefix is stripped or not.
- Add a `--format` option which allows using a format template for direct ouput similar to the template used for `--exec`. (#1043)
## Bugfixes
- Fix aarch64 page size again. This time it should actually work. (#1085, #1549) (@tavianator)
## Other
- aarch64-apple-darwin target added to builds on the release page. Note that this is a tier 2 rust target.
# v10.0.0
## Features
- Add `dir` as an alias to `directory` when using `-t` \ `--type`, see #1460 and #1464 (@Ato2207).
- Add support for @%s date format in time filters similar to GNU date (seconds since Unix epoch for --older/--newer), see #1493 (@nabellows)
- Breaking: No longer automatically ignore `.git` when using `--hidden` with vcs ignore enabled. This reverts the change in v9.0.0. While this feature
was often useful, it also broke some existing workflows, and there wasn't a good way to opt out of it. And there isn't really a good way for us to add
a way to opt out of it. And you can easily get similar behavior by adding `.git/` to your global fdignore file.
See #1457.
## Bugfixes
- Respect NO_COLOR environment variable with `--list-details` option. (#1455)
- Fix bug that would cause hidden files to be included despite gitignore rules
if search path is "." (#1461, BurntSushi/ripgrep#2711).
- aarch64 builds now use 64k page sizes with jemalloc. This fixes issues on some systems, such as ARM Macs that
have a larger system page size than the system that the binary was built on. (#1547)
- Address [CVE-2024-24576](https://blog.rust-lang.org/2024/04/09/cve-2024-24576.html), by increasing minimum rust version.
## Changes
- Minimum supported rust version is now 1.77.2
# v9.0.0
## Performance
- Performance has been *significantly improved*, both due to optimizations in the underlying `ignore`
crate (#1429), and in `fd` itself (#1422, #1408, #1362) - @tavianator.
[Benchmarks results](https://gist.github.com/tavianator/32edbe052f33ef60570cf5456b59de81) show gains
of 6-8x for full traversals of smaller directories (100k files) and up to 13x for larger directories (1M files).
- The default number of threads is now constrained to be at most 64. This should improve startup time on
systems with many CPU cores. (#1203, #1410, #1412, #1431) - @tmccombs and @tavianator
- New flushing behavior when writing output to stdout, providing better performance for TTY and non-TTY
use cases, see #1452 and #1313 (@tavianator).
## Features
- Support character and block device file types, see #1213 and #1336 (@cgzones)
- Breaking: `.git/` is now ignored by default when using `--hidden` / `-H`, use `--no-ignore` / `-I` or
`--no-ignore-vcs` to override, see #1387 and #1396 (@skoriop)
## Bugfixes
- Fix `NO_COLOR` support, see #1421 (@acuteenvy)
## Other
- Fixed documentation typos, see #1409 (@marcospb19)
## Thanks
Special thanks to @tavianator for his incredible work on performance in the `ignore` crate and `fd` itself.
# v8.7.1
## Bugfixes
- `-1` properly conflicts with the exec family of options.
- `--max-results` overrides `-1`
- `--quiet` properly conflicts with the exec family of options. This used to be the case, but broke during the switch to clap-derive
- `--changed-within` now accepts a space as well as a "T" as the separator between date and time (due to update of chrono dependency)
## Other
- Many dependencies were updated
- Some documentation was updated and fixed
# v8.7.0
## Features
- Add flag --no-require-git to always respect gitignore files, see #1216 (@vegerot)
## Bugfixes
- Fix logic for when to use global ignore file. There was a bug where the only case where the
global ignore file wasn't processed was if `--no-ignore` was passed, but neither `--unrestricted`
nor `--no-global-ignore-file` is passed. See #1209
# v8.6.0
## Features
- New `--and <pattern>` option to add additional patterns that must also be matched. See #315
and #1139 (@Uthar)
- Added `--changed-after` as alias for `--changed-within`, to have a name consistent with `--changed-before`.
## Changes
- Breaking: On Unix-like systems, `--type executable` now additionally checks if
the file is executable by the current user, see #1106 and #1169 (@ptipiak)
## Bugfixes
- Use fd instead of fd.exe for Powershell completions (when completions are generated on windows)
## Other
# v8.5.3
## Bugfixes
- Fix completion generation to not include full path of fd command
- Fix build error if completions feature is disabled
# v8.5.2
## Bugfixes
- Fix --owner option value parsing, see #1163 and #1164 (@tmccombs)
# v8.5.1
## Bugfixes
- Fix --threads/-j option value parsing, see #1160 and #1162 (@sharkdp)
# v8.5.0
## Features
+2 -2
View File
@@ -13,11 +13,11 @@ give us the chance to discuss any potential changes first.
## Add an entry to the changelog
If your contribution changes the behavior of `fd` (as opposed to a typo-fix
in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md) file
in the documentation), please update the [`CHANGELOG.md`](CHANGELOG.md#upcoming-release) file
and describe your changes. This makes the release process much easier and
therefore helps to get your changes into a new `fd` release faster.
The top of the `CHANGELOG` contains a *"unreleased"* section with a few
The top of the `CHANGELOG` contains an *"Upcoming release"* section with a few
subsections (Features, Bugfixes, …). Please add your entry to the subsection
that best describes your change.
Generated
+396 -614
View File
File diff suppressed because it is too large Load Diff
+28 -27
View File
@@ -5,6 +5,7 @@ categories = ["command-line-utilities"]
description = "fd is a simple, fast and user-friendly alternative to find."
exclude = ["/benchmarks/*"]
homepage = "https://github.com/sharkdp/fd"
documentation = "https://docs.rs/fd-find"
keywords = [
"search",
"find",
@@ -12,12 +13,13 @@ keywords = [
"filesystem",
"tool",
]
license = "MIT/Apache-2.0"
license = "MIT OR Apache-2.0"
name = "fd-find"
readme = "README.md"
repository = "https://github.com/sharkdp/fd"
version = "8.5.0"
version = "10.2.0"
edition= "2021"
rust-version = "1.77.2"
[badges.appveyor]
repository = "sharkdp/fd"
@@ -33,53 +35,52 @@ path = "src/main.rs"
version_check = "0.9"
[dependencies]
ansi_term = "0.12"
aho-corasick = "1.1"
nu-ansi-term = "0.50"
argmax = "0.3.1"
atty = "0.2"
ignore = "0.4.3"
num_cpus = "1.13"
regex = "1.6.0"
regex-syntax = "0.6"
ignore = "0.4.23"
regex = "1.11.1"
regex-syntax = "0.8"
ctrlc = "3.2"
humantime = "2.1"
lscolors = "0.12"
globset = "0.4"
anyhow = "1.0"
dirs-next = "2.0"
normpath = "0.3.2"
chrono = "0.4"
once_cell = "1.15.0"
crossbeam-channel = "0.5.6"
clap_complete = {version = "4.0", optional = true}
etcetera = "0.9"
normpath = "1.1.1"
crossbeam-channel = "0.5.14"
clap_complete = {version = "4.5.47", optional = true}
faccess = "0.2.4"
jiff = "0.2.5"
[dependencies.clap]
version = "4.0.12"
features = ["suggestions", "color", "wrap_help", "cargo", "unstable-grouped", "derive"]
version = "4.5.35"
features = ["suggestions", "color", "wrap_help", "cargo", "derive"]
[dependencies.lscolors]
version = "0.20"
default-features = false
features = ["nu-ansi-term"]
[target.'cfg(unix)'.dependencies]
users = "0.11.0"
nix = { version = "0.24.2", default-features = false, features = ["signal"] }
nix = { version = "0.29.0", default-features = false, features = ["signal", "user", "hostname"] }
[target.'cfg(all(unix, not(target_os = "redox")))'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
faccess = "0.2.4"
# FIXME: Re-enable jemalloc on macOS
# jemalloc is currently disabled on macOS due to a bug in jemalloc in combination with macOS
# Catalina. See https://github.com/sharkdp/fd/issues/498 for details.
[target.'cfg(all(not(windows), not(target_os = "android"), not(target_os = "macos"), not(target_os = "freebsd"), not(all(target_env = "musl", target_pointer_width = "32")), not(target_arch = "riscv64")))'.dependencies]
jemallocator = {version = "0.5.0", optional = true}
[target.'cfg(all(not(windows), not(target_os = "android"), not(target_os = "macos"), not(target_os = "freebsd"), not(target_os = "openbsd"), not(all(target_env = "musl", target_pointer_width = "32")), not(target_arch = "riscv64")))'.dependencies]
jemallocator = {version = "0.5.4", optional = true}
[dev-dependencies]
diff = "0.1"
tempdir = "0.3"
tempfile = "3.19"
filetime = "0.2"
test-case = "2.2"
test-case = "3.3"
[profile.release]
lto = true
strip = true
codegen-units = 1
[features]
+6
View File
@@ -0,0 +1,6 @@
# https://github.com/sharkdp/fd/issues/1085
[target.aarch64-unknown-linux-gnu.env]
passthrough = ["JEMALLOC_SYS_WITH_LG_PAGE=16"]
[target.aarch64-unknown-linux-musl.env]
passthrough = ["JEMALLOC_SYS_WITH_LG_PAGE=16"]
+1 -1
View File
@@ -6,7 +6,7 @@ datadir=$(prefix)/share
exe_name=fd
$(EXE): Cargo.toml src/**/*.rs
cargo build --profile $(PROFILE)
cargo build --profile $(PROFILE) --locked
.PHONY: completions
completions: autocomplete/fd.bash autocomplete/fd.fish autocomplete/fd.ps1 autocomplete/_fd
+114 -91
View File
@@ -2,7 +2,7 @@
[![CICD](https://github.com/sharkdp/fd/actions/workflows/CICD.yml/badge.svg)](https://github.com/sharkdp/fd/actions/workflows/CICD.yml)
[![Version info](https://img.shields.io/crates/v/fd-find.svg)](https://crates.io/crates/fd-find)
[[中文](https://github.com/chinanf-boy/fd-zh)]
[[中文](https://github.com/cha0ran/fd-zh)]
[[한국어](https://github.com/spearkkk/fd-kor)]
`fd` is a program to find entries in your filesystem.
@@ -10,10 +10,7 @@ It is a simple, fast and user-friendly alternative to [`find`](https://www.gnu.o
While it does not aim to support all of `find`'s powerful functionality, it provides sensible
(opinionated) defaults for a majority of use cases.
Quick links:
* [How to use](#how-to-use)
* [Installation](#installation)
* [Troubleshooting](#troubleshooting)
[Installation](#installation) • [How to use](#how-to-use) • [Troubleshooting](#troubleshooting)
## Features
@@ -63,7 +60,7 @@ X11/xinit/xinitrc
X11/xinit/xserverrc
```
The regular expression syntax used by `fd` is [documented here](https://docs.rs/regex/1.0.0/regex/#syntax).
The regular expression syntax used by `fd` is [documented here](https://docs.rs/regex/latest/regex/#syntax).
### Specifying the root directory
@@ -143,7 +140,7 @@ target/debug/deps/libnum_cpus-f5ce7ef99006aa05.rlib
```
To really search *all* files and directories, simply combine the hidden and ignore features to show
everything (`-HI`).
everything (`-HI`) or use `-u`/`--unrestricted`.
### Matching the full path
By default, *fd* only matches the filename of each file. However, using the `--full-path` or `-p` option,
@@ -261,12 +258,17 @@ To make exclude-patterns like these permanent, you can create a `.fdignore` file
/mnt/external-drive
*.bak
```
Note: `fd` also supports `.ignore` files that are used by other programs such as `rg` or `ag`.
> [!NOTE]
> `fd` also supports `.ignore` files that are used by other programs such as `rg` or `ag`.
If you want `fd` to ignore these patterns globally, you can put them in `fd`'s global ignore file.
This is usually located in `~/.config/fd/ignore` in macOS or Linux, and `%APPDATA%\fd\ignore` in
Windows.
You may wish to include `.git/` in your `fd/ignore` file so that `.git` directories, and their contents
are not included in output if you use the `--hidden` option.
### Deleting files
You can use `fd` to remove all files and directories that are matched by your search pattern.
@@ -284,7 +286,8 @@ option:
If you also want to remove a certain class of directories, you can use the same technique. You will
have to use `rm`s `--recursive`/`-r` flag to remove directories.
Note: there are scenarios where using `fd … -X rm -r` can cause race conditions: if you have a
> [!NOTE]
> There are scenarios where using `fd … -X rm -r` can cause race conditions: if you have a
path like `…/foo/bar/foo/…` and want to remove all directories named `foo`, you can end up in a
situation where the outer `foo` directory is removed first, leading to (harmless) *"'foo/bar/foo':
No such file or directory"* errors in the `rm` call.
@@ -313,81 +316,83 @@ Options:
-p, --full-path Search full abs. path (default: filename only)
-d, --max-depth <depth> Set maximum search depth (default: none)
-E, --exclude <pattern> Exclude entries that match the given glob pattern
-t, --type <filetype> Filter by type: file (f), directory (d), symlink (l),
executable (x), empty (e), socket (s), pipe (p)
-t, --type <filetype> Filter by type: file (f), directory (d/dir), symlink (l),
executable (x), empty (e), socket (s), pipe (p), char-device
(c), block-device (b)
-e, --extension <ext> Filter by file extension
-S, --size <size> Limit results based on the size of files
--changed-within <date|dur> Filter by file modification time (newer than)
--changed-before <date|dur> Filter by file modification time (older than)
-o, --owner <user:group> Filter by owning user and/or group
--format <fmt> Print results according to template
-x, --exec <cmd>... Execute a command for each search result
-X, --exec-batch <cmd>... Execute a command with all search results at once
-c, --color <when> When to use colors [default: auto] [possible values: auto,
always, never]
-h, --help Print help information (use `--help` for more detail)
-V, --version Print version information
--hyperlink[=<when>] Add hyperlinks to output paths [default: never] [possible
values: auto, always, never]
-h, --help Print help (see more with '--help')
-V, --version Print version
```
## Benchmark
Let's search my home folder for files that end in `[0-9].jpg`. It contains ~190.000
subdirectories and about a million files. For averaging and statistical analysis, I'm using
Let's search my home folder for files that end in `[0-9].jpg`. It contains ~750.000
subdirectories and about a 4 million files. For averaging and statistical analysis, I'm using
[hyperfine](https://github.com/sharkdp/hyperfine). The following benchmarks are performed
with a "warm"/pre-filled disk-cache (results for a "cold" disk-cache show the same trends).
Let's start with `find`:
```
Benchmark #1: find ~ -iregex '.*[0-9]\.jpg$'
Time (mean ± σ): 7.236 s ± 0.090 s
Range (min … max): 7.133 s … 7.385 s
Benchmark 1: find ~ -iregex '.*[0-9]\.jpg$'
Time (mean ± σ): 19.922 s ± 0.109 s
Range (min … max): 19.765 s … 20.065 s
```
`find` is much faster if it does not need to perform a regular-expression search:
```
Benchmark #2: find ~ -iname '*[0-9].jpg'
Time (mean ± σ): 3.914 s ± 0.027 s
Range (min … max): 3.876 s … 3.964 s
Benchmark 2: find ~ -iname '*[0-9].jpg'
Time (mean ± σ): 11.226 s ± 0.104 s
Range (min … max): 11.119 s … 11.466 s
```
Now let's try the same for `fd`. Note that `fd` *always* performs a regular expression
search. The options `--hidden` and `--no-ignore` are needed for a fair comparison,
otherwise `fd` does not have to traverse hidden folders and ignored paths (see below):
Now let's try the same for `fd`. Note that `fd` performs a regular expression
search by default. The options `-u`/`--unrestricted` option is needed here for
a fair comparison. Otherwise `fd` does not have to traverse hidden folders and
ignored paths (see below):
```
Benchmark #3: fd -HI '.*[0-9]\.jpg$' ~
Time (mean ± σ): 811.6 ms ± 26.9 ms
Range (min … max): 786.0 ms … 870.7 ms
Benchmark 3: fd -u '[0-9]\.jpg$' ~
Time (mean ± σ): 854.8 ms ± 10.0 ms
Range (min … max): 839.2 ms … 868.9 ms
```
For this particular example, `fd` is approximately nine times faster than `find -iregex`
and about five times faster than `find -iname`. By the way, both tools found the exact
same 20880 files :smile:.
For this particular example, `fd` is approximately **23 times faster** than `find -iregex`
and about **13 times faster** than `find -iname`. By the way, both tools found the exact
same 546 files :smile:.
Finally, let's run `fd` without `--hidden` and `--no-ignore` (this can lead to different
search results, of course). If *fd* does not have to traverse the hidden and git-ignored
folders, it is almost an order of magnitude faster:
```
Benchmark #4: fd '[0-9]\.jpg$' ~
Time (mean ± σ): 123.7 ms ± 6.0 ms
Range (min … max): 118.8 ms … 140.0 ms
```
**Note**: This is *one particular* benchmark on *one particular* machine. While I have
performed quite a lot of different tests (and found consistent results), things might
be different for you! I encourage everyone to try it out on their own. See
**Note**: This is *one particular* benchmark on *one particular* machine. While we have
performed a lot of different tests (and found consistent results), things might
be different for you! We encourage everyone to try it out on their own. See
[this repository](https://github.com/sharkdp/fd-benchmarks) for all necessary scripts.
Concerning *fd*'s speed, the main credit goes to the `regex` and `ignore` crates that are also used
in [ripgrep](https://github.com/BurntSushi/ripgrep) (check it out!).
Concerning *fd*'s speed, a lot of credit goes to the `regex` and `ignore` crates that are
also used in [ripgrep](https://github.com/BurntSushi/ripgrep) (check it out!).
## Troubleshooting
### `fd` does not find my file!
Remember that `fd` ignores hidden directories and files by default. It also ignores patterns
from `.gitignore` files. If you want to make sure to find absolutely every possible file, always
use the options `-u`/`--unrestricted` option (or `-HI` to enable hidden and ignored files):
``` bash
> fd -u …
```
Also remember that by default, `fd` only searches based on the filename and
doesn't compare the pattern to the full path. If you want to search based on the
full path (similar to the `-path` option of `find`) you need to use the `--full-path`
(or `-p`) option.
### Colorized output
`fd` can colorize files by extension, just like `ls`. In order for this to work, the environment
@@ -401,15 +406,6 @@ for alternative, more complete (or more colorful) variants, see [here](https://g
`fd` also honors the [`NO_COLOR`](https://no-color.org/) environment variable.
### `fd` does not find my file!
Remember that `fd` ignores hidden directories and files by default. It also ignores patterns
from `.gitignore` files. If you want to make sure to find absolutely every possible file, always
use the options `-H` and `-I` to disable these two features:
``` bash
> fd -HI …
```
### `fd` doesn't seem to interpret my regex pattern correctly
A lot of special regex characters (like `[]`, `^`, `$`, ..) are also special characters in your
@@ -488,16 +484,17 @@ In emacs, run `M-x find-file-in-project-by-selected` to find matching files. Alt
### Printing the output as a tree
To format the output of `fd` similar to the `tree` command, install [`as-tree`] and pipe the output
of `fd` to `as-tree`:
To format the output of `fd` as a file-tree you can use the `tree` command with
`--fromfile`:
```bash
fd | as-tree
fd | tree --fromfile
```
This can be more useful than running `tree` by itself because `tree` does not ignore any files by
default, nor does it support as rich a set of options as `fd` does to control what to print:
This can be more useful than running `tree` by itself because `tree` does not
ignore any files by default, nor does it support as rich a set of options as
`fd` does to control what to print:
```bash
fd --extension rs | as-tree
fd --extension rs | tree --fromfile
.
├── build.rs
└── src
@@ -505,9 +502,10 @@ default, nor does it support as rich a set of options as `fd` does to control wh
└── error.rs
```
For more information about `as-tree`, see [the `as-tree` README][`as-tree`].
[`as-tree`]: https://github.com/jez/as-tree
On bash and similar you can simply create an alias:
```bash
alias as-tree='tree --fromfile'
```
### Using fd with `xargs` or `parallel`
@@ -530,7 +528,7 @@ newlines). In the same way, the `-0` option of `xargs` tells it to read the inpu
If you run Ubuntu 19.04 (Disco Dingo) or newer, you can install the
[officially maintained package](https://packages.ubuntu.com/fd-find):
```
sudo apt install fd-find
apt install fd-find
```
Note that the binary is called `fdfind` as the binary name `fd` is already used by another package.
It is recommended that after installation, you add a link to `fd` by executing command
@@ -540,21 +538,25 @@ Make sure that `$HOME/.local/bin` is in your `$PATH`.
If you use an older version of Ubuntu, you can download the latest `.deb` package from the
[release page](https://github.com/sharkdp/fd/releases) and install it via:
``` bash
sudo dpkg -i fd_8.5.0_amd64.deb # adapt version number and architecture
dpkg -i fd_9.0.0_amd64.deb # adapt version number and architecture
```
Note that the .deb packages on the release page for this project still name the executable `fd`.
### On Debian
If you run Debian Buster or newer, you can install the
[officially maintained Debian package](https://tracker.debian.org/pkg/rust-fd-find):
```
sudo apt-get install fd-find
apt-get install fd-find
```
Note that the binary is called `fdfind` as the binary name `fd` is already used by another package.
It is recommended that after installation, you add a link to `fd` by executing command
`ln -s $(which fdfind) ~/.local/bin/fd`, in order to use `fd` in the same way as in this documentation.
Make sure that `$HOME/.local/bin` is in your `$PATH`.
Note that the .deb packages on the release page for this project still name the executable `fd`.
### On Fedora
Starting with Fedora 28, you can install `fd` from the official package sources:
@@ -572,10 +574,12 @@ apk add fd
### On Arch Linux
You can install [the fd package](https://www.archlinux.org/packages/community/x86_64/fd/) from the official repos:
You can install [the fd package](https://www.archlinux.org/packages/extra/x86_64/fd/) from the official repos:
```
pacman -S fd
```
You can also install fd [from the AUR](https://aur.archlinux.org/packages/fd-git).
### On Gentoo Linux
You can use [the fd ebuild](https://packages.gentoo.org/packages/sys-apps/fd) from the official repo:
@@ -597,22 +601,31 @@ You can install `fd` via xbps-install:
xbps-install -S fd
```
### On RedHat Enterprise Linux 8 (RHEL8), Almalinux 8, EuroLinux 8 or Rocky Linux 8
### On ALT Linux
Get the latest fd-v*-x86_64-unknown-linux-gnu.tar.gz file from [sharkdp on github](https://github.com/sharkdp/fd/releases)
You can install [the fd package](https://packages.altlinux.org/en/sisyphus/srpms/fd/) from the official repo:
```
tar xf fd-v*-x86_64-unknown-linux-gnu.tar.gz
chown -R root:root fd-v*-x86_64-unknown-linux-gnu
cd fd-v*-x86_64-unknown-linux-gnu
sudo cp fd /bin
gzip fd.1
chown root:root fd.1.gz
sudo cp fd.1.gz /usr/share/man/man1
sudo cp autocomplete/fd.bash /usr/share/bash-completion/completions/fd
source /usr/share/bash-completion/completions/fd
fd
apt-get install fd
```
### On Solus
You can install [the fd package](https://github.com/getsolus/packages/tree/main/packages/f/fd) from the official repo:
```
eopkg install fd
```
### On RedHat Enterprise Linux 8/9 (RHEL8/9), Almalinux 8/9, EuroLinux 8/9 or Rocky Linux 8/9
You can install [the `fd` package](https://copr.fedorainfracloud.org/coprs/tkbcopr/fd/) from Fedora Copr.
```bash
dnf copr enable tkbcopr/fd
dnf install fd
```
A different version using the [slower](https://github.com/sharkdp/fd/pull/481#issuecomment-534494592) malloc [instead of jemalloc](https://bugzilla.redhat.com/show_bug.cgi?id=2216193#c1) is also available from the EPEL8/9 repo as the package `fd-find`.
### On macOS
You can install `fd` with [Homebrew](https://formulae.brew.sh/formula/fd):
@@ -622,7 +635,7 @@ brew install fd
… or with MacPorts:
```
sudo port install fd
port install fd
```
### On Windows
@@ -639,6 +652,11 @@ Or via [Chocolatey](https://chocolatey.org):
choco install fd
```
Or via [Winget](https://learn.microsoft.com/en-us/windows/package-manager/):
```
winget install sharkdp.fd
```
### On GuixOS
You can install [the fd package](https://guix.gnu.org/en/packages/fd-8.1.1/) from the official repo:
@@ -653,6 +671,13 @@ You can use the [Nix package manager](https://nixos.org/nix/) to install `fd`:
nix-env -i fd
```
### Via Flox
You can use [Flox](https://flox.dev) to install `fd` into a Flox environment:
```
flox install fd
```
### On FreeBSD
You can install [the fd-find package](https://www.freshports.org/sysutils/fd) from the official repo:
@@ -662,7 +687,7 @@ pkg install fd-find
### From npm
On linux and macOS, you can install the [fd-find](https://npm.im/fd-find) package:
On Linux and macOS, you can install the [fd-find](https://npm.im/fd-find) package:
```
npm install -g fd-find
@@ -674,7 +699,7 @@ With Rust's package manager [cargo](https://github.com/rust-lang/cargo), you can
```
cargo install fd-find
```
Note that rust version *1.60.0* or later is required.
Note that rust version *1.77.2* or later is required.
`make` is also needed for the build.
@@ -705,8 +730,6 @@ cargo install --path .
## License
Copyright (c) 2017-2021 The fd developers
`fd` is distributed under the terms of both the MIT License and the Apache License 2.0.
See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details.
+2 -2
View File
@@ -1,11 +1,11 @@
fn main() {
let min_version = "1.60";
let min_version = "1.64";
match version_check::is_min_version(min_version) {
Some(true) => {}
// rustc version too small or can't figure it out
_ => {
eprintln!("'fd' requires rustc >= {}", min_version);
eprintln!("'fd' requires rustc >= {min_version}");
std::process::exit(1);
}
}
-1
View File
@@ -1 +0,0 @@
msrv = "1.60.0"
+14 -2
View File
@@ -26,6 +26,8 @@ _fd() {
{l,symlink}'\:"symbolic links"'
{e,empty}'\:"empty files or directories"'
{x,executable}'\:"executable (files)"'
{b,block-device}'\:"block devices"'
{c,char-device}'\:"character devices"'
{s,socket}'\:"sockets"'
{p,pipe}'\:"named pipes (FIFOs)"'
)
@@ -36,7 +38,7 @@ _fd() {
# for all of the potential negation options listed below!
if
# (--[bpsu]* => match all options marked with '$no')
[[ $PREFIX$SUFFIX == --[bopsu]* ]] ||
[[ $PREFIX$SUFFIX == --[bopsun]* ]] ||
zstyle -t ":complete:$curcontext:*" complete-all
then
no=
@@ -70,6 +72,9 @@ _fd() {
{-g,--glob}'[perform a glob-based search]'
{-F,--fixed-strings}'[treat pattern as literal string instead of a regex]'
+ '(no-require-git)'
"$no(no-ignore-full --no-ignore-vcs --no-require-git)--no-require-git[don't require git repo to respect gitignores]"
+ '(match-full)' # match against full path
{-p,--full-path}'[match the pattern against the full path instead of the basename]'
@@ -118,6 +123,7 @@ _fd() {
+ '(filter-mtime-newer)' # filter by files modified after than
'--changed-within=[limit search to files/directories modified within the given date/duration]:date or duration'
'--changed-after=[alias for --changed-within]:date/duration'
'!--change-newer-than=:date/duration'
'!--newer=:date/duration'
@@ -133,6 +139,8 @@ _fd() {
always\:"always use colorized output"
))'
'--hyperlink=-[add hyperlinks to output paths]::when:(auto never always)'
+ '(threads)'
{-j+,--threads=}'[set the number of threads for searching and executing]:number of threads'
@@ -156,7 +164,11 @@ _fd() {
$no'(*)*--search-path=[set search path (instead of positional <path> arguments)]:directory:_files -/'
+ strip-cwd-prefix
$no'(strip-cwd-prefix exec-cmds)--strip-cwd-prefix[Strip ./ prefix when output is redirected]'
$no'(strip-cwd-prefix exec-cmds)--strip-cwd-prefix=-[When to strip ./]::when:(always never auto)'
+ and
'--and=[additional required search path]:pattern'
+ args # positional arguments
'1: :_guard "^-*" pattern'
Vendored
+135 -39
View File
@@ -29,11 +29,19 @@ By default
.B fd
uses regular expressions for the pattern. However, this can be changed to use simple glob patterns
with the '\-\-glob' option.
.P
By default
.B fd
will exclude hidden files and directories, as well as any files that match gitignore rules
or ignore rules in .ignore or .fdignore files.
.SH OPTIONS
.TP
.B \-H, \-\-hidden
Include hidden files and directories in the search results
(default: hidden files and directories are skipped). The flag can be overridden with '--no-hidden'.
.IP
Ignored files are still excluded unless \-\-no\-ignore or \-\-no\-ignore\-vcs
is also used.
.TP
.B \-I, \-\-no\-ignore
Show search results from files and directories that would otherwise be ignored by
@@ -71,6 +79,14 @@ git setting, which defaults to
.IR $HOME/.config/git/ignore ).
The flag can be overridden with '--ignore-vcs'.
.TP
.B \-\-no\-require\-git
Do not require a git repository to respect gitignores. By default, fd will only
respect global gitignore rules, .gitignore rules and local exclude rules if fd
detects that you are searching inside a git repository. This flag allows you to
relax this restriction such that fd will respect all git related ignore rules
regardless of whether youre searching in a git repository or not. The flag can
be overridden with '--require-git'.
.TP
.B \-\-no\-ignore\-parent
Show search results from files and directories that would otherwise be ignored by gitignore files in
parent directories.
@@ -94,6 +110,11 @@ Perform a regular-expression based search (default). This can be used to overrid
Treat the pattern as a literal string instead of a regular expression. Note that this also
performs substring comparison. If you want to match on an exact filename, consider using '\-\-glob'.
.TP
.BI "\-\-and " pattern
Add additional required search patterns, all of which must be matched. Multiple additional
patterns can be specified. The patterns are regular expressions, unless '\-\-glob'
or '\-\-fixed\-strings' is used.
.TP
.B \-a, \-\-absolute\-path
Shows the full path starting from the root as opposed to relative paths.
The flag can be overridden with '--relative-path'.
@@ -135,9 +156,20 @@ can be used as an alias.
Enable the display of filesystem errors for situations such as insufficient
permissions or dead symlinks.
.TP
.B \-\-strip-cwd-prefix
By default, relative paths are prefixed with './' when the output goes to a non interactive terminal
(TTY). Use this flag to disable this behaviour.
.B \-\-strip-cwd-prefix [when]
By default, relative paths are prefixed with './' when -x/--exec,
-X/--exec-batch, or -0/--print0 are given, to reduce the risk of a
path starting with '-' being treated as a command line option. Use
this flag to change this behavior. If this flag is used without a value,
it is equivalent to passing "always". Possible values are:
.RS
.IP never
Never strip the ./ at the beginning of paths
.IP always
Always strip the ./ at the beginning of paths
.IP auto
Only strip if used with --exec, --exec-batch, or --print0. That is, it resets to the default behavior.
.RE
.TP
.B \-\-one\-file\-system, \-\-mount, \-\-xdev
By default, fd will traverse the file system tree as far as other options dictate. With this flag, fd ensures that it does not descend into a different file system than the one it started in. Comparable to the -mount or -xdev filters of find(1).
@@ -167,10 +199,14 @@ Filter search by type:
.RS
.IP "f, file"
regular files
.IP "d, directory"
.IP "d, dir, directory"
directories
.IP "l, symlink"
symbolic links
.IP "b, block-device"
block devices
.IP "c, char-device"
character devices
.IP "s, socket"
sockets
.IP "p, pipe"
@@ -240,6 +276,24 @@ Do not colorize output.
Always colorize output.
.RE
.TP
.B "\-\-hyperlink
Specify whether the output should use terminal escape codes to indicate a hyperlink to a
file url pointing to the path.
The value can be auto, always, or never.
Currently, the default is "never", and if the option is used without an argument "auto" is
used. In the future this may be changed to "auto" and "always".
.RS
.IP auto
Only output hyperlinks if color is also enabled, as a proxy for whether terminal escape
codes are acceptable.
.IP never
Never output hyperlink escapes.
.IP always
Always output hyperlink escapes, regardless of color settings.
.RE
.TP
.BI "\-j, \-\-threads " num
Set number of threads to use for searching & executing (default: number of available CPU cores).
.TP
@@ -282,29 +336,39 @@ tebibytes
.TP
.BI "\-\-changed-within " date|duration
Filter results based on the file modification time.
Files with modification times greater than the argument will be returned.
Files with modification timestamps greater than the argument will be returned.
The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point
in time in either full RFC3339 format with time zone, or as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR).
.B --change-newer-than
can be used as an alias.
in time as full RFC3339 format with time zone, as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR), or as the prefix '@'
followed by the number of seconds since the Unix epoch (@[0-9]+).
\fB\-\-change-newer-than\fR,
.B --newer
or
.B --changed-after
can be used as aliases.
Examples:
\-\-changed-within 2weeks
\-\-change-newer-than "2018-10-27 10:00:00"
\-\-newer 2018-10-27
\-\-changed-after @1704067200
.TP
.BI "\-\-changed-before " date|duration
Filter results based on the file modification time.
Files with modification times less than the argument will be returned.
Files with modification timestamps less than the argument will be returned.
The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point
in time in either full RFC3339 format with time zone, or as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR).
in time as full RFC3339 format with time zone, as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR), or as the prefix '@'
followed by the number of seconds since the Unix epoch (@[0-9]+).
.B --change-older-than
can be used as an alias.
or
.B --older
can be used as aliases.
Examples:
\-\-changed-before "2018-10-27 10:00:00"
\-\-change-older-than 2weeks
\-\-older @1704067200
.TP
.BI "-o, \-\-owner " [user][:group]
Filter files by their user and/or group. Format: [(user|uid)][:(group|gid)]. Either side
@@ -329,6 +393,30 @@ Set the path separator to use when printing file paths. The default is the OS-sp
Provide paths to search as an alternative to the positional \fIpath\fR argument. Changes the usage to
\'fd [FLAGS/OPTIONS] \-\-search\-path PATH \-\-search\-path PATH2 [PATTERN]\'
.TP
.BI "\-\-format " fmt
Specify a template string that is used for printing a line for each file found.
The following placeholders are substituted into the string for each file before printing:
.RS
.IP {}
path (of the current search result)
.IP {/}
basename
.IP {//}
parent directory
.IP {.}
path without file extension
.IP {/.}
basename without file extension
.IP {{
literal '{' (an escape sequence)
.IP }}
literal '}' (an escape sequence)
.P
Notice that you can use "{{" and "}}" to escape "{" and "}" respectively, which is especially
useful if you need to include the literal text of one of the above placeholders.
.RE
.TP
.BI "\-x, \-\-exec " command
.RS
Execute
@@ -345,19 +433,13 @@ This option can be specified multiple times, in which case all commands are run
file found, in the order they are provided. In that case, you must supply a ';' argument for
all but the last commands.
The following placeholders are substituted before the command is executed:
.RS
.IP {}
path (of the current search result)
.IP {/}
basename
.IP {//}
parent directory
.IP {.}
path without file extension
.IP {/.}
basename without file extension
.RE
If parallelism is enabled, the order commands will be executed in is non-deterministic. And even with
--threads=1, the order is determined by the operating system and may not be what you expect. Thus, it is
recommended that you don't rely on any ordering of the results.
Before executing the command, any placeholder patterns in the command are replaced with the
corresponding values for the current file. The same placeholders are used as in the "\-\-format"
option.
If no placeholder is present, an implicit "{}" at the end is assumed.
@@ -381,19 +463,12 @@ Examples:
Execute
.I command
once, with all search results as arguments.
One of the following placeholders is substituted before the command is executed:
.RS
.IP {}
path (of all search results)
.IP {/}
basename
.IP {//}
parent directory
.IP {.}
path without file extension
.IP {/.}
basename without file extension
.RE
The order of the arguments is non-deterministic and should not be relied upon.
This uses the same placeholders as "\-\-format" and "\-\-exec", but instead of expanding
once per command invocation each argument containing a placeholder is expanding for every
file in a batch and passed as separate arguments.
If no placeholder is present, an implicit "{}" at the end is assumed.
@@ -442,6 +517,17 @@ is set, use
.IR $XDG_CONFIG_HOME/fd/ignore .
Otherwise, use
.IR $HOME/.config/fd/ignore .
.SH FILES
.TP
.B .fdignore
This file works similarly to a .gitignore file anywhere in the searched tree and specifies patterns
that should be excluded from the search. However, this file is specific to fd, and will be used even
if the --no-ignore-vcs option is used.
.TP
.B $XDG_CONFIG_HOME/fd/ignore
Global ignore file. Unless ignore mode is turned off (such as with --no-ignore)
ignore entries in this file will be ignored, as if it was an .fdignore file in the
current directory.
.SH EXAMPLES
.TP
.RI "Find files and directories that match the pattern '" needle "':"
@@ -455,6 +541,16 @@ $ fd -e py
.TP
.RI "Open all search results with vim:"
$ fd pattern -X vim
.SH Tips and Tricks
.IP \[bu]
If you add ".git/" to your global ignore file ($XDG_CONFIG_HOME/fd/ignore), then
".git" folders will be ignored by default, even when the --hidden option is used.
.IP \[bu]
You can use a shell alias or a wrapper script in order to pass desired flags to fd
by default. For example if you do not like the default behavior of respecting gitignore,
you can use
`alias fd="/usr/bin/fd --no-ignore-vcs"`
in your .bashrc to create an alias for fd that doesn't ignore git files by default.
.SH BUGS
Bugs can be reported on GitHub: https://github.com/sharkdp/fd/issues
.SH SEE ALSO
+6 -3
View File
@@ -9,7 +9,7 @@ necessary changes for the upcoming release.
- [ ] Update version in `Cargo.toml`. Run `cargo build` to update `Cargo.lock`.
Make sure to `git add` the `Cargo.lock` changes as well.
- [ ] Find the current min. supported Rust version by running
`grep '^\s*MIN_SUPPORTED_RUST_VERSION' .github/workflows/CICD.yml`.
`grep rust-version Cargo.toml`.
- [ ] Update the `fd` version and the min. supported Rust version in `README.md`.
- [ ] Update `CHANGELOG.md`. Change the heading of the *"Upcoming release"* section
to the version of this release.
@@ -31,6 +31,7 @@ necessary changes for the upcoming release.
## Release
- [ ] Merge your release branch (should be a fast-forward merge).
- [ ] Create a tag and push it: `git tag vX.Y.Z; git push origin tag vX.Y.Z`.
This will trigger the deployment via GitHub Actions.
REMINDER: If your `origin` is a fork, don't forget to push to e.g. `upstream`
@@ -49,15 +50,17 @@ necessary changes for the upcoming release.
- [ ] Prepare a new *"Upcoming release"* section at the top of `CHANGELOG.md`.
Put this at the top:
```
# Upcoming release
## Features
## Bugfixes
## Changes
## Other
```
+12
View File
@@ -0,0 +1,12 @@
## Sponsors
`fd` development is sponsored by many individuals and companies. Thank you very much!
Please note, that being sponsored does not affect the individuality of the `fd`
project or affect the maintainers' actions in any way.
We remain impartial and continue to assess pull requests solely on merit - the
features added, bugs solved, and effect on the overall complexity of the code.
No issue will have a different priority based on sponsorship status of the
reporter.
Contributions from anybody are most welcomed, please see our [`CONTRIBUTING.md`](../CONTRIBUTING.md) guide.
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.2 KiB

+1
View File
@@ -0,0 +1 @@
# Defaults are used
+134
View File
@@ -0,0 +1,134 @@
#!/bin/bash
COPYRIGHT_YEARS="2018 - "$(date "+%Y")
MAINTAINER="David Peter <mail@david-peter.de>"
REPO="https://github.com/sharkdp/fd"
DPKG_STAGING="${CICD_INTERMEDIATES_DIR:-.}/debian-package"
DPKG_DIR="${DPKG_STAGING}/dpkg"
mkdir -p "${DPKG_DIR}"
if [[ -z "$TARGET" ]]; then
TARGET="$(rustc -vV | sed -n 's|host: \(.*\)|\1|p')"
fi
case "$TARGET" in
*-musl*)
DPKG_BASENAME=fd-musl
DPKG_CONFLICTS="fd, fd-find"
;;
*)
DPKG_BASENAME=fd
DPKG_CONFLICTS="fd-musl, fd-find"
;;
esac
if [[ -z "$DPKG_VERSION" ]]; then
DPKG_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r .packages[0].version)
fi
unset DPKG_ARCH
case "${TARGET}" in
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
i686-*-linux-*) DPKG_ARCH=i686 ;;
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
*) DPKG_ARCH=notset ;;
esac;
DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
BIN_PATH=${BIN_PATH:-target/${TARGET}/release/fd}
# Binary
install -Dm755 "${BIN_PATH}" "${DPKG_DIR}/usr/bin/fd"
# Man page
install -Dm644 'doc/fd.1' "${DPKG_DIR}/usr/share/man/man1/fd.1"
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/fd.1"
# Autocompletion files
install -Dm644 'autocomplete/fd.bash' "${DPKG_DIR}/usr/share/bash-completion/completions/fd"
install -Dm644 'autocomplete/fd.fish' "${DPKG_DIR}/usr/share/fish/vendor_completions.d/fd.fish"
install -Dm644 'autocomplete/_fd' "${DPKG_DIR}/usr/share/zsh/vendor-completions/_fd"
# README and LICENSE
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT"
install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE"
install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
# Create symlinks so fdfind can be used as well:
ln -s "/usr/bin/fd" "${DPKG_DIR}/usr/bin/fdfind"
ln -s './fd.bash' "${DPKG_DIR}/usr/share/bash-completion/completions/fdfind"
ln -s './fd.fish' "${DPKG_DIR}/usr/share/fish/vendor_completions.d/fdfind.fish"
ln -s './_fd' "${DPKG_DIR}/usr/share/zsh/vendor-completions/_fdfind"
cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: fd
Source: ${REPO}
Files: *
Copyright: ${MAINTAINER}
Copyright: $COPYRIGHT_YEARS ${MAINTAINER}
License: Apache-2.0 or MIT
License: Apache-2.0
On Debian systems, the complete text of the Apache-2.0 can be found in the
file /usr/share/common-licenses/Apache-2.0.
License: MIT
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
.
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
EOF
chmod 644 "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright"
# control file
mkdir -p "${DPKG_DIR}/DEBIAN"
cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
Package: ${DPKG_BASENAME}
Version: ${DPKG_VERSION}
Section: utils
Priority: optional
Maintainer: ${MAINTAINER}
Homepage: ${REPO}
Architecture: ${DPKG_ARCH}
Provides: fd
Conflicts: ${DPKG_CONFLICTS}
Description: simple, fast and user-friendly alternative to find
fd is a program to find entries in your filesystem.
It is a simple, fast and user-friendly alternative to find.
While it does not aim to support all of finds powerful functionality, it provides
sensible (opinionated) defaults for a majority of use cases.
EOF
DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
if [[ -n $GITHUB_OUTPUT ]]; then
echo "DPKG_NAME=${DPKG_NAME}" >> "$GITHUB_OUTPUT"
echo "DPKG_PATH=${DPKG_PATH}" >> "$GITHUB_OUTPUT"
fi
# build dpkg
fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/bash
set -eu
# This script automates the "Version bump" section
version="$1"
if [[ -z $version ]]; then
echo "Usage: must supply version as first argument" >&2
exit 1
fi
git switch -C "release-$version"
sed -i -e "0,/^\[badges/{s/^version =.*/version = \"$version\"/}" Cargo.toml
msrv="$(grep -F rust-version Cargo.toml | sed -e 's/^rust-version= "\(.*\)"/\1/')"
sed -i -e "s/Note that rust version \*[0-9.]+\* or later/Note that rust version *$msrv* or later/" README.md
sed -i -e "s/^# Upcoming release/# $version/" CHANGELOG.md
+410 -319
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -8,6 +8,7 @@ use crate::filetypes::FileTypes;
#[cfg(unix)]
use crate::filter::OwnerFilter;
use crate::filter::{SizeFilter, TimeFilter};
use crate::fmt::FormatTemplate;
/// Configuration options for *fd*.
pub struct Config {
@@ -30,6 +31,9 @@ pub struct Config {
/// Whether to respect VCS ignore files (`.gitignore`, ..) or not.
pub read_vcsignore: bool,
/// Whether to require a `.git` directory to respect gitignore files.
pub require_git_to_read_vcsignore: bool,
/// Whether to respect the global ignore file or not.
pub read_global_ignore: bool,
@@ -71,6 +75,7 @@ pub struct Config {
pub ls_colors: Option<LsColors>,
/// Whether or not we are writing to an interactive terminal
#[cfg_attr(not(unix), allow(unused))]
pub interactive_terminal: bool,
/// The type of file to search for. If set to `None`, all file types are displayed. If
@@ -82,6 +87,9 @@ pub struct Config {
/// The value (if present) will be a lowercase string without leading dots.
pub extensions: Option<RegexSet>,
/// A format string to use to format results, similarly to exec
pub format: Option<FormatTemplate>,
/// If a value is supplied, each item found will be used to generate and execute commands.
pub command: Option<Arc<CommandSet>>,
@@ -119,6 +127,9 @@ pub struct Config {
/// Whether or not to strip the './' prefix for search results
pub strip_cwd_prefix: bool,
/// Whether or not to use hyperlinks on paths
pub hyperlink: bool,
}
impl Config {
+5 -4
View File
@@ -1,19 +1,20 @@
use std::cell::OnceCell;
use std::ffi::OsString;
use std::fs::{FileType, Metadata};
use std::path::{Path, PathBuf};
use lscolors::{Colorable, LsColors, Style};
use once_cell::unsync::OnceCell;
use crate::config::Config;
use crate::filesystem::strip_current_dir;
#[derive(Debug)]
enum DirEntryInner {
Normal(ignore::DirEntry),
BrokenSymlink(PathBuf),
}
#[derive(Debug)]
pub struct DirEntry {
inner: DirEntryInner,
metadata: OnceCell<Option<Metadata>>,
@@ -112,7 +113,7 @@ impl Eq for DirEntry {}
impl PartialOrd for DirEntry {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.path().partial_cmp(other.path())
Some(self.cmp(other))
}
}
@@ -136,7 +137,7 @@ impl Colorable for DirEntry {
// but we want it for all component types, so we open code it.
// Copied from LsColors::style_for_path_with_metadata().
path.components()
.last()
.next_back()
.map(|c| c.as_os_str())
.unwrap_or_else(|| path.as_os_str())
}
+1 -1
View File
@@ -103,7 +103,7 @@ pub fn handle_cmd_error(cmd: Option<&Command>, err: io::Error) -> ExitCode {
ExitCode::GeneralError
}
(_, err) => {
print_error(format!("Problem while executing command: {}", err));
print_error(format!("Problem while executing command: {err}"));
ExitCode::GeneralError
}
}
+20 -19
View File
@@ -1,9 +1,6 @@
use std::sync::{Arc, Mutex};
use crossbeam_channel::Receiver;
use std::sync::Mutex;
use crate::config::Config;
use crate::dir_entry::DirEntry;
use crate::error::print_error;
use crate::exit_codes::{merge_exitcodes, ExitCode};
use crate::walk::WorkerResult;
@@ -14,43 +11,47 @@ use super::CommandSet;
/// generate a command with the supplied command template. The generated command will then
/// be executed, and this process will continue until the receiver's sender has closed.
pub fn job(
rx: Receiver<WorkerResult>,
cmd: Arc<CommandSet>,
out_perm: Arc<Mutex<()>>,
results: impl IntoIterator<Item = WorkerResult>,
cmd: &CommandSet,
out_perm: &Mutex<()>,
config: &Config,
) -> ExitCode {
// Output should be buffered when only running a single thread
let buffer_output: bool = config.threads > 1;
let mut results: Vec<ExitCode> = Vec::new();
loop {
let mut ret = ExitCode::Success;
for result in results {
// Obtain the next result from the receiver, else if the channel
// has closed, exit from the loop
let dir_entry: DirEntry = match rx.recv() {
Ok(WorkerResult::Entry(dir_entry)) => dir_entry,
Ok(WorkerResult::Error(err)) => {
let dir_entry = match result {
WorkerResult::Entry(dir_entry) => dir_entry,
WorkerResult::Error(err) => {
if config.show_filesystem_errors {
print_error(err.to_string());
}
continue;
}
Err(_) => break,
};
// Generate a command, execute it and store its exit code.
results.push(cmd.execute(
let code = cmd.execute(
dir_entry.stripped_path(config),
config.path_separator.as_deref(),
Arc::clone(&out_perm),
out_perm,
buffer_output,
))
);
ret = merge_exitcodes([ret, code]);
}
// Returns error in case of any error.
merge_exitcodes(results)
ret
}
pub fn batch(rx: Receiver<WorkerResult>, cmd: &CommandSet, config: &Config) -> ExitCode {
let paths = rx
pub fn batch(
results: impl IntoIterator<Item = WorkerResult>,
cmd: &CommandSet,
config: &Config,
) -> ExitCode {
let paths = results
.into_iter()
.filter_map(|worker_result| match worker_result {
WorkerResult::Entry(dir_entry) => Some(dir_entry.into_stripped_path(config)),
+62 -183
View File
@@ -1,27 +1,21 @@
mod command;
mod input;
mod job;
mod token;
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
use std::ffi::OsString;
use std::io;
use std::iter;
use std::path::{Component, Path, PathBuf, Prefix};
use std::path::{Path, PathBuf};
use std::process::Stdio;
use std::sync::{Arc, Mutex};
use std::sync::Mutex;
use anyhow::{bail, Result};
use argmax::Command;
use once_cell::sync::Lazy;
use regex::Regex;
use crate::exit_codes::{merge_exitcodes, ExitCode};
use crate::fmt::{FormatTemplate, Token};
use self::command::{execute_commands, handle_cmd_error};
use self::input::{basename, dirname, remove_extension};
pub use self::job::{batch, job};
use self::token::Token;
/// Execution mode of the command
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -39,9 +33,10 @@ pub struct CommandSet {
}
impl CommandSet {
pub fn new<I, S>(input: I) -> Result<CommandSet>
pub fn new<I, T, S>(input: I) -> Result<CommandSet>
where
I: IntoIterator<Item = Vec<S>>,
I: IntoIterator<Item = T>,
T: IntoIterator<Item = S>,
S: AsRef<str>,
{
Ok(CommandSet {
@@ -53,9 +48,10 @@ impl CommandSet {
})
}
pub fn new_batch<I, S>(input: I) -> Result<CommandSet>
pub fn new_batch<I, T, S>(input: I) -> Result<CommandSet>
where
I: IntoIterator<Item = Vec<S>>,
I: IntoIterator<Item = T>,
T: IntoIterator<Item = S>,
S: AsRef<str>,
{
Ok(CommandSet {
@@ -84,14 +80,14 @@ impl CommandSet {
&self,
input: &Path,
path_separator: Option<&str>,
out_perm: Arc<Mutex<()>>,
out_perm: &Mutex<()>,
buffer_output: bool,
) -> ExitCode {
let commands = self
.commands
.iter()
.map(|c| c.generate(input, path_separator));
execute_commands(commands, &out_perm, buffer_output)
execute_commands(commands, out_perm, buffer_output)
}
pub fn execute_batch<I>(&self, paths: I, limit: usize, path_separator: Option<&str>) -> ExitCode
@@ -131,7 +127,7 @@ impl CommandSet {
#[derive(Debug)]
struct CommandBuilder {
pre_args: Vec<OsString>,
path_arg: ArgumentTemplate,
path_arg: FormatTemplate,
post_args: Vec<OsString>,
cmd: Command,
count: usize,
@@ -148,7 +144,7 @@ impl CommandBuilder {
for arg in &template.args {
if arg.has_tokens() {
path_arg = Some(arg.clone());
} else if path_arg == None {
} else if path_arg.is_none() {
pre_args.push(arg.generate("", None));
} else {
post_args.push(arg.generate("", None));
@@ -220,7 +216,7 @@ impl CommandBuilder {
/// `generate_and_execute()` method will be used to generate a command and execute it.
#[derive(Debug, Clone, PartialEq)]
struct CommandTemplate {
args: Vec<ArgumentTemplate>,
args: Vec<FormatTemplate>,
}
impl CommandTemplate {
@@ -229,50 +225,15 @@ impl CommandTemplate {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
static PLACEHOLDER_PATTERN: Lazy<Regex> =
Lazy::new(|| Regex::new(r"\{(/?\.?|//)\}").unwrap());
let mut args = Vec::new();
let mut has_placeholder = false;
for arg in input {
let arg = arg.as_ref();
let mut tokens = Vec::new();
let mut start = 0;
for placeholder in PLACEHOLDER_PATTERN.find_iter(arg) {
// Leading text before the placeholder.
if placeholder.start() > start {
tokens.push(Token::Text(arg[start..placeholder.start()].to_owned()));
}
start = placeholder.end();
match placeholder.as_str() {
"{}" => tokens.push(Token::Placeholder),
"{.}" => tokens.push(Token::NoExt),
"{/}" => tokens.push(Token::Basename),
"{//}" => tokens.push(Token::Parent),
"{/.}" => tokens.push(Token::BasenameNoExt),
_ => unreachable!("Unhandled placeholder"),
}
has_placeholder = true;
}
// Without a placeholder, the argument is just fixed text.
if tokens.is_empty() {
args.push(ArgumentTemplate::Text(arg.to_owned()));
continue;
}
if start < arg.len() {
// Trailing text after last placeholder.
tokens.push(Token::Text(arg[start..].to_owned()));
}
args.push(ArgumentTemplate::Tokens(tokens));
let tmpl = FormatTemplate::parse(arg);
has_placeholder |= tmpl.has_tokens();
args.push(tmpl);
}
// We need to check that we have at least one argument, because if not
@@ -286,7 +247,7 @@ impl CommandTemplate {
// If a placeholder token was not supplied, append one at the end of the command.
if !has_placeholder {
args.push(ArgumentTemplate::Tokens(vec![Token::Placeholder]));
args.push(FormatTemplate::Tokens(vec![Token::Placeholder]));
}
Ok(CommandTemplate { args })
@@ -301,123 +262,26 @@ impl CommandTemplate {
/// Using the internal `args` field, and a supplied `input` variable, a `Command` will be
/// build.
fn generate(&self, input: &Path, path_separator: Option<&str>) -> io::Result<Command> {
let mut cmd = Command::new(self.args[0].generate(&input, path_separator));
let mut cmd = Command::new(self.args[0].generate(input, path_separator));
for arg in &self.args[1..] {
cmd.try_arg(arg.generate(&input, path_separator))?;
cmd.try_arg(arg.generate(input, path_separator))?;
}
Ok(cmd)
}
}
/// Represents a template for a single command argument.
///
/// The argument is either a collection of `Token`s including at least one placeholder variant, or
/// a fixed text.
#[derive(Clone, Debug, PartialEq)]
enum ArgumentTemplate {
Tokens(Vec<Token>),
Text(String),
}
impl ArgumentTemplate {
pub fn has_tokens(&self) -> bool {
matches!(self, ArgumentTemplate::Tokens(_))
}
/// Generate an argument from this template. If path_separator is Some, then it will replace
/// the path separator in all placeholder tokens. Text arguments and tokens are not affected by
/// path separator substitution.
pub fn generate(&self, path: impl AsRef<Path>, path_separator: Option<&str>) -> OsString {
use self::Token::*;
let path = path.as_ref();
match *self {
ArgumentTemplate::Tokens(ref tokens) => {
let mut s = OsString::new();
for token in tokens {
match *token {
Basename => s.push(Self::replace_separator(basename(path), path_separator)),
BasenameNoExt => s.push(Self::replace_separator(
&remove_extension(basename(path).as_ref()),
path_separator,
)),
NoExt => s.push(Self::replace_separator(
&remove_extension(path),
path_separator,
)),
Parent => s.push(Self::replace_separator(&dirname(path), path_separator)),
Placeholder => {
s.push(Self::replace_separator(path.as_ref(), path_separator))
}
Text(ref string) => s.push(string),
}
}
s
}
ArgumentTemplate::Text(ref text) => OsString::from(text),
}
}
/// Replace the path separator in the input with the custom separator string. If path_separator
/// is None, simply return a borrowed Cow<OsStr> of the input. Otherwise, the input is
/// interpreted as a Path and its components are iterated through and re-joined into a new
/// OsString.
fn replace_separator<'a>(path: &'a OsStr, path_separator: Option<&str>) -> Cow<'a, OsStr> {
// fast-path - no replacement necessary
if path_separator.is_none() {
return Cow::Borrowed(path);
}
let path_separator = path_separator.unwrap();
let mut out = OsString::with_capacity(path.len());
let mut components = Path::new(path).components().peekable();
while let Some(comp) = components.next() {
match comp {
// Absolute paths on Windows are tricky. A Prefix component is usually a drive
// letter or UNC path, and is usually followed by RootDir. There are also
// "verbatim" prefixes beginning with "\\?\" that skip normalization. We choose to
// ignore verbatim path prefixes here because they're very rare, might be
// impossible to reach here, and there's no good way to deal with them. If users
// are doing something advanced involving verbatim windows paths, they can do their
// own output filtering with a tool like sed.
Component::Prefix(prefix) => {
if let Prefix::UNC(server, share) = prefix.kind() {
// Prefix::UNC is a parsed version of '\\server\share'
out.push(path_separator);
out.push(path_separator);
out.push(server);
out.push(path_separator);
out.push(share);
} else {
// All other Windows prefix types are rendered as-is. This results in e.g. "C:" for
// drive letters. DeviceNS and Verbatim* prefixes won't have backslashes converted,
// but they're not returned by directories fd can search anyway so we don't worry
// about them.
out.push(comp.as_os_str());
}
}
// Root directory is always replaced with the custom separator.
Component::RootDir => out.push(path_separator),
// Everything else is joined normally, with a trailing separator if we're not last
_ => {
out.push(comp.as_os_str());
if components.peek().is_some() {
out.push(path_separator);
}
}
}
}
Cow::Owned(out)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn generate_str(template: &CommandTemplate, input: &str) -> Vec<String> {
template
.args
.iter()
.map(|arg| arg.generate(input, None).into_string().unwrap())
.collect()
}
#[test]
fn tokens_with_placeholder() {
assert_eq!(
@@ -425,9 +289,9 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Text("${SHELL}:".into()),
ArgumentTemplate::Tokens(vec![Token::Placeholder]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Text("${SHELL}:".into()),
FormatTemplate::Tokens(vec![Token::Placeholder]),
]
}],
mode: ExecutionMode::OneByOne,
@@ -442,8 +306,8 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Tokens(vec![Token::NoExt]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Tokens(vec![Token::NoExt]),
],
}],
mode: ExecutionMode::OneByOne,
@@ -458,8 +322,8 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Tokens(vec![Token::Basename]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Tokens(vec![Token::Basename]),
],
}],
mode: ExecutionMode::OneByOne,
@@ -474,8 +338,8 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Tokens(vec![Token::Parent]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Tokens(vec![Token::Parent]),
],
}],
mode: ExecutionMode::OneByOne,
@@ -490,8 +354,8 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Tokens(vec![Token::BasenameNoExt]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Tokens(vec![Token::BasenameNoExt]),
],
}],
mode: ExecutionMode::OneByOne,
@@ -499,6 +363,21 @@ mod tests {
);
}
#[test]
fn tokens_with_literal_braces() {
let template = CommandTemplate::new(vec!["{{}}", "{{", "{.}}"]).unwrap();
assert_eq!(
generate_str(&template, "foo"),
vec!["{}", "{", "{.}", "foo"]
);
}
#[test]
fn tokens_with_literal_braces_and_placeholder() {
let template = CommandTemplate::new(vec!["{{{},end}"]).unwrap();
assert_eq!(generate_str(&template, "foo"), vec!["{foo,end}"]);
}
#[test]
fn tokens_multiple() {
assert_eq!(
@@ -506,9 +385,9 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("cp".into()),
ArgumentTemplate::Tokens(vec![Token::Placeholder]),
ArgumentTemplate::Tokens(vec![
FormatTemplate::Text("cp".into()),
FormatTemplate::Tokens(vec![Token::Placeholder]),
FormatTemplate::Tokens(vec![
Token::BasenameNoExt,
Token::Text(".ext".into())
]),
@@ -526,8 +405,8 @@ mod tests {
CommandSet {
commands: vec![CommandTemplate {
args: vec![
ArgumentTemplate::Text("echo".into()),
ArgumentTemplate::Tokens(vec![Token::NoExt]),
FormatTemplate::Text("echo".into()),
FormatTemplate::Tokens(vec![Token::NoExt]),
],
}],
mode: ExecutionMode::Batch,
@@ -552,7 +431,7 @@ mod tests {
#[test]
fn generate_custom_path_separator() {
let arg = ArgumentTemplate::Tokens(vec![Token::Placeholder]);
let arg = FormatTemplate::Tokens(vec![Token::Placeholder]);
macro_rules! check {
($input:expr, $expected:expr) => {
assert_eq!(arg.generate($input, Some("#")), OsString::from($expected));
@@ -567,7 +446,7 @@ mod tests {
#[cfg(windows)]
#[test]
fn generate_custom_path_separator_windows() {
let arg = ArgumentTemplate::Tokens(vec![Token::Placeholder]);
let arg = FormatTemplate::Tokens(vec![Token::Placeholder]);
macro_rules! check {
($input:expr, $expected:expr) => {
assert_eq!(arg.generate($input, Some("#")), OsString::from($expected));
-29
View File
@@ -1,29 +0,0 @@
use std::fmt::{self, Display, Formatter};
/// Designates what should be written to a buffer
///
/// Each `Token` contains either text, or a placeholder variant, which will be used to generate
/// commands after all tokens for a given command template have been collected.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Token {
Placeholder,
Basename,
Parent,
NoExt,
BasenameNoExt,
Text(String),
}
impl Display for Token {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
Token::Placeholder => f.write_str("{}")?,
Token::Basename => f.write_str("{/}")?,
Token::Parent => f.write_str("{//}")?,
Token::NoExt => f.write_str("{.}")?,
Token::BasenameNoExt => f.write_str("{/.}")?,
Token::Text(ref string) => f.write_str(string)?,
}
Ok(())
}
}
+24 -19
View File
@@ -4,12 +4,9 @@ use std::ffi::OsStr;
use std::fs;
use std::io;
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::{FileTypeExt, PermissionsExt};
use std::os::unix::fs::FileTypeExt;
use std::path::{Path, PathBuf};
#[cfg(windows)]
use faccess::PathExt as _;
use normpath::PathExt;
use crate::dir_entry;
@@ -44,16 +41,6 @@ pub fn is_existing_directory(path: &Path) -> bool {
path.is_dir() && (path.file_name().is_some() || path.normalize().is_ok())
}
#[cfg(any(unix, target_os = "redox"))]
pub fn is_executable(_: &Path, md: &fs::Metadata) -> bool {
md.permissions().mode() & 0o111 != 0
}
#[cfg(windows)]
pub fn is_executable(path: &Path, _: &fs::Metadata) -> bool {
path.executable()
}
pub fn is_empty(entry: &dir_entry::DirEntry) -> bool {
if let Some(file_type) = entry.file_type() {
if file_type.is_dir() {
@@ -72,6 +59,26 @@ pub fn is_empty(entry: &dir_entry::DirEntry) -> bool {
}
}
#[cfg(any(unix, target_os = "redox"))]
pub fn is_block_device(ft: fs::FileType) -> bool {
ft.is_block_device()
}
#[cfg(windows)]
pub fn is_block_device(_: fs::FileType) -> bool {
false
}
#[cfg(any(unix, target_os = "redox"))]
pub fn is_char_device(ft: fs::FileType) -> bool {
ft.is_char_device()
}
#[cfg(windows)]
pub fn is_char_device(_: fs::FileType) -> bool {
false
}
#[cfg(any(unix, target_os = "redox"))]
pub fn is_socket(ft: fs::FileType) -> bool {
ft.is_socket()
@@ -121,13 +128,11 @@ pub fn strip_current_dir(path: &Path) -> &Path {
pub fn default_path_separator() -> Option<String> {
if cfg!(windows) {
let msystem = env::var("MSYSTEM").ok()?;
match msystem.as_str() {
"MINGW64" | "MINGW32" | "MSYS" => Some("/".to_owned()),
_ => None,
if !msystem.is_empty() {
return Some("/".to_owned());
}
} else {
None
}
None
}
#[cfg(test)]
+9 -5
View File
@@ -1,12 +1,16 @@
use crate::dir_entry;
use crate::filesystem;
use faccess::PathExt;
/// Whether or not to show
#[derive(Default)]
pub struct FileTypes {
pub files: bool,
pub directories: bool,
pub symlinks: bool,
pub block_devices: bool,
pub char_devices: bool,
pub sockets: bool,
pub pipes: bool,
pub executables_only: bool,
@@ -19,17 +23,17 @@ impl FileTypes {
(!self.files && entry_type.is_file())
|| (!self.directories && entry_type.is_dir())
|| (!self.symlinks && entry_type.is_symlink())
|| (!self.block_devices && filesystem::is_block_device(*entry_type))
|| (!self.char_devices && filesystem::is_char_device(*entry_type))
|| (!self.sockets && filesystem::is_socket(*entry_type))
|| (!self.pipes && filesystem::is_pipe(*entry_type))
|| (self.executables_only
&& !entry
.metadata()
.map(|md| filesystem::is_executable(entry.path(), md))
.unwrap_or(false))
|| (self.executables_only && !entry.path().executable())
|| (self.empty_only && !filesystem::is_empty(entry))
|| !(entry_type.is_file()
|| entry_type.is_dir()
|| entry_type.is_symlink()
|| filesystem::is_block_device(*entry_type)
|| filesystem::is_char_device(*entry_type)
|| filesystem::is_socket(*entry_type)
|| filesystem::is_pipe(*entry_type))
} else {
+40 -23
View File
@@ -1,13 +1,14 @@
use anyhow::{anyhow, Result};
use nix::unistd::{Group, User};
use std::fs;
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct OwnerFilter {
uid: Check<u32>,
gid: Check<u32>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Check<T> {
Equal(T),
NotEq(T),
@@ -15,10 +16,15 @@ enum Check<T> {
}
impl OwnerFilter {
const IGNORE: Self = OwnerFilter {
uid: Check::Ignore,
gid: Check::Ignore,
};
/// Parses an owner constraint
/// Returns an error if the string is invalid
/// Returns Ok(None) when string is acceptable but a noop (such as "" or ":")
pub fn from_string(input: &str) -> Result<Option<Self>> {
pub fn from_string(input: &str) -> Result<Self> {
let mut it = input.split(':');
let (fst, snd) = (it.next(), it.next());
@@ -30,22 +36,33 @@ impl OwnerFilter {
}
let uid = Check::parse(fst, |s| {
s.parse()
.ok()
.or_else(|| users::get_user_by_name(s).map(|user| user.uid()))
.ok_or_else(|| anyhow!("'{}' is not a recognized user name", s))
if let Ok(uid) = s.parse() {
Ok(uid)
} else {
User::from_name(s)?
.map(|user| user.uid.as_raw())
.ok_or_else(|| anyhow!("'{}' is not a recognized user name", s))
}
})?;
let gid = Check::parse(snd, |s| {
s.parse()
.ok()
.or_else(|| users::get_group_by_name(s).map(|group| group.gid()))
.ok_or_else(|| anyhow!("'{}' is not a recognized group name", s))
if let Ok(gid) = s.parse() {
Ok(gid)
} else {
Group::from_name(s)?
.map(|group| group.gid.as_raw())
.ok_or_else(|| anyhow!("'{}' is not a recognized group name", s))
}
})?;
if let (Check::Ignore, Check::Ignore) = (uid, gid) {
Ok(None)
Ok(OwnerFilter { uid, gid })
}
/// If self is a no-op (ignore both uid and gid) then return `None`, otherwise wrap in a `Some`
pub fn filter_ignore(self) -> Option<Self> {
if self == Self::IGNORE {
None
} else {
Ok(Some(OwnerFilter { uid, gid }))
Some(self)
}
}
@@ -106,16 +123,16 @@ mod owner_parsing {
use super::Check::*;
owner_tests! {
empty: "" => Ok(None),
uid_only: "5" => Ok(Some(OwnerFilter { uid: Equal(5), gid: Ignore })),
uid_gid: "9:3" => Ok(Some(OwnerFilter { uid: Equal(9), gid: Equal(3) })),
gid_only: ":8" => Ok(Some(OwnerFilter { uid: Ignore, gid: Equal(8) })),
colon_only: ":" => Ok(None),
trailing: "5:" => Ok(Some(OwnerFilter { uid: Equal(5), gid: Ignore })),
empty: "" => Ok(OwnerFilter::IGNORE),
uid_only: "5" => Ok(OwnerFilter { uid: Equal(5), gid: Ignore }),
uid_gid: "9:3" => Ok(OwnerFilter { uid: Equal(9), gid: Equal(3) }),
gid_only: ":8" => Ok(OwnerFilter { uid: Ignore, gid: Equal(8) }),
colon_only: ":" => Ok(OwnerFilter::IGNORE),
trailing: "5:" => Ok(OwnerFilter { uid: Equal(5), gid: Ignore }),
uid_negate: "!5" => Ok(Some(OwnerFilter { uid: NotEq(5), gid: Ignore })),
both_negate:"!4:!3" => Ok(Some(OwnerFilter { uid: NotEq(4), gid: NotEq(3) })),
uid_not_gid:"6:!8" => Ok(Some(OwnerFilter { uid: Equal(6), gid: NotEq(8) })),
uid_negate: "!5" => Ok(OwnerFilter { uid: NotEq(5), gid: Ignore }),
both_negate:"!4:!3" => Ok(OwnerFilter { uid: NotEq(4), gid: NotEq(3) }),
uid_not_gid:"6:!8" => Ok(OwnerFilter { uid: Equal(6), gid: NotEq(8) }),
more_colons:"3:5:" => Err(_),
only_colons:"::" => Err(_),
+7 -5
View File
@@ -1,9 +1,9 @@
use std::sync::OnceLock;
use anyhow::anyhow;
use once_cell::sync::Lazy;
use regex::Regex;
static SIZE_CAPTURES: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?i)^([+-]?)(\d+)(b|[kmgt]i?b?)$").unwrap());
static SIZE_CAPTURES: OnceLock<Regex> = OnceLock::new();
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SizeFilter {
@@ -31,11 +31,13 @@ impl SizeFilter {
}
fn parse_opt(s: &str) -> Option<Self> {
if !SIZE_CAPTURES.is_match(s) {
let pattern =
SIZE_CAPTURES.get_or_init(|| Regex::new(r"(?i)^([+-]?)(\d+)(b|[kmgt]i?b?)$").unwrap());
if !pattern.is_match(s) {
return None;
}
let captures = SIZE_CAPTURES.captures(s)?;
let captures = pattern.captures(s)?;
let limit_kind = captures.get(1).map_or("+", |m| m.as_str());
let quantity = captures
.get(2)
+121 -70
View File
@@ -1,6 +1,6 @@
use chrono::{offset::TimeZone, DateTime, Local, NaiveDate};
use jiff::{civil::DateTime, tz::TimeZone, Span, Timestamp, Zoned};
use std::time::SystemTime;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
/// Filter based on time ranges.
#[derive(Debug, PartialEq, Eq)]
@@ -9,32 +9,49 @@ pub enum TimeFilter {
After(SystemTime),
}
#[cfg(not(test))]
fn now() -> Zoned {
Zoned::now()
}
#[cfg(test)]
thread_local! {
static TESTTIME: std::cell::RefCell<Option<Zoned>> = None.into();
}
/// This allows us to set a specific time when running tests
#[cfg(test)]
fn now() -> Zoned {
TESTTIME.with_borrow(|reftime| reftime.as_ref().cloned().unwrap_or_else(Zoned::now))
}
impl TimeFilter {
fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> {
humantime::parse_duration(s)
.map(|duration| *ref_time - duration)
.ok()
.or_else(|| {
DateTime::parse_from_rfc3339(s)
.map(|dt| dt.into())
.ok()
.or_else(|| {
NaiveDate::parse_from_str(s, "%F")
.map(|nd| nd.and_hms(0, 0, 0))
.ok()
.and_then(|ndt| Local.from_local_datetime(&ndt).single())
})
.or_else(|| Local.datetime_from_str(s, "%F %T").ok())
.map(|dt| dt.into())
})
fn from_str(s: &str) -> Option<SystemTime> {
if let Ok(span) = s.parse::<Span>() {
let datetime = now().checked_sub(span).ok()?;
Some(datetime.into())
} else if let Ok(timestamp) = s.parse::<Timestamp>() {
Some(timestamp.into())
} else if let Ok(datetime) = s.parse::<DateTime>() {
Some(
TimeZone::system()
.to_ambiguous_zoned(datetime)
.later()
.ok()?
.into(),
)
} else {
let timestamp_secs: u64 = s.strip_prefix('@')?.parse().ok()?;
Some(UNIX_EPOCH + Duration::from_secs(timestamp_secs))
}
}
pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(ref_time, s).map(TimeFilter::Before)
pub fn before(s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(s).map(TimeFilter::Before)
}
pub fn after(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(ref_time, s).map(TimeFilter::After)
pub fn after(s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(s).map(TimeFilter::After)
}
pub fn applies_to(&self, t: &SystemTime) -> bool {
@@ -50,82 +67,116 @@ mod tests {
use super::*;
use std::time::Duration;
struct TestTime(SystemTime);
impl TestTime {
fn new(time: Zoned) -> Self {
TESTTIME.with_borrow_mut(|t| *t = Some(time.clone()));
TestTime(time.into())
}
fn set(&mut self, time: Zoned) {
TESTTIME.with_borrow_mut(|t| *t = Some(time.clone()));
self.0 = time.into();
}
fn timestamp(&self) -> SystemTime {
self.0
}
}
impl Drop for TestTime {
fn drop(&mut self) {
// Stop using manually set times
TESTTIME.with_borrow_mut(|t| *t = None);
}
}
#[test]
fn is_time_filter_applicable() {
let ref_time = Local
.datetime_from_str("2010-10-10 10:10:10", "%F %T")
.unwrap()
.into();
let local_tz = TimeZone::system();
let mut test_time = TestTime::new(
local_tz
.to_ambiguous_zoned("2010-10-10 10:10:10".parse::<DateTime>().unwrap())
.later()
.unwrap(),
);
let mut ref_time = test_time.timestamp();
assert!(TimeFilter::after(&ref_time, "1min")
.unwrap()
.applies_to(&ref_time));
assert!(!TimeFilter::before(&ref_time, "1min")
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::after("1min").unwrap().applies_to(&ref_time));
assert!(!TimeFilter::before("1min").unwrap().applies_to(&ref_time));
let t1m_ago = ref_time - Duration::from_secs(60);
assert!(!TimeFilter::after(&ref_time, "30sec")
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, "2min")
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::after("30sec").unwrap().applies_to(&t1m_ago));
assert!(TimeFilter::after("2min").unwrap().applies_to(&t1m_ago));
assert!(TimeFilter::before(&ref_time, "30sec")
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::before(&ref_time, "2min")
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::before("30sec").unwrap().applies_to(&t1m_ago));
assert!(!TimeFilter::before("2min").unwrap().applies_to(&t1m_ago));
let t10s_before = "2010-10-10 10:10:00";
assert!(!TimeFilter::before(&ref_time, t10s_before)
assert!(!TimeFilter::before(t10s_before)
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::before(&ref_time, t10s_before)
assert!(TimeFilter::before(t10s_before)
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, t10s_before)
assert!(TimeFilter::after(t10s_before)
.unwrap()
.applies_to(&ref_time));
assert!(!TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::after(t10s_before).unwrap().applies_to(&t1m_ago));
let same_day = "2010-10-10";
assert!(!TimeFilter::before(&ref_time, same_day)
.unwrap()
.applies_to(&ref_time));
assert!(!TimeFilter::before(&ref_time, same_day)
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::before(same_day).unwrap().applies_to(&ref_time));
assert!(!TimeFilter::before(same_day).unwrap().applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, same_day)
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::after(&ref_time, same_day)
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(same_day).unwrap().applies_to(&ref_time));
assert!(TimeFilter::after(same_day).unwrap().applies_to(&t1m_ago));
let ref_time = DateTime::parse_from_rfc3339("2010-10-10T10:10:10+00:00")
.unwrap()
.into();
test_time.set(
"2010-10-10T10:10:10+00:00"
.parse::<Timestamp>()
.unwrap()
.to_zoned(local_tz.clone()),
);
ref_time = test_time.timestamp();
let t1m_ago = ref_time - Duration::from_secs(60);
let t10s_before = "2010-10-10T10:10:00+00:00";
assert!(!TimeFilter::before(&ref_time, t10s_before)
assert!(!TimeFilter::before(t10s_before)
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::before(&ref_time, t10s_before)
assert!(TimeFilter::before(t10s_before)
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, t10s_before)
assert!(TimeFilter::after(t10s_before)
.unwrap()
.applies_to(&ref_time));
assert!(!TimeFilter::after(&ref_time, t10s_before)
assert!(!TimeFilter::after(t10s_before).unwrap().applies_to(&t1m_ago));
let ref_timestamp = 1707723412u64; // Mon Feb 12 07:36:52 UTC 2024
test_time.set(
"2024-02-12T07:36:52+00:00"
.parse::<Timestamp>()
.unwrap()
.to_zoned(local_tz),
);
ref_time = test_time.timestamp();
let t1m_ago = ref_time - Duration::from_secs(60);
let t1s_later = ref_time + Duration::from_secs(1);
// Timestamp only supported via '@' prefix
assert!(TimeFilter::before(&ref_timestamp.to_string()).is_none());
assert!(TimeFilter::before(&format!("@{ref_timestamp}"))
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::before(&format!("@{ref_timestamp}"))
.unwrap()
.applies_to(&t1s_later));
assert!(!TimeFilter::after(&format!("@{ref_timestamp}"))
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&format!("@{ref_timestamp}"))
.unwrap()
.applies_to(&t1s_later));
}
}
+2 -2
View File
@@ -34,10 +34,10 @@ pub fn dirname(path: &Path) -> OsString {
#[cfg(test)]
mod path_tests {
use super::*;
use std::path::MAIN_SEPARATOR;
use std::path::MAIN_SEPARATOR_STR;
fn correct(input: &str) -> String {
input.replace('/', &MAIN_SEPARATOR.to_string())
input.replace('/', MAIN_SEPARATOR_STR)
}
macro_rules! func_tests {
+281
View File
@@ -0,0 +1,281 @@
mod input;
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
use std::fmt::{self, Display, Formatter};
use std::path::{Component, Path, Prefix};
use std::sync::OnceLock;
use aho_corasick::AhoCorasick;
use self::input::{basename, dirname, remove_extension};
/// Designates what should be written to a buffer
///
/// Each `Token` contains either text, or a placeholder variant, which will be used to generate
/// commands after all tokens for a given command template have been collected.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Token {
Placeholder,
Basename,
Parent,
NoExt,
BasenameNoExt,
Text(String),
}
impl Display for Token {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
Token::Placeholder => f.write_str("{}")?,
Token::Basename => f.write_str("{/}")?,
Token::Parent => f.write_str("{//}")?,
Token::NoExt => f.write_str("{.}")?,
Token::BasenameNoExt => f.write_str("{/.}")?,
Token::Text(ref string) => f.write_str(string)?,
}
Ok(())
}
}
/// A parsed format string
///
/// This is either a collection of `Token`s including at least one placeholder variant,
/// or a fixed text.
#[derive(Clone, Debug, PartialEq)]
pub enum FormatTemplate {
Tokens(Vec<Token>),
Text(String),
}
static PLACEHOLDERS: OnceLock<AhoCorasick> = OnceLock::new();
impl FormatTemplate {
pub fn has_tokens(&self) -> bool {
matches!(self, FormatTemplate::Tokens(_))
}
pub fn parse(fmt: &str) -> Self {
// NOTE: we assume that { and } have the same length
const BRACE_LEN: usize = '{'.len_utf8();
let mut tokens = Vec::new();
let mut remaining = fmt;
let mut buf = String::new();
let placeholders = PLACEHOLDERS.get_or_init(|| {
AhoCorasick::new(["{{", "}}", "{}", "{/}", "{//}", "{.}", "{/.}"]).unwrap()
});
while let Some(m) = placeholders.find(remaining) {
match m.pattern().as_u32() {
0 | 1 => {
// we found an escaped {{ or }}, so add
// everything up to the first char to the buffer
// then skip the second one.
buf += &remaining[..m.start() + BRACE_LEN];
remaining = &remaining[m.end()..];
}
id if !remaining[m.end()..].starts_with('}') => {
buf += &remaining[..m.start()];
if !buf.is_empty() {
tokens.push(Token::Text(std::mem::take(&mut buf)));
}
tokens.push(token_from_pattern_id(id));
remaining = &remaining[m.end()..];
}
_ => {
// We got a normal pattern, but the final "}"
// is escaped, so add up to that to the buffer, then
// skip the final }
buf += &remaining[..m.end()];
remaining = &remaining[m.end() + BRACE_LEN..];
}
}
}
// Add the rest of the string to the buffer, and add the final buffer to the tokens
if !remaining.is_empty() {
buf += remaining;
}
if tokens.is_empty() {
// No placeholders were found, so just return the text
return FormatTemplate::Text(buf);
}
// Add final text segment
if !buf.is_empty() {
tokens.push(Token::Text(buf));
}
debug_assert!(!tokens.is_empty());
FormatTemplate::Tokens(tokens)
}
/// Generate a result string from this template. If path_separator is Some, then it will replace
/// the path separator in all placeholder tokens. Fixed text and tokens are not affected by
/// path separator substitution.
pub fn generate(&self, path: impl AsRef<Path>, path_separator: Option<&str>) -> OsString {
use Token::*;
let path = path.as_ref();
match *self {
Self::Tokens(ref tokens) => {
let mut s = OsString::new();
for token in tokens {
match token {
Basename => s.push(Self::replace_separator(basename(path), path_separator)),
BasenameNoExt => s.push(Self::replace_separator(
&remove_extension(basename(path).as_ref()),
path_separator,
)),
NoExt => s.push(Self::replace_separator(
&remove_extension(path),
path_separator,
)),
Parent => s.push(Self::replace_separator(&dirname(path), path_separator)),
Placeholder => {
s.push(Self::replace_separator(path.as_ref(), path_separator))
}
Text(ref string) => s.push(string),
}
}
s
}
Self::Text(ref text) => OsString::from(text),
}
}
/// Replace the path separator in the input with the custom separator string. If path_separator
/// is None, simply return a borrowed Cow<OsStr> of the input. Otherwise, the input is
/// interpreted as a Path and its components are iterated through and re-joined into a new
/// OsString.
fn replace_separator<'a>(path: &'a OsStr, path_separator: Option<&str>) -> Cow<'a, OsStr> {
// fast-path - no replacement necessary
if path_separator.is_none() {
return Cow::Borrowed(path);
}
let path_separator = path_separator.unwrap();
let mut out = OsString::with_capacity(path.len());
let mut components = Path::new(path).components().peekable();
while let Some(comp) = components.next() {
match comp {
// Absolute paths on Windows are tricky. A Prefix component is usually a drive
// letter or UNC path, and is usually followed by RootDir. There are also
// "verbatim" prefixes beginning with "\\?\" that skip normalization. We choose to
// ignore verbatim path prefixes here because they're very rare, might be
// impossible to reach here, and there's no good way to deal with them. If users
// are doing something advanced involving verbatim windows paths, they can do their
// own output filtering with a tool like sed.
Component::Prefix(prefix) => {
if let Prefix::UNC(server, share) = prefix.kind() {
// Prefix::UNC is a parsed version of '\\server\share'
out.push(path_separator);
out.push(path_separator);
out.push(server);
out.push(path_separator);
out.push(share);
} else {
// All other Windows prefix types are rendered as-is. This results in e.g. "C:" for
// drive letters. DeviceNS and Verbatim* prefixes won't have backslashes converted,
// but they're not returned by directories fd can search anyway so we don't worry
// about them.
out.push(comp.as_os_str());
}
}
// Root directory is always replaced with the custom separator.
Component::RootDir => out.push(path_separator),
// Everything else is joined normally, with a trailing separator if we're not last
_ => {
out.push(comp.as_os_str());
if components.peek().is_some() {
out.push(path_separator);
}
}
}
}
Cow::Owned(out)
}
}
// Convert the id from an aho-corasick match to the
// appropriate token
fn token_from_pattern_id(id: u32) -> Token {
use Token::*;
match id {
2 => Placeholder,
3 => Basename,
4 => Parent,
5 => NoExt,
6 => BasenameNoExt,
_ => unreachable!(),
}
}
#[cfg(test)]
mod fmt_tests {
use super::*;
use std::path::PathBuf;
#[test]
fn parse_no_placeholders() {
let templ = FormatTemplate::parse("This string has no placeholders");
assert_eq!(
templ,
FormatTemplate::Text("This string has no placeholders".into())
);
}
#[test]
fn parse_only_brace_escapes() {
let templ = FormatTemplate::parse("This string only has escapes like {{ and }}");
assert_eq!(
templ,
FormatTemplate::Text("This string only has escapes like { and }".into())
);
}
#[test]
fn all_placeholders() {
use Token::*;
let templ = FormatTemplate::parse(
"{{path={} \
basename={/} \
parent={//} \
noExt={.} \
basenameNoExt={/.} \
}}",
);
assert_eq!(
templ,
FormatTemplate::Tokens(vec![
Text("{path=".into()),
Placeholder,
Text(" basename=".into()),
Basename,
Text(" parent=".into()),
Parent,
Text(" noExt=".into()),
NoExt,
Text(" basenameNoExt=".into()),
BasenameNoExt,
Text(" }".into()),
])
);
let mut path = PathBuf::new();
path.push("a");
path.push("folder");
path.push("file.txt");
let expanded = templ.generate(&path, Some("/")).into_string().unwrap();
assert_eq!(
expanded,
"{path=a/folder/file.txt \
basename=file.txt \
parent=a/folder \
noExt=a/folder/file \
basenameNoExt=file }"
);
}
}
+87
View File
@@ -0,0 +1,87 @@
use crate::filesystem::absolute_path;
use std::fmt::{self, Formatter, Write};
use std::path::{Path, PathBuf};
pub(crate) struct PathUrl(PathBuf);
impl PathUrl {
pub(crate) fn new(path: &Path) -> Option<PathUrl> {
Some(PathUrl(absolute_path(path).ok()?))
}
}
impl fmt::Display for PathUrl {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "file://{}", host())?;
let bytes = self.0.as_os_str().as_encoded_bytes();
for &byte in bytes.iter() {
encode(f, byte)?;
}
Ok(())
}
}
fn encode(f: &mut Formatter, byte: u8) -> fmt::Result {
// NOTE:
// Most terminals can handle non-ascii unicode characters in a file url fine. But on some OSes (notably
// windows), the encoded bytes of the path may not be valid UTF-8. Since we don't know if a
// byte >= 128 is part of a valid UTF-8 encoding or not, we just percent encode any non-ascii
// byte.
// Percent encoding these bytes is probably safer anyway.
match byte {
b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z' | b'/' | b':' | b'-' | b'.' | b'_' | b'~' => {
f.write_char(byte.into())
}
#[cfg(windows)]
b'\\' => f.write_char('/'),
_ => {
write!(f, "%{byte:02X}")
}
}
}
#[cfg(unix)]
fn host() -> &'static str {
use std::sync::OnceLock;
static HOSTNAME: OnceLock<String> = OnceLock::new();
HOSTNAME
.get_or_init(|| {
nix::unistd::gethostname()
.ok()
.and_then(|h| h.into_string().ok())
.unwrap_or_default()
})
.as_ref()
}
#[cfg(not(unix))]
const fn host() -> &'static str {
""
}
#[cfg(test)]
mod test {
use super::*;
// This allows us to test the encoding without having to worry about the host, or absolute path
struct Encoded(&'static str);
impl fmt::Display for Encoded {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
for byte in self.0.bytes() {
encode(f, byte)?;
}
Ok(())
}
}
#[test]
fn test_unicode_encoding() {
assert_eq!(
Encoded("$*\x1bßé/∫😃\x07").to_string(),
"%24%2A%1B%C3%9F%C3%A9/%E2%88%AB%F0%9F%98%83%07",
);
}
}
+85 -36
View File
@@ -7,23 +7,24 @@ mod exit_codes;
mod filesystem;
mod filetypes;
mod filter;
mod fmt;
mod hyperlink;
mod output;
mod regex_helper;
mod walk;
use std::env;
use std::io::IsTerminal;
use std::path::Path;
use std::sync::Arc;
use std::time;
use anyhow::{anyhow, bail, Context, Result};
use atty::Stream;
use clap::{CommandFactory, Parser};
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};
use regex::bytes::{Regex, RegexBuilder, RegexSetBuilder};
use crate::cli::{ColorWhen, Opts};
use crate::cli::{ColorWhen, HyperlinkWhen, Opts};
use crate::config::Config;
use crate::exec::CommandSet;
use crate::exit_codes::ExitCode;
@@ -40,6 +41,7 @@ use crate::regex_helper::{pattern_has_uppercase_char, pattern_matches_strings_wi
not(target_os = "android"),
not(target_os = "macos"),
not(target_os = "freebsd"),
not(target_os = "openbsd"),
not(all(target_env = "musl", target_pointer_width = "32")),
not(target_arch = "riscv64"),
feature = "use-jemalloc"
@@ -60,7 +62,7 @@ fn main() {
exit_code.exit();
}
Err(err) => {
eprintln!("[fd error]: {:#}", err);
eprintln!("[fd error]: {err:#}");
ExitCode::GeneralError.exit();
}
}
@@ -81,22 +83,44 @@ fn run() -> Result<ExitCode> {
}
ensure_search_pattern_is_not_a_path(&opts)?;
let pattern_regex = build_pattern_regex(&opts)?;
let pattern = &opts.pattern;
let exprs = &opts.exprs;
let empty = Vec::new();
let config = construct_config(opts, &pattern_regex)?;
ensure_use_hidden_option_for_leading_dot_pattern(&config, &pattern_regex)?;
let re = build_regex(pattern_regex, &config)?;
walk::scan(&search_paths, Arc::new(re), Arc::new(config))
let pattern_regexps = exprs
.as_ref()
.unwrap_or(&empty)
.iter()
.chain([pattern])
.map(|pat| build_pattern_regex(pat, &opts))
.collect::<Result<Vec<String>>>()?;
let config = construct_config(opts, &pattern_regexps)?;
ensure_use_hidden_option_for_leading_dot_pattern(&config, &pattern_regexps)?;
let regexps = pattern_regexps
.into_iter()
.map(|pat| build_regex(pat, &config))
.collect::<Result<Vec<Regex>>>()?;
walk::scan(&search_paths, regexps, config)
}
#[cfg(feature = "completions")]
#[cold]
fn print_completions(shell: clap_complete::Shell) -> Result<ExitCode> {
// The program name is the first argument.
let program_name = env::args().next().unwrap_or_else(|| "fd".to_string());
let first_arg = env::args().next();
let program_name = first_arg
.as_ref()
.map(Path::new)
.and_then(|path| path.file_stem())
.and_then(|file| file.to_str())
.unwrap_or("fd");
let mut cmd = Opts::command();
cmd.build();
clap_complete::generate(shell, &mut cmd, &program_name, &mut std::io::stdout());
clap_complete::generate(shell, &mut cmd, program_name, &mut std::io::stdout());
Ok(ExitCode::Success)
}
@@ -139,8 +163,7 @@ fn ensure_search_pattern_is_not_a_path(opts: &Opts) -> Result<()> {
}
}
fn build_pattern_regex(opts: &Opts) -> Result<String> {
let pattern = &opts.pattern;
fn build_pattern_regex(pattern: &str, opts: &Opts) -> Result<String> {
Ok(if opts.glob && !pattern.is_empty() {
let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
glob.regex().to_owned()
@@ -166,11 +189,14 @@ fn check_path_separator_length(path_separator: Option<&str>) -> Result<()> {
}
}
fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
fn construct_config(mut opts: Opts, pattern_regexps: &[String]) -> Result<Config> {
// The search will be case-sensitive if the command line flag is set or
// if the pattern has an uppercase character (smart case).
let case_sensitive =
!opts.ignore_case && (opts.case_sensitive || pattern_has_uppercase_char(pattern_regex));
// if any of the patterns has an uppercase character (smart case).
let case_sensitive = !opts.ignore_case
&& (opts.case_sensitive
|| pattern_regexps
.iter()
.any(|pat| pattern_has_uppercase_char(pat)));
let path_separator = opts
.path_separator
@@ -184,20 +210,22 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
let size_limits = std::mem::take(&mut opts.size);
let time_constraints = extract_time_constraints(&opts)?;
#[cfg(unix)]
let owner_constraint: Option<OwnerFilter> = opts.owner;
let owner_constraint: Option<OwnerFilter> = opts.owner.and_then(OwnerFilter::filter_ignore);
#[cfg(windows)]
let ansi_colors_support =
ansi_term::enable_ansi_support().is_ok() || std::env::var_os("TERM").is_some();
nu_ansi_term::enable_ansi_support().is_ok() || std::env::var_os("TERM").is_some();
#[cfg(not(windows))]
let ansi_colors_support = true;
let interactive_terminal = atty::is(Stream::Stdout);
let interactive_terminal = std::io::stdout().is_terminal();
let colored_output = match opts.color {
ColorWhen::Always => true,
ColorWhen::Never => false,
ColorWhen::Auto => {
ansi_colors_support && env::var_os("NO_COLOR").is_none() && interactive_terminal
let no_color = env::var_os("NO_COLOR").is_some_and(|x| !x.is_empty());
ansi_colors_support && !no_color && interactive_terminal
}
};
@@ -206,6 +234,11 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
} else {
None
};
let hyperlink = match opts.hyperlink {
HyperlinkWhen::Always => true,
HyperlinkWhen::Never => false,
HyperlinkWhen::Auto => colored_output,
};
let command = extract_command(&mut opts, colored_output)?;
let has_command = command.is_some();
@@ -215,8 +248,11 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
ignore_hidden: !(opts.hidden || opts.rg_alias_ignore()),
read_fdignore: !(opts.no_ignore || opts.rg_alias_ignore()),
read_vcsignore: !(opts.no_ignore || opts.rg_alias_ignore() || opts.no_ignore_vcs),
require_git_to_read_vcsignore: !opts.no_require_git,
read_parent_ignore: !opts.no_ignore_parent,
read_global_ignore: !opts.no_ignore || opts.rg_alias_ignore() || opts.no_global_ignore_file,
read_global_ignore: !(opts.no_ignore
|| opts.rg_alias_ignore()
|| opts.no_global_ignore_file),
follow_links: opts.follow,
one_file_system: opts.one_file_system,
null_separator: opts.null_separator,
@@ -224,9 +260,10 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
max_depth: opts.max_depth(),
min_depth: opts.min_depth(),
prune: opts.prune,
threads: opts.threads(),
threads: opts.threads().get(),
max_buffer_time: opts.max_buffer_time,
ls_colors,
hyperlink,
interactive_terminal,
file_types: opts.filetype.as_ref().map(|values| {
use crate::cli::FileType::*;
@@ -241,6 +278,8 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
file_types.files = true;
}
Empty => file_types.empty_only = true,
BlockDevice => file_types.block_devices = true,
CharDevice => file_types.char_devices = true,
Socket => file_types.sockets = true,
Pipe => file_types.pipes = true,
}
@@ -267,6 +306,10 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
.build()
})
.transpose()?,
format: opts
.format
.as_deref()
.map(crate::fmt::FormatTemplate::parse),
command: command.map(Arc::new),
batch_size: opts.batch_size,
exclude_patterns: opts.exclude.iter().map(|p| String::from("!") + p).collect(),
@@ -279,8 +322,7 @@ fn construct_config(mut opts: Opts, pattern_regex: &str) -> Result<Config> {
path_separator,
actual_path_separator,
max_results: opts.max_results(),
strip_cwd_prefix: (opts.no_search_paths()
&& (opts.strip_cwd_prefix || !(opts.null_separator || has_command))),
strip_cwd_prefix: opts.strip_cwd_prefix(|| !(opts.null_separator || has_command)),
})
}
@@ -293,18 +335,22 @@ fn extract_command(opts: &mut Opts, colored_output: bool) -> Result<Option<Comma
if !opts.list_details {
return None;
}
let color_arg = format!("--color={}", opts.color.as_str());
let res = determine_ls_command(&color_arg, colored_output)
let res = determine_ls_command(colored_output)
.map(|cmd| CommandSet::new_batch([cmd]).unwrap());
Some(res)
})
.transpose()
}
fn determine_ls_command(color_arg: &str, colored_output: bool) -> Result<Vec<&str>> {
fn determine_ls_command(colored_output: bool) -> Result<Vec<&'static str>> {
#[allow(unused)]
let gnu_ls = |command_name| {
let color_arg = if colored_output {
"--color=always"
} else {
"--color=never"
};
// Note: we use short options here (instead of --long-options) to support more
// platforms (like BusyBox).
vec![
@@ -382,10 +428,9 @@ fn determine_ls_command(color_arg: &str, colored_output: bool) -> Result<Vec<&st
}
fn extract_time_constraints(opts: &Opts) -> Result<Vec<TimeFilter>> {
let now = time::SystemTime::now();
let mut time_constraints: Vec<TimeFilter> = Vec::new();
if let Some(ref t) = opts.changed_within {
if let Some(f) = TimeFilter::after(&now, t) {
if let Some(f) = TimeFilter::after(t) {
time_constraints.push(f);
} else {
return Err(anyhow!(
@@ -395,7 +440,7 @@ fn extract_time_constraints(opts: &Opts) -> Result<Vec<TimeFilter>> {
}
}
if let Some(ref t) = opts.changed_before {
if let Some(f) = TimeFilter::before(&now, t) {
if let Some(f) = TimeFilter::before(t) {
time_constraints.push(f);
} else {
return Err(anyhow!(
@@ -409,14 +454,18 @@ fn extract_time_constraints(opts: &Opts) -> Result<Vec<TimeFilter>> {
fn ensure_use_hidden_option_for_leading_dot_pattern(
config: &Config,
pattern_regex: &str,
pattern_regexps: &[String],
) -> Result<()> {
if cfg!(unix) && config.ignore_hidden && pattern_matches_strings_with_leading_dot(pattern_regex)
if cfg!(unix)
&& config.ignore_hidden
&& pattern_regexps
.iter()
.any(|pat| pattern_matches_strings_with_leading_dot(pat))
{
Err(anyhow!(
"The pattern seems to only match files with a leading dot, but hidden files are \
"The pattern(s) seems to only match files with a leading dot, but hidden files are \
filtered by default. Consider adding -H/--hidden to search hidden files as well \
or adjust your search pattern."
or adjust your search pattern(s)."
))
} else {
Ok(())
+46 -31
View File
@@ -5,29 +5,39 @@ use lscolors::{Indicator, LsColors, Style};
use crate::config::Config;
use crate::dir_entry::DirEntry;
use crate::error::print_error;
use crate::exit_codes::ExitCode;
use crate::fmt::FormatTemplate;
use crate::hyperlink::PathUrl;
fn replace_path_separator(path: &str, new_path_separator: &str) -> String {
path.replace(std::path::MAIN_SEPARATOR, new_path_separator)
}
// TODO: this function is performance critical and can probably be optimized
pub fn print_entry<W: Write>(stdout: &mut W, entry: &DirEntry, config: &Config) {
let r = if let Some(ref ls_colors) = config.ls_colors {
print_entry_colorized(stdout, entry, config, ls_colors)
pub fn print_entry<W: Write>(stdout: &mut W, entry: &DirEntry, config: &Config) -> io::Result<()> {
let mut has_hyperlink = false;
if config.hyperlink {
if let Some(url) = PathUrl::new(entry.path()) {
write!(stdout, "\x1B]8;;{url}\x1B\\")?;
has_hyperlink = true;
}
}
if let Some(ref format) = config.format {
print_entry_format(stdout, entry, config, format)?;
} else if let Some(ref ls_colors) = config.ls_colors {
print_entry_colorized(stdout, entry, config, ls_colors)?;
} else {
print_entry_uncolorized(stdout, entry, config)
print_entry_uncolorized(stdout, entry, config)?;
};
if let Err(e) = r {
if e.kind() == ::std::io::ErrorKind::BrokenPipe {
// Exit gracefully in case of a broken pipe (e.g. 'fd ... | head -n 3').
ExitCode::Success.exit();
} else {
print_error(format!("Could not write to output: {}", e));
ExitCode::GeneralError.exit();
}
if has_hyperlink {
write!(stdout, "\x1B]8;;\x1B\\")?;
}
if config.null_separator {
write!(stdout, "\0")
} else {
writeln!(stdout)
}
}
@@ -41,12 +51,12 @@ fn print_trailing_slash<W: Write>(
config: &Config,
style: Option<&Style>,
) -> io::Result<()> {
if entry.file_type().map_or(false, |ft| ft.is_dir()) {
if entry.file_type().is_some_and(|ft| ft.is_dir()) {
write!(
stdout,
"{}",
style
.map(Style::to_ansi_term_style)
.map(Style::to_nu_ansi_term_style)
.unwrap_or_default()
.paint(&config.actual_path_separator)
)?;
@@ -54,6 +64,21 @@ fn print_trailing_slash<W: Write>(
Ok(())
}
// TODO: this function is performance critical and can probably be optimized
fn print_entry_format<W: Write>(
stdout: &mut W,
entry: &DirEntry,
config: &Config,
format: &FormatTemplate,
) -> io::Result<()> {
let output = format.generate(
entry.stripped_path(config),
config.path_separator.as_deref(),
);
// TODO: support writing raw bytes on unix?
write!(stdout, "{}", output.to_string_lossy())
}
// TODO: this function is performance critical and can probably be optimized
fn print_entry_colorized<W: Write>(
stdout: &mut W,
@@ -85,14 +110,14 @@ fn print_entry_colorized<W: Write>(
let style = ls_colors
.style_for_indicator(Indicator::Directory)
.map(Style::to_ansi_term_style)
.map(Style::to_nu_ansi_term_style)
.unwrap_or_default();
write!(stdout, "{}", style.paint(parent_str))?;
}
let style = entry
.style(ls_colors)
.map(Style::to_ansi_term_style)
.map(Style::to_nu_ansi_term_style)
.unwrap_or_default();
write!(stdout, "{}", style.paint(&path_str[offset..]))?;
@@ -103,12 +128,6 @@ fn print_entry_colorized<W: Write>(
ls_colors.style_for_indicator(Indicator::Directory),
)?;
if config.null_separator {
write!(stdout, "\0")?;
} else {
writeln!(stdout)?;
}
Ok(())
}
@@ -118,16 +137,14 @@ fn print_entry_uncolorized_base<W: Write>(
entry: &DirEntry,
config: &Config,
) -> io::Result<()> {
let separator = if config.null_separator { "\0" } else { "\n" };
let path = entry.stripped_path(config);
let mut path_string = path.to_string_lossy();
if let Some(ref separator) = config.path_separator {
*path_string.to_mut() = replace_path_separator(&path_string, separator);
}
write!(stdout, "{}", path_string)?;
print_trailing_slash(stdout, entry, config, None)?;
write!(stdout, "{}", separator)
write!(stdout, "{path_string}")?;
print_trailing_slash(stdout, entry, config, None)
}
#[cfg(not(unix))]
@@ -152,9 +169,7 @@ fn print_entry_uncolorized<W: Write>(
print_entry_uncolorized_base(stdout, entry, config)
} else {
// Print path as raw bytes, allowing invalid UTF-8 filenames to be passed to other processes
let separator = if config.null_separator { b"\0" } else { b"\n" };
stdout.write_all(entry.stripped_path(config).as_os_str().as_bytes())?;
print_trailing_slash(stdout, entry, config, None)?;
stdout.write_all(separator)
print_trailing_slash(stdout, entry, config, None)
}
}
+13 -8
View File
@@ -3,7 +3,7 @@ use regex_syntax::ParserBuilder;
/// Determine if a regex pattern contains a literal uppercase character.
pub fn pattern_has_uppercase_char(pattern: &str) -> bool {
let mut parser = ParserBuilder::new().allow_invalid_utf8(true).build();
let mut parser = ParserBuilder::new().utf8(false).build();
parser
.parse(pattern)
@@ -16,16 +16,18 @@ fn hir_has_uppercase_char(hir: &Hir) -> bool {
use regex_syntax::hir::*;
match hir.kind() {
HirKind::Literal(Literal::Unicode(c)) => c.is_uppercase(),
HirKind::Literal(Literal::Byte(b)) => char::from(*b).is_uppercase(),
HirKind::Literal(Literal(bytes)) => match std::str::from_utf8(bytes) {
Ok(s) => s.chars().any(|c| c.is_uppercase()),
Err(_) => bytes.iter().any(|b| char::from(*b).is_uppercase()),
},
HirKind::Class(Class::Unicode(ranges)) => ranges
.iter()
.any(|r| r.start().is_uppercase() || r.end().is_uppercase()),
HirKind::Class(Class::Bytes(ranges)) => ranges
.iter()
.any(|r| char::from(r.start()).is_uppercase() || char::from(r.end()).is_uppercase()),
HirKind::Group(Group { hir, .. }) | HirKind::Repetition(Repetition { hir, .. }) => {
hir_has_uppercase_char(hir)
HirKind::Capture(Capture { sub, .. }) | HirKind::Repetition(Repetition { sub, .. }) => {
hir_has_uppercase_char(sub)
}
HirKind::Concat(hirs) | HirKind::Alternation(hirs) => {
hirs.iter().any(hir_has_uppercase_char)
@@ -36,7 +38,7 @@ fn hir_has_uppercase_char(hir: &Hir) -> bool {
/// Determine if a regex pattern only matches strings starting with a literal dot (hidden files)
pub fn pattern_matches_strings_with_leading_dot(pattern: &str) -> bool {
let mut parser = ParserBuilder::new().allow_invalid_utf8(true).build();
let mut parser = ParserBuilder::new().utf8(false).build();
parser
.parse(pattern)
@@ -56,7 +58,7 @@ fn hir_matches_strings_with_leading_dot(hir: &Hir) -> bool {
HirKind::Concat(hirs) => {
let mut hirs = hirs.iter();
if let Some(hir) = hirs.next() {
if hir.kind() != &HirKind::Anchor(Anchor::StartText) {
if hir.kind() != &HirKind::Look(Look::Start) {
return false;
}
} else {
@@ -64,7 +66,10 @@ fn hir_matches_strings_with_leading_dot(hir: &Hir) -> bool {
}
if let Some(hir) = hirs.next() {
hir.kind() == &HirKind::Literal(Literal::Unicode('.'))
match hir.kind() {
HirKind::Literal(Literal(bytes)) => bytes.starts_with(b"."),
_ => false,
}
} else {
false
}
+473 -354
View File
@@ -1,17 +1,18 @@
use std::borrow::Cow;
use std::ffi::OsStr;
use std::io;
use std::io::{self, Write};
use std::mem;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::sync::{Arc, Mutex, MutexGuard};
use std::thread;
use std::time::{Duration, Instant};
use std::{borrow::Cow, io::Write};
use anyhow::{anyhow, Result};
use crossbeam_channel::{bounded, Receiver, RecvTimeoutError, Sender};
use ignore::overrides::OverrideBuilder;
use ignore::{self, WalkBuilder};
use crossbeam_channel::{bounded, Receiver, RecvTimeoutError, SendError, Sender};
use etcetera::BaseStrategy;
use ignore::overrides::{Override, OverrideBuilder};
use ignore::{WalkBuilder, WalkParallel, WalkState};
use regex::bytes::Regex;
use crate::config::Config;
@@ -34,144 +35,107 @@ enum ReceiverMode {
}
/// The Worker threads can result in a valid entry having PathBuf or an error.
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum WorkerResult {
// Errors should be rare, so it's probably better to allow large_enum_variant than
// to box the Entry variant
Entry(DirEntry),
Error(ignore::Error),
}
/// Maximum size of the output buffer before flushing results to the console
pub const MAX_BUFFER_LENGTH: usize = 1000;
/// Default duration until output buffering switches to streaming.
pub const DEFAULT_MAX_BUFFER_TIME: Duration = Duration::from_millis(100);
/// A batch of WorkerResults to send over a channel.
#[derive(Clone)]
struct Batch {
items: Arc<Mutex<Option<Vec<WorkerResult>>>>,
}
/// Recursively scan the given search path for files / pathnames matching the pattern.
///
/// If the `--exec` argument was supplied, this will create a thread pool for executing
/// jobs in parallel from a given command line and the discovered paths. Otherwise, each
/// path will simply be written to standard output.
pub fn scan(paths: &[PathBuf], pattern: Arc<Regex>, config: Arc<Config>) -> Result<ExitCode> {
let first_path = &paths[0];
// Channel capacity was chosen empircally to perform similarly to an unbounded channel
let (tx, rx) = bounded(0x4000 * config.threads);
let mut override_builder = OverrideBuilder::new(first_path);
for pattern in &config.exclude_patterns {
override_builder
.add(pattern)
.map_err(|e| anyhow!("Malformed exclude pattern: {}", e))?;
}
let overrides = override_builder
.build()
.map_err(|_| anyhow!("Mismatch in exclude patterns"))?;
let mut walker = WalkBuilder::new(first_path);
walker
.hidden(config.ignore_hidden)
.ignore(config.read_fdignore)
.parents(config.read_parent_ignore && (config.read_fdignore || config.read_vcsignore))
.git_ignore(config.read_vcsignore)
.git_global(config.read_vcsignore)
.git_exclude(config.read_vcsignore)
.overrides(overrides)
.follow_links(config.follow_links)
// No need to check for supported platforms, option is unavailable on unsupported ones
.same_file_system(config.one_file_system)
.max_depth(config.max_depth);
if config.read_fdignore {
walker.add_custom_ignore_filename(".fdignore");
}
if config.read_global_ignore {
#[cfg(target_os = "macos")]
let config_dir_op = std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs_next::home_dir().map(|d| d.join(".config")));
#[cfg(not(target_os = "macos"))]
let config_dir_op = dirs_next::config_dir();
if let Some(global_ignore_file) = config_dir_op
.map(|p| p.join("fd").join("ignore"))
.filter(|p| p.is_file())
{
let result = walker.add_ignore(global_ignore_file);
match result {
Some(ignore::Error::Partial(_)) => (),
Some(err) => {
print_error(format!("Malformed pattern in global ignore file. {}.", err));
}
None => (),
}
impl Batch {
fn new() -> Self {
Self {
items: Arc::new(Mutex::new(Some(vec![]))),
}
}
for ignore_file in &config.ignore_files {
let result = walker.add_ignore(ignore_file);
match result {
Some(ignore::Error::Partial(_)) => (),
Some(err) => {
print_error(format!("Malformed pattern in custom ignore file. {}.", err));
}
None => (),
}
}
for path in &paths[1..] {
walker.add(path);
}
let parallel_walker = walker.threads(config.threads).build_parallel();
// Flag for cleanly shutting down the parallel walk
let quit_flag = Arc::new(AtomicBool::new(false));
// Flag specifically for quitting due to ^C
let interrupt_flag = Arc::new(AtomicBool::new(false));
if config.ls_colors.is_some() && config.is_printing() {
let quit_flag = Arc::clone(&quit_flag);
let interrupt_flag = Arc::clone(&interrupt_flag);
ctrlc::set_handler(move || {
quit_flag.store(true, Ordering::Relaxed);
if interrupt_flag.fetch_or(true, Ordering::Relaxed) {
// Ctrl-C has been pressed twice, exit NOW
ExitCode::KilledBySigint.exit();
}
})
.unwrap();
}
// Spawn the thread that receives all results through the channel.
let receiver_thread = spawn_receiver(&config, &quit_flag, &interrupt_flag, rx);
// Spawn the sender threads.
spawn_senders(&config, &quit_flag, pattern, parallel_walker, tx);
// Wait for the receiver thread to print out all results.
let exit_code = receiver_thread.join().unwrap();
if interrupt_flag.load(Ordering::Relaxed) {
Ok(ExitCode::KilledBySigint)
} else {
Ok(exit_code)
fn lock(&self) -> MutexGuard<'_, Option<Vec<WorkerResult>>> {
self.items.lock().unwrap()
}
}
impl IntoIterator for Batch {
type Item = WorkerResult;
type IntoIter = std::vec::IntoIter<WorkerResult>;
fn into_iter(self) -> Self::IntoIter {
self.lock().take().unwrap().into_iter()
}
}
/// Wrapper that sends batches of items at once over a channel.
struct BatchSender {
batch: Batch,
tx: Sender<Batch>,
limit: usize,
}
impl BatchSender {
fn new(tx: Sender<Batch>, limit: usize) -> Self {
Self {
batch: Batch::new(),
tx,
limit,
}
}
/// Check if we need to flush a batch.
fn needs_flush(&self, batch: Option<&Vec<WorkerResult>>) -> bool {
match batch {
// Limit the batch size to provide some backpressure
Some(vec) => vec.len() >= self.limit,
// Batch was already taken by the receiver, so make a new one
None => true,
}
}
/// Add an item to a batch.
fn send(&mut self, item: WorkerResult) -> Result<(), SendError<()>> {
let mut batch = self.batch.lock();
if self.needs_flush(batch.as_ref()) {
drop(batch);
self.batch = Batch::new();
batch = self.batch.lock();
}
let items = batch.as_mut().unwrap();
items.push(item);
if items.len() == 1 {
// New batch, send it over the channel
self.tx
.send(self.batch.clone())
.map_err(|_| SendError(()))?;
}
Ok(())
}
}
/// Maximum size of the output buffer before flushing results to the console
const MAX_BUFFER_LENGTH: usize = 1000;
/// Default duration until output buffering switches to streaming.
const DEFAULT_MAX_BUFFER_TIME: Duration = Duration::from_millis(100);
/// Wrapper for the receiver thread's buffering behavior.
struct ReceiverBuffer<W> {
struct ReceiverBuffer<'a, W> {
/// The configuration.
config: Arc<Config>,
config: &'a Config,
/// For shutting down the senders.
quit_flag: Arc<AtomicBool>,
quit_flag: &'a AtomicBool,
/// The ^C notifier.
interrupt_flag: Arc<AtomicBool>,
interrupt_flag: &'a AtomicBool,
/// Receiver for worker results.
rx: Receiver<WorkerResult>,
rx: Receiver<Batch>,
/// Standard output.
stdout: W,
/// The current buffer mode.
@@ -184,15 +148,12 @@ struct ReceiverBuffer<W> {
num_results: usize,
}
impl<W: Write> ReceiverBuffer<W> {
impl<'a, W: Write> ReceiverBuffer<'a, W> {
/// Create a new receiver buffer.
fn new(
config: Arc<Config>,
quit_flag: Arc<AtomicBool>,
interrupt_flag: Arc<AtomicBool>,
rx: Receiver<WorkerResult>,
stdout: W,
) -> Self {
fn new(state: &'a WorkerState, rx: Receiver<Batch>, stdout: W) -> Self {
let config = &state.config;
let quit_flag = state.quit_flag.as_ref();
let interrupt_flag = state.interrupt_flag.as_ref();
let max_buffer_time = config.max_buffer_time.unwrap_or(DEFAULT_MAX_BUFFER_TIME);
let deadline = Instant::now() + max_buffer_time;
@@ -220,7 +181,7 @@ impl<W: Write> ReceiverBuffer<W> {
}
/// Receive the next worker result.
fn recv(&self) -> Result<WorkerResult, RecvTimeoutError> {
fn recv(&self) -> Result<Batch, RecvTimeoutError> {
match self.mode {
ReceiverMode::Buffering => {
// Wait at most until we should switch to streaming
@@ -236,34 +197,44 @@ impl<W: Write> ReceiverBuffer<W> {
/// Wait for a result or state change.
fn poll(&mut self) -> Result<(), ExitCode> {
match self.recv() {
Ok(WorkerResult::Entry(dir_entry)) => {
if self.config.quiet {
return Err(ExitCode::HasResults(true));
}
Ok(batch) => {
for result in batch {
match result {
WorkerResult::Entry(dir_entry) => {
if self.config.quiet {
return Err(ExitCode::HasResults(true));
}
match self.mode {
ReceiverMode::Buffering => {
self.buffer.push(dir_entry);
if self.buffer.len() > MAX_BUFFER_LENGTH {
self.stream()?;
match self.mode {
ReceiverMode::Buffering => {
self.buffer.push(dir_entry);
if self.buffer.len() > MAX_BUFFER_LENGTH {
self.stream()?;
}
}
ReceiverMode::Streaming => {
self.print(&dir_entry)?;
}
}
self.num_results += 1;
if let Some(max_results) = self.config.max_results {
if self.num_results >= max_results {
return self.stop();
}
}
}
WorkerResult::Error(err) => {
if self.config.show_filesystem_errors {
print_error(err.to_string());
}
}
}
ReceiverMode::Streaming => {
self.print(&dir_entry)?;
self.flush()?;
}
}
self.num_results += 1;
if let Some(max_results) = self.config.max_results {
if self.num_results >= max_results {
return self.stop();
}
}
}
Ok(WorkerResult::Error(err)) => {
if self.config.show_filesystem_errors {
print_error(err.to_string());
// If we don't have another batch ready, flush before waiting
if self.mode == ReceiverMode::Streaming && self.rx.is_empty() {
self.flush()?;
}
}
Err(RecvTimeoutError::Timeout) => {
@@ -279,7 +250,12 @@ impl<W: Write> ReceiverBuffer<W> {
/// Output a path.
fn print(&mut self, entry: &DirEntry) -> Result<(), ExitCode> {
output::print_entry(&mut self.stdout, entry, &self.config);
if let Err(e) = output::print_entry(&mut self.stdout, entry, self.config) {
if e.kind() != ::std::io::ErrorKind::BrokenPipe {
print_error(format!("Could not write to output: {e}"));
return Err(ExitCode::GeneralError);
}
}
if self.interrupt_flag.load(Ordering::Relaxed) {
// Ignore any errors on flush, because we're about to exit anyway
@@ -318,7 +294,7 @@ impl<W: Write> ReceiverBuffer<W> {
/// Flush stdout if necessary.
fn flush(&mut self) -> Result<(), ExitCode> {
if self.config.interactive_terminal && self.stdout.flush().is_err() {
if self.stdout.flush().is_err() {
// Probably a broken pipe. Exit gracefully.
return Err(ExitCode::GeneralError);
}
@@ -326,226 +302,369 @@ impl<W: Write> ReceiverBuffer<W> {
}
}
fn spawn_receiver(
config: &Arc<Config>,
quit_flag: &Arc<AtomicBool>,
interrupt_flag: &Arc<AtomicBool>,
rx: Receiver<WorkerResult>,
) -> thread::JoinHandle<ExitCode> {
let config = Arc::clone(config);
let quit_flag = Arc::clone(quit_flag);
let interrupt_flag = Arc::clone(interrupt_flag);
/// State shared by the sender and receiver threads.
struct WorkerState {
/// The search patterns.
patterns: Vec<Regex>,
/// The command line configuration.
config: Config,
/// Flag for cleanly shutting down the parallel walk
quit_flag: Arc<AtomicBool>,
/// Flag specifically for quitting due to ^C
interrupt_flag: Arc<AtomicBool>,
}
impl WorkerState {
fn new(patterns: Vec<Regex>, config: Config) -> Self {
let quit_flag = Arc::new(AtomicBool::new(false));
let interrupt_flag = Arc::new(AtomicBool::new(false));
Self {
patterns,
config,
quit_flag,
interrupt_flag,
}
}
fn build_overrides(&self, paths: &[PathBuf]) -> Result<Override> {
let first_path = &paths[0];
let config = &self.config;
let mut builder = OverrideBuilder::new(first_path);
for pattern in &config.exclude_patterns {
builder
.add(pattern)
.map_err(|e| anyhow!("Malformed exclude pattern: {}", e))?;
}
builder
.build()
.map_err(|_| anyhow!("Mismatch in exclude patterns"))
}
fn build_walker(&self, paths: &[PathBuf]) -> Result<WalkParallel> {
let first_path = &paths[0];
let config = &self.config;
let overrides = self.build_overrides(paths)?;
let mut builder = WalkBuilder::new(first_path);
builder
.hidden(config.ignore_hidden)
.ignore(config.read_fdignore)
.parents(config.read_parent_ignore && (config.read_fdignore || config.read_vcsignore))
.git_ignore(config.read_vcsignore)
.git_global(config.read_vcsignore)
.git_exclude(config.read_vcsignore)
.require_git(config.require_git_to_read_vcsignore)
.overrides(overrides)
.follow_links(config.follow_links)
// No need to check for supported platforms, option is unavailable on unsupported ones
.same_file_system(config.one_file_system)
.max_depth(config.max_depth);
if config.read_fdignore {
builder.add_custom_ignore_filename(".fdignore");
}
if config.read_global_ignore {
if let Ok(basedirs) = etcetera::choose_base_strategy() {
let global_ignore_file = basedirs.config_dir().join("fd").join("ignore");
if global_ignore_file.is_file() {
let result = builder.add_ignore(global_ignore_file);
match result {
Some(ignore::Error::Partial(_)) => (),
Some(err) => {
print_error(format!("Malformed pattern in global ignore file. {err}."));
}
None => (),
}
}
}
}
for ignore_file in &config.ignore_files {
let result = builder.add_ignore(ignore_file);
match result {
Some(ignore::Error::Partial(_)) => (),
Some(err) => {
print_error(format!("Malformed pattern in custom ignore file. {err}."));
}
None => (),
}
}
for path in &paths[1..] {
builder.add(path);
}
let walker = builder.threads(config.threads).build_parallel();
Ok(walker)
}
/// Run the receiver work, either on this thread or a pool of background
/// threads (for --exec).
fn receive(&self, rx: Receiver<Batch>) -> ExitCode {
let config = &self.config;
let threads = config.threads;
thread::spawn(move || {
// This will be set to `Some` if the `--exec` argument was supplied.
if let Some(ref cmd) = config.command {
if cmd.in_batch_mode() {
exec::batch(rx, cmd, &config)
exec::batch(rx.into_iter().flatten(), cmd, config)
} else {
let out_perm = Arc::new(Mutex::new(()));
let out_perm = Mutex::new(());
// Each spawned job will store it's thread handle in here.
let mut handles = Vec::with_capacity(threads);
for _ in 0..threads {
let config = Arc::clone(&config);
let rx = rx.clone();
let cmd = Arc::clone(cmd);
let out_perm = Arc::clone(&out_perm);
thread::scope(|scope| {
// Each spawned job will store its thread handle in here.
let threads = config.threads;
let mut handles = Vec::with_capacity(threads);
for _ in 0..threads {
let rx = rx.clone();
// Spawn a job thread that will listen for and execute inputs.
let handle = thread::spawn(move || exec::job(rx, cmd, out_perm, &config));
// Spawn a job thread that will listen for and execute inputs.
let handle = scope
.spawn(|| exec::job(rx.into_iter().flatten(), cmd, &out_perm, config));
// Push the handle of the spawned thread into the vector for later joining.
handles.push(handle);
}
let exit_codes = handles
.into_iter()
.map(|handle| handle.join().unwrap())
.collect::<Vec<_>>();
merge_exitcodes(exit_codes)
// Push the handle of the spawned thread into the vector for later joining.
handles.push(handle);
}
let exit_codes = handles.into_iter().map(|handle| handle.join().unwrap());
merge_exitcodes(exit_codes)
})
}
} else {
let stdout = io::stdout();
let stdout = stdout.lock();
let stdout = io::stdout().lock();
let stdout = io::BufWriter::new(stdout);
let mut rxbuffer = ReceiverBuffer::new(config, quit_flag, interrupt_flag, rx, stdout);
rxbuffer.process()
ReceiverBuffer::new(self, rx, stdout).process()
}
})
}
}
fn spawn_senders(
config: &Arc<Config>,
quit_flag: &Arc<AtomicBool>,
pattern: Arc<Regex>,
parallel_walker: ignore::WalkParallel,
tx: Sender<WorkerResult>,
) {
parallel_walker.run(|| {
let config = Arc::clone(config);
let pattern = Arc::clone(&pattern);
let tx_thread = tx.clone();
let quit_flag = Arc::clone(quit_flag);
/// Spawn the sender threads.
fn spawn_senders(&self, walker: WalkParallel, tx: Sender<Batch>) {
walker.run(|| {
let patterns = &self.patterns;
let config = &self.config;
let quit_flag = self.quit_flag.as_ref();
Box::new(move |entry_o| {
if quit_flag.load(Ordering::Relaxed) {
return ignore::WalkState::Quit;
}
let entry = match entry_o {
Ok(ref e) if e.depth() == 0 => {
// Skip the root directory entry.
return ignore::WalkState::Continue;
let mut limit = 0x100;
if let Some(cmd) = &config.command {
if !cmd.in_batch_mode() && config.threads > 1 {
// Evenly distribute work between multiple receivers
limit = 1;
}
Ok(e) => DirEntry::normal(e),
Err(ignore::Error::WithPath {
path,
err: inner_err,
}) => match inner_err.as_ref() {
ignore::Error::Io(io_error)
if io_error.kind() == io::ErrorKind::NotFound
&& path
.symlink_metadata()
.ok()
.map_or(false, |m| m.file_type().is_symlink()) =>
{
DirEntry::broken_symlink(path)
}
let mut tx = BatchSender::new(tx.clone(), limit);
Box::new(move |entry| {
if quit_flag.load(Ordering::Relaxed) {
return WalkState::Quit;
}
let entry = match entry {
Ok(ref e) if e.depth() == 0 => {
// Skip the root directory entry.
return WalkState::Continue;
}
_ => {
return match tx_thread.send(WorkerResult::Error(ignore::Error::WithPath {
path,
err: inner_err,
})) {
Ok(_) => ignore::WalkState::Continue,
Err(_) => ignore::WalkState::Quit,
}
}
},
Err(err) => {
return match tx_thread.send(WorkerResult::Error(err)) {
Ok(_) => ignore::WalkState::Continue,
Err(_) => ignore::WalkState::Quit,
}
}
};
if let Some(min_depth) = config.min_depth {
if entry.depth().map_or(true, |d| d < min_depth) {
return ignore::WalkState::Continue;
}
}
// Check the name first, since it doesn't require metadata
let entry_path = entry.path();
let search_str: Cow<OsStr> = if config.search_full_path {
let path_abs_buf = filesystem::path_absolute_form(entry_path)
.expect("Retrieving absolute path succeeds");
Cow::Owned(path_abs_buf.as_os_str().to_os_string())
} else {
match entry_path.file_name() {
Some(filename) => Cow::Borrowed(filename),
None => unreachable!(
"Encountered file system entry without a file name. This should only \
happen for paths like 'foo/bar/..' or '/' which are not supposed to \
appear in a file system traversal."
),
}
};
if !pattern.is_match(&filesystem::osstr_to_bytes(search_str.as_ref())) {
return ignore::WalkState::Continue;
}
// Filter out unwanted extensions.
if let Some(ref exts_regex) = config.extensions {
if let Some(path_str) = entry_path.file_name() {
if !exts_regex.is_match(&filesystem::osstr_to_bytes(path_str)) {
return ignore::WalkState::Continue;
}
} else {
return ignore::WalkState::Continue;
}
}
// Filter out unwanted file types.
if let Some(ref file_types) = config.file_types {
if file_types.should_ignore(&entry) {
return ignore::WalkState::Continue;
}
}
#[cfg(unix)]
{
if let Some(ref owner_constraint) = config.owner_constraint {
if let Some(metadata) = entry.metadata() {
if !owner_constraint.matches(metadata) {
return ignore::WalkState::Continue;
}
} else {
return ignore::WalkState::Continue;
}
}
}
// Filter out unwanted sizes if it is a file and we have been given size constraints.
if !config.size_constraints.is_empty() {
if entry_path.is_file() {
if let Some(metadata) = entry.metadata() {
let file_size = metadata.len();
if config
.size_constraints
.iter()
.any(|sc| !sc.is_within(file_size))
Ok(e) => DirEntry::normal(e),
Err(ignore::Error::WithPath {
path,
err: inner_err,
}) => match inner_err.as_ref() {
ignore::Error::Io(io_error)
if io_error.kind() == io::ErrorKind::NotFound
&& path
.symlink_metadata()
.ok()
.is_some_and(|m| m.file_type().is_symlink()) =>
{
return ignore::WalkState::Continue;
DirEntry::broken_symlink(path)
}
_ => {
return match tx.send(WorkerResult::Error(ignore::Error::WithPath {
path,
err: inner_err,
})) {
Ok(_) => WalkState::Continue,
Err(_) => WalkState::Quit,
}
}
},
Err(err) => {
return match tx.send(WorkerResult::Error(err)) {
Ok(_) => WalkState::Continue,
Err(_) => WalkState::Quit,
}
}
};
if let Some(min_depth) = config.min_depth {
if entry.depth().map_or(true, |d| d < min_depth) {
return WalkState::Continue;
}
}
// Check the name first, since it doesn't require metadata
let entry_path = entry.path();
let search_str: Cow<OsStr> = if config.search_full_path {
let path_abs_buf = filesystem::path_absolute_form(entry_path)
.expect("Retrieving absolute path succeeds");
Cow::Owned(path_abs_buf.as_os_str().to_os_string())
} else {
match entry_path.file_name() {
Some(filename) => Cow::Borrowed(filename),
None => unreachable!(
"Encountered file system entry without a file name. This should only \
happen for paths like 'foo/bar/..' or '/' which are not supposed to \
appear in a file system traversal."
),
}
};
if !patterns
.iter()
.all(|pat| pat.is_match(&filesystem::osstr_to_bytes(search_str.as_ref())))
{
return WalkState::Continue;
}
// Filter out unwanted extensions.
if let Some(ref exts_regex) = config.extensions {
if let Some(path_str) = entry_path.file_name() {
if !exts_regex.is_match(&filesystem::osstr_to_bytes(path_str)) {
return WalkState::Continue;
}
} else {
return ignore::WalkState::Continue;
}
} else {
return ignore::WalkState::Continue;
}
}
// Filter out unwanted modification times
if !config.time_constraints.is_empty() {
let mut matched = false;
if let Some(metadata) = entry.metadata() {
if let Ok(modified) = metadata.modified() {
matched = config
.time_constraints
.iter()
.all(|tf| tf.applies_to(&modified));
return WalkState::Continue;
}
}
if !matched {
return ignore::WalkState::Continue;
// Filter out unwanted file types.
if let Some(ref file_types) = config.file_types {
if file_types.should_ignore(&entry) {
return WalkState::Continue;
}
}
}
if config.is_printing() {
if let Some(ls_colors) = &config.ls_colors {
// Compute colors in parallel
entry.style(ls_colors);
#[cfg(unix)]
{
if let Some(ref owner_constraint) = config.owner_constraint {
if let Some(metadata) = entry.metadata() {
if !owner_constraint.matches(metadata) {
return WalkState::Continue;
}
} else {
return WalkState::Continue;
}
}
}
}
let send_result = tx_thread.send(WorkerResult::Entry(entry));
// Filter out unwanted sizes if it is a file and we have been given size constraints.
if !config.size_constraints.is_empty() {
if entry_path.is_file() {
if let Some(metadata) = entry.metadata() {
let file_size = metadata.len();
if config
.size_constraints
.iter()
.any(|sc| !sc.is_within(file_size))
{
return WalkState::Continue;
}
} else {
return WalkState::Continue;
}
} else {
return WalkState::Continue;
}
}
if send_result.is_err() {
return ignore::WalkState::Quit;
}
// Filter out unwanted modification times
if !config.time_constraints.is_empty() {
let mut matched = false;
if let Some(metadata) = entry.metadata() {
if let Ok(modified) = metadata.modified() {
matched = config
.time_constraints
.iter()
.all(|tf| tf.applies_to(&modified));
}
}
if !matched {
return WalkState::Continue;
}
}
// Apply pruning.
if config.prune {
return ignore::WalkState::Skip;
}
if config.is_printing() {
if let Some(ls_colors) = &config.ls_colors {
// Compute colors in parallel
entry.style(ls_colors);
}
}
ignore::WalkState::Continue
})
});
let send_result = tx.send(WorkerResult::Entry(entry));
if send_result.is_err() {
return WalkState::Quit;
}
// Apply pruning.
if config.prune {
return WalkState::Skip;
}
WalkState::Continue
})
});
}
/// Perform the recursive scan.
fn scan(&self, paths: &[PathBuf]) -> Result<ExitCode> {
let config = &self.config;
let walker = self.build_walker(paths)?;
if config.ls_colors.is_some() && config.is_printing() {
let quit_flag = Arc::clone(&self.quit_flag);
let interrupt_flag = Arc::clone(&self.interrupt_flag);
ctrlc::set_handler(move || {
quit_flag.store(true, Ordering::Relaxed);
if interrupt_flag.fetch_or(true, Ordering::Relaxed) {
// Ctrl-C has been pressed twice, exit NOW
ExitCode::KilledBySigint.exit();
}
})
.unwrap();
}
let (tx, rx) = bounded(2 * config.threads);
let exit_code = thread::scope(|scope| {
// Spawn the receiver thread(s)
let receiver = scope.spawn(|| self.receive(rx));
// Spawn the sender threads.
self.spawn_senders(walker, tx);
receiver.join().unwrap()
});
if self.interrupt_flag.load(Ordering::Relaxed) {
Ok(ExitCode::KilledBySigint)
} else {
Ok(exit_code)
}
}
}
/// Recursively scan the given search path for files / pathnames matching the patterns.
///
/// If the `--exec` argument was supplied, this will create a thread pool for executing
/// jobs in parallel from a given command line and the discovered paths. Otherwise, each
/// path will simply be written to standard output.
pub fn scan(paths: &[PathBuf], patterns: Vec<Regex>, config: Config) -> Result<ExitCode> {
WorkerState::new(patterns, config).scan(paths)
}
+55 -21
View File
@@ -8,7 +8,7 @@ use std::os::windows;
use std::path::{Path, PathBuf};
use std::process;
use tempdir::TempDir;
use tempfile::TempDir;
/// Environment for the integration tests.
pub struct TestEnv {
@@ -20,6 +20,9 @@ pub struct TestEnv {
/// Normalize each line by sorting the whitespace-separated words
normalize_line: bool,
/// Temporary directory for storing test config (global ignore file)
config_dir: Option<TempDir>,
}
/// Create the working directory and the test files.
@@ -27,7 +30,7 @@ fn create_working_directory(
directories: &[&'static str],
files: &[&'static str],
) -> Result<TempDir, io::Error> {
let temp_dir = TempDir::new("fd-tests")?;
let temp_dir = tempfile::Builder::new().prefix("fd-tests").tempdir()?;
{
let root = temp_dir.path();
@@ -59,6 +62,16 @@ fn create_working_directory(
Ok(temp_dir)
}
fn create_config_directory_with_global_ignore(ignore_file_content: &str) -> io::Result<TempDir> {
let config_dir = tempfile::Builder::new().prefix("fd-config").tempdir()?;
let fd_dir = config_dir.path().join("fd");
fs::create_dir(&fd_dir)?;
let mut ignore_file = fs::File::create(fd_dir.join("ignore"))?;
ignore_file.write_all(ignore_file_content.as_bytes())?;
Ok(config_dir)
}
/// Find the *fd* executable.
fn find_fd_exe() -> PathBuf {
// Tests exe is in target/debug/deps, the *fd* exe is in target/debug
@@ -91,9 +104,9 @@ fn format_output_error(args: &[&str], expected: &str, actual: &str) -> String {
let diff_text = diff::lines(expected, actual)
.into_iter()
.map(|diff| match diff {
diff::Result::Left(l) => format!("-{}", l),
diff::Result::Both(l, _) => format!(" {}", l),
diff::Result::Right(r) => format!("+{}", r),
diff::Result::Left(l) => format!("-{l}"),
diff::Result::Both(l, _) => format!(" {l}"),
diff::Result::Right(r) => format!("+{r}"),
})
.collect::<Vec<_>>()
.join("\n");
@@ -116,7 +129,7 @@ fn normalize_output(s: &str, trim_start: bool, normalize_line: bool) -> String {
.lines()
.map(|line| {
let line = if trim_start { line.trim_start() } else { line };
let line = line.replace('/', &std::path::MAIN_SEPARATOR.to_string());
let line = line.replace('/', std::path::MAIN_SEPARATOR_STR);
if normalize_line {
let mut words: Vec<_> = line.split_whitespace().collect();
words.sort_unstable();
@@ -150,6 +163,7 @@ impl TestEnv {
temp_dir,
fd_exe,
normalize_line: false,
config_dir: None,
}
}
@@ -158,6 +172,16 @@ impl TestEnv {
temp_dir: self.temp_dir,
fd_exe: self.fd_exe,
normalize_line: normalize,
config_dir: self.config_dir,
}
}
pub fn global_ignore_file(self, content: &str) -> TestEnv {
let config_dir =
create_config_directory_with_global_ignore(content).expect("config directory");
TestEnv {
config_dir: Some(config_dir),
..self
}
}
@@ -169,7 +193,9 @@ impl TestEnv {
let root = self.test_root();
let broken_symlink_link = root.join(link_path);
{
let temp_target_dir = TempDir::new("fd-tests-broken-symlink")?;
let temp_target_dir = tempfile::Builder::new()
.prefix("fd-tests-broken-symlink")
.tempdir()?;
let broken_symlink_target = temp_target_dir.path().join("broken_symlink_target");
fs::File::create(&broken_symlink_target)?;
#[cfg(unix)]
@@ -186,6 +212,7 @@ impl TestEnv {
}
/// Get the path of the fd executable.
#[cfg_attr(windows, allow(unused))]
pub fn test_exe(&self) -> &PathBuf {
&self.fd_exe
}
@@ -203,13 +230,8 @@ impl TestEnv {
path: P,
args: &[&str],
) -> process::Output {
// Setup *fd* command.
let mut cmd = process::Command::new(&self.fd_exe);
cmd.current_dir(self.temp_dir.path().join(path));
cmd.arg("--no-global-ignore-file").args(args);
// Run *fd*.
let output = cmd.output().expect("fd output");
let output = self.run_command(path.as_ref(), args);
// Check for exit status.
if !output.status.success() {
@@ -268,7 +290,7 @@ impl TestEnv {
pub fn assert_failure_with_error(&self, args: &[&str], expected: &str) {
let status = self.assert_error_subdirectory(".", args, Some(expected));
if status.success() {
panic!("error '{}' did not occur.", expected);
panic!("error '{expected}' did not occur.");
}
}
@@ -285,6 +307,24 @@ impl TestEnv {
self.assert_error_subdirectory(".", args, Some(expected))
}
fn run_command(&self, path: &Path, args: &[&str]) -> process::Output {
// Setup *fd* command.
let mut cmd = process::Command::new(&self.fd_exe);
cmd.current_dir(self.temp_dir.path().join(path));
if let Some(config_dir) = &self.config_dir {
cmd.env("XDG_CONFIG_HOME", config_dir.path());
} else {
cmd.arg("--no-global-ignore-file");
}
// Make sure LS_COLORS is unset to ensure consistent
// color output
cmd.env("LS_COLORS", "");
cmd.args(args);
// Run *fd*.
cmd.output().expect("fd output")
}
/// Assert that calling *fd* in the specified path under the root working directory,
/// and with the specified arguments produces an error with the expected message.
fn assert_error_subdirectory<P: AsRef<Path>>(
@@ -293,13 +333,7 @@ impl TestEnv {
args: &[&str],
expected: Option<&str>,
) -> process::ExitStatus {
// Setup *fd* command.
let mut cmd = process::Command::new(&self.fd_exe);
cmd.current_dir(self.temp_dir.path().join(path));
cmd.arg("--no-global-ignore-file").args(args);
// Run *fd*.
let output = cmd.output().expect("fd output");
let output = self.run_command(path.as_ref(), args);
if let Some(expected) = expected {
// Normalize both expected and actual output.
+542 -16
View File
@@ -1,11 +1,14 @@
mod testenv;
#[cfg(unix)]
use nix::unistd::{Gid, Group, Uid, User};
use std::fs;
use std::io::Write;
use std::path::Path;
use std::time::{Duration, SystemTime};
use test_case::test_case;
use jiff::Timestamp;
use normpath::PathExt;
use regex::escape;
@@ -76,6 +79,217 @@ fn test_simple() {
);
}
static AND_EXTRA_FILES: &[&str] = &[
"a.foo",
"one/b.foo",
"one/two/c.foo",
"one/two/C.Foo2",
"one/two/three/baz-quux",
"one/two/three/Baz-Quux2",
"one/two/three/d.foo",
"fdignored.foo",
"gitignored.foo",
".hidden.foo",
"A-B.jpg",
"A-C.png",
"B-A.png",
"B-C.png",
"C-A.jpg",
"C-B.png",
"e1 e2",
];
/// AND test
#[test]
fn test_and_basic() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["foo", "--and", "c"],
"one/two/C.Foo2
one/two/c.foo
one/two/three/directory_foo/",
);
te.assert_output(
&["f", "--and", "[ad]", "--and", "[_]"],
"one/two/three/directory_foo/",
);
te.assert_output(
&["f", "--and", "[ad]", "--and", "[.]"],
"a.foo
one/two/three/d.foo",
);
te.assert_output(&["Foo", "--and", "C"], "one/two/C.Foo2");
te.assert_output(&["foo", "--and", "asdasdasdsadasd"], "");
}
#[test]
fn test_and_empty_pattern() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(&["Foo", "--and", "2", "--and", ""], "one/two/C.Foo2");
}
#[test]
fn test_and_bad_pattern() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_failure(&["Foo", "--and", "2", "--and", "[", "--and", "C"]);
te.assert_failure(&["Foo", "--and", "[", "--and", "2", "--and", "C"]);
te.assert_failure(&["Foo", "--and", "2", "--and", "C", "--and", "["]);
te.assert_failure(&["[", "--and", "2", "--and", "C", "--and", "Foo"]);
}
#[test]
fn test_and_pattern_starts_with_dash() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["baz", "--and", "quux"],
"one/two/three/Baz-Quux2
one/two/three/baz-quux",
);
te.assert_output(
&["baz", "--and", "-"],
"one/two/three/Baz-Quux2
one/two/three/baz-quux",
);
te.assert_output(
&["Quu", "--and", "x", "--and", "-"],
"one/two/three/Baz-Quux2",
);
}
#[test]
fn test_and_plus_extension() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&[
"A",
"--and",
"B",
"--extension",
"jpg",
"--extension",
"png",
],
"A-B.jpg
B-A.png",
);
te.assert_output(
&[
"A",
"--extension",
"jpg",
"--and",
"B",
"--extension",
"png",
],
"A-B.jpg
B-A.png",
);
}
#[test]
fn test_and_plus_type() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["c", "--type", "d", "--and", "foo"],
"one/two/three/directory_foo/",
);
te.assert_output(
&["c", "--type", "f", "--and", "foo"],
"one/two/C.Foo2
one/two/c.foo",
);
}
#[test]
fn test_and_plus_glob() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(&["*foo", "--glob", "--and", "c*"], "one/two/c.foo");
}
#[test]
fn test_and_plus_fixed_strings() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["foo", "--fixed-strings", "--and", "c", "--and", "."],
"one/two/c.foo
one/two/C.Foo2",
);
te.assert_output(
&["foo", "--fixed-strings", "--and", "[c]", "--and", "."],
"",
);
te.assert_output(
&["Foo", "--fixed-strings", "--and", "C", "--and", "."],
"one/two/C.Foo2",
);
}
#[test]
fn test_and_plus_ignore_case() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["Foo", "--ignore-case", "--and", "C", "--and", "[.]"],
"one/two/C.Foo2
one/two/c.foo",
);
}
#[test]
fn test_and_plus_case_sensitive() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&["foo", "--case-sensitive", "--and", "c", "--and", "[.]"],
"one/two/c.foo",
);
}
#[test]
fn test_and_plus_full_path() {
let te = TestEnv::new(DEFAULT_DIRS, AND_EXTRA_FILES);
te.assert_output(
&[
"three",
"--full-path",
"--and",
"_foo",
"--and",
r"[/\\]dir",
],
"one/two/three/directory_foo/",
);
te.assert_output(
&[
"three",
"--full-path",
"--and",
r"[/\\]two",
"--and",
r"[/\\]dir",
],
"one/two/three/directory_foo/",
);
}
/// Test each pattern type with an empty pattern.
#[test]
fn test_empty_pattern() {
@@ -382,10 +596,7 @@ fn test_full_path() {
let prefix = escape(&root.to_string_lossy());
te.assert_output(
&[
"--full-path",
&format!("^{prefix}.*three.*foo$", prefix = prefix),
],
&["--full-path", &format!("^{prefix}.*three.*foo$")],
"one/two/three/d.foo
one/two/three/directory_foo/",
);
@@ -597,6 +808,62 @@ fn test_custom_ignore_precedence() {
te.assert_output(&["--no-ignore", "foo"], "inner/foo");
}
/// Don't require git to respect gitignore (--no-require-git)
#[test]
fn test_respect_ignore_files() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
// Not in a git repo anymore
fs::remove_dir(te.test_root().join(".git")).unwrap();
// don't respect gitignore because we're not in a git repo
te.assert_output(
&["foo"],
"a.foo
gitignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/",
);
// respect gitignore because we set `--no-require-git`
te.assert_output(
&["--no-require-git", "foo"],
"a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/",
);
// make sure overriding works
te.assert_output(
&["--no-require-git", "--require-git", "foo"],
"a.foo
gitignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/",
);
te.assert_output(
&["--no-require-git", "--no-ignore", "foo"],
"a.foo
gitignored.foo
fdignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/",
);
}
/// VCS ignored files (--no-ignore-vcs)
#[test]
fn test_no_ignore_vcs() {
@@ -668,6 +935,47 @@ fn test_no_ignore_aliases() {
);
}
#[cfg(not(windows))]
#[test]
fn test_global_ignore() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES).global_ignore_file("one");
te.assert_output(
&[],
"a.foo
e1 e2
symlink",
);
}
#[cfg(not(windows))]
#[test_case("--unrestricted", ".hidden.foo
a.foo
fdignored.foo
gitignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/"; "unrestricted")]
#[test_case("--no-ignore", "a.foo
fdignored.foo
gitignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/"; "no-ignore")]
#[test_case("--no-global-ignore-file", "a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo/"; "no-global-ignore-file")]
fn test_no_global_ignore(flag: &str, expected_output: &str) {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES).global_ignore_file("one");
te.assert_output(&[flag, "foo"], expected_output);
}
/// Symlinks (--follow)
#[test]
fn test_follow() {
@@ -991,15 +1299,31 @@ fn test_type() {
fn test_type_executable() {
use std::os::unix::fs::OpenOptionsExt;
// This test assumes the current user isn't root
// (otherwise if the executable bit is set for any level, it is executable for the current
// user)
if Uid::current().is_root() {
return;
}
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
fs::OpenOptions::new()
.create(true)
.create_new(true)
.truncate(true)
.write(true)
.mode(0o777)
.open(te.test_root().join("executable-file.sh"))
.unwrap();
fs::OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.mode(0o645)
.open(te.test_root().join("not-user-executable-file.sh"))
.unwrap();
te.assert_output(&["--type", "executable"], "executable-file.sh");
te.assert_output(
@@ -1192,7 +1516,7 @@ fn test_symlink_as_absolute_root() {
let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES);
te.assert_output(
&["", &format!("{abs_path}/symlink", abs_path = abs_path)],
&["", &format!("{abs_path}/symlink")],
&format!(
"{abs_path}/symlink/c.foo
{abs_path}/symlink/C.Foo2
@@ -1217,7 +1541,7 @@ fn test_symlink_and_full_path() {
&[
"--absolute-path",
"--full-path",
&format!("^{prefix}.*three", prefix = prefix),
&format!("^{prefix}.*three"),
],
&format!(
"{abs_path}/{expected_path}/three/
@@ -1237,8 +1561,8 @@ fn test_symlink_and_full_path_abs_path() {
te.assert_output(
&[
"--full-path",
&format!("^{prefix}.*symlink.*three", prefix = prefix),
&format!("{abs_path}/symlink", abs_path = abs_path),
&format!("^{prefix}.*symlink.*three"),
&format!("{abs_path}/symlink"),
],
&format!(
"{abs_path}/symlink/three/
@@ -1298,6 +1622,66 @@ fn test_excludes() {
);
}
#[test]
fn format() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
te.assert_output(
&["--format", "path={}", "--path-separator=/"],
"path=a.foo
path=e1 e2
path=one
path=one/b.foo
path=one/two
path=one/two/C.Foo2
path=one/two/c.foo
path=one/two/three
path=one/two/three/d.foo
path=one/two/three/directory_foo
path=symlink",
);
te.assert_output(
&["foo", "--format", "noExt={.}", "--path-separator=/"],
"noExt=a
noExt=one/b
noExt=one/two/C
noExt=one/two/c
noExt=one/two/three/d
noExt=one/two/three/directory_foo",
);
te.assert_output(
&["foo", "--format", "basename={/}", "--path-separator=/"],
"basename=a.foo
basename=b.foo
basename=C.Foo2
basename=c.foo
basename=d.foo
basename=directory_foo",
);
te.assert_output(
&["foo", "--format", "name={/.}", "--path-separator=/"],
"name=a
name=b
name=C
name=c
name=d
name=directory_foo",
);
te.assert_output(
&["foo", "--format", "parent={//}", "--path-separator=/"],
"parent=.
parent=one
parent=one/two
parent=one/two
parent=one/two/three
parent=one/two/three",
);
}
/// Shell script execution (--exec)
#[test]
fn test_exec() {
@@ -1483,18 +1867,26 @@ fn test_exec_batch() {
\n\
Usage: fd [OPTIONS] [pattern] [path]...\n\
\n\
For more information try '--help'\n\
For more information, try '--help'.\n\
",
);
te.assert_failure_with_error(
&["foo", "--exec-batch", "echo", "{/}", ";", "-x", "echo"],
"error: The argument '--exec-batch <cmd>...' cannot be used with '--exec <cmd>...'",
"error: the argument '--exec-batch <cmd>...' cannot be used with '--exec <cmd>...'\n\
\n\
Usage: fd --exec-batch <cmd>... <pattern> [path]...\n\
\n\
For more information, try '--help'.\n\
",
);
te.assert_failure_with_error(
&["foo", "--exec-batch"],
"error: The argument '--exec-batch <cmd>...' requires a value but none was supplied",
"error: a value is required for '--exec-batch <cmd>...' but none was supplied\n\
\n\
For more information, try '--help'.\n\
",
);
te.assert_failure_with_error(
@@ -1503,7 +1895,7 @@ fn test_exec_batch() {
\n\
Usage: fd [OPTIONS] [pattern] [path]...\n\
\n\
For more information try '--help'\n\
For more information, try '--help'.\n\
",
);
@@ -1897,7 +2289,10 @@ fn test_modified_relative() {
#[cfg(test)]
fn change_file_modified<P: AsRef<Path>>(path: P, iso_date: &str) {
let st = humantime::parse_rfc3339(iso_date).expect("invalid date");
let st = iso_date
.parse::<Timestamp>()
.map(SystemTime::from)
.expect("invalid date");
let ft = filetime::FileTime::from_system_time(st);
filetime::set_file_times(path, ft, ft).expect("time modification failde");
}
@@ -1919,6 +2314,50 @@ fn test_modified_absolute() {
);
}
#[cfg(unix)]
#[test]
fn test_owner_ignore_all() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
te.assert_output(&["--owner", ":", "a.foo"], "a.foo");
te.assert_output(&["--owner", "", "a.foo"], "a.foo");
}
#[cfg(unix)]
#[test]
fn test_owner_current_user() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
let uid = Uid::current();
te.assert_output(&["--owner", &uid.to_string(), "a.foo"], "a.foo");
if let Ok(Some(user)) = User::from_uid(uid) {
te.assert_output(&["--owner", &user.name, "a.foo"], "a.foo");
}
}
#[cfg(unix)]
#[test]
fn test_owner_current_group() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
let gid = Gid::current();
te.assert_output(&["--owner", &format!(":{gid}"), "a.foo"], "a.foo");
if let Ok(Some(group)) = Group::from_gid(gid) {
te.assert_output(&["--owner", &format!(":{}", group.name), "a.foo"], "a.foo");
}
}
#[cfg(target_os = "linux")]
#[test]
fn test_owner_root() {
// This test assumes the current user isn't root
if Uid::current().is_root() || Gid::current() == Gid::from_raw(0) {
return;
}
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
te.assert_output(&["--owner", "root", "a.foo"], "");
te.assert_output(&["--owner", "0", "a.foo"], "");
te.assert_output(&["--owner", ":root", "a.foo"], "");
te.assert_output(&["--owner", ":0", "a.foo"], "");
}
#[test]
fn test_custom_path_separator() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
@@ -2010,6 +2449,11 @@ fn test_max_results() {
};
assert_just_one_result_with_option("--max-results=1");
assert_just_one_result_with_option("-1");
// check that --max-results & -1 conflic with --exec
te.assert_failure(&["thing", "--max-results=0", "--exec=cat"]);
te.assert_failure(&["thing", "-1", "--exec=cat"]);
te.assert_failure(&["thing", "--max-results=1", "-1", "--exec=cat"]);
}
/// Filenames with non-utf8 paths are passed to the executed program unchanged
@@ -2066,6 +2510,14 @@ fn test_list_details() {
te.assert_success_and_get_output(".", &["--list-details"]);
}
#[test]
fn test_single_and_multithreaded_execution() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
te.assert_output(&["--threads=1", "a.foo"], "a.foo");
te.assert_output(&["--threads=16", "a.foo"], "a.foo");
}
/// Make sure that fd fails if numeric arguments can not be parsed
#[test]
fn test_number_parsing_errors() {
@@ -2076,6 +2528,7 @@ fn test_number_parsing_errors() {
te.assert_failure(&["--threads=0"]);
te.assert_failure(&["--min-depth=a"]);
te.assert_failure(&["--mindepth=a"]);
te.assert_failure(&["--max-depth=a"]);
te.assert_failure(&["--maxdepth=a"]);
te.assert_failure(&["--exact-depth=a"]);
@@ -2088,6 +2541,7 @@ fn test_number_parsing_errors() {
#[test_case("--hidden", &["--no-hidden"] ; "hidden")]
#[test_case("--no-ignore", &["--ignore"] ; "no-ignore")]
#[test_case("--no-ignore-vcs", &["--ignore-vcs"] ; "no-ignore-vcs")]
#[test_case("--no-require-git", &["--require-git"] ; "no-require-git")]
#[test_case("--follow", &["--no-follow"] ; "follow")]
#[test_case("--absolute-path", &["--relative-path"] ; "absolute-path")]
#[test_case("-u", &["--ignore", "--no-hidden"] ; "u")]
@@ -2156,13 +2610,85 @@ fn test_invalid_cwd() {
std::env::set_current_dir(&root).unwrap();
fs::remove_dir(&root).unwrap();
let output = std::process::Command::new(&te.test_exe())
let output = std::process::Command::new(te.test_exe())
.arg("query")
.arg(te.test_root())
.output()
.unwrap();
if !output.status.success() {
panic!("{:?}", output);
panic!("{output:?}");
}
}
/// Test behavior of .git directory with various flags
#[test]
fn test_git_dir() {
let te = TestEnv::new(
&[".git/one", "other_dir/.git", "nested/dir/.git"],
&[
".git/one/foo.a",
".git/.foo",
".git/a.foo",
"other_dir/.git/foo1",
"nested/dir/.git/foo2",
],
);
te.assert_output(
&["--hidden", "foo"],
".git/one/foo.a
.git/.foo
.git/a.foo
other_dir/.git/foo1
nested/dir/.git/foo2",
);
te.assert_output(&["--no-ignore", "foo"], "");
te.assert_output(
&["--hidden", "--no-ignore", "foo"],
".git/one/foo.a
.git/.foo
.git/a.foo
other_dir/.git/foo1
nested/dir/.git/foo2",
);
te.assert_output(
&["--hidden", "--no-ignore-vcs", "foo"],
".git/one/foo.a
.git/.foo
.git/a.foo
other_dir/.git/foo1
nested/dir/.git/foo2",
);
}
#[test]
fn test_gitignore_parent() {
let te = TestEnv::new(&["sub"], &[".abc", "sub/.abc"]);
fs::File::create(te.test_root().join(".gitignore"))
.unwrap()
.write_all(b".abc\n")
.unwrap();
te.assert_output_subdirectory("sub", &["--hidden"], "");
te.assert_output_subdirectory("sub", &["--hidden", "--search-path", "."], "");
}
#[test]
fn test_hyperlink() {
let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
#[cfg(unix)]
let hostname = nix::unistd::gethostname().unwrap().into_string().unwrap();
#[cfg(not(unix))]
let hostname = "";
let expected = format!(
"\x1b]8;;file://{}{}/a.foo\x1b\\a.foo\x1b]8;;\x1b\\",
hostname,
get_absolute_root_path(&te),
);
te.assert_output(&["--hyperlink=always", "a.foo"], &expected);
}