From 6ce55624f7155a3ed68d885cb8fa4ba33f14cb7c Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Mon, 2 Aug 2021 10:34:11 +0200 Subject: [PATCH 01/22] Add dependabot config for cargo updates --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..564713e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + From 148fa64a731dad45296abbdba24c07fc26af402a Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Tue, 3 Aug 2021 08:39:23 +0200 Subject: [PATCH 02/22] Change dependabot interval to monthly --- .github/dependabot.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 564713e..2cebf5b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,5 +3,4 @@ updates: - package-ecosystem: "cargo" directory: "/" schedule: - interval: "weekly" - + interval: "monthly" From b80764b19a5a8bbebd793a2db5d71801e55e5951 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:16:05 +0000 Subject: [PATCH 03/22] Bump regex from 1.4.2 to 1.4.6 Bumps [regex](https://github.com/rust-lang/regex) from 1.4.2 to 1.4.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.4.2...1.4.6) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 9 ++++----- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa3c14d..5cc5499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,21 +395,20 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.21" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remove_dir_all" diff --git a/Cargo.toml b/Cargo.toml index c3e4ccc..ae8df8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ atty = "0.2" ignore = "0.4.3" lazy_static = "1.1.0" num_cpus = "1.8" -regex = "1.0.0" +regex = "1.4.6" regex-syntax = "0.6" ctrlc = "3.1" humantime = "2.0" From 252beb8df799339ef678b46988feac56bf4e3b0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:16:09 +0000 Subject: [PATCH 04/22] Bump libc from 0.2.80 to 0.2.98 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.80 to 0.2.98. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.80...0.2.98) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cc5499..fd7891b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,9 +290,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "log" From ca92bea0d7e0e9ffae563ce013931d8deeb07848 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:16:12 +0000 Subject: [PATCH 05/22] Bump version_check from 0.9.2 to 0.9.3 Bumps [version_check](https://github.com/SergioBenitez/version_check) from 0.9.2 to 0.9.3. - [Release notes](https://github.com/SergioBenitez/version_check/releases) - [Commits](https://github.com/SergioBenitez/version_check/compare/v0.9.2...v0.9.3) --- updated-dependencies: - dependency-name: version_check dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd7891b..2791ed4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -497,9 +497,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "walkdir" From 04829c287d6aeb2bc988b28468984d7a7a6a3e33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:16:12 +0000 Subject: [PATCH 06/22] Bump anyhow from 1.0.35 to 1.0.42 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.35 to 1.0.42. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.35...1.0.42) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2791ed4..9861d90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.35" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "atty" From ad1b26760195efcb718b0eb05018740fc0af24e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:28:20 +0000 Subject: [PATCH 07/22] Bump filetime from 0.2.13 to 0.2.14 Bumps [filetime](https://github.com/alexcrichton/filetime) from 0.2.13 to 0.2.14. - [Release notes](https://github.com/alexcrichton/filetime/releases) - [Commits](https://github.com/alexcrichton/filetime/compare/0.2.13...0.2.14) --- updated-dependencies: - dependency-name: filetime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 17 +++++++++++++---- Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9861d90..8e7b41e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -176,13 +176,13 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe" +checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.10", "winapi", ] @@ -383,6 +383,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.3.5" @@ -390,7 +399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.1.57", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ae8df8b..4c44292 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ jemallocator = "0.3.0" [dev-dependencies] diff = "0.1" tempdir = "0.3" -filetime = "0.2.1" +filetime = "0.2.14" [profile.release] lto = true From 8b0db189a139bc9ff84e4391b2afb12628024634 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:28:23 +0000 Subject: [PATCH 08/22] Bump ctrlc from 3.1.7 to 3.1.9 Bumps [ctrlc](https://github.com/Detegr/rust-ctrlc) from 3.1.7 to 3.1.9. - [Release notes](https://github.com/Detegr/rust-ctrlc/releases) - [Commits](https://github.com/Detegr/rust-ctrlc/compare/3.1.7...3.1.9) --- updated-dependencies: - dependency-name: ctrlc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e7b41e..a004bf5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,9 +112,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.1.7" +version = "3.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57a92e9749e10f25a171adcebfafe72991d45e7ec2dcb853e8f83d9dafaeb08" +checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a" dependencies = [ "nix", "winapi", @@ -320,13 +320,13 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "nix" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", ] From 70850629e97c7fddca3ba45af83748fb567f61c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:43:40 +0000 Subject: [PATCH 09/22] Bump globset from 0.4.6 to 0.4.8 Bumps [globset](https://github.com/BurntSushi/ripgrep) from 0.4.6 to 0.4.8. - [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.6...globset-0.4.8) --- updated-dependencies: - dependency-name: globset dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a004bf5..d4d0507 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "globset" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", From ab81cad3b5f4a2c1b2adeeb74970351786f3a93e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Aug 2021 09:43:43 +0000 Subject: [PATCH 10/22] Bump regex from 1.4.6 to 1.5.4 Bumps [regex](https://github.com/rust-lang/regex) from 1.4.6 to 1.5.4. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.4.6...1.5.4) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4d0507..6dcf882 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "nix" @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.6" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 4c44292..7c93224 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ atty = "0.2" ignore = "0.4.3" lazy_static = "1.1.0" num_cpus = "1.8" -regex = "1.4.6" +regex = "1.5.4" regex-syntax = "0.6" ctrlc = "3.1" humantime = "2.0" From 693325bcf272844ad5c8762a1768ae10eac178af Mon Sep 17 00:00:00 2001 From: Kaleb Olson Date: Wed, 30 Jun 2021 16:31:56 -0600 Subject: [PATCH 11/22] Adds path separator checking and hint for automatic `/` expansion for some windows shells, eg., msys --- src/main.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main.rs b/src/main.rs index 4b5f71c..1ba2275 100644 --- a/src/main.rs +++ b/src/main.rs @@ -176,6 +176,18 @@ fn run() -> Result { let path_separator = matches .value_of("path-separator") .map_or_else(filesystem::default_path_separator, |s| Some(s.to_owned())); + if let Some(sep) = path_separator.clone() { + if sep.len() > 1 { + return Err(anyhow!( + "A path separator must be exactly one byte, but \ + the given separator is {} bytes: {}\n\ + In some shells on Windows '/' is automatically \ + expanded. Use '//' instead.", + sep.len(), + sep + )); + }; + }; let ls_colors = if colored_output { Some(LsColors::from_env().unwrap_or_else(|| LsColors::from_string(DEFAULT_LS_COLORS))) From a0ca460901897037da015f4b4246dc303e5ce3b4 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 12:02:28 +0200 Subject: [PATCH 12/22] Adjust error message --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1ba2275..e282eb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -180,9 +180,9 @@ fn run() -> Result { if sep.len() > 1 { return Err(anyhow!( "A path separator must be exactly one byte, but \ - the given separator is {} bytes: {}\n\ - In some shells on Windows '/' is automatically \ - expanded. Use '//' instead.", + the given separator is {} bytes: '{}'.\n\ + In some shells on Windows, '/' is automatically \ + expanded. Try to use '//' instead.", sep.len(), sep )); From 515e0ee4693812626b70f95f1ca4e88cdaefd10a Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 12:02:34 +0200 Subject: [PATCH 13/22] Do not use .clone() --- src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index e282eb6..dae2aa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -176,7 +176,8 @@ fn run() -> Result { let path_separator = matches .value_of("path-separator") .map_or_else(filesystem::default_path_separator, |s| Some(s.to_owned())); - if let Some(sep) = path_separator.clone() { + + if let Some(ref sep) = path_separator { if sep.len() > 1 { return Err(anyhow!( "A path separator must be exactly one byte, but \ From d9697d14867c59dad487bb202c23840a430a6bb0 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 12:02:57 +0200 Subject: [PATCH 14/22] Make the path-separator check Windows-only --- src/main.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index dae2aa7..8a315a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -177,18 +177,21 @@ fn run() -> Result { .value_of("path-separator") .map_or_else(filesystem::default_path_separator, |s| Some(s.to_owned())); - if let Some(ref sep) = path_separator { - if sep.len() > 1 { - return Err(anyhow!( - "A path separator must be exactly one byte, but \ + #[cfg(windows)] + { + if let Some(ref sep) = path_separator { + if sep.len() > 1 { + return Err(anyhow!( + "A path separator must be exactly one byte, but \ the given separator is {} bytes: '{}'.\n\ In some shells on Windows, '/' is automatically \ expanded. Try to use '//' instead.", - sep.len(), - sep - )); + sep.len(), + sep + )); + }; }; - }; + } let ls_colors = if colored_output { Some(LsColors::from_env().unwrap_or_else(|| LsColors::from_string(DEFAULT_LS_COLORS))) From b507449146be2fb113ab117f05ed46ccd2fcb94f Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 13:02:52 +0200 Subject: [PATCH 15/22] Handle IO errors based on type, closes #737 --- src/output.rs | 12 +++++++++--- tests/tests.rs | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/output.rs b/src/output.rs index 5705087..471b8fb 100644 --- a/src/output.rs +++ b/src/output.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use lscolors::{LsColors, Style}; +use crate::error::print_error; use crate::exit_codes::ExitCode; use crate::filesystem::strip_current_dir; use crate::options::Options; @@ -33,9 +34,14 @@ pub fn print_entry( print_entry_uncolorized(stdout, path, config) }; - if r.is_err() { - // Probably a broken pipe. Exit gracefully. - process::exit(ExitCode::GeneralError.into()); + 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'). + process::exit(0); + } else { + print_error(format!("Could not write to output: {}", e)); + process::exit(ExitCode::GeneralError.into()); + } } } diff --git a/tests/tests.rs b/tests/tests.rs index 056a064..783420a 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1663,7 +1663,7 @@ fn test_base_directory() { let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES); let abs_base_dir = &format!("{abs_path}/one/two", abs_path = &abs_path); te.assert_output( - &["--base-directory", &abs_base_dir, "foo", &abs_path], + &["--base-directory", abs_base_dir, "foo", &abs_path], &format!( "{abs_path}/a.foo {abs_path}/one/b.foo From 6e44828cc8d1dc9691079cd38ac50d0bb3019762 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 13:13:58 +0200 Subject: [PATCH 16/22] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b037a..13ed333 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## Bugfixes - Set default path separator to `/` in MSYS, see #537 and #730 (@aswild) +- Properly handle write errors to devices that are full, see #737 ## Changes From 2d398dc4a7849d6074b166482548195c187b46f7 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 13:24:56 +0200 Subject: [PATCH 17/22] Fix directory-existence check on Windows This fixes a bug on Windows where `fd` could not be used on ram disks and encrypted folders. closes #752 --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 1 + src/filesystem.rs | 10 ++++++---- src/main.rs | 8 ++++---- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6dcf882..dede4b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.18" @@ -166,6 +168,7 @@ dependencies = [ "lazy_static", "libc", "lscolors", + "normpath", "num_cpus", "regex", "regex-syntax", @@ -330,6 +333,15 @@ dependencies = [ "libc", ] +[[package]] +name = "normpath" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e6e8f70e9fbbe3752d330d769e3424f24b9458ce266df93a3b456902fd696a" +dependencies = [ + "winapi", +] + [[package]] name = "num_cpus" version = "1.13.0" diff --git a/Cargo.toml b/Cargo.toml index 7c93224..a4d479d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ lscolors = "0.7" globset = "0.4" anyhow = "1.0" dirs-next = "2.0" +normpath = "0.3" [dependencies.clap] version = "2.31.2" diff --git a/src/filesystem.rs b/src/filesystem.rs index 19fc0e6..6680ae5 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -7,6 +7,8 @@ use std::io; use std::os::unix::fs::{FileTypeExt, PermissionsExt}; use std::path::{Path, PathBuf}; +use normpath::PathExt; + use crate::walk; pub fn path_absolute_form(path: &Path) -> io::Result { @@ -33,10 +35,10 @@ pub fn absolute_path(path: &Path) -> io::Result { Ok(path_buf) } -// Path::is_dir() is not guaranteed to be intuitively correct for "." and ".." -// See: https://github.com/rust-lang/rust/issues/45302 -pub fn is_dir(path: &Path) -> bool { - path.is_dir() && (path.file_name().is_some() || path.canonicalize().is_ok()) +pub fn is_existing_directory(path: &Path) -> bool { + // Note: we do not use `.exists()` here, as `.` always exists, even if + // the CWD has been deleted. + path.is_dir() && (path.file_name().is_some() || path.normalize().is_ok()) } #[cfg(any(unix, target_os = "redox"))] diff --git a/src/main.rs b/src/main.rs index 8a315a0..5221d95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,7 @@ fn run() -> Result { // Set the current working directory of the process if let Some(base_directory) = matches.value_of_os("base-directory") { let base_directory = Path::new(base_directory); - if !filesystem::is_dir(base_directory) { + if !filesystem::is_existing_directory(base_directory) { return Err(anyhow!( "The '--base-directory' path '{}' is not a directory.", base_directory.to_string_lossy() @@ -70,7 +70,7 @@ fn run() -> Result { } let current_directory = Path::new("."); - if !filesystem::is_dir(current_directory) { + if !filesystem::is_existing_directory(current_directory) { return Err(anyhow!( "Could not retrieve current directory (has it been deleted?)." )); @@ -95,7 +95,7 @@ fn run() -> Result { let mut directories = vec![]; for path in paths { let path_buffer = PathBuf::from(path); - if filesystem::is_dir(&path_buffer) { + if filesystem::is_existing_directory(&path_buffer) { directories.push(path_buffer); } else { print_error(format!( @@ -130,7 +130,7 @@ fn run() -> Result { // Detect if the user accidentally supplied a path instead of a search pattern if !matches.is_present("full-path") && pattern.contains(std::path::MAIN_SEPARATOR) - && filesystem::is_dir(Path::new(pattern)) + && Path::new(pattern).is_dir() { return Err(anyhow!( "The search pattern '{pattern}' contains a path-separation character ('{sep}') \ From aeff525c300481dc3eaa57cbbe1340cf798641d0 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 14:13:32 +0200 Subject: [PATCH 18/22] Attempt to fix #365 --- src/main.rs | 3 ++- tests/tests.rs | 30 +++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5221d95..8654688 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ use atty::Stream; use globset::GlobBuilder; use lscolors::LsColors; use regex::bytes::{RegexBuilder, RegexSetBuilder}; +use normpath::PathExt; use crate::error::print_error; use crate::exec::CommandTemplate; @@ -120,7 +121,7 @@ fn run() -> Result { .iter() .map(|path_buffer| { path_buffer - .canonicalize() + .normalize() .and_then(|pb| filesystem::absolute_path(pb.as_path())) .unwrap() }) diff --git a/tests/tests.rs b/tests/tests.rs index 783420a..7fe2c70 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -5,6 +5,7 @@ use std::io::Write; use std::path::Path; use std::time::{Duration, SystemTime}; +use normpath::PathExt; use regex::escape; use crate::testenv::TestEnv; @@ -26,8 +27,9 @@ static DEFAULT_FILES: &[&str] = &[ fn get_absolute_root_path(env: &TestEnv) -> String { let path = env .test_root() - .canonicalize() + .normalize() .expect("absolute path") + .as_path() .to_str() .expect("string") .to_string(); @@ -1090,16 +1092,19 @@ fn test_symlink_as_root() { fn test_symlink_and_absolute_path() { let (te, abs_path) = get_test_env_with_abs_path(DEFAULT_DIRS, DEFAULT_FILES); + let expected_path = if cfg!(windows) { "symlink" } else { "one/two" }; + te.assert_output_subdirectory( "symlink", &["--absolute-path"], &format!( - "{abs_path}/one/two/c.foo - {abs_path}/one/two/C.Foo2 - {abs_path}/one/two/three - {abs_path}/one/two/three/d.foo - {abs_path}/one/two/three/directory_foo", - abs_path = &abs_path + "{abs_path}/{expected_path}/c.foo + {abs_path}/{expected_path}/C.Foo2 + {abs_path}/{expected_path}/three + {abs_path}/{expected_path}/three/d.foo + {abs_path}/{expected_path}/three/directory_foo", + abs_path = &abs_path, + expected_path = expected_path ), ); } @@ -1127,6 +1132,8 @@ fn test_symlink_and_full_path() { let root = te.system_root(); let prefix = escape(&root.to_string_lossy()); + let expected_path = if cfg!(windows) { "symlink" } else { "one/two" }; + te.assert_output_subdirectory( "symlink", &[ @@ -1135,10 +1142,11 @@ fn test_symlink_and_full_path() { &format!("^{prefix}.*three", prefix = prefix), ], &format!( - "{abs_path}/one/two/three - {abs_path}/one/two/three/d.foo - {abs_path}/one/two/three/directory_foo", - abs_path = &abs_path + "{abs_path}/{expected_path}/three + {abs_path}/{expected_path}/three/d.foo + {abs_path}/{expected_path}/three/directory_foo", + abs_path = &abs_path, + expected_path = expected_path ), ); } From 018556a367e2a4534385575dbcf7e8ebd7f83aca Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 15:04:28 +0200 Subject: [PATCH 19/22] Add CHANGELOG entries --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13ed333..08e4e60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ## Bugfixes - Set default path separator to `/` in MSYS, see #537 and #730 (@aswild) +- fd cannot search files under a RAM disk, see #752 +- fd doesn't show substituted drive on Windows, see #365 - Properly handle write errors to devices that are full, see #737 ## Changes From b5344dac304b5938d8a41c91bf6c1e2dc00d8984 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 22:49:32 +0200 Subject: [PATCH 20/22] Improve -x/-X help text and man page description closes #605 --- doc/fd.1 | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/app.rs | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/doc/fd.1 b/doc/fd.1 index 7824987..bff3b0e 100644 --- a/doc/fd.1 +++ b/doc/fd.1 @@ -259,12 +259,22 @@ Provide paths to search as an alternative to the positional \fIpath\fR argument. \'fd [FLAGS/OPTIONS] \-\-search\-path PATH \-\-search\-path PATH2 [PATTERN]\' .TP .BI "\-x, \-\-exec " command +.RS Execute .I command -for each search result in parallel (use --threads=1 for sequential command execution). The following placeholders are substituted by a path derived from the current search result: +for each search result in parallel (use --threads=1 for sequential command execution). + +Note that all subsequent positional arguments are considered to be arguments to the +.I command +- not to fd. +It is therefore recommended to place the \-x/\-\-exec option last. Alternatively, you can supply +a ';' argument to end the argument list and continue with more fd options. +Most shells require ';' to be escaped: '\\;'. + +The following placeholders are substituted before the command is executed: .RS .IP {} -path +path (of the current search result) .IP {/} basename .IP {//} @@ -274,15 +284,33 @@ path without file extension .IP {/.} basename without file extension .RE + +If no placeholder is present, an implicit "{}" at the end is assumed. + +Examples: + + - find all *.zip files and unzip them: + + fd -e zip -x unzip + + - find *.h and *.cpp files and run "clang-format -i .." for each of them: + + fd -e h -e cpp -x clang-format -i + + - Convert all *.jpg files to *.png files: + + fd -e jpg -x convert {} {.}.png +.RE .TP .BI "\-X, \-\-exec-batch " command +.RS Execute .I command -with all search results at once. -A single occurence of the following placeholders is authorized and substituted by the paths derived from the search results before the command is executed: +once, with all search results as arguments. +One of the following placeholders is substituted before the command is executed: .RS .IP {} -path +path (of all search results) .IP {/} basename .IP {//} @@ -292,6 +320,22 @@ path without file extension .IP {/.} basename without file extension .RE + +If no placeholder is present, an implicit "{}" at the end is assumed. + +Examples: + + - Find all test_*.py files and open them in your favorite editor: + + fd -g 'test_*.py' -X vim + + Note that this executes a single "vim" process with all search results as arguments. + + - Find all *.rs files and count the lines with "wc -l ...": + + fd -e rs -X wc -l +.RE + .SH PATTERN SYNTAX The regular expression syntax used by fd is documented here: diff --git a/src/app.rs b/src/app.rs index 5781daa..2d6ec94 100644 --- a/src/app.rs +++ b/src/app.rs @@ -298,16 +298,24 @@ pub fn build_app() -> App<'static, 'static> { .conflicts_with("list-details") .help("Execute a command for each search result") .long_help( - "Execute a command for each search result in parallel (use --threads=1 for sequential command execution).\n\ - All arguments following --exec are taken to be arguments to the command until the \ - argument ';' is encountered.\n\ - Each occurrence of the following placeholders is substituted by a path derived from the \ - current search result before the command is executed:\n \ - '{}': path\n \ + "Execute a command for each search result in parallel (use --threads=1 for sequential command execution). \ + All positional arguments following --exec are considered to be arguments to the command - not to fd. \ + It is therefore recommended to place the '-x'/'--exec' option last.\n\ + The following placeholders are substituted before the command is executed:\n \ + '{}': path (of the current search result)\n \ '{/}': basename\n \ '{//}': parent directory\n \ '{.}': path without file extension\n \ - '{/.}': basename without file extension", + '{/.}': basename without file extension\n\n\ + If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\ + Examples:\n\n \ + - find all *.zip files and unzip them:\n\n \ + fd -e zip -x unzip\n\n \ + - find *.h and *.cpp files and run \"clang-format -i ..\" for each of them:\n\n \ + fd -e h -e cpp -x clang-format -i\n\n \ + - Convert all *.jpg files to *.png files:\n\n \ + fd -e jpg -x convert {} {.}.png\ + ", ), ) .arg( @@ -321,16 +329,20 @@ pub fn build_app() -> App<'static, 'static> { .conflicts_with_all(&["exec", "list-details"]) .help("Execute a command with all search results at once") .long_help( - "Execute a command with all search results at once.\n\ - All arguments following --exec-batch are taken to be arguments to the command until the \ - argument ';' is encountered.\n\ - A single occurrence of the following placeholders is authorized and substituted by the paths derived from the \ - search results before the command is executed:\n \ - '{}': path\n \ + "Execute the given command once, with all search results as arguments.\n\ + One of the following placeholders is substituted before the command is executed:\n \ + '{}': path (of all search results)\n \ '{/}': basename\n \ '{//}': parent directory\n \ '{.}': path without file extension\n \ - '{/.}': basename without file extension", + '{/.}': basename without file extension\n\n\ + If no placeholder is present, an implicit \"{}\" at the end is assumed.\n\n\ + Examples:\n\n \ + - Find all test_*.py files and open them in your favorite editor:\n\n \ + fd -g 'test_*.py' -X vim\n\n \ + - Find all *.rs files and count the lines with \"wc -l ...\":\n\n \ + fd -e rs -X wc -l\ + " ), ) .arg( From 224b7f2354d2c5c18719ec845fa958e13955679e Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 8 Aug 2021 23:32:13 +0200 Subject: [PATCH 21/22] Silence wrong clippy warning --- tests/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests.rs b/tests/tests.rs index 7fe2c70..0b6e6b5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -24,6 +24,7 @@ static DEFAULT_FILES: &[&str] = &[ "e1 e2", ]; +#[allow(clippy::let_and_return)] fn get_absolute_root_path(env: &TestEnv) -> String { let path = env .test_root() From c37592b0b7396d84db02182880b94828572b9ed5 Mon Sep 17 00:00:00 2001 From: David Peter Date: Mon, 9 Aug 2021 07:34:26 +0200 Subject: [PATCH 22/22] Add tavianator as a maintainer --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 66d5752..450e721 100644 --- a/README.md +++ b/README.md @@ -646,6 +646,7 @@ cargo install --path . - [sharkdp](https://github.com/sharkdp) - [tmccombs](https://github.com/tmccombs) +- [tavianator](https://github.com/tavianator) ## License