diff --git a/crates/pm/src/cmd/clean.rs b/crates/pm/src/cmd/clean.rs index a10a645d8..e916a9cde 100644 --- a/crates/pm/src/cmd/clean.rs +++ b/crates/pm/src/cmd/clean.rs @@ -2,12 +2,11 @@ use anyhow::{Context, Result}; use std::io::{self, Write}; use tokio::fs; -use crate::util::cache::{collect_matching_versions, matches_pattern, parse_pattern}; +use crate::util::cache::{collect_matching_versions, get_cache_dir, matches_pattern, parse_pattern}; pub async fn clean(pattern: &str) -> Result<()> { - let cache_dir = dirs::home_dir() - .map(|p| p.join(".cache").join("nm")) - .context("Failed to get cache directory")?; + // Use get_cache_dir() which includes registry isolation + let cache_dir = get_cache_dir(); let (pkg_pattern, version_pattern) = parse_pattern(pattern); let mut to_delete = Vec::new(); diff --git a/crates/pm/src/util/cache.rs b/crates/pm/src/util/cache.rs index 178c6d22c..5b535ea35 100644 --- a/crates/pm/src/util/cache.rs +++ b/crates/pm/src/util/cache.rs @@ -84,8 +84,21 @@ pub async fn collect_matching_versions( Ok(()) } +/// Converts registry URL to directory name by removing protocol prefix and trailing slash. +fn registry_to_dir_name(registry_url: &str) -> String { + let url = registry_url + .strip_prefix("https://") + .or_else(|| registry_url.strip_prefix("http://")) + .unwrap_or(registry_url); + url.trim_end_matches('/').to_string() +} + +/// Returns cache directory path with registry isolation: ~/.cache/nm/registry-host/ pub fn get_cache_dir() -> PathBuf { - config::get_cache_dir() + let base_cache_dir = config::get_cache_dir(); + let registry = config::get_registry(); + let registry_dir = registry_to_dir_name(®istry); + base_cache_dir.join(registry_dir) } pub fn get_package_versions_cache_file(package_name: &str) -> PathBuf { @@ -265,6 +278,26 @@ mod tests { Ok(()) } + #[test] + fn test_registry_to_dir_name() { + assert_eq!( + registry_to_dir_name("https://registry.npmjs.org"), + "registry.npmjs.org" + ); + assert_eq!( + registry_to_dir_name("https://registry.npmmirror.com"), + "registry.npmmirror.com" + ); + assert_eq!( + registry_to_dir_name("https://registry.npmjs.org/"), + "registry.npmjs.org" + ); + assert_eq!( + registry_to_dir_name("http://registry.npmjs.org"), + "registry.npmjs.org" + ); + } + #[test] fn test_get_cache_dir_uses_config() { // Test that get_cache_dir delegates to config module @@ -274,6 +307,17 @@ mod tests { assert!(result.is_absolute() || result.starts_with("~") || result.starts_with(".")); } + #[test] + fn test_get_cache_dir_includes_registry() { + // Test that cache directory includes registry dimension + let cache_dir = get_cache_dir(); + let cache_dir_str = cache_dir.to_string_lossy(); + + // Should contain registry directory name + // The exact structure depends on current registry setting + assert!(cache_dir_str.contains("nm") || cache_dir_str.contains("cache")); + } + #[test] fn test_get_package_versions_cache_file() { let result = get_package_versions_cache_file("lodash");