Skip to content

Commit

Permalink
Add support for GNU-compatible printf
Browse files Browse the repository at this point in the history
This adds initial support for GNU find-compatible printf syntax. As far
as I can tell, it should implement all the specifiers, with the
following exceptions:

- Using zero as padding instead of space: GNU find isn't consistent with
  which numeric format specifiers support this.
- Specifying precision (`%x.yz`): I believe sparseness (%S)
  and seconds-since-epoch (`%A@` / `%C@` / `%T@`) are the only ones that
  allow this, making it only partially useful.
- Printing SELinux contexts (`%Z`): requires some extra dependencies and
  isn't within our scope.

uucore is added as a dependency, because it has several utility
functions that we need, the complexity of which is high enough that
using the extra dependency is quite helpful.

This also stubs out many of the specifiers for Windows, simply because I
have no idea how these should work there. (The defaults chosen should be
"good enough" for the moment, though.)

Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
  • Loading branch information
refi64 committed Dec 23, 2021
1 parent 87ceb10 commit da16f97
Show file tree
Hide file tree
Showing 8 changed files with 1,367 additions and 8 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ target
.project
.cargo
.settings
test_data/links/link-f
test_data/links/link-d
test_data/links/link-*
192 changes: 192 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ description = "Rust implementation of GNU findutils"
authors = ["uutils developers"]

[dependencies]
chrono = "0.4"
glob = "0.3"
walkdir = "2.3"
tempfile = "3"
regex = "1.5"
once_cell = "1.9"
uucore = { git = "https://github.com/uutils/coreutils", features = ["entries", "fs", "fsext"] }

[dev-dependencies]
assert_cmd = "2"
Expand Down
8 changes: 4 additions & 4 deletions src/find/matchers/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl Matcher for DeleteMatcher {

#[cfg(test)]
mod tests {
use std::fs::File;
use std::fs::{create_dir, File};
use tempfile::Builder;

use super::*;
Expand All @@ -79,6 +79,7 @@ mod tests {

let temp_dir_path = temp_dir.path().to_string_lossy();
File::create(temp_dir.path().join("test")).expect("created test file");
create_dir(temp_dir.path().join("test_dir")).expect("created test directory");
let test_entry = get_dir_entry_for(&temp_dir_path, "test");
assert!(
matcher.matches(&test_entry, &mut deps.new_matcher_io()),
Expand All @@ -89,14 +90,13 @@ mod tests {
"DeleteMatcher should actually delete files it matches",
);

let temp_dir_name = temp_dir.path().file_name().unwrap().to_string_lossy();
let temp_dir_entry = get_dir_entry_for(&temp_dir_path, &temp_dir_name);
let temp_dir_entry = get_dir_entry_for(&temp_dir_path, "test_dir");
assert!(
matcher.matches(&temp_dir_entry, &mut deps.new_matcher_io()),
"DeleteMatcher should match directories",
);
assert!(
!temp_dir.path().exists(),
!temp_dir.path().join("test_dir").exists(),
"DeleteMatcher should actually delete (empty) directories it matches",
);
}
Expand Down
16 changes: 15 additions & 1 deletion src/find/matchers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod logical_matchers;
mod name;
mod perm;
mod printer;
mod printf;
mod prune;
mod size;
mod time;
Expand Down Expand Up @@ -206,6 +207,13 @@ fn build_matcher_tree(
while i < args.len() {
let possible_submatcher = match args[i] {
"-print" => Some(printer::Printer::new_box()),
"-printf" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
i += 1;
Some(printf::Printf::new_box(args[i])?)
}
"-true" => Some(logical_matchers::TrueMatcher::new_box()),
"-false" => Some(logical_matchers::FalseMatcher::new_box()),
"-name" => {
Expand Down Expand Up @@ -423,7 +431,13 @@ mod tests {
pub fn get_dir_entry_for(directory: &str, filename: &str) -> DirEntry {
for wrapped_dir_entry in WalkDir::new(fix_up_slashes(directory)) {
let dir_entry = wrapped_dir_entry.unwrap();
if dir_entry.file_name().to_string_lossy() == filename {
if dir_entry
.path()
.strip_prefix(directory)
.unwrap()
.to_string_lossy()
== fix_up_slashes(filename)
{
return dir_entry;
}
}
Expand Down
Loading

0 comments on commit da16f97

Please sign in to comment.