aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/mozart-registry/src/lockfile.rs13
-rw-r--r--crates/mozart-registry/src/packagist.rs17
-rw-r--r--crates/mozart-registry/src/resolver.rs27
-rw-r--r--crates/mozart/src/commands/archive.rs9
-rw-r--r--crates/mozart/src/commands/browse.rs8
-rw-r--r--crates/mozart/src/commands/create_project.rs9
-rw-r--r--crates/mozart/src/commands/init.rs30
-rw-r--r--crates/mozart/src/commands/outdated.rs12
-rw-r--r--crates/mozart/src/commands/remove.rs34
-rw-r--r--crates/mozart/src/commands/require.rs33
-rw-r--r--crates/mozart/src/commands/show.rs52
-rw-r--r--crates/mozart/src/commands/update.rs17
12 files changed, 174 insertions, 87 deletions
diff --git a/crates/mozart-registry/src/lockfile.rs b/crates/mozart-registry/src/lockfile.rs
index 8f27fbf..eea9b29 100644
--- a/crates/mozart-registry/src/lockfile.rs
+++ b/crates/mozart-registry/src/lockfile.rs
@@ -242,8 +242,8 @@ pub struct LockFileGenerationRequest {
pub composer_json: RawPackageData,
/// Whether require-dev was included in resolution.
pub include_dev: bool,
- /// Optional repo cache for Packagist API calls made during generation.
- pub repo_cache: Option<Cache>,
+ /// Repo cache for Packagist API calls made during generation.
+ pub repo_cache: Cache,
}
/// Convert a `PackagistSource` to a `LockedSource`.
@@ -396,8 +396,7 @@ pub async fn generate_lock_file(request: &LockFileGenerationRequest) -> anyhow::
// 1. Fetch full metadata for all resolved packages
let mut package_metadata: HashMap<String, PackagistVersion> = HashMap::new();
for pkg in &request.resolved_packages {
- let versions =
- packagist::fetch_package_versions(&pkg.name, request.repo_cache.as_ref()).await?;
+ let versions = packagist::fetch_package_versions(&pkg.name, &request.repo_cache).await?;
// Find the exact version matching pkg.version_normalized
let matching = versions
.into_iter()
@@ -925,7 +924,7 @@ mod tests {
composer_json_content: composer_json_content.clone(),
composer_json,
include_dev: true,
- repo_cache: None,
+ repo_cache: Cache::new(std::env::temp_dir().join("mozart-test-cache"), false),
};
let lock = generate_lock_file(&request).await.unwrap();
@@ -1030,7 +1029,7 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: Cache::new(std::env::temp_dir().join("mozart-test-cache"), false),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -1049,7 +1048,7 @@ mod tests {
composer_json_content: composer_json_content.clone(),
composer_json,
include_dev: false,
- repo_cache: None,
+ repo_cache: Cache::new(std::env::temp_dir().join("mozart-test-cache"), false),
};
let lock = generate_lock_file(&gen_request)
diff --git a/crates/mozart-registry/src/packagist.rs b/crates/mozart-registry/src/packagist.rs
index 8a5f205..64ff11a 100644
--- a/crates/mozart-registry/src/packagist.rs
+++ b/crates/mozart-registry/src/packagist.rs
@@ -212,21 +212,20 @@ pub fn parse_p2_response(json: &str, package_name: &str) -> anyhow::Result<Vec<P
/// Fetch package version metadata from the Packagist p2 API.
///
-/// If `repo_cache` is provided, the JSON response is cached on disk under the
-/// key `"provider-{vendor}~{package}.json"`. Subsequent calls for the same
-/// package are served from cache without a network request.
+/// The JSON response is cached on disk under the key
+/// `"provider-{vendor}~{package}.json"`. Subsequent calls for the same
+/// package are served from cache without a network request (unless the
+/// cache is disabled).
#[tracing::instrument(skip(repo_cache))]
pub async fn fetch_package_versions(
package_name: &str,
- repo_cache: Option<&Cache>,
+ repo_cache: &Cache,
) -> anyhow::Result<Vec<PackagistVersion>> {
// Build cache key: replace `/` with `~` per cache key convention
let cache_key = format!("provider-{}.json", package_name.replace('/', "~"));
// Check cache first
- if let Some(cache) = repo_cache
- && let Some(cached) = cache.read(&cache_key)
- {
+ if let Some(cached) = repo_cache.read(&cache_key) {
tracing::debug!("cache hit");
return parse_p2_response(&cached, package_name);
}
@@ -250,9 +249,7 @@ pub async fn fetch_package_versions(
let body = response.text().await?;
// Write to cache
- if let Some(cache) = repo_cache {
- let _ = cache.write(&cache_key, &body);
- }
+ let _ = repo_cache.write(&cache_key, &body);
parse_p2_response(&body, package_name)
}
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs
index 1cd5bb6..fe59824 100644
--- a/crates/mozart-registry/src/resolver.rs
+++ b/crates/mozart-registry/src/resolver.rs
@@ -344,8 +344,8 @@ pub struct ResolveRequest {
pub ignore_platform_reqs: bool,
/// Specific platform requirements to ignore.
pub ignore_platform_req_list: Vec<String>,
- /// Optional on-disk repo cache for Packagist API responses.
- pub repo_cache: Option<Cache>,
+ /// On-disk repo cache for Packagist API responses.
+ pub repo_cache: Cache,
/// Temporary version constraint overrides (from --with flag).
/// Maps package name (lowercase) to constraint string.
pub temporary_constraints: HashMap<String, String>,
@@ -475,7 +475,7 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R
}
// Fetch available versions from Packagist
- let versions = packagist::fetch_package_versions(name, request.repo_cache.as_ref())
+ let versions = packagist::fetch_package_versions(name, &request.repo_cache)
.await
.map_err(|e| {
ResolveError::DependencyFetchError(format!("Failed to fetch {}: {}", name, e))
@@ -506,16 +506,15 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R
continue;
}
- let versions =
- match packagist::fetch_package_versions(&name, request.repo_cache.as_ref()).await {
- Ok(v) => v,
- Err(_) => {
- // Virtual/meta packages (e.g. "psr/http-client-implementation")
- // don't exist on Packagist. They are resolved via provides/replaces
- // from other packages already in the pool.
- continue;
- }
- };
+ let versions = match packagist::fetch_package_versions(&name, &request.repo_cache).await {
+ Ok(v) => v,
+ Err(_) => {
+ // Virtual/meta packages (e.g. "psr/http-client-implementation")
+ // don't exist on Packagist. They are resolved via provides/replaces
+ // from other packages already in the pool.
+ continue;
+ }
+ };
for pv in &versions {
let inputs = packagist_to_pool_inputs(
@@ -965,7 +964,7 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: Cache::new(std::env::temp_dir().join("mozart-test-cache"), false),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
diff --git a/crates/mozart/src/commands/archive.rs b/crates/mozart/src/commands/archive.rs
index 335343d..2490246 100644
--- a/crates/mozart/src/commands/archive.rs
+++ b/crates/mozart/src/commands/archive.rs
@@ -94,6 +94,9 @@ pub async fn execute(
self_exclusion_patterns,
};
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// 1. Determine working directory
let working_dir = match &cli.working_dir {
Some(dir) => PathBuf::from(dir),
@@ -150,7 +153,7 @@ pub async fn execute(
let meta: PackageMeta = if let Some(ref pkg_name) = args.package {
// Remote package mode
console.info("Searching for the specified package.");
- resolve_remote_package(pkg_name, args.version.as_deref(), console).await?
+ resolve_remote_package(pkg_name, args.version.as_deref(), &repo_cache, console).await?
} else {
// Root package mode
if !composer_json_path.exists() {
@@ -244,6 +247,7 @@ pub async fn execute(
async fn resolve_remote_package(
package_name: &str,
version_constraint: Option<&str>,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<PackageMeta> {
use mozart_core::package::Stability;
@@ -265,7 +269,8 @@ async fn resolve_remote_package(
let version_constraint = constraint_stripped.as_deref();
// Fetch versions from Packagist
- let versions = mozart_registry::packagist::fetch_package_versions(package_name, None).await?;
+ let versions =
+ mozart_registry::packagist::fetch_package_versions(package_name, repo_cache).await?;
if versions.is_empty() {
anyhow::bail!("No versions found for package \"{}\"", package_name);
}
diff --git a/crates/mozart/src/commands/browse.rs b/crates/mozart/src/commands/browse.rs
index 905c3f8..768c53c 100644
--- a/crates/mozart/src/commands/browse.rs
+++ b/crates/mozart/src/commands/browse.rs
@@ -25,6 +25,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
let working_dir = match &cli.working_dir {
Some(dir) => PathBuf::from(dir),
None => std::env::current_dir()?,
@@ -48,7 +51,7 @@ pub async fn execute(
let mut exit_code = 0i32;
for package_name in &packages {
- match resolve_url(package_name, &working_dir, args.homepage).await? {
+ match resolve_url(package_name, &working_dir, args.homepage, &repo_cache).await? {
ResolveResult::Found(url) => {
if args.show {
console.write_stdout(
@@ -100,6 +103,7 @@ async fn resolve_url(
package_name: &str,
working_dir: &Path,
prefer_homepage: bool,
+ repo_cache: &mozart_registry::cache::Cache,
) -> anyhow::Result<ResolveResult> {
// 1. Check root package (composer.json)
let composer_json = working_dir.join("composer.json");
@@ -134,7 +138,7 @@ async fn resolve_url(
}
// 3. Fall back to Packagist API
- match mozart_registry::packagist::fetch_package_versions(package_name, None).await {
+ match mozart_registry::packagist::fetch_package_versions(package_name, repo_cache).await {
Ok(versions) if !versions.is_empty() => {
// Find the latest stable version (first non-dev, or fallback to first)
let best = versions
diff --git a/crates/mozart/src/commands/create_project.rs b/crates/mozart/src/commands/create_project.rs
index 83ad21d..63d8a1a 100644
--- a/crates/mozart/src/commands/create_project.rs
+++ b/crates/mozart/src/commands/create_project.rs
@@ -272,7 +272,10 @@ pub async fn execute(
));
console.info("Loading composer repositories with package information");
- let versions = packagist::fetch_package_versions(&package_name, None).await?;
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
+ let versions = packagist::fetch_package_versions(&package_name, &repo_cache).await?;
// Find the best candidate matching the version constraint and stability
let best = if let Some(ref constraint) = version_constraint {
@@ -411,7 +414,7 @@ pub async fn execute(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
temporary_constraints: HashMap::new(),
repositories: raw.repositories.clone(),
};
@@ -432,7 +435,7 @@ pub async fn execute(
composer_json_content: composer_json_content.clone(),
composer_json: raw.clone(),
include_dev: dev_mode,
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
})
.await?;
diff --git a/crates/mozart/src/commands/init.rs b/crates/mozart/src/commands/init.rs
index 0b5ab9e..25600f7 100644
--- a/crates/mozart/src/commands/init.rs
+++ b/crates/mozart/src/commands/init.rs
@@ -65,6 +65,9 @@ pub async fn execute(
cli: &super::Cli,
console: &console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
let working_dir = match &cli.working_dir {
Some(dir) => PathBuf::from(dir),
None => std::env::current_dir().context("Failed to get current directory")?,
@@ -85,7 +88,7 @@ pub async fn execute(
}
let composer = if console.interactive {
- build_interactive(args, console, &working_dir).await?
+ build_interactive(args, console, &working_dir, &repo_cache).await?
} else {
build_non_interactive(args, &working_dir)?
};
@@ -206,6 +209,7 @@ async fn build_interactive(
args: &InitArgs,
console: &console::Console,
working_dir: &Path,
+ repo_cache: &mozart_registry::cache::Cache,
) -> anyhow::Result<RawPackageData> {
console.info("");
console.info(&format!(
@@ -347,8 +351,14 @@ async fn build_interactive(
console.info("");
let mut require = parse_requirements(&args.require)?;
- let interactive_require =
- interactive_search_packages("require", &require, preferred_stability, console).await?;
+ let interactive_require = interactive_search_packages(
+ "require",
+ &require,
+ preferred_stability,
+ repo_cache,
+ console,
+ )
+ .await?;
for (name, constraint) in interactive_require {
require.insert(name, constraint);
}
@@ -366,9 +376,14 @@ async fn build_interactive(
.chain(require_dev.iter())
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
- let interactive_dev =
- interactive_search_packages("require-dev", &all_required, preferred_stability, console)
- .await?;
+ let interactive_dev = interactive_search_packages(
+ "require-dev",
+ &all_required,
+ preferred_stability,
+ repo_cache,
+ console,
+ )
+ .await?;
for (name, constraint) in interactive_dev {
require_dev.insert(name, constraint);
}
@@ -418,6 +433,7 @@ async fn interactive_search_packages(
label: &str,
already_required: &BTreeMap<String, String>,
preferred_stability: Stability,
+ repo_cache: &mozart_registry::cache::Cache,
console: &console::Console,
) -> anyhow::Result<BTreeMap<String, String>> {
let stdin = std::io::stdin();
@@ -546,7 +562,7 @@ async fn interactive_search_packages(
"<info>Using version constraint for {package_name} from Packagist...</info>"
));
- match packagist::fetch_package_versions(&package_name, None).await {
+ match packagist::fetch_package_versions(&package_name, repo_cache).await {
Ok(versions) => {
match version::find_best_candidate(&versions, preferred_stability) {
Some(best) => {
diff --git a/crates/mozart/src/commands/outdated.rs b/crates/mozart/src/commands/outdated.rs
index 09e36a9..4d0226d 100644
--- a/crates/mozart/src/commands/outdated.rs
+++ b/crates/mozart/src/commands/outdated.rs
@@ -102,6 +102,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// Validate mutually exclusive level filters
let level_count = args.major_only as u8 + args.minor_only as u8 + args.patch_only as u8;
if level_count > 1 {
@@ -172,7 +175,7 @@ pub async fn execute(
}
// Fetch latest version from Packagist
- let latest = match fetch_latest_version(&pkg.name).await {
+ let latest = match fetch_latest_version(&pkg.name, &repo_cache).await {
Ok(v) => v,
Err(_) => {
// Skip packages we can't fetch (platform packages, private, etc.)
@@ -323,11 +326,14 @@ fn load_locked_packages(working_dir: &Path, no_dev: bool) -> anyhow::Result<Vec<
// ─── Version fetching ────────────────────────────────────────────────────────
-async fn fetch_latest_version(name: &str) -> anyhow::Result<PackageInfo> {
+async fn fetch_latest_version(
+ name: &str,
+ repo_cache: &mozart_registry::cache::Cache,
+) -> anyhow::Result<PackageInfo> {
use mozart_core::package::Stability;
use mozart_registry::version::find_best_candidate;
- let versions = mozart_registry::packagist::fetch_package_versions(name, None).await?;
+ let versions = mozart_registry::packagist::fetch_package_versions(name, repo_cache).await?;
let best = find_best_candidate(&versions, Stability::Stable)
.ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?;
diff --git a/crates/mozart/src/commands/remove.rs b/crates/mozart/src/commands/remove.rs
index 2529391..d489466 100644
--- a/crates/mozart/src/commands/remove.rs
+++ b/crates/mozart/src/commands/remove.rs
@@ -102,6 +102,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// Step 1: Validate inputs
if args.packages.is_empty() && !args.unused {
anyhow::bail!("Not enough arguments (missing: \"packages\").");
@@ -132,7 +135,7 @@ pub async fn execute(
// When --unused is set with no explicit packages, we re-resolve to detect
// packages in the lock file that are no longer reachable from root requirements.
if args.unused && args.packages.is_empty() {
- return remove_unused(&raw, &working_dir, args, console).await;
+ return remove_unused(&raw, &working_dir, args, &repo_cache, console).await;
}
// Step 5: Determine which packages to remove and remove them
@@ -250,7 +253,7 @@ pub async fn execute(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
temporary_constraints: HashMap::new(),
repositories: raw.repositories.clone(),
};
@@ -343,7 +346,7 @@ pub async fn execute(
composer_json_content: composer_json_content.clone(),
composer_json: raw.clone(),
include_dev: dev_mode,
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
})
.await?;
@@ -455,6 +458,7 @@ async fn remove_unused(
raw: &package::RawPackageData,
working_dir: &std::path::Path,
args: &RemoveArgs,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let lock_path = working_dir.join("composer.lock");
@@ -499,7 +503,7 @@ async fn remove_unused(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
temporary_constraints: HashMap::new(),
repositories: raw.repositories.clone(),
};
@@ -556,7 +560,7 @@ async fn remove_unused(
composer_json_content,
composer_json: raw.clone(),
include_dev: dev_mode,
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
})
.await?;
@@ -831,7 +835,10 @@ mod tests {
platform: mozart_registry::resolver::PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -843,7 +850,10 @@ mod tests {
composer_json_content: content.to_string(),
composer_json: raw.clone(),
include_dev: false,
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
})
.await
.expect("initial lock file generation should succeed");
@@ -868,7 +878,10 @@ mod tests {
platform: mozart_registry::resolver::PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -882,7 +895,10 @@ mod tests {
composer_json_content: composer_json_content2,
composer_json: raw,
include_dev: false,
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
})
.await
.expect("post-remove lock file generation should succeed");
diff --git a/crates/mozart/src/commands/require.rs b/crates/mozart/src/commands/require.rs
index 2dda5fb..5f02f5f 100644
--- a/crates/mozart/src/commands/require.rs
+++ b/crates/mozart/src/commands/require.rs
@@ -136,6 +136,7 @@ async fn interactive_search_packages(
already_required: &std::collections::HashSet<String>,
preferred_stability: Stability,
fixed: bool,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<Vec<String>> {
let stdin = std::io::stdin();
@@ -272,7 +273,7 @@ async fn interactive_search_packages(
"<info>Using version constraint for {package_name} from Packagist...</info>"
));
- match packagist::fetch_package_versions(&package_name, None).await {
+ match packagist::fetch_package_versions(&package_name, repo_cache).await {
Ok(versions) => {
match version::find_best_candidate(&versions, preferred_stability) {
Some(best) => {
@@ -336,6 +337,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// Collect the effective list of packages to add.
// If none were provided on the CLI, try interactive search (unless --no-interaction).
let cli_packages: Vec<String> = if args.packages.is_empty() {
@@ -380,6 +384,7 @@ pub async fn execute(
&already_required,
preferred_stability,
args.fixed,
+ &repo_cache,
console,
)
.await?;
@@ -466,7 +471,7 @@ pub async fn execute(
Verbosity::Normal,
);
- let versions = packagist::fetch_package_versions(&name, None).await?;
+ let versions = packagist::fetch_package_versions(&name, &repo_cache).await?;
let best = version::find_best_candidate(&versions, preferred_stability)
.ok_or_else(|| {
anyhow::anyhow!(
@@ -637,7 +642,7 @@ pub async fn execute(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
temporary_constraints: HashMap::new(),
repositories: raw.repositories.clone(),
};
@@ -731,7 +736,7 @@ pub async fn execute(
composer_json_content: composer_json_content.clone(),
composer_json: raw.clone(),
include_dev: dev_mode,
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
})
.await?;
@@ -1016,7 +1021,10 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -1032,7 +1040,10 @@ mod tests {
composer_json_content: composer_json_content.to_string(),
composer_json,
include_dev: false,
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
})
.await
.expect("Lock file generation should succeed");
@@ -1070,7 +1081,10 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -1083,7 +1097,10 @@ mod tests {
composer_json_content: content.to_string(),
composer_json: raw,
include_dev: false,
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
})
.await
.expect("Lock file generation should succeed");
diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs
index 9bcc4ce..fa77321 100644
--- a/crates/mozart/src/commands/show.rs
+++ b/crates/mozart/src/commands/show.rs
@@ -107,6 +107,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// Validate mutually exclusive level filters
let level_count = args.major_only as u8 + args.minor_only as u8 + args.patch_only as u8;
if level_count > 1 {
@@ -185,16 +188,16 @@ pub async fn execute(
// --available: show available versions for installed packages
if args.available {
- return show_available(args, &working_dir, console).await;
+ return show_available(args, &working_dir, &repo_cache, console).await;
}
// --locked: show from lock file
if args.locked {
- return execute_locked(args, &working_dir, console).await;
+ return execute_locked(args, &working_dir, &repo_cache, console).await;
}
// Default: installed mode
- execute_installed(args, &working_dir, console).await
+ execute_installed(args, &working_dir, &repo_cache, console).await
}
// ─── Installed mode ────────────────────────────────────────────────────────
@@ -202,6 +205,7 @@ pub async fn execute(
async fn execute_installed(
args: &ShowArgs,
working_dir: &Path,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let vendor_dir = working_dir.join("vendor");
@@ -256,7 +260,7 @@ async fn execute_installed(
if let Some(ref package_filter) = args.package {
if package_filter.contains('*') {
packages.retain(|p| matches_wildcard(&p.name, package_filter));
- show_installed_package_list(&packages, args, &vendor_dir, console).await?;
+ show_installed_package_list(&packages, args, &vendor_dir, repo_cache, console).await?;
return Ok(());
} else {
// Single package detail view
@@ -275,7 +279,7 @@ async fn execute_installed(
}
// List view
- show_installed_package_list(&packages, args, &vendor_dir, console).await
+ show_installed_package_list(&packages, args, &vendor_dir, repo_cache, console).await
}
fn filter_installed_packages<'a>(
@@ -320,6 +324,7 @@ async fn show_installed_package_list(
packages: &[&mozart_registry::installed::InstalledPackageEntry],
args: &ShowArgs,
_vendor_dir: &Path,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
// --latest / --outdated: fetch latest versions from Packagist
@@ -354,7 +359,7 @@ async fn show_installed_package_list(
let description = get_installed_description(pkg);
let latest_info = if show_latest {
- fetch_latest_for_package(&pkg.name).await.ok()
+ fetch_latest_for_package(&pkg.name, repo_cache).await.ok()
} else {
None
};
@@ -555,11 +560,14 @@ fn extract_major(version_normalized: &str) -> u64 {
.unwrap_or(0)
}
-async fn fetch_latest_for_package(name: &str) -> anyhow::Result<LatestInfo> {
+async fn fetch_latest_for_package(
+ name: &str,
+ repo_cache: &mozart_registry::cache::Cache,
+) -> anyhow::Result<LatestInfo> {
use mozart_core::package::Stability;
use mozart_registry::version::find_best_candidate;
- let versions = mozart_registry::packagist::fetch_package_versions(name, None).await?;
+ let versions = mozart_registry::packagist::fetch_package_versions(name, repo_cache).await?;
let best = find_best_candidate(&versions, Stability::Stable)
.ok_or_else(|| anyhow::anyhow!("No stable version found for {name}"))?;
@@ -777,6 +785,7 @@ fn show_installed_package_detail(
async fn execute_locked(
args: &ShowArgs,
working_dir: &Path,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let lock_path = working_dir.join("composer.lock");
@@ -818,12 +827,12 @@ async fn execute_locked(
if let Some(ref package_filter) = args.package {
if package_filter.contains('*') {
packages.retain(|p| matches_wildcard(&p.name, package_filter));
- show_locked_package_list(&packages, args, console).await?;
+ show_locked_package_list(&packages, args, repo_cache, console).await?;
} else {
show_locked_package_detail(&lock, package_filter, console)?;
}
} else {
- show_locked_package_list(&packages, args, console).await?;
+ show_locked_package_list(&packages, args, repo_cache, console).await?;
}
Ok(())
@@ -832,6 +841,7 @@ async fn execute_locked(
async fn show_locked_package_list(
packages: &[&mozart_registry::lockfile::LockedPackage],
args: &ShowArgs,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
let show_latest = args.latest || args.outdated;
@@ -865,7 +875,7 @@ async fn show_locked_package_list(
let description = pkg.description.as_deref().unwrap_or("").to_string();
let latest_info = if show_latest {
- fetch_latest_for_package(&pkg.name).await.ok()
+ fetch_latest_for_package(&pkg.name, repo_cache).await.ok()
} else {
None
};
@@ -1636,11 +1646,12 @@ fn show_platform(
async fn show_available(
args: &ShowArgs,
working_dir: &Path,
+ repo_cache: &mozart_registry::cache::Cache,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
// If a specific package name is given, show available versions for it
if let Some(ref pkg_name) = args.package {
- return show_available_versions(pkg_name, args, console).await;
+ return show_available_versions(pkg_name, repo_cache, args, console).await;
}
// Otherwise, show all installed packages with their available (latest) versions
@@ -1675,7 +1686,7 @@ async fn show_available(
if is_platform_package(&pkg.name) {
continue;
}
- show_available_versions_inline(&pkg.name, console).await;
+ show_available_versions_inline(&pkg.name, repo_cache, console).await;
}
return Ok(());
}
@@ -1706,7 +1717,7 @@ async fn show_available(
if is_platform_package(&pkg.name) {
continue;
}
- match mozart_registry::packagist::fetch_package_versions(&pkg.name, None).await {
+ match mozart_registry::packagist::fetch_package_versions(&pkg.name, repo_cache).await {
Ok(versions) => {
let version_strings: Vec<String> =
versions.iter().map(|v| v.version.clone()).collect();
@@ -1734,7 +1745,7 @@ async fn show_available(
if is_platform_package(&pkg.name) {
continue;
}
- show_available_versions_inline(&pkg.name, console).await;
+ show_available_versions_inline(&pkg.name, repo_cache, console).await;
}
Ok(())
@@ -1742,10 +1753,11 @@ async fn show_available(
async fn show_available_versions(
pkg_name: &str,
+ repo_cache: &mozart_registry::cache::Cache,
args: &ShowArgs,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
- let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, None).await?;
+ let versions = mozart_registry::packagist::fetch_package_versions(pkg_name, repo_cache).await?;
if versions.is_empty() {
console.write_stdout(
&format!("No versions found for {pkg_name}"),
@@ -1778,8 +1790,12 @@ async fn show_available_versions(
Ok(())
}
-async fn show_available_versions_inline(pkg_name: &str, console: &mozart_core::console::Console) {
- match mozart_registry::packagist::fetch_package_versions(pkg_name, None).await {
+async fn show_available_versions_inline(
+ pkg_name: &str,
+ repo_cache: &mozart_registry::cache::Cache,
+ console: &mozart_core::console::Console,
+) {
+ match mozart_registry::packagist::fetch_package_versions(pkg_name, repo_cache).await {
Ok(versions) => {
if versions.is_empty() {
console.write_stdout(
diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs
index b937d5c..9f47794 100644
--- a/crates/mozart/src/commands/update.rs
+++ b/crates/mozart/src/commands/update.rs
@@ -712,6 +712,9 @@ pub async fn execute(
cli: &super::Cli,
console: &mozart_core::console::Console,
) -> anyhow::Result<()> {
+ let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
+ let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
+
// Step 1: Resolve the working directory
let working_dir = super::install::resolve_working_dir(cli);
@@ -846,7 +849,7 @@ pub async fn execute(
platform: PlatformConfig::new(),
ignore_platform_reqs: args.ignore_platform_reqs,
ignore_platform_req_list: args.ignore_platform_req.clone(),
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
temporary_constraints,
repositories: composer_json.repositories.clone(),
};
@@ -1004,7 +1007,7 @@ pub async fn execute(
composer_json_content: composer_json_content.clone(),
composer_json: composer_json.clone(),
include_dev: dev_mode,
- repo_cache: None,
+ repo_cache: repo_cache.clone(),
})
.await?;
@@ -1942,7 +1945,10 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
temporary_constraints: HashMap::new(),
repositories: vec![],
};
@@ -1956,7 +1962,10 @@ mod tests {
composer_json_content: composer_json_content.to_string(),
composer_json,
include_dev: false,
- repo_cache: None,
+ repo_cache: mozart_registry::cache::Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ),
})
.await
.expect("Lock file generation should succeed");