diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-23 00:59:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-23 01:57:21 +0900 |
| commit | d707cc1ed26efa62c74243254a95fae17192a840 (patch) | |
| tree | 30ce45b22cb1eb9173e6060380ce4b257d83d413 /crates/mozart/src/commands/clear_cache.rs | |
| parent | d348ff405ca9f37711f918db9570598ca85e3a55 (diff) | |
| download | php-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/commands/clear_cache.rs')
| -rw-r--r-- | crates/mozart/src/commands/clear_cache.rs | 101 |
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(()) |
