aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/dependency_resolver
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs59
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs50
-rw-r--r--crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs3
3 files changed, 60 insertions, 52 deletions
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index 489b358..273d19f 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -34,8 +34,10 @@ use crate::package::version::StabilityFilter;
use crate::plugin::PluginEvents;
use crate::plugin::PrePoolCreateEvent;
use crate::repository::CanonicalPackagesTrait;
+use crate::repository::LockArrayRepository;
use crate::repository::PlatformRepository;
use crate::repository::RepositoryInterface;
+use crate::repository::RepositoryInterfaceHandle;
use crate::repository::RootPackageRepository;
#[derive(Debug)]
@@ -134,7 +136,7 @@ impl PoolBuilder {
pub fn build_pool(
&mut self,
- repositories: Vec<Box<dyn RepositoryInterface>>,
+ repositories: Vec<RepositoryInterfaceHandle>,
request: &mut Request,
) -> anyhow::Result<Pool> {
self.restricted_packages_list = if request.get_restricted_packages().is_some() {
@@ -206,13 +208,9 @@ impl PoolBuilder {
// TODO in how far can we do the above for conflicts? It's more tricky cause conflicts can be limited to
// specific versions while replace is a conflict with all versions of the name
- // TODO(phase-c): package->repository back-reference not yet on handles
- let in_root_or_platform = None
- .map(|r: &dyn RepositoryInterface| {
- r.as_any().is::<RootPackageRepository>()
- || r.as_any().is::<PlatformRepository>()
- })
- .unwrap_or(false);
+ let in_root_or_platform = package.get_repository().map_or(false, |r| {
+ r.is::<RootPackageRepository>() || r.is::<PlatformRepository>()
+ });
if in_root_or_platform
|| StabilityFilter::is_package_acceptable(
&self.acceptable_stabilities,
@@ -446,7 +444,7 @@ impl PoolBuilder {
fn load_packages_marked_for_loading(
&mut self,
request: &mut Request,
- repositories: &Vec<Box<dyn RepositoryInterface>>,
+ repositories: &Vec<RepositoryInterfaceHandle>,
) -> anyhow::Result<()> {
let to_remove: Vec<String> = self
.packages_to_load
@@ -493,16 +491,14 @@ impl PoolBuilder {
for (repo_index, repository) in repositories.iter().enumerate() {
// these repos have their packages fixed or locked if they need to be loaded so we
// never need to load anything else from them
- let is_locked_repo = request
- .get_locked_repository()
- .map(|lr| {
- std::ptr::eq(
- lr as *const _ as *const u8,
- repository.as_ref() as *const _ as *const u8,
- )
- })
- .unwrap_or(false);
- if repository.as_any().is::<PlatformRepository>() || is_locked_repo {
+ // TODO(phase-c): PHP compares `$request->getLockedRepository() === $repository` by
+ // strict identity, but `Request.locked_repository` is held by value, not as a handle.
+ // This approximates the check by matching any `LockArrayRepository` when the request
+ // has a locked repository set. Tighten to `ptr_eq` once `Request` stores the locked
+ // repository as `RepositoryInterfaceHandle`.
+ let is_locked_repo =
+ request.get_locked_repository().is_some() && repository.is::<LockArrayRepository>();
+ if repository.is::<PlatformRepository>() || is_locked_repo {
continue;
}
@@ -611,7 +607,7 @@ impl PoolBuilder {
fn load_package(
&mut self,
request: &mut Request,
- repositories: &Vec<Box<dyn RepositoryInterface>>,
+ repositories: &Vec<RepositoryInterfaceHandle>,
package: BasePackageHandle,
propagate_update: bool,
) -> anyhow::Result<()> {
@@ -872,7 +868,7 @@ impl PoolBuilder {
fn unlock_package(
&mut self,
request: &mut Request,
- repositories: &Vec<Box<dyn RepositoryInterface>>,
+ repositories: &Vec<RepositoryInterfaceHandle>,
name: &str,
) -> anyhow::Result<()> {
let skipped: Vec<PackageInterfaceHandle> = self
@@ -1029,15 +1025,19 @@ impl PoolBuilder {
fn remove_loaded_package(
&mut self,
_request: &Request,
- repositories: &Vec<Box<dyn RepositoryInterface>>,
+ repositories: &Vec<RepositoryInterfaceHandle>,
package: BasePackageHandle,
index: i64,
) {
- let repos_box: Vec<Box<dyn RepositoryInterface>> =
- repositories.iter().map(|r| r.clone_box()).collect();
- let _ = &repos_box;
- // TODO(phase-c): package->repository back-reference not yet on handles
- let repo_index: i64 = -1;
+ let repo_index: i64 = package
+ .get_repository()
+ .and_then(|pkg_repo| {
+ repositories
+ .iter()
+ .position(|r| r.ptr_eq(&pkg_repo))
+ .map(|i| i as i64)
+ })
+ .unwrap_or(-1);
if repo_index >= 0 {
if let Some(repo_map) = self.loaded_per_repo.get_mut(&repo_index) {
@@ -1115,7 +1115,7 @@ impl PoolBuilder {
fn run_security_advisory_filter(
&mut self,
pool: Pool,
- repositories: &Vec<Box<dyn RepositoryInterface>>,
+ repositories: &Vec<RepositoryInterfaceHandle>,
request: &Request,
) -> Pool {
if self.security_advisory_pool_filter.is_none() {
@@ -1127,8 +1127,7 @@ impl PoolBuilder {
let before = microtime(true);
let total = pool.get_packages().len() as f64;
- let repos_owned: Vec<Box<dyn RepositoryInterface>> =
- repositories.iter().map(|r| r.clone_box()).collect();
+ let repos_owned: Vec<RepositoryInterfaceHandle> = repositories.iter().cloned().collect();
let pool =
self.security_advisory_pool_filter
.as_mut()
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index 58d47f1..740909f 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -1127,11 +1127,14 @@ impl Problem {
if available.len() > 0 {
let mut selected: Option<&BasePackageHandle> = None;
- // TODO(phase-c): the handle does not expose get_repository (a `RefCell`-borrowed
- // back-reference); preferring the package from a PlatformRepository needs repository
- // back-references on handles. Falling back to the first candidate for now.
for pkg in &available {
- let _ = pkg;
+ if pkg
+ .get_repository()
+ .map_or(false, |r| r.is::<PlatformRepository>())
+ {
+ selected = Some(pkg);
+ break;
+ }
}
if selected.is_none() {
selected = available.first();
@@ -1240,13 +1243,23 @@ impl Problem {
reason: &str,
constraint: Option<&AnyConstraint>,
) -> (String, String) {
- // TODO(phase-c): selecting the next repository's packages relies on each package's
- // repository back-reference, which the handle does not yet expose (phase-c handoff
- // item #1). Both `next_repo_packages` and `next_repo` are blocked on that decision.
- let _ = all_repos_packages;
- let next_repo_packages: Vec<BasePackageHandle> = Vec::new();
- let next_repo: Box<dyn crate::repository::RepositoryInterface> =
- todo!("repository back-reference on handle pending (phase-c handoff item #1)");
+ let mut next_repo_packages: Vec<BasePackageHandle> = Vec::new();
+ let mut next_repo: Option<crate::repository::RepositoryInterfaceHandle> = None;
+ for package in all_repos_packages {
+ let pkg_repo = package.get_repository();
+ let same_repo = match (&next_repo, &pkg_repo) {
+ (None, _) => true,
+ (Some(nr), Some(pr)) => nr.ptr_eq(pr),
+ _ => false,
+ };
+ if same_repo {
+ next_repo_packages.push(package.clone());
+ next_repo = pkg_repo;
+ } else {
+ break;
+ }
+ }
+ let next_repo = next_repo.expect("next_repo must be set");
if higher_repo_packages.len() > 0 {
let top_package = higher_repo_packages.first().unwrap();
@@ -1274,11 +1287,7 @@ impl Problem {
}
}
- if next_repo
- .as_any()
- .downcast_ref::<LockArrayRepository>()
- .is_some()
- {
+ if next_repo.is::<LockArrayRepository>() {
let singular = higher_repo_packages.len() == 1;
let mut suggestion = format!(
@@ -1351,10 +1360,11 @@ impl Problem {
constraint,
false
),
- // TODO(phase-c): the higher repo's name needs the handle's repository
- // back-reference (phase-c handoff item #1); unreachable until `next_repo` above
- // is resolved.
- String::new(),
+ higher_repo_packages
+ .first()
+ .and_then(|p| p.get_repository())
+ .map(|r| r.get_repo_name())
+ .unwrap_or_default(),
reason
),
)
diff --git a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
index 785e758..ec224b4 100644
--- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
+++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
@@ -6,7 +6,6 @@ use crate::advisory::PartialSecurityAdvisory;
use crate::dependency_resolver::Pool;
use crate::dependency_resolver::Request;
use crate::package::BasePackageHandle;
-use crate::repository::RepositoryInterface;
use indexmap::IndexMap;
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
@@ -28,7 +27,7 @@ impl SecurityAdvisoryPoolFilter {
pub fn filter(
&self,
pool: Pool,
- repositories: Vec<Box<dyn RepositoryInterface>>,
+ repositories: Vec<crate::repository::RepositoryInterfaceHandle>,
request: &Request,
) -> Pool {
// TODO(phase-c): port the filter() body. Blockers: