shitbox/corebox/commands/rmdir/mod.rs

66 lines
2.0 KiB
Rust

use super::Cmd;
use clap::{Arg, ArgAction, Command, ValueHint};
use shitbox::args;
use std::{error::Error, fs, path::Path};
#[derive(Debug)]
pub struct Rmdir;
impl Cmd for Rmdir {
fn cli(&self) -> clap::Command {
Command::new("rmdir")
.about("remove directories")
.author("Nathan Fisher")
.version(env!("CARGO_PKG_VERSION"))
.args([
Arg::new("parents")
.help("remove DIRECTORY and it's ancestors")
.short('p')
.long("parents")
.action(ArgAction::SetTrue),
Arg::new("dir")
.num_args(1..)
.value_name("DIRECTORY")
.value_hint(ValueHint::DirPath)
.required(true),
args::verbose(),
])
}
fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box<dyn std::error::Error>> {
if let Some(directories) = matches.get_many::<String>("dir") {
for dir in directories {
if matches.get_flag("parents") {
let path = Path::new(dir);
rmdir_recursive(path, matches.get_flag("verbose"))?;
} else {
fs::remove_dir(dir)?;
if matches.get_flag("verbose") {
println!("rmdir: removing directory, '{dir}'");
}
}
}
}
Ok(())
}
fn path(&self) -> Option<shitbox::Path> {
Some(shitbox::Path::Bin)
}
}
fn rmdir_recursive(dir: &Path, verbose: bool) -> Result<(), Box<dyn Error>> {
fs::remove_dir(dir)?;
if verbose {
println!("rmdir: removing directory, '{}'", dir.display());
}
if let Some(parent) = dir.parent() {
if let Some(name) = parent.to_str() {
if !name.is_empty() {
rmdir_recursive(parent, verbose)?;
}
}
}
Ok(())
}