aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-23 00:59:33 +0900
committernsfisis <nsfisis@gmail.com>2026-02-23 01:57:21 +0900
commitd707cc1ed26efa62c74243254a95fae17192a840 (patch)
tree30ce45b22cb1eb9173e6060380ce4b257d83d413 /crates/mozart/src
parentd348ff405ca9f37711f918db9570598ca85e3a55 (diff)
downloadphp-mozart-d707cc1ed26efa62c74243254a95fae17192a840.tar.gz
php-mozart-d707cc1ed26efa62c74243254a95fae17192a840.tar.zst
php-mozart-d707cc1ed26efa62c74243254a95fae17192a840.zip
fix(clear-cache): add per-directory output, read-only guard, and always exit 0
Match Composer's ClearCacheCommand behavior: - Print per-directory status messages (clearing/GC) instead of a single summary - Skip read-only caches with an informational message - Print message for non-existent cache directories instead of silently skipping - Catch filesystem errors and always return exit code 0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart/src')
-rw-r--r--crates/mozart/src/commands/clear_cache.rs101
1 files changed, 72 insertions, 29 deletions
diff --git a/crates/mozart/src/commands/clear_cache.rs b/crates/mozart/src/commands/clear_cache.rs
index 7bca623..d3acc28 100644
--- a/crates/mozart/src/commands/clear_cache.rs
+++ b/crates/mozart/src/commands/clear_cache.rs
@@ -15,42 +15,85 @@ pub async fn execute(
) -> anyhow::Result<()> {
let config = build_cache_config(cli.no_cache);
- if args.gc {
- // Run GC only (probabilistic under normal circumstances, but forced here)
- let repo_cache = Cache::repo(&config);
- let files_cache = Cache::files(&config);
+ // Build the list of (key, path) pairs to process.
+ // cache-dir is only included in full clear mode, not GC mode.
+ let mut cache_paths: Vec<(&str, &std::path::PathBuf)> = vec![
+ ("cache-repo-dir", &config.cache_repo_dir),
+ ("cache-files-dir", &config.cache_files_dir),
+ ];
+ if !args.gc {
+ cache_paths.push(("cache-dir", &config.cache_dir));
+ }
- // Composer enforces a 1 GB cap on the repo cache during GC
- repo_cache.gc(config.cache_ttl, 1024 * 1024 * 1024)?;
- files_cache.gc(config.cache_files_ttl, config.cache_files_maxsize)?;
+ for (key, path) in &cache_paths {
+ // Read-only guard: skip with informational message
+ if config.read_only {
+ console.info(&format!("Cache is not enabled ({key}): {}", path.display()));
+ continue;
+ }
- console.info("Cache garbage collection complete.");
- console.info(&format!("Cache directory: {}", config.cache_dir.display()));
- } else {
- // Full clear of all cache directories
- let repo_cache = Cache::repo(&config);
- let files_cache = Cache::files(&config);
- repo_cache.clear()?;
- files_cache.clear()?;
- // Clear anything else at the root that isn't covered by sub-caches
- if config.cache_dir.exists() {
- for entry in std::fs::read_dir(&config.cache_dir)? {
- let entry = entry?;
- let path = entry.path();
- // Skip repo/files subdirs (already cleared above)
- if path == config.cache_files_dir || path == config.cache_repo_dir {
- continue;
+ // Non-existent directory: skip with informational message
+ if !path.exists() {
+ console.info(&format!(
+ "Cache directory does not exist ({key}): {}",
+ path.display()
+ ));
+ continue;
+ }
+
+ if args.gc {
+ console.info(&format!(
+ "Garbage-collecting cache ({key}): {}",
+ path.display()
+ ));
+ let cache = Cache::new((*path).clone(), !config.no_cache);
+ let result = if *key == "cache-files-dir" {
+ cache.gc(config.cache_files_ttl, config.cache_files_maxsize)
+ } else {
+ // cache-repo-dir: 1 GB cap (matches Composer)
+ cache.gc(config.cache_ttl, 1024 * 1024 * 1024)
+ };
+ if let Err(e) = result {
+ console.error(&format!("Error during GC of {key}: {e}"));
+ }
+ } else {
+ console.info(&format!("Clearing cache ({key}): {}", path.display()));
+ if *key == "cache-dir" {
+ // Clear anything at the root that isn't covered by sub-caches
+ let result = (|| -> anyhow::Result<()> {
+ for entry in std::fs::read_dir(path)? {
+ let entry = entry?;
+ let entry_path = entry.path();
+ // Skip repo/files subdirs (cleared by their own iterations)
+ if entry_path == config.cache_files_dir
+ || entry_path == config.cache_repo_dir
+ {
+ continue;
+ }
+ if entry_path.is_file() {
+ std::fs::remove_file(&entry_path)?;
+ } else if entry_path.is_dir() {
+ std::fs::remove_dir_all(&entry_path)?;
+ }
+ }
+ Ok(())
+ })();
+ if let Err(e) = result {
+ console.error(&format!("Error clearing {key}: {e}"));
}
- if path.is_file() {
- std::fs::remove_file(&path)?;
- } else if path.is_dir() {
- std::fs::remove_dir_all(&path)?;
+ } else {
+ let cache = Cache::new((*path).clone(), !config.no_cache);
+ if let Err(e) = cache.clear() {
+ console.error(&format!("Error clearing {key}: {e}"));
}
}
}
+ }
- console.info("Cache cleared.");
- console.info(&format!("Cache directory: {}", config.cache_dir.display()));
+ if args.gc {
+ console.info("All caches garbage-collected.");
+ } else {
+ console.info("All caches cleared.");
}
Ok(())