Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

find: Implement -ok[dir] predicate. #369

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/find/matchers/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use std::error::Error;
use std::ffi::OsString;
use std::io::{stderr, Write};
use std::io::{stderr, stdin, stdout, Write};
use std::path::Path;
use std::process::Command;

Expand All @@ -21,13 +21,15 @@
executable: String,
args: Vec<Arg>,
exec_in_parent_dir: bool,
interactive: bool,
}

impl SingleExecMatcher {
pub fn new(
executable: &str,
args: &[&str],
exec_in_parent_dir: bool,
interactive: bool,
) -> Result<Self, Box<dyn Error>> {
let transformed_args = args
.iter()
Expand All @@ -46,6 +48,7 @@
executable: executable.to_string(),
args: transformed_args,
exec_in_parent_dir,
interactive,
})
}
}
Expand Down Expand Up @@ -83,6 +86,25 @@
}
}
}

// support interactive exec
if self.interactive {
let tips = format!(

Check warning on line 92 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L92

Added line #L92 was not covered by tests
"{} ... {} > ? [y/n]: ",
self.executable,
path_to_file.to_string_lossy()

Check warning on line 95 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L95

Added line #L95 was not covered by tests
);
#[allow(clippy::explicit_write)]
write!(stdout(), "{}", tips).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POSIX specifies

  • The -ok primary shall write a prompt to standard error
  • In the POSIX locale, the last non-<blank> in the prompt shall be '?'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I overlooked these, I will fix them later.

stdout().flush().unwrap();

Check warning on line 99 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L98-L99

Added lines #L98 - L99 were not covered by tests

let mut input = String::new();
let _result = stdin().read_line(&mut input).unwrap();

Check warning on line 102 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L101-L102

Added lines #L101 - L102 were not covered by tests
if !input.trim().contains('y') {
return false;

Check warning on line 104 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L104

Added line #L104 was not covered by tests
}
}

Check warning on line 106 in src/find/matchers/exec.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/exec.rs#L106

Added line #L106 was not covered by tests

match command.status() {
Ok(status) => status.success(),
Err(e) => {
Expand Down
12 changes: 9 additions & 3 deletions src/find/matchers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@
Some(SizeMatcher::new(size, &unit)?.into_box())
}
"-empty" => Some(EmptyMatcher::new().into_box()),
"-exec" | "-execdir" => {
"-exec" | "-execdir" | "-ok" | "-okdir" => {
let mut arg_index = i + 1;
while arg_index < args.len() && args[arg_index] != ";" {
if args[arg_index - 1] == "{}" && args[arg_index] == "+" {
Expand All @@ -616,10 +616,16 @@
let expression = args[i];
let executable = args[i + 1];
let exec_args = &args[i + 2..arg_index];
let interactive = expression == "-ok" || expression == "-okdir";
i = arg_index;
Some(
SingleExecMatcher::new(executable, exec_args, expression == "-execdir")?
.into_box(),
SingleExecMatcher::new(
executable,
exec_args,
expression == "-execdir",
interactive,
)?

Check warning on line 627 in src/find/matchers/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/find/matchers/mod.rs#L627

Added line #L627 was not covered by tests
.into_box(),
)
}
#[cfg(unix)]
Expand Down
6 changes: 6 additions & 0 deletions tests/exec_unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ fn matching_executes_code() {
&path_to_testing_commandline(),
&[temp_dir_path.as_ref(), "abc", "{}", "xyz"],
false,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -65,6 +66,7 @@ fn matching_executes_code_in_files_directory() {
&path_to_testing_commandline(),
&[temp_dir_path.as_ref(), "abc", "{}", "xyz"],
true,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -96,6 +98,7 @@ fn matching_embedded_filename() {
&path_to_testing_commandline(),
&[temp_dir_path.as_ref(), "abc{}x{}yz"],
false,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -129,6 +132,7 @@ fn execdir_in_current_directory() {
&path_to_testing_commandline(),
&[temp_dir_path.as_ref(), "abc", "{}", "xyz"],
true,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -167,6 +171,7 @@ fn execdir_in_root_directory() {
&path_to_testing_commandline(),
&[temp_dir_path.as_ref(), "abc", "{}", "xyz"],
true,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -205,6 +210,7 @@ fn matching_fails_if_executable_fails() {
"xyz",
],
true,
false,
)
.expect("Failed to create matcher");
let deps = FakeDependencies::new();
Expand Down
Loading