-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.
GNU xargs treats the arguments to -I, -E, and -e as values even when
they begin with a hyphen. Clap was parsing those strings as options
instead, so invocations like 'xargs -I -_' failed before xargs could
process input.
Allow hyphen-leading values for those options and add regression
coverage for replacement and EOF markers that start with '-'.
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.
These tests failed on my system because directory entries were returned
in a different order, causing an output mismatch. Add --sort to the
testing_commandline to make the output deterministic.
* add argmax dependency
* implement finished and finished_dir callback
* implement multi exec matcher
* fix finished_dir not working correctly
* add more test for multi exec matcher
* fix execdir multi in current directory not working
* add more test for parsing multi exec
* set exit code when exec + failed
* fix clippy warnings
* prevent multi exec panics on long paths
---------
Co-authored-by: hanbings <hanbings@hanbings.io>
* xargs: print help/version without error prefix
xargs, when executed with -h/--help or -V/--version, is printing an
"Error: " prefix before the help and version text. The exit code is
also incorrect (1, instead of 0).
Display the help/version text without the erroneous prefix, and exit
with the correct exit code (success, 0).
Add tests for this bug to prevent regressions.
* 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>