Feature/Bugfix: Allow multiple regexs to be used

The -e and -v flags allow multiple values. Before values after the first
were ignored. This change allows the user to specify multiple regexs and
have them all applied.
This commit is contained in:
andy.boot
2021-10-24 10:13:12 +01:00
parent 1b07c3c4f3
commit 9f91d446c1
4 changed files with 40 additions and 32 deletions
+5 -5
View File
@@ -20,8 +20,8 @@ use crate::platform::get_metadata;
pub struct WalkData {
pub ignore_directories: HashSet<PathBuf>,
pub filter_regex: Option<Regex>,
pub invert_filter_regex: Option<Regex>,
pub filter_regex: Vec<Regex>,
pub invert_filter_regex: Vec<Regex>,
pub allowed_filesystems: HashSet<u64>,
pub use_apparent_size: bool,
pub by_filecount: bool,
@@ -90,15 +90,15 @@ fn ignore_file(entry: &DirEntry, walk_data: &WalkData) -> bool {
}
}
// Keeping `walk_data.filter_regex.is_some()` is important for performance reasons, it stops unnecessary work
if walk_data.filter_regex.is_some()
// Keeping `walk_data.filter_regex.is_empty()` is important for performance reasons, it stops unnecessary work
if !walk_data.filter_regex.is_empty()
&& entry.path().is_file()
&& is_filtered_out_due_to_regex(&walk_data.filter_regex, &entry.path())
{
return true;
}
if walk_data.invert_filter_regex.is_some()
if !walk_data.invert_filter_regex.is_empty()
&& entry.path().is_file()
&& is_filtered_out_due_to_invert_regex(&walk_data.invert_filter_regex, &entry.path())
{
+22 -16
View File
@@ -8,6 +8,7 @@ use std::collections::HashSet;
use std::process;
use self::display::draw_it;
use clap::Values;
use clap::{App, AppSettings, Arg};
use dir_walker::walk_it;
use dir_walker::WalkData;
@@ -83,17 +84,20 @@ fn get_width_of_terminal() -> usize {
}
}
fn get_regex_value(maybe_value: Option<&str>) -> Option<Regex> {
match maybe_value {
Some(v) => match Regex::new(v) {
Ok(r) => Some(r),
Err(e) => {
eprintln!("Ignoring bad value for regex {:?}", e);
process::exit(1);
fn get_regex_value(maybe_value: Option<Values>) -> Vec<Regex> {
let mut result = vec![];
if let Some(v) = maybe_value {
for reg in v {
match Regex::new(reg) {
Ok(r) => result.push(r),
Err(e) => {
eprintln!("Ignoring bad value for regex {:?}", e);
process::exit(1);
}
}
},
None => None,
}
}
result
}
fn main() {
@@ -225,8 +229,8 @@ fn main() {
let summarize_file_types = options.is_present("types");
let maybe_filter = get_regex_value(options.value_of("filter"));
let maybe_invert_filter = get_regex_value(options.value_of("invert_filter"));
let filter_regexs = get_regex_value(options.values_of("filter"));
let invert_filter_regexs = get_regex_value(options.values_of("invert_filter"));
let number_of_lines = match value_t!(options.value_of("number_of_lines"), usize) {
Ok(v) => v,
@@ -269,6 +273,11 @@ fn main() {
}
};
if options.is_present("filter") {
println!("Filtering by: {:?}", filter_regexs);
}
// todo incl invert regex
let ignored_full_path: HashSet<PathBuf> = ignore_directories
.into_iter()
.flat_map(|x| simplified_dirs.iter().map(move |d| d.join(x.clone())))
@@ -276,8 +285,8 @@ fn main() {
let walk_data = WalkData {
ignore_directories: ignored_full_path,
filter_regex: maybe_filter,
invert_filter_regex: maybe_invert_filter,
filter_regex: filter_regexs,
invert_filter_regex: invert_filter_regexs,
allowed_filesystems,
use_apparent_size,
by_filecount,
@@ -299,9 +308,6 @@ fn main() {
}
};
if options.is_present("filter") {
println!("Filtering by: {}", options.value_of("filter").unwrap());
}
if has_errors {
eprintln!("Did not have permissions for all directories");
}
+2 -2
View File
@@ -18,8 +18,8 @@ pub struct Node {
pub fn build_node(
dir: PathBuf,
children: Vec<Node>,
filter_regex: &Option<Regex>,
invert_filter_regex: &Option<Regex>,
filter_regex: &[Regex],
invert_filter_regex: &[Regex],
use_apparent_size: bool,
is_symlink: bool,
is_file: bool,
+11 -9
View File
@@ -57,18 +57,20 @@ pub fn normalize_path<P: AsRef<Path>>(path: P) -> PathBuf {
path.as_ref().components().collect::<PathBuf>()
}
pub fn is_filtered_out_due_to_regex(filter_regex: &Option<Regex>, dir: &Path) -> bool {
match filter_regex {
Some(fr) => !fr.is_match(&dir.as_os_str().to_string_lossy()),
None => false,
pub fn is_filtered_out_due_to_regex(filter_regex: &[Regex], dir: &Path) -> bool {
if filter_regex.is_empty() {
false
} else {
filter_regex
.iter()
.all(|f| !f.is_match(&dir.as_os_str().to_string_lossy()))
}
}
pub fn is_filtered_out_due_to_invert_regex(filter_regex: &Option<Regex>, dir: &Path) -> bool {
match filter_regex {
Some(fr) => fr.is_match(&dir.as_os_str().to_string_lossy()),
None => false,
}
pub fn is_filtered_out_due_to_invert_regex(filter_regex: &[Regex], dir: &Path) -> bool {
filter_regex
.iter()
.any(|f| f.is_match(&dir.as_os_str().to_string_lossy()))
}
fn is_a_parent_of<P: AsRef<Path>>(parent: P, child: P) -> bool {