Merge branch 'master' into pr/opposing-options

This commit is contained in:
Thayne McCombs 2021-08-11 01:44:51 -06:00
commit 8984e57dd6
10 changed files with 301 additions and 110 deletions

View File

@ -16,7 +16,7 @@ on:
jobs: jobs:
min_version: min_version:
name: Minimum supported rust version name: Minimum supported rust version
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -45,13 +45,13 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
job: job:
- { os: ubuntu-18.04, target: arm-unknown-linux-gnueabihf , use-cross: true } - { os: ubuntu-20.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
- { os: ubuntu-18.04, target: arm-unknown-linux-musleabihf, use-cross: true } - { os: ubuntu-20.04, target: arm-unknown-linux-musleabihf, use-cross: true }
- { os: ubuntu-18.04, target: aarch64-unknown-linux-gnu , use-cross: true } - { os: ubuntu-20.04, target: aarch64-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-18.04, target: i686-unknown-linux-gnu , use-cross: true } - { os: ubuntu-20.04, target: i686-unknown-linux-gnu , use-cross: true }
- { os: ubuntu-18.04, target: i686-unknown-linux-musl , use-cross: true } - { os: ubuntu-20.04, target: i686-unknown-linux-musl , use-cross: true }
- { os: ubuntu-18.04, target: x86_64-unknown-linux-gnu } - { os: ubuntu-20.04, target: x86_64-unknown-linux-gnu }
- { os: ubuntu-18.04, target: x86_64-unknown-linux-musl , use-cross: true } - { os: ubuntu-20.04, target: x86_64-unknown-linux-musl , use-cross: true }
- { os: macos-10.15 , target: x86_64-apple-darwin } - { os: macos-10.15 , 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-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
- { os: windows-2019, target: i686-pc-windows-msvc } - { os: windows-2019, target: i686-pc-windows-msvc }

View File

@ -10,6 +10,8 @@
- fd cannot search files under a RAM disk, see #752 - fd cannot search files under a RAM disk, see #752
- fd doesn't show substituted drive on Windows, see #365 - fd doesn't show substituted drive on Windows, see #365
- Properly handle write errors to devices that are full, see #737 - Properly handle write errors to devices that are full, see #737
- Use local time zone for time functions (`--change-newer-than`, `--change-older-than`), see #631 (@jacobmischka)
- Support `--list-details` on more platforms (like BusyBox), see #783
## Changes ## Changes

219
Cargo.lock generated
View File

@ -31,9 +31,21 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.42" version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]] [[package]]
name = "atty" name = "atty"
@ -48,9 +60,15 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@ -59,19 +77,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]] [[package]]
name = "bstr" name = "blake2b_simd"
version = "0.2.14" version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "bstr"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.66" version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" checksum = "404b1fe4f65288577753b17e3b36a04596ee784493ec249bf81c7f2d2acd751c"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -86,10 +115,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "chrono"
version = "2.33.3" version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "clap"
version = "2.33.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
dependencies = [ dependencies = [
"ansi_term 0.11.0", "ansi_term 0.11.0",
"atty", "atty",
@ -102,21 +144,27 @@ dependencies = [
] ]
[[package]] [[package]]
name = "crossbeam-utils" name = "constant_time_eq"
version = "0.8.1" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"cfg-if 1.0.0", "cfg-if 0.1.10",
"lazy_static", "lazy_static",
] ]
[[package]] [[package]]
name = "ctrlc" name = "ctrlc"
version = "3.1.9" version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a" checksum = "7a4ba686dff9fa4c1c9636ce1010b0cf98ceb421361b0bb3d6faeec43bd217a7"
dependencies = [ dependencies = [
"nix", "nix",
"winapi", "winapi",
@ -140,9 +188,9 @@ dependencies = [
[[package]] [[package]]
name = "dirs-sys-next" name = "dirs-sys-next"
version = "0.1.1" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99de365f605554ae33f115102a02057d4fc18b01f3284d6870be0938743cfe7d" checksum = "9c60f7b8a8953926148223260454befb50c751d3c50e1c178c4fd1ace4083c9a"
dependencies = [ dependencies = [
"libc", "libc",
"redox_users", "redox_users",
@ -156,6 +204,7 @@ dependencies = [
"ansi_term 0.12.1", "ansi_term 0.12.1",
"anyhow", "anyhow",
"atty", "atty",
"chrono",
"clap", "clap",
"ctrlc", "ctrlc",
"diff", "diff",
@ -198,9 +247,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "fs_extra" name = "fs_extra"
version = "1.2.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
[[package]] [[package]]
name = "fuchsia-cprng" name = "fuchsia-cprng"
@ -210,20 +259,20 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.1.15" version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
"libc", "libc",
"wasi", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]] [[package]]
name = "globset" name = "globset"
version = "0.4.8" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"bstr", "bstr",
@ -234,24 +283,24 @@ dependencies = [
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.17" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "humantime" name = "humantime"
version = "2.0.1" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" checksum = "b9b6c53306532d3c8e8087b44e6580e10db51a023cf9b433cea2ac38066b92da"
[[package]] [[package]]
name = "ignore" name = "ignore"
version = "0.4.17" version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" checksum = "128b9e89d15a3faa642ee164c998fd4fae3d89d054463cddb2c25a7baad3a352"
dependencies = [ dependencies = [
"crossbeam-utils", "crossbeam-utils",
"globset", "globset",
@ -294,24 +343,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.98" version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.11" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
] ]
[[package]] [[package]]
name = "lscolors" name = "lscolors"
version = "0.7.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d24b894c45c9da468621cdd615a5a79ee5e5523dd4f75c76ebc03d458940c16e" checksum = "1f77452267149eac960ded529fe5f5460ddf792845a1d71b5d0cfcee5642e47e"
dependencies = [ dependencies = [
"ansi_term 0.12.1", "ansi_term 0.12.1",
] ]
@ -324,14 +373,15 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.20.0" version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 0.1.10",
"libc", "libc",
"void",
] ]
[[package]] [[package]]
@ -343,6 +393,25 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "num-integer"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.13.0" version = "1.13.0"
@ -410,9 +479,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.57" version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
@ -425,12 +494,13 @@ dependencies = [
[[package]] [[package]]
name = "redox_users" name = "redox_users"
version = "0.3.5" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"redox_syscall 0.1.57", "redox_syscall 0.1.56",
"rust-argon2",
] ]
[[package]] [[package]]
@ -452,13 +522,25 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
dependencies = [ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@ -538,10 +620,21 @@ dependencies = [
] ]
[[package]] [[package]]
name = "unicode-width" name = "time"
version = "0.1.8" version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
@ -567,9 +660,15 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.3" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
@ -589,10 +688,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]] [[package]]
name = "winapi" name = "wasi"
version = "0.3.9" version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu",

View File

@ -48,6 +48,7 @@ globset = "0.4"
anyhow = "1.0" anyhow = "1.0"
dirs-next = "2.0" dirs-next = "2.0"
normpath = "0.3" normpath = "0.3"
chrono = "0.4"
[dependencies.clap] [dependencies.clap]
version = "2.31.2" version = "2.31.2"

View File

@ -115,6 +115,15 @@ src/lscolors/mod.rs
tests/testenv/mod.rs tests/testenv/mod.rs
``` ```
### Searching for a particular file name
To find files with exactly the provided search pattern, use the `-g` (or `--glob`) option:
``` bash
> fd -g libc.so /usr
/usr/lib32/libc.so
/usr/lib/libc.so
```
### Hidden and ignored files ### Hidden and ignored files
By default, *fd* does not search hidden directories and does not show hidden files in the By default, *fd* does not search hidden directories and does not show hidden files in the
search results. To disable this behavior, we can use the `-H` (or `--hidden`) option: search results. To disable this behavior, we can use the `-H` (or `--hidden`) option:
@ -136,6 +145,15 @@ target/debug/deps/libnum_cpus-f5ce7ef99006aa05.rlib
To really search *all* files and directories, simply combine the hidden and ignore features to show To really search *all* files and directories, simply combine the hidden and ignore features to show
everything (`-HI`). everything (`-HI`).
### Matching the full path
By default, *fd* only matches the filename of each file. However, using the `--full-path` or `-p` option,
you can match against the full path.
```bash
> fd -p -g '**/.git/config'
> fd -p '.*/lesson-\d+/[a-z]+.(jpg|png)'
```
### Command execution ### Command execution
Instead of just showing the search results, you often want to *do something* with them. `fd` Instead of just showing the search results, you often want to *do something* with them. `fd`
@ -623,6 +641,8 @@ cargo install fd-find
``` ```
Note that rust version *1.42.0* or later is required. Note that rust version *1.42.0* or later is required.
`make` is also needed for the build.
### From binaries ### From binaries
The [release page](https://github.com/sharkdp/fd/releases) includes precompiled binaries for Linux, macOS and Windows. Statically-linked binaries are also available: look for archives with `musl` in the file name. The [release page](https://github.com/sharkdp/fd/releases) includes precompiled binaries for Linux, macOS and Windows. Statically-linked binaries are also available: look for archives with `musl` in the file name.
@ -647,6 +667,7 @@ cargo install --path .
- [sharkdp](https://github.com/sharkdp) - [sharkdp](https://github.com/sharkdp)
- [tmccombs](https://github.com/tmccombs) - [tmccombs](https://github.com/tmccombs)
- [tavianator](https://github.com/tavianator) - [tavianator](https://github.com/tavianator)
- [pemistahl](https://github.com/pemistahl/)
## License ## License

15
doc/fd.1 vendored
View File

@ -55,6 +55,7 @@ pattern contains an uppercase character (smart case).
.TP .TP
.B \-g, \-\-glob .B \-g, \-\-glob
Perform a glob-based search instead of a regular expression search. Perform a glob-based search instead of a regular expression search.
If combined with the '\-\-full-path' option, '**' can be used to match multiple path components.
.TP .TP
.B \-\-regex .B \-\-regex
Perform a regular-expression based search (default). This can be used to override --glob. Perform a regular-expression based search (default). This can be used to override --glob.
@ -216,8 +217,11 @@ tebibytes
.RE .RE
.TP .TP
.BI "\-\-changed-within " date|duration .BI "\-\-changed-within " date|duration
Filter results based on the file modification time. The argument can be provided as a specific Filter results based on the file modification time.
point in time (\fIYYYY-MM-DD HH:MM:SS\fR) or as a duration (\fI10h, 1d, 35min\fR). Files with modification times greater than or equal to 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 .B --change-newer-than
can be used as an alias. can be used as an alias.
@ -226,8 +230,11 @@ Examples:
\-\-change-newer-than "2018-10-27 10:00:00" \-\-change-newer-than "2018-10-27 10:00:00"
.TP .TP
.BI "\-\-changed-before " date|duration .BI "\-\-changed-before " date|duration
Filter results based on the file modification time. The argument can be provided as a specific Filter results based on the file modification time.
point in time (\fIYYYY-MM-DD HH:MM:SS\fR) or as a duration (\fI10h, 1d, 35min\fR). Files with modification times less than or equal to 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-older-than .B --change-older-than
can be used as an alias. can be used as an alias.

View File

@ -1,3 +1,6 @@
use crate::filesystem;
use crate::walk;
/// Whether or not to show /// Whether or not to show
pub struct FileTypes { pub struct FileTypes {
pub files: bool, pub files: bool,
@ -22,3 +25,28 @@ impl Default for FileTypes {
} }
} }
} }
impl FileTypes {
pub fn should_ignore(&self, entry: &walk::DirEntry) -> bool {
if let Some(ref entry_type) = entry.file_type() {
(!self.files && entry_type.is_file())
|| (!self.directories && entry_type.is_dir())
|| (!self.symlinks && entry_type.is_symlink())
|| (!self.sockets && filesystem::is_socket(*entry_type))
|| (!self.pipes && filesystem::is_pipe(*entry_type))
|| (self.executables_only
&& !entry
.metadata()
.map(|m| filesystem::is_executable(&m))
.unwrap_or(false))
|| (self.empty_only && !filesystem::is_empty(&entry))
|| !(entry_type.is_file()
|| entry_type.is_dir()
|| entry_type.is_symlink()
|| filesystem::is_socket(*entry_type)
|| filesystem::is_pipe(*entry_type))
} else {
true
}
}
}

View File

@ -1,3 +1,5 @@
use chrono::{offset::TimeZone, DateTime, Local, NaiveDate};
use std::time::SystemTime; use std::time::SystemTime;
/// Filter based on time ranges. /// Filter based on time ranges.
@ -11,9 +13,20 @@ impl TimeFilter {
fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> { fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> {
humantime::parse_duration(s) humantime::parse_duration(s)
.map(|duration| *ref_time - duration) .map(|duration| *ref_time - duration)
.or_else(|_| humantime::parse_rfc3339_weak(s))
.or_else(|_| humantime::parse_rfc3339_weak(&(s.to_owned() + " 00:00:00")))
.ok() .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())
})
} }
pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> { pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
@ -39,7 +52,11 @@ mod tests {
#[test] #[test]
fn is_time_filter_applicable() { fn is_time_filter_applicable() {
let ref_time = humantime::parse_rfc3339("2010-10-10T10:10:10Z").unwrap(); let ref_time = Local
.datetime_from_str("2010-10-10 10:10:10", "%F %T")
.unwrap()
.into();
assert!(TimeFilter::after(&ref_time, "1min") assert!(TimeFilter::after(&ref_time, "1min")
.unwrap() .unwrap()
.applies_to(&ref_time)); .applies_to(&ref_time));
@ -76,5 +93,39 @@ mod tests {
assert!(!TimeFilter::after(&ref_time, t10s_before) assert!(!TimeFilter::after(&ref_time, t10s_before)
.unwrap() .unwrap()
.applies_to(&t1m_ago)); .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::after(&ref_time, same_day)
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::after(&ref_time, same_day)
.unwrap()
.applies_to(&t1m_ago));
let ref_time = DateTime::parse_from_rfc3339("2010-10-10T10:10:10+00:00")
.unwrap()
.into();
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)
.unwrap()
.applies_to(&ref_time));
assert!(TimeFilter::before(&ref_time, t10s_before)
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.applies_to(&ref_time));
assert!(!TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.applies_to(&t1m_ago));
} }
} }

View File

@ -210,11 +210,13 @@ fn run() -> Result<ExitCode> {
#[allow(unused)] #[allow(unused)]
let gnu_ls = |command_name| { let gnu_ls = |command_name| {
// Note: we use short options here (instead of --long-options) to support more
// platforms (like BusyBox).
vec![ vec![
command_name, command_name,
"-l", // long listing format "-l", // long listing format
"--human-readable", // human readable file sizes "-h", // human readable file sizes
"--directory", // list directories themselves, not their contents "-d", // list directories themselves, not their contents
&color_arg, &color_arg,
] ]
}; };

View File

@ -358,27 +358,21 @@ fn spawn_senders(
DirEntry::BrokenSymlink(path) DirEntry::BrokenSymlink(path)
} }
_ => { _ => {
match tx_thread.send(WorkerResult::Error(ignore::Error::WithPath { return match tx_thread.send(WorkerResult::Error(ignore::Error::WithPath {
path, path,
err: inner_err, err: inner_err,
})) { })) {
Ok(_) => { Ok(_) => ignore::WalkState::Continue,
return ignore::WalkState::Continue; Err(_) => ignore::WalkState::Quit,
}
Err(_) => {
return ignore::WalkState::Quit;
}
} }
} }
}, },
Err(err) => match tx_thread.send(WorkerResult::Error(err)) { Err(err) => {
Ok(_) => { return match tx_thread.send(WorkerResult::Error(err)) {
return ignore::WalkState::Continue; Ok(_) => ignore::WalkState::Continue,
Err(_) => ignore::WalkState::Quit,
} }
Err(_) => { }
return ignore::WalkState::Quit;
}
},
}; };
if let Some(min_depth) = config.min_depth { if let Some(min_depth) = config.min_depth {
@ -422,27 +416,7 @@ fn spawn_senders(
// Filter out unwanted file types. // Filter out unwanted file types.
if let Some(ref file_types) = config.file_types { if let Some(ref file_types) = config.file_types {
if let Some(ref entry_type) = entry.file_type() { if file_types.should_ignore(&entry) {
if (!file_types.files && entry_type.is_file())
|| (!file_types.directories && entry_type.is_dir())
|| (!file_types.symlinks && entry_type.is_symlink())
|| (!file_types.sockets && filesystem::is_socket(*entry_type))
|| (!file_types.pipes && filesystem::is_pipe(*entry_type))
|| (file_types.executables_only
&& !entry
.metadata()
.map(|m| filesystem::is_executable(&m))
.unwrap_or(false))
|| (file_types.empty_only && !filesystem::is_empty(&entry))
|| !(entry_type.is_file()
|| entry_type.is_dir()
|| entry_type.is_symlink()
|| filesystem::is_socket(*entry_type)
|| filesystem::is_pipe(*entry_type))
{
return ignore::WalkState::Continue;
}
} else {
return ignore::WalkState::Continue; return ignore::WalkState::Continue;
} }
} }