use crate::dirs::CACHE;
use crate::file::{display_path, remove_all};
use crate::toolset::env_cache::CachedEnv;
use eyre::Result;
use filetime::set_file_times;
use heck::ToKebabCase;
use walkdir::WalkDir;
#[derive(Debug, clap::Args)]
#[clap(verbatim_doc_comment, visible_alias = "c", alias = "clean")]
pub struct CacheClear {
plugin: Option<Vec<String>>,
#[clap(long, hide = true)]
outdate: bool,
}
impl CacheClear {
pub fn run(self) -> Result<()> {
let cache_dirs = match &self.plugin {
Some(plugins) => plugins
.iter()
.filter_map(|p| {
let kebab = p.to_kebab_case();
if kebab.is_empty() {
warn!("invalid plugin name: {p}");
None
} else {
Some(CACHE.join(kebab))
}
})
.collect(),
None => vec![CACHE.to_path_buf()],
};
if self.outdate {
for p in cache_dirs {
if p.exists() {
debug!("outdating cache from {}", display_path(&p));
let files = WalkDir::new(&p)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file() || e.file_type().is_dir());
for e in files {
set_file_times(
e.path(),
filetime::FileTime::zero(),
filetime::FileTime::zero(),
)?;
}
}
}
} else {
for p in cache_dirs {
if p.exists() {
debug!("clearing cache from {}", display_path(&p));
remove_all(p)?;
}
}
if self.plugin.is_none() {
CachedEnv::clear()?;
}
match &self.plugin {
Some(plugins) => info!("cache cleared for {}", plugins.join(", ")),
None => info!("cache cleared"),
}
}
Ok(())
}
}