use std::path::{Component, Path, PathBuf};
use std::{env, fs, io};
fn is_node_modules_path(path: &Path) -> bool {
let comps = path.components();
for comp in comps {
if comp == Component::Normal("node_modules".as_ref()) {
return true;
}
}
false
}
fn find_node_module_dirs(dir: &Path) -> io::Result<Vec<PathBuf>> {
let mut nm_dirs: Vec<PathBuf> = Vec::new();
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if is_node_modules_path(&path) {
nm_dirs.push(path.clone());
} else if path.is_dir() {
let mut paths = find_node_module_dirs(&path)?;
if paths.len() > 0 {
nm_dirs.append(&mut paths);
}
}
}
}
Ok(nm_dirs)
}
fn remove_dirs(dirs: Vec<PathBuf>) -> io::Result<()> {
for dir in dirs {
println!("{} has removed", dir.display());
fs::remove_dir_all(dir)?
}
Ok(())
}
fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();
let mut is_check_only = true;
if args.len() > 1 {
is_check_only = &args[1] != "clean";
}
if is_check_only {
println!("!!check mode!!");
} else {
println!("!!clean mode!!");
}
let current_dir = env::current_dir()?;
println!("current dir: {:?}", current_dir);
let nm_paths = find_node_module_dirs(¤t_dir)?;
println!("{} node_modules to be cleaned", nm_paths.len());
if is_check_only {
println!("paths: {:?}", nm_paths);
Ok(())
} else {
remove_dirs(nm_paths)
}
}