use crate::args::Args;
use ignore::{WalkBuilder, WalkParallel};
use std::path::PathBuf;
pub fn build_walker(args: &Args, paths: &[PathBuf]) -> WalkParallel {
let first_path = &paths[0];
let mut builder = WalkBuilder::new(first_path);
builder
.hidden(false)
.standard_filters(false)
.follow_links(args.follow_symlinks)
.same_file_system(args.one_filesystem)
.max_depth(args.max_depth);
for p in &paths[1..] {
builder.add(p);
}
builder.threads(args.threads - 1).build_parallel()
}
#[cfg(test)]
mod tests {
use super::*;
use crate::args;
use tempfile::TempDir;
fn base_args(path: PathBuf) -> Args {
Args {
threads: 2,
path: vec![path],
follow_symlinks: false,
one_filesystem: true,
max_depth: None,
name: None,
regex: None,
case_insensitive: false,
file_type: vec![
args::FileType::File,
args::FileType::Directory,
args::FileType::Symlink,
],
}
}
#[test]
fn test_build_walker_no_panic() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().to_path_buf();
let args = base_args(path.clone());
let _walker = build_walker(&args, &[path]);
}
#[test]
fn test_build_walker_with_max_depth() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().to_path_buf();
let mut args = base_args(path.clone());
args.max_depth = Some(1);
let _walker = build_walker(&args, &[path]);
}
#[test]
fn test_build_walker_follow_symlinks() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().to_path_buf();
let mut args = base_args(path.clone());
args.follow_symlinks = true;
let _walker = build_walker(&args, &[path]);
}
#[test]
fn test_build_walker_no_one_filesystem() {
let tmp = TempDir::new().unwrap();
let path = tmp.path().to_path_buf();
let mut args = base_args(path.clone());
args.one_filesystem = false;
let _walker = build_walker(&args, &[path]);
}
#[test]
fn test_build_walker_multiple_paths() {
let tmp1 = TempDir::new().unwrap();
let tmp2 = TempDir::new().unwrap();
let p1 = tmp1.path().to_path_buf();
let p2 = tmp2.path().to_path_buf();
let args = base_args(p1.clone());
let _walker = build_walker(&args, &[p1, p2]);
}
#[test]
fn test_build_walker_yields_entries() {
use std::fs;
use std::sync::{Arc, Mutex};
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join("a.txt"), b"hi").unwrap();
let path = tmp.path().to_path_buf();
let args = base_args(path.clone());
let walker = build_walker(&args, &[path]);
let paths: Arc<Mutex<Vec<PathBuf>>> =
Arc::new(Mutex::new(Vec::new()));
walker.run(|| {
let paths = Arc::clone(&paths);
Box::new(move |entry| {
if let Ok(e) = entry {
paths.lock().unwrap().push(e.path().to_path_buf());
}
ignore::WalkState::Continue
})
});
let paths = paths.lock().unwrap();
assert!(
paths.iter().any(|p| p.ends_with("a.txt")),
"a.txt not found in walk results"
);
}
}