clean-up first implementation of modification date filter

This commit is contained in:
Karim SENHAJI 2018-10-10 12:13:19 +02:00 committed by David Peter
parent 54c117d72f
commit abe8aa55c0
6 changed files with 102 additions and 58 deletions

7
Cargo.lock generated
View File

@ -84,7 +84,6 @@ dependencies = [
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
@ -144,11 +143,6 @@ dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "if_chain"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ignore"
version = "0.4.3"
@ -424,7 +418,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum globset 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8e49edbcc9c7fc5beb8c0a54e7319ff8bed353a2b55e85811c6281188c2a6c84"
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
"checksum ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9faa7c84064f07b40da27044af629f578bc7994b650d3e458d0c29183c1d91"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"

View File

@ -41,7 +41,6 @@ regex = "1.0.0"
regex-syntax = "0.6"
ctrlc = "3.1"
humantime = "1.1.1"
if_chain = "0.1.3"
[dependencies.clap]
version = "2.31.2"

View File

@ -108,23 +108,23 @@ pub enum TimeFilter {
}
impl TimeFilter {
fn from_str(s: &str) -> Option<SystemTime> {
fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> {
use humantime;
humantime::parse_duration(s)
.map(|duration| SystemTime::now() - duration)
.map(|duration| *ref_time - duration)
.or_else(|_| humantime::parse_rfc3339_weak(s))
.ok()
}
pub fn before(s: &str) -> Option<TimeFilter> {
Some(TimeFilter::Before(TimeFilter::from_str(s)?))
pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(ref_time, s).map(TimeFilter::Before)
}
pub fn after(s: &str) -> Option<TimeFilter> {
Some(TimeFilter::After(TimeFilter::from_str(s)?))
pub fn after(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
TimeFilter::from_str(ref_time, s).map(TimeFilter::After)
}
pub fn is_within(&self, t: &SystemTime) -> bool {
pub fn applies_to(&self, t: &SystemTime) -> bool {
match self {
TimeFilter::Before(limit) => t <= limit,
TimeFilter::After(limit) => t >= limit,
@ -196,7 +196,7 @@ pub struct FdOptions {
pub size_constraints: Vec<SizeFilter>,
/// Constraints on last modification time of files
pub modification_constraints: Vec<TimeFilter>,
pub time_constraints: Vec<TimeFilter>,
}
/// Print error message to stderr.
@ -505,16 +505,65 @@ mod tests {
}
#[test]
fn is_time_within() {
let now = SystemTime::now();
assert!(TimeFilter::after("1min").unwrap().is_within(&now));
assert!(!TimeFilter::before("1min").unwrap().is_within(&now));
fn is_time_filter_applicable() {
use humantime;
let t1m_ago = SystemTime::now() - time::Duration::from_secs(60);
assert!(!TimeFilter::after("30sec").unwrap().is_within(&t1m_ago));
assert!(TimeFilter::after("2min").unwrap().is_within(&t1m_ago));
let ref_time = humantime::parse_rfc3339("2010-10-10T10:10:10Z").unwrap();
assert!(
TimeFilter::after(&ref_time, "1min")
.unwrap()
.applies_to(&ref_time)
);
assert!(
!TimeFilter::before(&ref_time, "1min")
.unwrap()
.applies_to(&ref_time)
);
assert!(TimeFilter::before("30sec").unwrap().is_within(&t1m_ago));
assert!(!TimeFilter::before("2min").unwrap().is_within(&t1m_ago));
let t1m_ago = ref_time - time::Duration::from_secs(60);
assert!(
!TimeFilter::after(&ref_time, "30sec")
.unwrap()
.applies_to(&t1m_ago)
);
assert!(
TimeFilter::after(&ref_time, "2min")
.unwrap()
.applies_to(&t1m_ago)
);
assert!(
TimeFilter::before(&ref_time, "30sec")
.unwrap()
.applies_to(&t1m_ago)
);
assert!(
!TimeFilter::before(&ref_time, "2min")
.unwrap()
.applies_to(&t1m_ago)
);
let t10s_before = "2010-10-10 10:10:00";
assert!(
!TimeFilter::before(&ref_time, t10s_before)
.unwrap()
.applies_to(&ref_time)
);
assert!(
TimeFilter::before(&ref_time, t10s_before)
.unwrap()
.applies_to(&t1m_ago)
);
assert!(
TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.applies_to(&ref_time)
);
assert!(
!TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.applies_to(&t1m_ago)
);
}
}

View File

@ -19,8 +19,6 @@ extern crate libc;
extern crate num_cpus;
extern crate regex;
extern crate regex_syntax;
#[macro_use]
extern crate if_chain;
mod app;
mod exec;
@ -153,17 +151,18 @@ fn main() {
})
.unwrap_or_else(|| vec![]);
let mut modification_constraints: Vec<TimeFilter> = Vec::new();
let now = time::SystemTime::now();
let mut time_constraints: Vec<TimeFilter> = Vec::new();
if let Some(t) = matches.value_of("changed-within") {
if let Some(f) = TimeFilter::after(t) {
modification_constraints.push(f);
if let Some(f) = TimeFilter::after(&now, t) {
time_constraints.push(f);
} else {
print_error_and_exit(&format!("Error: {} is not a valid time.", t));
}
}
if let Some(t) = matches.value_of("changed-before") {
if let Some(f) = TimeFilter::before(t) {
modification_constraints.push(f);
if let Some(f) = TimeFilter::before(&now, t) {
time_constraints.push(f);
} else {
print_error_and_exit(&format!("Error: {} is not a valid time.", t));
}
@ -245,7 +244,7 @@ fn main() {
.map(|vs| vs.map(PathBuf::from).collect())
.unwrap_or_else(|| vec![]),
size_constraints: size_limits,
modification_constraints,
time_constraints,
};
match RegexBuilder::new(&pattern_regex)

View File

@ -290,18 +290,21 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<FdOptions>) {
}
// Filter out unwanted modification times
if !config.modification_constraints.is_empty() {
if_chain!{
if entry_path.is_file();
if let Ok(metadata) = entry_path.metadata();
if let Ok(modified) = metadata.modified();
if config.modification_constraints.iter().all(|tf| tf.is_within(&modified));
then {
// When all is good, we just continue with pattern match
} else {
return ignore::WalkState::Continue;
if !config.time_constraints.is_empty() {
let mut matched = false;
if entry_path.is_file() {
if let Ok(metadata) = entry_path.metadata() {
if let Ok(modified) = metadata.modified() {
matched = config
.time_constraints
.iter()
.all(|tf| tf.applies_to(&modified));
}
}
}
if !matched {
return ignore::WalkState::Continue;
}
}
let search_str_o = if config.search_full_path {

View File

@ -1125,31 +1125,32 @@ fn create_file_with_modified<P: AsRef<Path>>(path: P, duration_in_secs: u64) {
#[test]
fn test_modified_relative() {
let te = TestEnv::new(&[], &[]);
create_file_with_modified(te.test_root().join("0_now"), 0);
create_file_with_modified(te.test_root().join("1_min"), 60);
create_file_with_modified(te.test_root().join("10_min"), 600);
create_file_with_modified(te.test_root().join("1_h"), 60 * 60);
create_file_with_modified(te.test_root().join("2_h"), 2 * 60 * 60);
create_file_with_modified(te.test_root().join("1_day"), 24 * 60 * 60);
create_file_with_modified(te.test_root().join("foo_0_now"), 0);
create_file_with_modified(te.test_root().join("bar_1_min"), 60);
create_file_with_modified(te.test_root().join("foo_10_min"), 600);
create_file_with_modified(te.test_root().join("bar_1_h"), 60 * 60);
create_file_with_modified(te.test_root().join("foo_2_h"), 2 * 60 * 60);
create_file_with_modified(te.test_root().join("bar_1_day"), 24 * 60 * 60);
te.assert_output(
&["", "--changed-within", "15min"],
"0_now
1_min
10_min",
"foo_0_now
bar_1_min
foo_10_min",
);
te.assert_output(
&["", "--changed-before", "15min"],
"1_h
2_h
1_day",
"bar_1_h
foo_2_h
bar_1_day",
);
te.assert_output(
&["min", "--changed-within", "12h"],
"1_min
10_min",
&["foo", "--changed-within", "12h"],
"foo_0_now
foo_10_min
foo_2_h",
);
}