21 Commits

Author SHA1 Message Date
Sylvestre Ledru e7c34ab12f test: properly exercise {} in -exec utility name (#702)
The test from #647 used {} only in an argument, so it passed on
unpatched code. Rewrite it to make the matched entry the
testing-commandline binary and pass {} as the utility name, so the
placeholder must resolve to the entry's path and execute.
2026-06-06 09:35:34 +02:00
Matt Van Horn 1a77a83432 fix: replace {} placeholder in -exec utility name (#647)
* fix: replace {} placeholder in -exec utility name

The {} placeholder was only replaced in arguments to -exec, not in the
utility_name position itself. Running `find -exec {} \;` passed the
literal string "{}" to Command::new, causing "No such file or directory".

Extracted arg parsing into a shared `parse_arg` helper and changed the
`executable` field from String to the existing Arg enum so it undergoes
the same {} replacement as other arguments.

Fixes #614

* test: add test for {} placeholder in utility name

Verify that SingleExecMatcher resolves {} in arguments
when the executable is a known path. Covers the case
where -exec receives {} in argument positions.

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-06 08:50:24 +02:00
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
milkory 5235d78291 find: Implement exec[dir] + (#515)
* 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>
2025-04-02 21:04:48 +08: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
Daniel Hofstetter 55f297fd88 tests: remove "extern crate x" 2024-03-26 16:14:24 +01:00
Sylvestre Ledru d7bb67e53d Fix more clippy warnings 2023-04-02 18:53:40 +02:00
Jez Ng 30a22453d6 Add support for embedded "{}"
Given

  find . -exec foo{}bar \;

GNU find will replace `{}` by the filename. This commit matches that
behavior.

Note that this is not required by the POSIX spec.

The GNU testsuite doesn't cover this case, so I've added a test in this
repo.
2023-02-23 23:38:40 +01:00
Sylvestre Ledru 4eb943fea2 rustfmt recent changes 2022-02-05 15:16:36 +01:00
Sylvestre Ledru f399291533 fix clippy warning: Fix the needless_pass_by_value 2022-02-05 15:09:29 +01:00
Sylvestre Ledru f9e736d194 replace tempdir by tempfile 2021-09-07 10:36:07 +02:00
Tavian Barnes 88cbbff332 exec: Handle parent directories more carefully
Fixes #23, fixes #28.
2021-03-28 17:47:46 -04:00
Alex Lyon 73d4ad5b8f Format using rustfmt 2019-04-24 03:06:42 -07:00
mcharsley a3e8f51b6d Merge branch 'master' into master 2017-06-30 14:21:45 +01:00
Mark Charsley 8c7cf29e69 Fix for issue #23 -execdir fails for the root directory 2017-06-30 14:17:34 +01: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
Mark Charsley 372493be7c Revert "Revert "Fixed windows compatability. This required""
This reverts commit 384da6d2f4.
2017-03-24 14:56:40 +00:00
Mark Charsley 384da6d2f4 Revert "Fixed windows compatability. This required"
This reverts commit 0e2c385237.
2017-03-24 14:44:43 +00:00
mcharsley 0e2c385237 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
2017-03-24 14:38:37 +00: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
mcharsley 32fa744cf8 Added support for -exec and -execdir 2017-03-15 16:58:48 +00:00