use std::{fs, path::{Path}};
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
use failure::Error;
use gitignore::File;
use regex::Regex;
use walkdir::WalkDir;
fn should_delete(
path: &Path,
_gitignore: &File,
re: &Regex,
ignored_roots: &Vec<&str>,
) -> Result<bool, Error> {
let path = path.strip_prefix("./")?;
Ok(
!ignored_roots
.iter()
.any(|ignore| path.starts_with(ignore))
&& re.is_match(path.to_str().unwrap())
)
}
fn main() {
let matches = App::new(crate_name!())
.author(crate_authors!())
.about(crate_description!())
.version(crate_version!())
.arg(
Arg::with_name("pattern")
.takes_value(true)
.help("File or path REGEX pattern to delete")
.required(true),
)
.arg(
Arg::with_name("dry_run")
.long("dry-run")
.takes_value(false)
.required(false)
.help("Just print file paths to stdout. Don't delete anything"),
)
.arg(
Arg::with_name("root_ignores")
.long("ignore-root-dir")
.short("i")
.help("Add a root-level directory to the list of dirs to ignore")
.takes_value(true)
.multiple(true)
.required(false),
)
.get_matches();
let pattern = matches.value_of("pattern").unwrap();
let dry_run = matches.is_present("dry_run");
let mut ignores = match matches.values_of("root_ignores") {
Some(ignores) => ignores.collect::<Vec<&str>>(),
None => Vec::new(),
};
if pattern.is_empty() {
println!("You do NOT want an empty pattern!!!!");
return;
}
ignores.push(".git");
let re = regex::Regex::new(pattern).unwrap();
let gitignore = gitignore::File::new(Path::new(".gitignore"))
.expect("Could not load '.gitignore'. Are you in the correct directory?");
for path in WalkDir::new(".") {
match path {
Ok(path) => {
if should_delete(path.path(), &gitignore, &re, &ignores).unwrap_or(false) {
println!("DEL: {}", path.path().display());
if !dry_run {
fs::remove_file(path.path()).unwrap();
}
}
}
Err(_) => todo!(),
}
}
}