13 Commits

Author SHA1 Message Date
Jesse Rosenstock 5269e233a6 find: implement -ok and -okdir (#650)
-ok is like -exec ... ; but prompts the user on stderr before each
invocation and only runs the command if the response is affirmative
(starts with 'y' or 'Y').  -okdir is the corresponding -execdir variant.
Only the ';' terminator is accepted: POSIX does not define -ok ... + and
GNU find rejects it.

Response source: GNU find reads from /dev/tty so that the user's answer
always comes from the real terminal even when stdin is occupied (e.g.
`find -files0-from - -ok rm {} \;` reads paths from stdin, so responses
cannot also come from there).  /dev/tty is the POSIX name for a
process's controlling terminal and exists on all Unix-like systems.  We
open /dev/tty only when stdin is itself a terminal
(std::io::stdin().is_terminal() == true).  When stdin is a pipe or file,
we read from stdin directly — matching BSD find and making scripted use
(and integration tests via pipe_in()) work naturally without any special
environment variable.  On Windows, or when /dev/tty cannot be opened, we
likewise fall back to stdin.

Implementation: rather than a separate OkMatcher that duplicated
SingleExecMatcher's fields, constructor, and exec logic, the interactive
prompt is folded into SingleExecMatcher behind an `interactive: bool`
field.  `SingleExecMatcher::new_interactive()` constructs the -ok/-okdir
variant; `matches()` adds a guarded block that builds a GNU-find-style
prompt ("< executable arg... >? ") and calls `matcher_io.confirm()`
before executing.  If the user declines, the expression is false and the
command is not run.  This keeps the arg-parsing, path resolution,
current_dir logic, and error handling in one place so bug fixes apply to
both -exec and -ok.

Dependencies::confirm() trait method: abstracts prompt+read so matchers
remain testable without a real terminal; FakeDependencies uses a
VecDeque of preset responses.

Tests:
- Unit tests (exec_unit_tests.rs): confirmed executes command, declined
  skips command and returns false, confirmed but command fails returns
  false, -okdir runs in parent dir
- Parser unit tests (matchers/mod.rs): missing-arg errors, missing
  semicolon, correct parse, confirm/decline via FakeDependencies
- Integration tests (test_find.rs): pipe_in() makes stdin a pipe so
  is_terminal() returns false and responses are read from the pipe;
  "y"/"Y"/"yes"/" y" run command, "n" and empty response skip command,
  -okdir runs in parent dir, prompt format verified, missing-semicolon
  error

Closes https://github.com/uutils/findutils/issues/8.
2026-06-04 20:31:54 +02:00
Daniel Hofstetter 29c644fc72 tests/common/mod.rs: adapt to change in ctor 2026-05-07 10:47:04 +02:00
Jesse Rosenstock 41778576e2 tests: port to uutests (#645)
Replaces assert_cmd/predicates/pretty_assertions/serial_test with uutests and
ctor in dev-dependencies.

Closes https://github.com/uutils/findutils/issues/537.

- Port tests/find_cmd_tests.rs → tests/test_find.rs (uutests API)
- Port tests/xargs_tests.rs → tests/test_xargs.rs (uutests API)
- Centralize UUTESTS_BINARY_PATH init via #[ctor::ctor] in tests/common/mod.rs

Implementation notes:
- Use TestScenario::cmd(BINARY_PATH) rather than ucmd(): find/xargs are
  dedicated binaries, not multi-call, so ucmd() would prepend the utility name
  as a spurious first argument
- Set CWD to CARGO_MANIFEST_DIR in find's ucmd() so relative test_data/ paths
  resolve correctly regardless of where cargo runs
- delete_on_dot_dir sets the child process CWD via UCommand::current_dir()
  instead of mutating the process-wide CWD, removing the need for serial_test
  and all #[serial(working_dir)] attributes

Also fixes find_samefile, find_fprinter, and find_fprintf, which were writing
temporary files directly into test_data/. They now use isolated temp
directories, eliminating a source of test pollution when running in parallel.
2026-04-03 10:21:47 +02:00
Tavian Barnes a7a73c325d Wrap walkdir::DirEntry in a new type (#436)
* Add -follow support.

* tests/find: Serialize find_time()

find_time() relies on the working directory, but e.g.
delete_on_dot_dir() will temporarily change directories, causing
find_time() to fail when run in parallel.

* find: Don't use uutils::error::set_exit_code()

The global exit code can polute the results of other tests.

Link: https://github.com/uutils/coreutils/issues/5777

* find: New WalkEntry wrapper

The new type wraps DirEntry when possible, but also lets us pass a valid
entry to matchers when walkdir returns a broken symlink error.  It also
implements a Metadata cache (part of #430).

* find: Implement -H, -L, -P flags

* find: Fix -follow -samefile

* find: Fix -follow -newer

* find: Implement -xtype

* find: Fix -delete error handling

---------

Co-authored-by: hanbings <hanbings@hanbings.io>
2024-08-15 04:01:19 +08:00
Tavian Barnes 8771861b0c Remove unnecessary lifetime parameter from Dependencies 2024-07-27 19:54:28 -04:00
Sylvestre Ledru b4fbbe50c2 Run clippy pedantic fixes
Done with:
$ cargo +nightly clippy --tests --fix --allow-dirty -- -W clippy::pedantic
2024-04-03 17:50:13 +02:00
Daniel Hofstetter f2bf4b0fd9 find: fix "item x imported redundantly" warnings 2024-02-26 09:47:24 +01:00
Sylvestre Ledru d7bb67e53d Fix more clippy warnings 2023-04-02 18:53:40 +02:00
Sylvestre Ledru 384aa23e74 fix clippy warning: use Self when possible 2022-02-05 15:06:18 +01:00
Chad Williamson f4a69f4614 Fix various compiler warnings 2021-01-01 06:01:52 -08:00
Alex Lyon 73d4ad5b8f Format using rustfmt 2019-04-24 03:06:42 -07:00
mcharsley 1a6262cd5f Fixed windows compatability (#21)
* Deleted vertical whitespace

In an attempt to get around a mistake I made when merging from the
master fork

* Added a default implementation for has_side_effects

And removed all the "return false" implementations (as specified by most
of the Matchers).

* Added support for -exec and -execdir

* Fixed path_to_testing_commandline

* Minor tweaks from code review

* Added support for -perm

* Fixed string constant

* Fixed error caused by merging changes

* Tweaks after code review

* Fixed windows compatability. This required
 - changing a lot of test code to supply/expect backslashes rather than
slashes when running on windows
  - tweaking the way testing-commandline reported its args (debug format
escapes backslashes when printing strings)
  - changing the NewerMatcher to get metadata from fs::metadata() rather
than from File's metadata method (the latter caused mysterious test
failures, which I didn't bother tracking down becasue the former is more
efficient anyway)
  - hiding more of perm.rs behind #[cfg(unix)] to stop "unused X"
warnings

* Revert "Fixed windows compatability. This required"

This reverts commit 0e2c385237.

* Revert "Revert "Fixed windows compatability. This required""

This reverts commit 384da6d2f4.
2017-03-27 11:11:11 +01:00
mcharsley 8b3842b1f9 Added support for -exec[dir] (#17)
* Deleted vertical whitespace

In an attempt to get around a mistake I made when merging from the
master fork

* Added a default implementation for has_side_effects

And removed all the "return false" implementations (as specified by most
of the Matchers).

* Added support for -exec and -execdir

* Fixed path_to_testing_commandline

* Minor tweaks from code review
2017-03-17 17:02:45 +00:00