aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-registry/src/resolver.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-02 17:21:29 +0900
committernsfisis <nsfisis@gmail.com>2026-05-02 17:21:29 +0900
commit43efd895d24b7ccd2853fa5bcf08ad0e621f33ce (patch)
tree6caa14192cb2c753b9699bc3c5d62fe334920718 /crates/mozart-registry/src/resolver.rs
parent5b767cdd832d39816ee4c2dbf94274c0130dd572 (diff)
downloadphp-mozart-43efd895d24b7ccd2853fa5bcf08ad0e621f33ce.tar.gz
php-mozart-43efd895d24b7ccd2853fa5bcf08ad0e621f33ce.tar.zst
php-mozart-43efd895d24b7ccd2853fa5bcf08ad0e621f33ce.zip
refactor(registry): plumb RepositorySet and executor through callers
ResolveRequest and LockFileGenerationRequest now take Arc<RepositorySet> instead of a raw Cache. install_from_lock now accepts &mut dyn InstallerExecutor instead of constructing FilesystemExecutor internally. Both changes expose the DI injection points needed by the upcoming in-process test harness, where Packagist must be replaced with an empty RepositorySet (Composer's `'packagist' => false` test config) and filesystem install execution must be replaced with a tracing recorder (Composer's InstallationManagerMock). The eager VCS scan and inline-package preload still happen inside resolve(), so the RawRepository array is kept on ResolveRequest as raw_repositories - migrating those through RepositorySet remains a follow-up. RepositorySet gains with_packagist and empty constructors so production callers and future tests have a uniform construction shape. All 136 enabled installer fixtures + 114 mozart-registry tests + 541 mozart lib tests still green; clippy clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-registry/src/resolver.rs')
-rw-r--r--crates/mozart-registry/src/resolver.rs58
1 files changed, 27 insertions, 31 deletions
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs
index 878dc02..336d6d7 100644
--- a/crates/mozart-registry/src/resolver.rs
+++ b/crates/mozart-registry/src/resolver.rs
@@ -6,11 +6,10 @@
use std::collections::{HashMap, HashSet};
use std::fmt;
+use std::sync::Arc;
-use crate::cache::Cache;
use crate::packagist;
-use crate::repository::packagist_repo::PackagistRepository;
-use crate::repository::{PackageQuery, Repository, RepositorySet};
+use crate::repository::{PackageQuery, RepositorySet};
use crate::vcs_bridge;
use mozart_core::package::{RawRepository, Stability};
use mozart_sat_resolver::{
@@ -348,14 +347,20 @@ pub struct ResolveRequest {
pub ignore_platform_reqs: bool,
/// Specific platform requirements to ignore.
pub ignore_platform_req_list: Vec<String>,
- /// On-disk repo cache for Packagist API responses.
- pub repo_cache: Cache,
+ /// Repository set used to fetch package metadata. Mirrors Composer's
+ /// `RepositoryManager`. Production builders construct this with a single
+ /// `PackagistRepository`; in-process test harnesses can construct one
+ /// without any HTTP-backed repos to mimic Composer's
+ /// `'packagist' => false` test config.
+ pub repositories: Arc<RepositorySet>,
/// Temporary version constraint overrides (from --with flag).
/// Maps package name (lowercase) to constraint string.
pub temporary_constraints: HashMap<String, String>,
- /// VCS repositories from composer.json "repositories" section.
- /// Used to fetch packages from VCS before falling back to Packagist.
- pub repositories: Vec<RawRepository>,
+ /// VCS / inline-package repository entries from composer.json's
+ /// `repositories` section, used by the eager VCS scan and inline-package
+ /// preload that still live in `resolve()` (Step B follow-up will move
+ /// these through `RepositorySet` too).
+ pub raw_repositories: Vec<RawRepository>,
}
/// A single package in the resolution output.
@@ -369,19 +374,6 @@ pub struct ResolvedPackage {
pub is_dev: bool,
}
-/// Build a [`RepositorySet`] containing only [`PackagistRepository`].
-///
-/// The resolver still preloads VCS and inline packages directly into the
-/// pool builder (and tracks their names in skip-lists) — Step B routes
-/// only Packagist queries through the trait. Migrating VCS/inline through
-/// `RepositorySet` is a follow-up. The function returns a single-repo set
-/// purely so the seed and transitive loops have a uniform call shape.
-fn build_packagist_repo_set(repo_cache: &Cache) -> RepositorySet {
- let repos: Vec<Box<dyn Repository>> =
- vec![Box::new(PackagistRepository::new(repo_cache.clone()))];
- RepositorySet::new(repos)
-}
-
// ─────────────────────────────────────────────────────────────────────────────
// Public resolve() function
// ─────────────────────────────────────────────────────────────────────────────
@@ -460,7 +452,7 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R
}
// Scan VCS repositories and collect packages from them
- let vcs_packages = vcs_bridge::scan_vcs_repositories(&request.repositories).await;
+ let vcs_packages = vcs_bridge::scan_vcs_repositories(&request.raw_repositories).await;
let mut vcs_package_names: HashSet<String> = HashSet::new();
for vpkg in &vcs_packages {
vcs_package_names.insert(vpkg.name.clone());
@@ -481,7 +473,7 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R
// Collect inline `type: package` repositories. These don't require any
// network fetch; they go straight into the pool and are also tracked by
// name so the Packagist seed/transitive loops below skip them.
- let inline_packages = crate::inline_package::collect_inline_packages(&request.repositories);
+ let inline_packages = crate::inline_package::collect_inline_packages(&request.raw_repositories);
let mut inline_package_names: HashSet<String> = HashSet::new();
for ipkg in &inline_packages {
inline_package_names.insert(ipkg.name.clone());
@@ -496,12 +488,12 @@ pub async fn resolve(request: &ResolveRequest) -> Result<Vec<ResolvedPackage>, R
}
}
- // Build the repository set used for Packagist queries (and, in future
- // steps, inline + VCS too). Today only Packagist flows through the
- // trait — VCS and inline packages above are still preloaded directly,
- // and their names go into the skip lists so we don't double-load them
- // through this set.
- let repo_set: RepositorySet = build_packagist_repo_set(&request.repo_cache);
+ // The repository set is supplied by the caller. Today production
+ // builders pass a single-Packagist set; in-process tests can pass a
+ // set with no HTTP-backed repos. VCS and inline packages above are
+ // still preloaded directly, and their names go into the skip lists so
+ // we don't double-load them through this set.
+ let repo_set: &RepositorySet = &request.repositories;
// Seed the builder with packages for root requirements.
let seed_names: Vec<String> = root_requires
@@ -993,6 +985,7 @@ mod tests {
#[tokio::test]
#[ignore]
async fn test_resolve_monolog_e2e() {
+ use crate::cache::Cache;
let request = ResolveRequest {
root_name: String::new(),
require: vec![("monolog/monolog".to_string(), "^3.0".to_string())],
@@ -1005,9 +998,12 @@ mod tests {
platform: PlatformConfig::new(),
ignore_platform_reqs: false,
ignore_platform_req_list: vec![],
- repo_cache: Cache::new(std::env::temp_dir().join("mozart-test-cache"), false),
+ repositories: Arc::new(RepositorySet::with_packagist(Cache::new(
+ std::env::temp_dir().join("mozart-test-cache"),
+ false,
+ ))),
temporary_constraints: HashMap::new(),
- repositories: vec![],
+ raw_repositories: vec![],
};
let result = resolve(&request).await;