use std::path::PathBuf;
use crate::error::CliError;
pub fn execute_cache_clear(store: Option<&str>) -> Result<(), CliError> {
match store {
Some(store_name) => clear_store(store_name),
None => clear_all(),
}
}
fn clear_store(store: &str) -> Result<(), CliError> {
let cache_dir = get_cache_dir(store);
if !cache_dir.exists() {
println!(
"Cache store '{}' directory not found: {}",
store,
cache_dir.display()
);
return Ok(());
}
let count = remove_dir_contents(&cache_dir)?;
println!(
"Cache store '{}' cleared: {} file(s) removed from {}",
store,
count,
cache_dir.display()
);
Ok(())
}
fn clear_all() -> Result<(), CliError> {
let cache_root = get_cache_root();
if !cache_root.exists() {
println!("Cache root directory not found: {}", cache_root.display());
println!("Nothing to clear.");
return Ok(());
}
let count = remove_dir_contents(&cache_root)?;
println!(
"All caches cleared: {} file(s)/dir(s) removed from {}",
count,
cache_root.display()
);
Ok(())
}
fn get_cache_root() -> PathBuf {
PathBuf::from("runtime/cache")
}
fn get_cache_dir(store: &str) -> PathBuf {
get_cache_root().join(store)
}
fn remove_dir_contents(path: &PathBuf) -> Result<usize, CliError> {
let mut count = 0;
let entries = std::fs::read_dir(path)?;
for entry in entries {
let entry = entry?;
let entry_path = entry.path();
if entry_path.is_dir() {
std::fs::remove_dir_all(&entry_path)?;
} else {
std::fs::remove_file(&entry_path)?;
}
count += 1;
}
Ok(count)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::io::Write;
#[test]
fn test_get_cache_root_default() {
let root = get_cache_root();
assert_eq!(root, PathBuf::from("runtime/cache"));
}
#[test]
fn test_get_cache_dir_with_store() {
let dir = get_cache_dir("redis");
assert_eq!(dir, PathBuf::from("runtime/cache/redis"));
}
#[test]
fn test_clear_all_nonexistent_dir() {
let temp = tempfile::tempdir().unwrap();
let cache_root = temp.path().join("runtime/cache");
assert!(!cache_root.exists());
}
#[test]
fn test_clear_all_with_files_via_remove_dir_contents() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().to_path_buf();
let file1 = root.join("cache1.txt");
let file2 = root.join("cache2.txt");
let mut f1 = fs::File::create(&file1).unwrap();
writeln!(f1, "data1").unwrap();
let mut f2 = fs::File::create(&file2).unwrap();
writeln!(f2, "data2").unwrap();
let count = remove_dir_contents(&root).unwrap();
assert_eq!(count, 2);
assert!(!file1.exists());
assert!(!file2.exists());
}
#[test]
fn test_clear_store_nonexistent() {
let temp = tempfile::tempdir().unwrap();
let store_dir = temp.path().join("nonexistent_store");
assert!(!store_dir.exists());
}
#[test]
fn test_clear_store_with_files_via_remove_dir_contents() {
let temp = tempfile::tempdir().unwrap();
let store_dir = temp.path().join("redis");
fs::create_dir_all(&store_dir).unwrap();
let cache_file = store_dir.join("key1.txt");
let mut f = fs::File::create(&cache_file).unwrap();
writeln!(f, "redis_data").unwrap();
let count = remove_dir_contents(&store_dir).unwrap();
assert_eq!(count, 1);
assert!(!cache_file.exists());
}
#[test]
fn test_remove_dir_contents_with_subdirs() {
let temp = tempfile::tempdir().unwrap();
let root = temp.path().to_path_buf();
let sub_dir = root.join("subdir");
fs::create_dir_all(&sub_dir).unwrap();
fs::File::create(root.join("file1.txt")).unwrap();
fs::File::create(sub_dir.join("file2.txt")).unwrap();
let count = remove_dir_contents(&root).unwrap();
assert_eq!(count, 2);
assert!(root.exists());
assert!(root.read_dir().unwrap().next().is_none());
}
#[test]
fn test_execute_cache_clear_no_store_nonexistent() {
let _lock = super::super::test_support::acquire_global_lock();
let temp = tempfile::tempdir().unwrap();
let original = std::env::current_dir().unwrap();
std::env::set_current_dir(temp.path()).unwrap();
let result = execute_cache_clear(None);
std::env::set_current_dir(&original).unwrap();
assert!(result.is_ok());
}
#[test]
fn test_execute_cache_clear_with_store_nonexistent() {
let result = execute_cache_clear(Some("nonexistent_store_xyz"));
assert!(result.is_ok());
}
}