use crate::classifier::{self, ClipboardStrategy};
use crate::debug_logger::create_logger;
use anyhow::Result;
use ignore::WalkBuilder;
use std::path::PathBuf;
pub struct WalkerOptions {
pub include_binary: bool,
pub no_ignore: bool,
pub include_hidden: bool,
}
pub fn walk_and_expand(
paths: &[PathBuf],
options: &WalkerOptions,
) -> Result<(Vec<PathBuf>, usize)> {
let log = create_logger("walker");
let mut results = Vec::new();
let mut dir_count = 0;
if paths.is_empty() {
return Ok((results, 0));
}
let mut builder = WalkBuilder::new(&paths[0]);
for p in &paths[1..] {
builder.add(p);
}
if options.no_ignore {
log.debug("Disabling ignore rules (.gitignore, etc.)");
builder.git_ignore(false).git_global(false).ignore(false);
}
if options.include_hidden {
log.debug("Including hidden files");
builder.hidden(false);
}
log.debug(&format!("Starting recursive walk on {} roots", paths.len()));
for result in builder.build() {
match result {
Ok(entry) => {
let path = entry.path();
if path.is_dir() {
dir_count += 1;
continue;
}
if options.include_binary {
log.debug(&format!("Accepted file (binary check skipped): {:?}", path));
results.push(path.to_path_buf());
continue;
}
match classifier::inspect(path) {
Ok(ClipboardStrategy::Text) => {
log.debug(&format!("Accepted text file: {:?}", path));
results.push(path.to_path_buf());
}
Ok(_) => {
log.warn(&format!("Ignoring binary/image file: {:?}", path));
if !options.include_binary {
eprintln!("Warning: Ignoring binary file: {:?}", path);
}
}
Err(e) => {
log.warn(&format!("Failed to classify {:?}: {}", path, e));
}
}
}
Err(err) => {
log.error(&format!("Walker error: {}", err));
}
}
}
results.sort();
log.info(&format!(
"Found {} valid files in {} directories",
results.len(),
dir_count
));
Ok((results, dir_count))
}