Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package fd for openSUSE:Factory checked in at 2022-01-08 23:23:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/fd (Old) and /work/SRC/openSUSE:Factory/.fd.new.1892 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "fd" Sat Jan 8 23:23:42 2022 rev:12 rq:944794 version:8.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/fd/fd.changes 2021-12-08 22:10:34.834908321 +0100 +++ /work/SRC/openSUSE:Factory/.fd.new.1892/fd.changes 2022-01-08 23:24:24.446270249 +0100 @@ -1,0 +2,19 @@ +Fri Jan 7 16:09:29 UTC 2022 - Avindra Goolcharan <avin...@opensuse.org> + +- remove service files + +------------------------------------------------------------------- +Thu Jan 06 14:33:13 UTC 2022 - sebix+novell....@sebix.at + +- Update to version 8.3.1: + - Bugfixes + - Stop implying --no-ignore-parent when --no-vcs-ignore is supplied, see #907, #901, #908 (@tmccombs) + - fd no longer waits for the whole traversal if the only matches arrive within max_buffer_time, see #868 and #895 (@tavianator) + - --max-results=1 now immediately quits after the first result, see #867 (@tavianator) + - fd -h does not panic anymore when stdout is closed, see #897 + - Changes + - Disable jemalloc on FreeBSD, see #896 (@xanderio) + - Updated man page, see #912 (@rlue) + - Updated zsh completions, see #932 (@tmccombs) + +------------------------------------------------------------------- Old: ---- fd-8.3.0.tar.gz New: ---- fd-8.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ fd.spec ++++++ --- /var/tmp/diff_new_pack.iiGky2/_old 2022-01-08 23:24:25.350270987 +0100 +++ /var/tmp/diff_new_pack.iiGky2/_new 2022-01-08 23:24:25.354270990 +0100 @@ -1,7 +1,7 @@ # # spec file for package fd # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: fd -Version: 8.3.0 +Version: 8.3.1 Release: 0 Summary: An alternative to the "find" utility License: Apache-2.0 AND MIT @@ -27,6 +27,77 @@ Source1: vendor.tar.xz Source2: cargo_config BuildRequires: cargo-packaging +Provides: bundled(crate(aho-corasick)) = 0.7.18 +Provides: bundled(crate(ansi_term)) = 0.12.1 +Provides: bundled(crate(anyhow)) = 1.0.52 +Provides: bundled(crate(atty)) = 0.2.14 +Provides: bundled(crate(autocfg)) = 1.0.1 +Provides: bundled(crate(bitflags)) = 1.3.2 +Provides: bundled(crate(bstr)) = 0.2.17 +Provides: bundled(crate(cc)) = 1.0.72 +Provides: bundled(crate(cfg-if)) = 1.0.0 +Provides: bundled(crate(chrono)) = 0.4.19 +Provides: bundled(crate(clap)) = 2.34.0 +Provides: bundled(crate(crossbeam-utils)) = 0.8.5 +Provides: bundled(crate(ctrlc)) = 3.2.1 +Provides: bundled(crate(diff)) = 0.1.12 +Provides: bundled(crate(dirs-next)) = 2.0.0 +Provides: bundled(crate(dirs-sys-next)) = 0.1.2 +Provides: bundled(crate(fd-find)) = 8.3.1 +Provides: bundled(crate(filetime)) = 0.2.15 +Provides: bundled(crate(fnv)) = 1.0.7 +Provides: bundled(crate(fs_extra)) = 1.2.0 +Provides: bundled(crate(fuchsia-cprng)) = 0.1.1 +Provides: bundled(crate(getrandom)) = 0.2.3 +Provides: bundled(crate(globset)) = 0.4.8 +Provides: bundled(crate(hermit-abi)) = 0.1.19 +Provides: bundled(crate(humantime)) = 2.1.0 +Provides: bundled(crate(ignore)) = 0.4.18 +Provides: bundled(crate(jemalloc-sys)) = 0.3.2 +Provides: bundled(crate(jemallocator)) = 0.3.2 +Provides: bundled(crate(lazy_static)) = 1.4.0 +Provides: bundled(crate(libc)) = 0.2.112 +Provides: bundled(crate(log)) = 0.4.14 +Provides: bundled(crate(lscolors)) = 0.8.1 +Provides: bundled(crate(memchr)) = 2.4.1 +Provides: bundled(crate(memoffset)) = 0.6.4 +Provides: bundled(crate(nix)) = 0.23.1 +Provides: bundled(crate(normpath)) = 0.3.1 +Provides: bundled(crate(num-integer)) = 0.1.44 +Provides: bundled(crate(num-traits)) = 0.2.14 +Provides: bundled(crate(num_cpus)) = 1.13.1 +Provides: bundled(crate(once_cell)) = 1.9.0 +Provides: bundled(crate(proc-macro2)) = 1.0.32 +Provides: bundled(crate(quote)) = 1.0.10 +Provides: bundled(crate(rand)) = 0.4.6 +Provides: bundled(crate(rand_core)) = 0.3.1 +Provides: bundled(crate(rand_core)) = 0.4.2 +Provides: bundled(crate(rdrand)) = 0.4.0 +Provides: bundled(crate(redox_syscall)) = 0.2.10 +Provides: bundled(crate(redox_users)) = 0.4.0 +Provides: bundled(crate(regex)) = 1.5.4 +Provides: bundled(crate(regex-syntax)) = 0.6.25 +Provides: bundled(crate(remove_dir_all)) = 0.5.3 +Provides: bundled(crate(same-file)) = 1.0.6 +Provides: bundled(crate(strsim)) = 0.8.0 +Provides: bundled(crate(syn)) = 1.0.82 +Provides: bundled(crate(tempdir)) = 0.3.7 +Provides: bundled(crate(term_size)) = 0.3.2 +Provides: bundled(crate(test-case)) = 1.2.1 +Provides: bundled(crate(textwrap)) = 0.11.0 +Provides: bundled(crate(thread_local)) = 1.1.3 +Provides: bundled(crate(time)) = 0.1.43 +Provides: bundled(crate(unicode-width)) = 0.1.9 +Provides: bundled(crate(unicode-xid)) = 0.2.2 +Provides: bundled(crate(users)) = 0.11.0 +Provides: bundled(crate(vec_map)) = 0.8.2 +Provides: bundled(crate(version_check)) = 0.9.4 +Provides: bundled(crate(walkdir)) = 2.3.2 +Provides: bundled(crate(wasi)) = 0.10.2+wasi-snapshot_preview1 +Provides: bundled(crate(winapi)) = 0.3.9 +Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(winapi-util)) = 0.1.5 +Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 %description fd is an alternative to GNU find. It features: ++++++ fd-8.3.0.tar.gz -> fd-8.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/.github/workflows/CICD.yml new/fd-8.3.1/.github/workflows/CICD.yml --- old/fd-8.3.0/.github/workflows/CICD.yml 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/.github/workflows/CICD.yml 2022-01-06 14:20:02.000000000 +0100 @@ -313,8 +313,11 @@ Architecture: ${DPKG_ARCH} Provides: ${{ env.PROJECT_NAME }} Conflicts: ${DPKG_CONFLICTS} - Description: cat(1) clone with wings. - A cat(1) clone with syntax highlighting and Git integration. + 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}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/CHANGELOG.md new/fd-8.3.1/CHANGELOG.md --- old/fd-8.3.0/CHANGELOG.md 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/CHANGELOG.md 2022-01-06 14:20:02.000000000 +0100 @@ -2,16 +2,37 @@ ## Performance improvements + ## Features + ## Bugfixes + ## Changes + ## Other + +# v8.3.1 + +## Bugfixes + +- Stop implying `--no-ignore-parent` when `--no-vcs-ignore` is supplied, see #907, #901, #908 (@tmccombs) +- fd no longer waits for the whole traversal if the only matches arrive within max_buffer_time, see #868 and #895 (@tavianator) +- `--max-results=1` now immediately quits after the first result, see #867 +- `fd -h` does not panic anymore when stdout is closed, see #897 + +## Changes + +- Disable jemalloc on FreeBSD, see #896 (@xanderio) +- Updated man page, see #912 (@rlue) +- Updated zsh completions, see #932 (@tmccombs) + + # v8.3.0 ## Performance improvements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/Cargo.lock new/fd-8.3.1/Cargo.lock --- old/fd-8.3.0/Cargo.lock 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/Cargo.lock 2022-01-06 14:20:02.000000000 +0100 @@ -13,15 +13,6 @@ [[package]] name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" @@ -31,9 +22,9 @@ [[package]] name = "anyhow" -version = "1.0.48" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "atty" @@ -94,11 +85,11 @@ [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term 0.11.0", + "ansi_term", "atty", "bitflags", "strsim", @@ -157,9 +148,9 @@ [[package]] name = "fd-find" -version = "8.3.0" +version = "8.3.1" dependencies = [ - "ansi_term 0.12.1", + "ansi_term", "anyhow", "atty", "chrono", @@ -302,9 +293,9 @@ [[package]] name = "libc" -version = "0.2.108" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "log" @@ -321,7 +312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dd58d8727f3035fa6d5272f16b519741fd4875936b99d8a7cde21291b7d9174" dependencies = [ - "ansi_term 0.12.1", + "ansi_term", ] [[package]] @@ -341,9 +332,9 @@ [[package]] name = "nix" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", @@ -382,9 +373,9 @@ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -392,9 +383,9 @@ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "proc-macro2" @@ -614,9 +605,9 @@ [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/Cargo.toml new/fd-8.3.1/Cargo.toml --- old/fd-8.3.0/Cargo.toml 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/Cargo.toml 2022-01-06 14:20:02.000000000 +0100 @@ -16,7 +16,7 @@ name = "fd-find" readme = "README.md" repository = "https://github.com/sharkdp/fd" -version = "8.3.0" +version = "8.3.1" edition= "2018" [badges.appveyor] @@ -30,14 +30,14 @@ path = "src/main.rs" [build-dependencies] -clap = "2.31.2" +clap = "2.34.0" version_check = "0.9" [dependencies] ansi_term = "0.12" atty = "0.2" ignore = "0.4.3" -num_cpus = "1.8" +num_cpus = "1.13" regex = "1.5.4" regex-syntax = "0.6" ctrlc = "3.2" @@ -48,15 +48,15 @@ dirs-next = "2.0" normpath = "0.3" chrono = "0.4" -once_cell = "1.8.0" +once_cell = "1.9.0" [dependencies.clap] -version = "2.31.3" +version = "2.34.0" features = ["suggestions", "color", "wrap_help"] [target.'cfg(unix)'.dependencies] users = "0.11.0" -nix = "0.23.0" +nix = "0.23.1" [target.'cfg(all(unix, not(target_os = "redox")))'.dependencies] libc = "0.2" @@ -64,8 +64,8 @@ # 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_env = "musl")))'.dependencies] -jemallocator = "0.3.0" +[target.'cfg(all(not(windows), not(target_os = "android"), not(target_os = "macos"), not(target_os = "freebsd"), not(target_env = "musl"), not(target_arch = "riscv64")))'.dependencies] +jemallocator = {version = "0.3.0", optional = true} [dev-dependencies] diff = "0.1" @@ -76,3 +76,7 @@ [profile.release] lto = true codegen-units = 1 + +[features] +use-jemalloc = ["jemallocator"] +default = ["use-jemalloc"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/README.md new/fd-8.3.1/README.md --- old/fd-8.3.0/README.md 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/README.md 2022-01-06 14:20:02.000000000 +0100 @@ -535,7 +535,7 @@ 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.3.0_amd64.deb # adapt version number and architecture +sudo dpkg -i fd_8.3.1_amd64.deb # adapt version number and architecture ``` ### On Debian diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/contrib/completion/_fd new/fd-8.3.1/contrib/completion/_fd --- old/fd-8.3.0/contrib/completion/_fd 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/contrib/completion/_fd 2022-01-06 14:20:02.000000000 +0100 @@ -57,6 +57,7 @@ + no-ignore-partial # some ignore files "(no-ignore-full --no-ignore-vcs)--no-ignore-vcs[don't respect .gitignore files]" "!(no-ignore-full --no-global-ignore-file)--no-global-ignore-file[don't respect the global ignore file]" + $no'(no-ignore-full --no-ignore-parent)--no-ignore-parent[]' + '(case)' # case-sensitivity {-s,--case-sensitive}'[perform a case-sensitive search]' @@ -154,6 +155,9 @@ $no'(--base-directory)--base-directory=[change the current working directory to the given path]:directory:_files -/' $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]' + + args # positional arguments '1: :_guard "^-*" pattern' '(--search-path)*:directory:_files -/' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/doc/fd.1 new/fd-8.3.1/doc/fd.1 --- old/fd-8.3.0/doc/fd.1 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/doc/fd.1 2022-01-06 14:20:02.000000000 +0100 @@ -66,6 +66,10 @@ .IR $HOME/.config/git/ignore ). The flag can be overridden with '--ignore-vcs'. .TP +.B \-\-no\-ignore\-parent +Show search results from files and directories that would otherwise be ignored by gitignore files in +parent directories. +.TP .B \-s, \-\-case\-sensitive Perform a case-sensitive search. By default, fd uses case-insensitive searches, unless the pattern contains an uppercase character (smart case). @@ -126,6 +130,10 @@ 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. +.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). .TP @@ -393,7 +401,11 @@ fd -e rs -X wc -l .RE - +.TP +.BI "\-\-batch-size " size +Maximum number of arguments to pass to the command given with -X. If the number of results is +greater than the given size, the command given with -X is run again with remaining arguments. A +batch size of zero means there is no limit. .SH PATTERN SYNTAX The regular expression syntax used by fd is documented here: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/src/filetypes.rs new/fd-8.3.1/src/filetypes.rs --- old/fd-8.3.0/src/filetypes.rs 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/src/filetypes.rs 2022-01-06 14:20:02.000000000 +0100 @@ -2,6 +2,7 @@ use crate::walk; /// Whether or not to show +#[derive(Default)] pub struct FileTypes { pub files: bool, pub directories: bool, @@ -12,20 +13,6 @@ pub empty_only: bool, } -impl Default for FileTypes { - fn default() -> FileTypes { - FileTypes { - files: false, - directories: false, - symlinks: false, - sockets: false, - pipes: false, - executables_only: false, - empty_only: false, - } - } -} - impl FileTypes { pub fn should_ignore(&self, entry: &walk::DirEntry) -> bool { if let Some(ref entry_type) = entry.file_type() { @@ -37,7 +24,7 @@ || (self.executables_only && !entry .metadata() - .map(|m| filesystem::is_executable(m)) + .map(filesystem::is_executable) .unwrap_or(false)) || (self.empty_only && !filesystem::is_empty(entry)) || !(entry_type.is_file() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/src/main.rs new/fd-8.3.1/src/main.rs --- old/fd-8.3.0/src/main.rs 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/src/main.rs 2022-01-06 14:20:02.000000000 +0100 @@ -38,7 +38,10 @@ not(windows), not(target_os = "android"), not(target_os = "macos"), - not(target_env = "musl") + not(target_os = "freebsd"), + not(target_env = "musl"), + not(target_arch = "riscv64"), + feature = "use-jemalloc" ))] #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; @@ -259,10 +262,7 @@ read_vcsignore: !(matches.is_present("no-ignore") || matches.is_present("rg-alias-hidden-ignore") || matches.is_present("no-ignore-vcs")), - read_parent_ignore: !(matches.is_present("no-ignore") - || matches.is_present("rg-alias-hidden-ignore") - || matches.is_present("no-ignore-vcs") - || matches.is_present("no-ignore-parent")), + read_parent_ignore: !matches.is_present("no-ignore-parent"), read_global_ignore: !(matches.is_present("no-ignore") || matches.is_present("rg-alias-hidden-ignore") || matches.is_present("no-global-ignore-file")), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/src/output.rs new/fd-8.3.1/src/output.rs --- old/fd-8.3.0/src/output.rs 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/src/output.rs 2022-01-06 14:20:02.000000000 +0100 @@ -1,7 +1,6 @@ use std::borrow::Cow; use std::io::{self, Write}; use std::path::Path; -use std::sync::atomic::{AtomicBool, Ordering}; use lscolors::{Indicator, LsColors, Style}; @@ -15,12 +14,7 @@ } // TODO: this function is performance critical and can probably be optimized -pub fn print_entry<W: Write>( - stdout: &mut W, - entry: &Path, - config: &Config, - wants_to_quit: &AtomicBool, -) { +pub fn print_entry<W: Write>(stdout: &mut W, entry: &Path, config: &Config) { let path = if config.strip_cwd_prefix { strip_current_dir(entry) } else { @@ -28,7 +22,7 @@ }; let r = if let Some(ref ls_colors) = config.ls_colors { - print_entry_colorized(stdout, path, config, ls_colors, wants_to_quit) + print_entry_colorized(stdout, path, config, ls_colors) } else { print_entry_uncolorized(stdout, path, config) }; @@ -50,7 +44,6 @@ path: &Path, config: &Config, ls_colors: &LsColors, - wants_to_quit: &AtomicBool, ) -> io::Result<()> { // Split the path between the parent and the last component let mut offset = 0; @@ -92,12 +85,6 @@ writeln!(stdout)?; } - if wants_to_quit.load(Ordering::Relaxed) { - // Ignore any errors on flush, because we're about to exit anyway - let _ = stdout.flush(); - ExitCode::KilledBySigint.exit(); - } - Ok(()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/src/walk.rs new/fd-8.3.1/src/walk.rs --- old/fd-8.3.0/src/walk.rs 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/src/walk.rs 2022-01-06 14:20:02.000000000 +0100 @@ -1,12 +1,13 @@ use std::ffi::OsStr; use std::fs::{FileType, Metadata}; use std::io; +use std::mem; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender}; use std::sync::{Arc, Mutex}; use std::thread; -use std::time; +use std::time::{Duration, Instant}; use std::{borrow::Cow, io::Write}; use anyhow::{anyhow, Result}; @@ -23,6 +24,7 @@ use crate::output; /// The receiver thread can either be buffering results or directly streaming to the console. +#[derive(PartialEq)] enum ReceiverMode { /// Receiver is still buffering in order to sort the results, if the search finishes fast /// enough. @@ -41,7 +43,7 @@ /// 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: time::Duration = time::Duration::from_millis(100); +pub const DEFAULT_MAX_BUFFER_TIME: Duration = Duration::from_millis(100); /// Recursively scan the given search path for files / pathnames matching the pattern. /// @@ -70,7 +72,7 @@ walker .hidden(config.ignore_hidden) .ignore(config.read_fdignore) - .parents(config.read_parent_ignore) + .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) @@ -132,11 +134,19 @@ let parallel_walker = walker.threads(config.threads).build_parallel(); - let wants_to_quit = Arc::new(AtomicBool::new(false)); + // 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.command.is_none() { - let wq = Arc::clone(&wants_to_quit); + let quit_flag = Arc::clone(&quit_flag); + let interrupt_flag = Arc::clone(&interrupt_flag); + ctrlc::set_handler(move || { - if wq.fetch_or(true, Ordering::Relaxed) { + 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(); } @@ -145,28 +155,198 @@ } // Spawn the thread that receives all results through the channel. - let receiver_thread = spawn_receiver(&config, &wants_to_quit, rx); + let receiver_thread = spawn_receiver(&config, &quit_flag, &interrupt_flag, rx); // Spawn the sender threads. - spawn_senders(&config, &wants_to_quit, pattern, parallel_walker, tx); + 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 wants_to_quit.load(Ordering::Relaxed) { + if interrupt_flag.load(Ordering::Relaxed) { Ok(ExitCode::KilledBySigint) } else { Ok(exit_code) } } +/// Wrapper for the receiver thread's buffering behavior. +struct ReceiverBuffer<W> { + /// The configuration. + config: Arc<Config>, + /// For shutting down the senders. + quit_flag: Arc<AtomicBool>, + /// The ^C notifier. + interrupt_flag: Arc<AtomicBool>, + /// Receiver for worker results. + rx: Receiver<WorkerResult>, + /// Standard output. + stdout: W, + /// The current buffer mode. + mode: ReceiverMode, + /// The deadline to switch to streaming mode. + deadline: Instant, + /// The buffer of quickly received paths. + buffer: Vec<PathBuf>, + /// Result count. + num_results: usize, +} + +impl<W: Write> ReceiverBuffer<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 { + let max_buffer_time = config.max_buffer_time.unwrap_or(DEFAULT_MAX_BUFFER_TIME); + let deadline = Instant::now() + max_buffer_time; + + Self { + config, + quit_flag, + interrupt_flag, + rx, + stdout, + mode: ReceiverMode::Buffering, + deadline, + buffer: Vec::with_capacity(MAX_BUFFER_LENGTH), + num_results: 0, + } + } + + /// Process results until finished. + fn process(&mut self) -> ExitCode { + loop { + if let Err(ec) = self.poll() { + self.quit_flag.store(true, Ordering::Relaxed); + return ec; + } + } + } + + /// Receive the next worker result. + fn recv(&self) -> Result<WorkerResult, RecvTimeoutError> { + match self.mode { + ReceiverMode::Buffering => { + // Wait at most until we should switch to streaming + let now = Instant::now(); + self.deadline + .checked_duration_since(now) + .ok_or(RecvTimeoutError::Timeout) + .and_then(|t| self.rx.recv_timeout(t)) + } + ReceiverMode::Streaming => { + // Wait however long it takes for a result + Ok(self.rx.recv()?) + } + } + } + + /// Wait for a result or state change. + fn poll(&mut self) -> Result<(), ExitCode> { + match self.recv() { + Ok(WorkerResult::Entry(path)) => { + if self.config.quiet { + return Err(ExitCode::HasResults(true)); + } + + match self.mode { + ReceiverMode::Buffering => { + self.buffer.push(path); + if self.buffer.len() > MAX_BUFFER_LENGTH { + self.stream()?; + } + } + ReceiverMode::Streaming => { + self.print(&path)?; + 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()); + } + } + Err(RecvTimeoutError::Timeout) => { + self.stream()?; + } + Err(RecvTimeoutError::Disconnected) => { + return self.stop(); + } + } + + Ok(()) + } + + /// Output a path. + fn print(&mut self, path: &Path) -> Result<(), ExitCode> { + output::print_entry(&mut self.stdout, path, &self.config); + + if self.interrupt_flag.load(Ordering::Relaxed) { + // Ignore any errors on flush, because we're about to exit anyway + let _ = self.flush(); + return Err(ExitCode::KilledBySigint); + } + + Ok(()) + } + + /// Switch ourselves into streaming mode. + fn stream(&mut self) -> Result<(), ExitCode> { + self.mode = ReceiverMode::Streaming; + + let buffer = mem::take(&mut self.buffer); + for path in buffer { + self.print(&path)?; + } + + self.flush() + } + + /// Stop looping. + fn stop(&mut self) -> Result<(), ExitCode> { + if self.mode == ReceiverMode::Buffering { + self.buffer.sort(); + self.stream()?; + } + + if self.config.quiet { + Err(ExitCode::HasResults(self.num_results > 0)) + } else { + Err(ExitCode::Success) + } + } + + /// Flush stdout if necessary. + fn flush(&mut self) -> Result<(), ExitCode> { + if self.config.interactive_terminal && self.stdout.flush().is_err() { + // Probably a broken pipe. Exit gracefully. + return Err(ExitCode::GeneralError); + } + Ok(()) + } +} + fn spawn_receiver( config: &Arc<Config>, - wants_to_quit: &Arc<AtomicBool>, + quit_flag: &Arc<AtomicBool>, + interrupt_flag: &Arc<AtomicBool>, rx: Receiver<WorkerResult>, ) -> thread::JoinHandle<ExitCode> { let config = Arc::clone(config); - let wants_to_quit = Arc::clone(wants_to_quit); + let quit_flag = Arc::clone(quit_flag); + let interrupt_flag = Arc::clone(interrupt_flag); let show_filesystem_errors = config.show_filesystem_errors; let threads = config.threads; @@ -218,90 +398,12 @@ merge_exitcodes(exit_codes) } } else { - let start = time::Instant::now(); - - // Start in buffering mode - let mut mode = ReceiverMode::Buffering; - - // Maximum time to wait before we start streaming to the console. - let max_buffer_time = config.max_buffer_time.unwrap_or(DEFAULT_MAX_BUFFER_TIME); - let stdout = io::stdout(); let stdout = stdout.lock(); - let mut stdout = io::BufWriter::new(stdout); - - let mut num_results = 0; - let is_interactive = config.interactive_terminal; - let mut buffer = Vec::with_capacity(MAX_BUFFER_LENGTH); - for worker_result in rx { - match worker_result { - WorkerResult::Entry(path) => { - if config.quiet { - return ExitCode::HasResults(true); - } - - match mode { - ReceiverMode::Buffering => { - buffer.push(path); - - // Have we reached the maximum buffer size or maximum buffering time? - if buffer.len() > MAX_BUFFER_LENGTH - || start.elapsed() > max_buffer_time - { - // Flush the buffer - for path in &buffer { - output::print_entry( - &mut stdout, - path, - &config, - &wants_to_quit, - ); - } - buffer.clear(); - if is_interactive && stdout.flush().is_err() { - // Probably a broken pipe. Exit gracefully. - return ExitCode::GeneralError; - } - // Start streaming - mode = ReceiverMode::Streaming; - } - } - ReceiverMode::Streaming => { - output::print_entry(&mut stdout, &path, &config, &wants_to_quit); - if is_interactive && stdout.flush().is_err() { - // Probably a broken pipe. Exit gracefully. - return ExitCode::GeneralError; - } - } - } + let stdout = io::BufWriter::new(stdout); - num_results += 1; - if let Some(max_results) = config.max_results { - if num_results >= max_results { - break; - } - } - } - WorkerResult::Error(err) => { - if show_filesystem_errors { - print_error(err.to_string()); - } - } - } - } - - // If we have finished fast enough (faster than max_buffer_time), we haven't streamed - // anything to the console, yet. In this case, sort the results and print them: - buffer.sort(); - for value in buffer { - output::print_entry(&mut stdout, &value, &config, &wants_to_quit); - } - - if config.quiet { - ExitCode::HasResults(false) - } else { - ExitCode::Success - } + let mut rxbuffer = ReceiverBuffer::new(config, quit_flag, interrupt_flag, rx, stdout); + rxbuffer.process() } }) } @@ -364,7 +466,7 @@ fn spawn_senders( config: &Arc<Config>, - wants_to_quit: &Arc<AtomicBool>, + quit_flag: &Arc<AtomicBool>, pattern: Arc<Regex>, parallel_walker: ignore::WalkParallel, tx: Sender<WorkerResult>, @@ -373,10 +475,10 @@ let config = Arc::clone(config); let pattern = Arc::clone(&pattern); let tx_thread = tx.clone(); - let wants_to_quit = Arc::clone(wants_to_quit); + let quit_flag = Arc::clone(quit_flag); Box::new(move |entry_o| { - if wants_to_quit.load(Ordering::Relaxed) { + if quit_flag.load(Ordering::Relaxed) { return ignore::WalkState::Quit; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fd-8.3.0/tests/tests.rs new/fd-8.3.1/tests/tests.rs --- old/fd-8.3.0/tests/tests.rs 2021-11-26 22:18:50.000000000 +0100 +++ new/fd-8.3.1/tests/tests.rs 2022-01-06 14:20:02.000000000 +0100 @@ -614,6 +614,22 @@ ); } +/// Test that --no-ignore-vcs still respects .fdignored in parent directory +#[test] +fn test_no_ignore_vcs_child_dir() { + let te = TestEnv::new( + &["inner"], + &["inner/fdignored.foo", "inner/foo", "inner/gitignored.foo"], + ); + + te.assert_output_subdirectory( + "inner", + &["--no-ignore-vcs", "foo"], + "./foo + ./gitignored.foo", + ); +} + /// Custom ignore files (--ignore-file) #[test] fn test_custom_ignore_files() { ++++++ vendor.tar.xz ++++++ ++++ 18238 lines of diff (skipped)