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/default_policy.rs13
-rw-r--r--crates/shirabe/src/dependency_resolver/pool.rs38
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_builder.rs88
-rw-r--r--crates/shirabe/src/dependency_resolver/pool_optimizer.rs84
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs105
-rw-r--r--crates/shirabe/src/dependency_resolver/request.rs10
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs36
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs18
-rw-r--r--crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs7
-rw-r--r--crates/shirabe/src/dependency_resolver/solver.rs9
10 files changed, 229 insertions, 179 deletions
diff --git a/crates/shirabe/src/dependency_resolver/default_policy.rs b/crates/shirabe/src/dependency_resolver/default_policy.rs
index c24e382..cc33b81 100644
--- a/crates/shirabe/src/dependency_resolver/default_policy.rs
+++ b/crates/shirabe/src/dependency_resolver/default_policy.rs
@@ -5,7 +5,8 @@ use std::cell::RefCell;
use indexmap::IndexMap;
use shirabe_semver::compiling_matcher::CompilingMatcher;
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::dependency_resolver::PolicyInterface;
use crate::dependency_resolver::Pool;
@@ -209,14 +210,16 @@ impl PolicyInterface for DefaultPolicy {
if (a.is_dev() && a.get_version().starts_with("dev-"))
|| (b.is_dev() && b.get_version().starts_with("dev-"))
{
- let constraint = Constraint::new(operator, b.get_version());
- let version = Constraint::new("==", a.get_version());
+ let constraint =
+ SimpleConstraint::new(operator.to_string(), b.get_version().to_string(), None);
+ let version =
+ SimpleConstraint::new("==".to_string(), a.get_version().to_string(), None);
return constraint.match_specific(&version, true);
}
CompilingMatcher::r#match(
- &Constraint::new(operator, b.get_version()),
- Constraint::OP_EQ,
+ &SimpleConstraint::new(operator.to_string(), b.get_version().to_string(), None).into(),
+ SimpleConstraint::OP_EQ,
a.get_version().to_string(),
)
}
diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs
index e43eb53..771f363 100644
--- a/crates/shirabe/src/dependency_resolver/pool.rs
+++ b/crates/shirabe/src/dependency_resolver/pool.rs
@@ -5,8 +5,8 @@ use std::fmt;
use indexmap::IndexMap;
use shirabe_php_shim::{Countable, STR_PAD_LEFT, abs, spl_object_hash, str_pad};
use shirabe_semver::compiling_matcher::CompilingMatcher;
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::advisory::PartialSecurityAdvisory;
use crate::package::BasePackage;
@@ -70,7 +70,7 @@ impl Pool {
pub fn get_removed_versions(
&self,
name: &str,
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
) -> IndexMap<String, String> {
let Some(versions) = self.removed_versions.get(name) else {
return IndexMap::new();
@@ -78,7 +78,9 @@ impl Pool {
let mut result: IndexMap<String, String> = IndexMap::new();
for (version, pretty_version) in versions {
- if constraint.matches(&Constraint::new("==", version)) {
+ if constraint
+ .matches(&SimpleConstraint::new("==".to_string(), version.to_string(), None).into())
+ {
result.insert(version.clone(), pretty_version.clone());
}
}
@@ -110,7 +112,7 @@ impl Pool {
pub fn is_security_removed_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let empty = IndexMap::new();
let versions = self
@@ -119,7 +121,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, _package_with_security_advisories) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return true;
}
}
@@ -132,7 +136,7 @@ impl Pool {
pub fn get_security_advisory_identifiers_for_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<String> {
let empty = IndexMap::new();
let versions = self
@@ -141,7 +145,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, package_with_security_advisories) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return package_with_security_advisories
.iter()
.map(|advisory| advisory.advisory_id.clone())
@@ -156,7 +162,7 @@ impl Pool {
pub fn is_abandoned_removed_package_version(
&self,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let empty = IndexMap::new();
let versions = self
@@ -165,7 +171,9 @@ impl Pool {
.unwrap_or(&empty);
for (version, _pretty_version) in versions {
if let Some(c) = constraint {
- if c.matches(&Constraint::new("==", version)) {
+ if c.matches(
+ &SimpleConstraint::new("==".to_string(), version.to_string(), None).into(),
+ ) {
return true;
}
}
@@ -226,11 +234,11 @@ impl Pool {
pub fn what_provides(
&mut self,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<Box<dyn BasePackage>> {
// PHP: $key = (string) $constraint;
let key = match constraint {
- Some(c) => c.__to_string(),
+ Some(c) => c.to_string(),
None => String::new(),
};
if let Some(by_key) = self.provider_cache.get(name) {
@@ -254,7 +262,7 @@ impl Pool {
pub(crate) fn compute_what_provides(
&self,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> Vec<Box<dyn BasePackage>> {
let Some(candidates) = self.package_by_name.get(name) else {
return vec![];
@@ -306,7 +314,7 @@ impl Pool {
&self,
candidate: &dyn BasePackage,
name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> bool {
let candidate_name = candidate.get_name();
let candidate_version = candidate.get_version();
@@ -315,7 +323,7 @@ impl Pool {
return constraint.is_none()
|| CompilingMatcher::r#match(
constraint.unwrap(),
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
candidate_version.to_string(),
);
}
diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs
index fcc0339..f80ef38 100644
--- a/crates/shirabe/src/dependency_resolver/pool_builder.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs
@@ -11,10 +11,10 @@ use shirabe_php_shim::{
array_search, array_search_mixed, count, in_array, microtime, number_format, round,
spl_object_hash, sprintf, strpos,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use shirabe_semver::constraint::MultiConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::dependency_resolver::Pool;
use crate::dependency_resolver::PoolOptimizer;
@@ -41,13 +41,13 @@ pub struct PoolBuilder {
stability_flags: IndexMap<String, i64>,
root_aliases: IndexMap<String, IndexMap<String, IndexMap<String, String>>>,
root_references: IndexMap<String, String>,
- temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ temporary_constraints: IndexMap<String, AnyConstraint>,
event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
pool_optimizer: Option<PoolOptimizer>,
io: Box<dyn IOInterface>,
alias_map: IndexMap<String, IndexMap<i64, AliasPackage>>,
- packages_to_load: IndexMap<String, Box<dyn ConstraintInterface>>,
- loaded_packages: IndexMap<String, Box<dyn ConstraintInterface>>,
+ packages_to_load: IndexMap<String, AnyConstraint>,
+ loaded_packages: IndexMap<String, AnyConstraint>,
loaded_per_repo: IndexMap<i64, IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>>,
packages: IndexMap<i64, Box<dyn BasePackage>>,
unacceptable_fixed_or_locked_packages: Vec<Box<dyn BasePackage>>,
@@ -88,7 +88,7 @@ impl PoolBuilder {
io: Box<dyn IOInterface>,
event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
pool_optimizer: Option<PoolOptimizer>,
- temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>,
+ temporary_constraints: IndexMap<String, AnyConstraint>,
security_advisory_pool_filter: Option<SecurityAdvisoryPoolFilter>,
) -> Self {
Self {
@@ -195,14 +195,14 @@ impl PoolBuilder {
// loading any packages
self.loaded_packages.insert(
package.get_name().to_string(),
- Box::new(MatchAllConstraint::new()),
+ MatchAllConstraint::new(None).into(),
);
// replace means conflict, so if a fixed package replaces a name, no need to load that one, packages would conflict anyways
for (_k, link) in &package.get_replaces() {
self.loaded_packages.insert(
link.get_target().to_string(),
- Box::new(MatchAllConstraint::new()),
+ MatchAllConstraint::new(None).into(),
);
}
@@ -238,7 +238,7 @@ impl PoolBuilder {
}
self.packages_to_load
- .insert(package_name.clone(), constraint.clone_box());
+ .insert(package_name.clone(), constraint.clone());
self.max_extended_reqs.insert(package_name.clone(), true);
}
@@ -271,7 +271,7 @@ impl PoolBuilder {
for package_name in package.get_names(true) {
let constraint = match self.temporary_constraints.get(&package_name) {
- Some(c) => c.clone_box(),
+ Some(c) => c.clone(),
None => continue,
};
@@ -288,7 +288,8 @@ impl PoolBuilder {
let mut found = false;
for (_idx, version) in &package_and_aliases {
- if CompilingMatcher::matches(&*constraint, Constraint::OP_EQ, version) {
+ if CompilingMatcher::matches(&constraint, SimpleConstraint::OP_EQ, version)
+ {
found = true;
}
}
@@ -377,9 +378,9 @@ impl PoolBuilder {
&mut self,
request: &Request,
name: &str,
- constraint: &dyn ConstraintInterface,
+ constraint: &AnyConstraint,
) {
- let constraint = constraint.clone_box();
+ let constraint = constraint.clone();
// Skip platform requires at this stage
if PlatformRepository::is_platform_package(name) {
return;
@@ -398,8 +399,8 @@ impl PoolBuilder {
let root_requires = request.get_requires();
let mut constraint = constraint;
if let Some(root_constraint) = root_requires.get(name) {
- if !Intervals::is_subset_of(&*constraint, &**root_constraint).unwrap_or(false) {
- constraint = root_constraint.clone_box();
+ if !Intervals::is_subset_of(&constraint, root_constraint).unwrap_or(false) {
+ constraint = root_constraint.clone();
}
}
@@ -410,17 +411,18 @@ impl PoolBuilder {
// MultiConstraint::create() will optimize anyway)
if let Some(existing) = self.packages_to_load.get(name) {
// Already marked for loading and this does not expand the constraint to be loaded, nothing to do
- if Intervals::is_subset_of(&*constraint, &**existing).unwrap_or(false) {
+ if Intervals::is_subset_of(&constraint, existing).unwrap_or(false) {
return;
}
// extend the constraint to be loaded
constraint = Intervals::compact_constraint(
MultiConstraint::create(
- vec![existing.clone_box(), constraint.clone_box()],
+ vec![existing.clone(), constraint.clone()],
false,
+ None,
)
- .unwrap_or_else(|_| Box::new(MatchAllConstraint::new())),
+ .unwrap_or_else(|_| MatchAllConstraint::new(None).into()),
);
}
@@ -431,7 +433,7 @@ impl PoolBuilder {
// No need to load this package with this constraint because it is
// a subset of the constraint with which we have already loaded packages
- if Intervals::is_subset_of(&*constraint, &**self.loaded_packages.get(name).unwrap())
+ if Intervals::is_subset_of(&constraint, self.loaded_packages.get(name).unwrap())
.unwrap_or(false)
{
return;
@@ -444,13 +446,11 @@ impl PoolBuilder {
name.to_string(),
Intervals::compact_constraint(
MultiConstraint::create(
- vec![
- self.loaded_packages.get(name).unwrap().clone_box(),
- constraint,
- ],
+ vec![self.loaded_packages.get(name).unwrap().clone(), constraint],
false,
+ None,
)
- .unwrap_or_else(|_| Box::new(MatchAllConstraint::new())),
+ .unwrap_or_else(|_| MatchAllConstraint::new(None).into()),
),
);
self.loaded_packages.shift_remove(name);
@@ -475,23 +475,23 @@ impl PoolBuilder {
for name in to_remove {
self.packages_to_load.shift_remove(&name);
}
- let snapshot: Vec<(String, Box<dyn ConstraintInterface>)> = self
+ let snapshot: Vec<(String, AnyConstraint)> = self
.packages_to_load
.iter()
- .map(|(k, v)| (k.clone(), v.clone_box()))
+ .map(|(k, v)| (k.clone(), v.clone()))
.collect();
for (name, constraint) in &snapshot {
self.loaded_packages
- .insert(name.clone(), constraint.clone_box());
+ .insert(name.clone(), constraint.clone());
}
// Load packages in chunks of 50 to prevent memory usage build-up due to caches of all sorts
// TODO(phase-b): array_chunk shim signature expects &[T]; build IndexMap chunks manually.
- let mut package_batches: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = {
- let mut chunks: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = Vec::new();
- let mut current: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut package_batches: Vec<IndexMap<String, AnyConstraint>> = {
+ let mut chunks: Vec<IndexMap<String, AnyConstraint>> = Vec::new();
+ let mut current: IndexMap<String, AnyConstraint> = IndexMap::new();
for (k, v) in self.packages_to_load.iter() {
- current.insert(k.clone(), v.clone_box());
+ current.insert(k.clone(), v.clone());
if current.len() as i64 >= Self::LOAD_BATCH_SIZE {
chunks.push(std::mem::take(&mut current));
}
@@ -525,11 +525,11 @@ impl PoolBuilder {
// Iterate by index because we mutate package_batches inside the loop.
for batch_index in 0..package_batches.len() {
- let package_batch: IndexMap<String, Option<Box<dyn ConstraintInterface>>> =
- package_batches[batch_index]
- .iter()
- .map(|(k, v)| (k.clone(), Some(v.clone_box())))
- .collect();
+ let package_batch: IndexMap<String, Option<AnyConstraint>> = package_batches
+ [batch_index]
+ .iter()
+ .map(|(k, v)| (k.clone(), Some(v.clone())))
+ .collect();
let result = repository.load_packages(
package_batch,
self.acceptable_stabilities.clone(),
@@ -598,18 +598,18 @@ impl PoolBuilder {
}
// PHP: array_chunk(array_merge(...$packageBatches), self::LOAD_BATCH_SIZE, true)
- let mut merged: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut merged: IndexMap<String, AnyConstraint> = IndexMap::new();
for batch in &package_batches {
for (k, v) in batch {
- merged.insert(k.clone(), v.clone_box());
+ merged.insert(k.clone(), v.clone());
}
}
// Rebuild chunks from merged.
package_batches = {
- let mut chunks: Vec<IndexMap<String, Box<dyn ConstraintInterface>>> = Vec::new();
- let mut current: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new();
+ let mut chunks: Vec<IndexMap<String, AnyConstraint>> = Vec::new();
+ let mut current: IndexMap<String, AnyConstraint> = IndexMap::new();
for (k, v) in merged.iter() {
- current.insert(k.clone(), v.clone_box());
+ current.insert(k.clone(), v.clone());
if current.len() as i64 >= Self::LOAD_BATCH_SIZE {
chunks.push(std::mem::take(&mut current));
}
@@ -929,7 +929,7 @@ impl PoolBuilder {
self.mark_package_name_for_loading(
request,
&replacer_name,
- &MatchAllConstraint::new(),
+ &MatchAllConstraint::new(None).into(),
);
} else {
let pkgs: Vec<Box<dyn BasePackage>> =
@@ -1050,8 +1050,8 @@ impl PoolBuilder {
fn mark_package_name_for_loading_if_required(&mut self, request: &Request, name: &str) {
if self.is_root_require(request, name) {
- let cons = request.get_requires()[name].clone_box();
- self.mark_package_name_for_loading(request, name, &*cons);
+ let cons = request.get_requires()[name].clone();
+ self.mark_package_name_for_loading(request, name, &cons);
}
let pkgs: Vec<Box<dyn BasePackage>> =
diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
index 326587a..27b3ffb 100644
--- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
+++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs
@@ -6,9 +6,9 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_php_shim::{LogicException, PhpMixed, implode, ksort, spl_object_hash};
use shirabe_semver::compiling_matcher::CompilingMatcher;
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MultiConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use shirabe_semver::intervals::Intervals;
use crate::dependency_resolver::PolicyInterface;
@@ -29,12 +29,10 @@ pub struct PoolOptimizer {
irremovable_packages: IndexMap<i64, bool>,
/// @var array<string, array<string, ConstraintInterface>>
- require_constraints_per_package:
- IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
+ require_constraints_per_package: IndexMap<String, IndexMap<String, AnyConstraint>>,
/// @var array<string, array<string, ConstraintInterface>>
- conflict_constraints_per_package:
- IndexMap<String, IndexMap<String, Box<dyn ConstraintInterface>>>,
+ conflict_constraints_per_package: IndexMap<String, IndexMap<String, AnyConstraint>>,
/// @var array<int, true>
packages_to_remove: IndexMap<i64, bool>,
@@ -90,23 +88,27 @@ impl PoolOptimizer {
}
fn prepare(&mut self, request: &Request, pool: &Pool) {
- let mut irremovable_package_constraint_groups: IndexMap<
- String,
- Vec<Box<dyn ConstraintInterface>>,
- > = IndexMap::new();
+ let mut irremovable_package_constraint_groups: IndexMap<String, Vec<AnyConstraint>> =
+ IndexMap::new();
// Mark fixed or locked packages as irremovable
for (_, package) in request.get_fixed_or_locked_packages() {
irremovable_package_constraint_groups
.entry(PackageInterface::get_name(package.as_ref()).to_string())
.or_insert_with(Vec::new)
- .push(Box::new(Constraint::new("==", package.get_version())));
+ .push(
+ SimpleConstraint::new(
+ "==".to_string(),
+ package.get_version().to_string(),
+ None,
+ )
+ .into(),
+ );
}
// Extract requested package requirements
for (require, constraint) in request.get_requires() {
- // TODO(phase-b): clone Box<dyn ConstraintInterface>
- self.extract_require_constraints_per_package(require, todo!("constraint.clone_box()"));
+ self.extract_require_constraints_per_package(require, constraint.clone());
}
// First pass over all packages to extract information and mark package constraints irremovable
@@ -115,16 +117,14 @@ impl PoolOptimizer {
for link in package.get_requires().values() {
self.extract_require_constraints_per_package(
link.get_target(),
- // TODO(phase-b): clone constraint
- todo!("link.get_constraint().clone_box()"),
+ link.get_constraint().clone(),
);
}
// Extract package conflicts
for link in package.get_conflicts().values() {
self.extract_conflict_constraints_per_package(
link.get_target(),
- // TODO(phase-b): clone constraint
- todo!("link.get_constraint().clone_box()"),
+ link.get_constraint().clone(),
);
}
@@ -138,16 +138,14 @@ impl PoolOptimizer {
}
}
- let mut irremovable_package_constraints: IndexMap<String, Box<dyn ConstraintInterface>> =
- IndexMap::new();
+ let mut irremovable_package_constraints: IndexMap<String, AnyConstraint> = IndexMap::new();
for (package_name, constraints) in irremovable_package_constraint_groups {
- // TODO(phase-b): MultiConstraint::new signature; move ownership of constraints vec
irremovable_package_constraints.insert(
package_name,
if 1 == constraints.len() {
- todo!("constraints[0] moved out")
+ constraints.into_iter().next().unwrap()
} else {
- Box::new(MultiConstraint::new(constraints, false))
+ MultiConstraint::new(constraints, false, None).into()
},
);
}
@@ -165,8 +163,8 @@ impl PoolOptimizer {
.get(PackageInterface::get_name(package.as_ref()))
.unwrap();
if CompilingMatcher::r#match(
- constraint.as_ref(),
- Constraint::OP_EQ,
+ constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
self.mark_package_irremovable(package.as_ref());
@@ -262,8 +260,8 @@ impl PoolOptimizer {
let mut group_hash_parts: Vec<String> = vec![];
if CompilingMatcher::r#match(
- require_constraint.as_ref(),
- Constraint::OP_EQ,
+ require_constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
group_hash_parts.push(format!(
@@ -276,7 +274,7 @@ impl PoolOptimizer {
for (_, link) in package.get_replaces() {
if CompilingMatcher::r#match(
link.get_constraint(),
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
// Use the same hash part as the regular require hash because that's what the replacement does
@@ -293,8 +291,8 @@ impl PoolOptimizer {
{
for (_, conflict_constraint) in conflict_constraints {
if CompilingMatcher::r#match(
- conflict_constraint.as_ref(),
- Constraint::OP_EQ,
+ conflict_constraint,
+ SimpleConstraint::OP_EQ,
package.get_version().to_string(),
) {
group_hash_parts.push(format!(
@@ -415,7 +413,7 @@ impl PoolOptimizer {
// performance more than the additional few packages that could be filtered out would benefit the process.
subhash.insert(
link.get_target().to_string(),
- link.get_constraint().__to_string(),
+ link.get_constraint().to_string(),
);
}
@@ -638,7 +636,7 @@ impl PoolOptimizer {
if false
== CompilingMatcher::r#match(
link_constraint,
- Constraint::OP_EQ,
+ SimpleConstraint::OP_EQ,
version_str,
)
{
@@ -662,13 +660,13 @@ impl PoolOptimizer {
fn extract_require_constraints_per_package(
&mut self,
package: &str,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
) {
for expanded in self.expand_disjunctive_multi_constraints(constraint) {
self.require_constraints_per_package
.entry(package.to_string())
.or_insert_with(IndexMap::new)
- .insert(expanded.__to_string(), expanded);
+ .insert(expanded.to_string(), expanded);
}
}
@@ -680,32 +678,28 @@ impl PoolOptimizer {
fn extract_conflict_constraints_per_package(
&mut self,
package: &str,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
) {
for expanded in self.expand_disjunctive_multi_constraints(constraint) {
self.conflict_constraints_per_package
.entry(package.to_string())
.or_insert_with(IndexMap::new)
- .insert(expanded.__to_string(), expanded);
+ .insert(expanded.to_string(), expanded);
}
}
/// @return ConstraintInterface[]
fn expand_disjunctive_multi_constraints(
&self,
- constraint: Box<dyn ConstraintInterface>,
- ) -> Vec<Box<dyn ConstraintInterface>> {
- let constraint = Intervals::compact_constraint(&*constraint).unwrap_or(constraint);
+ constraint: AnyConstraint,
+ ) -> Vec<AnyConstraint> {
+ let constraint = Intervals::compact_constraint(&constraint).unwrap_or(constraint);
- if let Some(multi) = constraint.as_any().downcast_ref::<MultiConstraint>() {
- if multi.is_disjunctive() {
+ if let Some(multi) = constraint.as_multi_constraint() {
+ if multi.is_disjunctive_mc() {
// No need to call ourselves recursively here because Intervals::compactConstraint() ensures that there
// are no nested disjunctive MultiConstraint instances possible
- return multi
- .get_constraints()
- .iter()
- .map(|c| c.clone_box())
- .collect();
+ return multi.get_constraints().iter().map(|c| c.clone()).collect();
}
}
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index a69a4a2..4436ec8 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -9,9 +9,9 @@ use shirabe_php_shim::{
phpversion, spl_object_hash, sprintf, str_replace, str_starts_with, stripos, strpos,
strtolower, substr, substr_count, version_compare,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MultiConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::advisory::SecurityAdvisory;
use crate::dependency_resolver::Pool;
@@ -92,14 +92,13 @@ impl Problem {
let reason_data = rule_ref.get_reason_data();
// TODO(phase-b): reason_data for RULE_ROOT_REQUIRE; extract via ReasonData::RootRequire variant.
- let (package_name, constraint): (String, Option<&dyn ConstraintInterface>) =
- match reason_data {
- rule::ReasonData::RootRequire {
- package_name,
- constraint,
- } => (package_name.clone(), Some(constraint.as_ref())),
- _ => (String::new(), None),
- };
+ let (package_name, constraint): (String, Option<&AnyConstraint>) = match reason_data {
+ rule::ReasonData::RootRequire {
+ package_name,
+ constraint,
+ } => (package_name.clone(), Some(constraint)),
+ _ => (String::new(), None),
+ };
let packages = pool.compute_what_provides(&package_name, constraint);
if packages.len() == 0 {
@@ -393,7 +392,7 @@ impl Problem {
pool: &mut Pool,
is_verbose: bool,
package_name: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> (String, String) {
if PlatformRepository::is_platform_package(package_name) {
// handle php/php-*/hhvm
@@ -572,7 +571,7 @@ impl Problem {
if let Some(c) = constraint {
if c.is_constraint()
- && c.get_operator() == Constraint::STR_OP_EQ
+ && c.get_operator() == SimpleConstraint::STR_OP_EQ
&& Preg::is_match3(r"{^dev-.*#.*}", &c.get_pretty_string(), None).unwrap_or(false)
{
let new_constraint =
@@ -580,17 +579,25 @@ impl Problem {
.unwrap_or_else(|_| c.get_pretty_string());
let packages = repository_set.find_packages(
package_name,
- Some(Box::new(MultiConstraint::new(
- vec![
- Box::new(Constraint::new(Constraint::STR_OP_EQ, &new_constraint))
- as Box<dyn ConstraintInterface>,
- Box::new(Constraint::new(
- Constraint::STR_OP_EQ,
- &str_replace("#", "+", &new_constraint),
- )) as Box<dyn ConstraintInterface>,
- ],
- false,
- ))),
+ Some(
+ MultiConstraint::new(
+ vec![
+ AnyConstraint::Simple(SimpleConstraint::new(
+ SimpleConstraint::STR_OP_EQ.to_string(),
+ new_constraint.clone(),
+ None,
+ )),
+ AnyConstraint::Simple(SimpleConstraint::new(
+ SimpleConstraint::STR_OP_EQ.to_string(),
+ str_replace("#", "+", &new_constraint),
+ None,
+ )),
+ ],
+ false,
+ None,
+ )
+ .into(),
+ ),
0,
);
if packages.len() > 0 {
@@ -618,15 +625,21 @@ impl Problem {
// first check if the actual requested package is found in normal conditions
// if so it must mean it is rejected by another constraint than the one given here
- let packages =
- repository_set.find_packages(package_name, constraint.map(|c| c.clone_box()), 0);
+ let packages = repository_set.find_packages(package_name, constraint.map(|c| c.clone()), 0);
if packages.len() > 0 {
let root_reqs = repository_set.get_root_requires();
if root_reqs.contains_key(package_name) {
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
.filter(|p| {
- root_reqs[package_name].matches(&Constraint::new("==", p.get_version()))
+ root_reqs[package_name].matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
})
.collect();
if filtered.len() == 0 {
@@ -663,7 +676,14 @@ impl Problem {
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
.filter(|p| {
- temp_reqs[&name].matches(&Constraint::new("==", p.get_version()))
+ temp_reqs[&name].matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
})
.collect();
if filtered.len() == 0 {
@@ -696,10 +716,23 @@ impl Problem {
}
if let Some(ref lp) = locked_package {
- let fixed_constraint = Constraint::new("==", lp.get_version());
+ let fixed_constraint = AnyConstraint::from(SimpleConstraint::new(
+ "==".to_string(),
+ lp.get_version().to_string(),
+ None,
+ ));
let filtered: Vec<&Box<dyn BasePackage>> = packages
.iter()
- .filter(|p| fixed_constraint.matches(&Constraint::new("==", p.get_version())))
+ .filter(|p| {
+ fixed_constraint.matches(
+ &SimpleConstraint::new(
+ "==".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ )
+ })
.collect();
if filtered.len() == 0 {
return (
@@ -837,14 +870,14 @@ impl Problem {
// check if the package is found when bypassing stability checks
let packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES,
);
if packages.len() > 0 {
// we must first verify if a valid package would be found in a lower priority repository
let all_repos_packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_SHADOWED_REPOSITORIES,
);
if all_repos_packages.len() > 0 {
@@ -887,7 +920,7 @@ impl Problem {
// we must first verify if a valid package would be found in a lower priority repository
let all_repos_packages = repository_set.find_packages(
package_name,
- constraint.map(|c| c.clone_box()),
+ constraint.map(|c| c.clone()),
RepositorySet::ALLOW_SHADOWED_REPOSITORIES,
);
if all_repos_packages.len() > 0 {
@@ -993,7 +1026,7 @@ impl Problem {
packages: &Vec<Box<dyn BasePackage>>,
is_verbose: bool,
pool: Option<&Pool>,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
struct PreparedEntry {
@@ -1213,7 +1246,7 @@ impl Problem {
higher_repo_packages: &Vec<Box<dyn BasePackage>>,
all_repos_packages: &Vec<Box<dyn BasePackage>>,
reason: &str,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
) -> (String, String) {
let mut next_repo_packages: Vec<Box<dyn BasePackage>> = Vec::new();
let mut next_repo: Option<Box<dyn crate::repository::RepositoryInterface>> = None;
@@ -1346,10 +1379,10 @@ impl Problem {
}
/// Turns a constraint into text usable in a sentence describing a request
- pub(crate) fn constraint_to_text(constraint: Option<&dyn ConstraintInterface>) -> String {
+ pub(crate) fn constraint_to_text(constraint: Option<&AnyConstraint>) -> String {
if let Some(c) = constraint {
if c.is_constraint()
- && c.get_operator() == Constraint::STR_OP_EQ
+ && c.get_operator() == SimpleConstraint::STR_OP_EQ
&& !str_starts_with(&c.get_version(), "dev-")
{
if !Preg::is_match3(r"{^\d+(?:\.\d+)*$}", &c.get_pretty_string(), None)
diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs
index d181bd2..e2bfc3c 100644
--- a/crates/shirabe/src/dependency_resolver/request.rs
+++ b/crates/shirabe/src/dependency_resolver/request.rs
@@ -2,7 +2,7 @@
use indexmap::IndexMap;
use shirabe_php_shim::{LogicException, spl_object_hash, strtolower};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use crate::package::BasePackage;
@@ -43,7 +43,7 @@ pub enum UpdateAllowTransitiveDeps {
#[derive(Debug)]
pub struct Request {
pub(crate) locked_repository: Option<LockArrayRepository>,
- pub(crate) requires: IndexMap<String, Box<dyn ConstraintInterface>>,
+ pub(crate) requires: IndexMap<String, AnyConstraint>,
pub(crate) fixed_packages: IndexMap<String, Box<dyn BasePackage>>,
pub(crate) locked_packages: IndexMap<String, Box<dyn BasePackage>>,
pub(crate) fixed_locked_packages: IndexMap<String, Box<dyn BasePackage>>,
@@ -69,10 +69,10 @@ impl Request {
pub fn require_name(
&mut self,
package_name: &str,
- constraint: Option<Box<dyn ConstraintInterface>>,
+ constraint: Option<AnyConstraint>,
) -> anyhow::Result<()> {
let package_name = strtolower(package_name);
- let constraint = constraint.unwrap_or_else(|| Box::new(MatchAllConstraint::new()));
+ let constraint = constraint.unwrap_or_else(|| MatchAllConstraint::new(None).into());
if self.requires.contains_key(&package_name) {
return Err(LogicException {
message: format!(
@@ -155,7 +155,7 @@ impl Request {
== UpdateAllowTransitiveDeps::UpdateListedWithTransitiveDeps
}
- pub fn get_requires(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> {
+ pub fn get_requires(&self) -> &IndexMap<String, AnyConstraint> {
&self.requires
}
diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs
index 90223e2..fbc8521 100644
--- a/crates/shirabe/src/dependency_resolver/rule.rs
+++ b/crates/shirabe/src/dependency_resolver/rule.rs
@@ -10,8 +10,8 @@ use shirabe_php_shim::{
LogicException, PhpMixed, RuntimeException, abs, array_filter, array_keys, array_shift,
array_values, implode, is_object,
};
-use shirabe_semver::constraint::Constraint;
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
use crate::dependency_resolver::GenericRule;
use crate::dependency_resolver::MultiConflictRule;
@@ -36,7 +36,7 @@ pub enum ReasonData {
Int(i64),
RootRequire {
package_name: String,
- constraint: Box<dyn ConstraintInterface>,
+ constraint: AnyConstraint,
},
Fixed {
package: Box<dyn BasePackage>,
@@ -238,10 +238,14 @@ impl Rule {
if pool.is_unacceptable_fixed_or_locked_package(p) {
return true;
}
- if !link
- .get_constraint()
- .matches(&Constraint::new("=", p.get_version()))
- {
+ if !link.get_constraint().matches(
+ &SimpleConstraint::new(
+ "=".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ ) {
return true;
}
// required package was locked but has been unlocked and still matches
@@ -275,7 +279,14 @@ impl Rule {
if pool.is_unacceptable_fixed_or_locked_package(p) {
return true;
}
- if !constraint.matches(&Constraint::new("=", p.get_version())) {
+ if !constraint.matches(
+ &SimpleConstraint::new(
+ "=".to_string(),
+ p.get_version().to_string(),
+ None,
+ )
+ .into(),
+ ) {
return true;
}
break;
@@ -345,12 +356,11 @@ impl Rule {
match self.get_reason() {
r if r == RULE_ROOT_REQUIRE => {
let reason_data = self.get_reason_data();
- let (package_name, constraint): (&str, &dyn ConstraintInterface) = match reason_data
- {
+ let (package_name, constraint): (&str, &AnyConstraint) = match reason_data {
ReasonData::RootRequire {
package_name,
constraint,
- } => (package_name.as_str(), constraint.as_ref()),
+ } => (package_name.as_str(), constraint),
_ => return String::new(),
};
@@ -712,7 +722,7 @@ impl Rule {
pool: &Pool,
packages: Vec<Box<dyn BasePackage>>,
is_verbose: bool,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
Problem::get_package_list(
@@ -730,7 +740,7 @@ impl Rule {
pool: &Pool,
literals: &[i64],
is_verbose: bool,
- constraint: Option<&dyn ConstraintInterface>,
+ constraint: Option<&AnyConstraint>,
use_removed_version_group: bool,
) -> String {
let mut packages: Vec<Box<dyn BasePackage>> = vec![];
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index 45f1331..076ce42 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -205,14 +205,14 @@ impl RuleSetGenerator {
}
for link in package.get_requires().values() {
- let mut constraint = link.get_constraint().clone_box();
+ let mut constraint = link.get_constraint().clone();
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, true)
.unwrap_or(fallback);
@@ -221,7 +221,7 @@ impl RuleSetGenerator {
let possible_requires: Vec<Box<dyn PackageInterface>> = self
.pool
.borrow_mut()
- .what_provides(link.get_target(), Some(&*constraint))
+ .what_provides(link.get_target(), Some(&constraint))
.into_iter()
.map(|p| p.clone_package_box())
.collect();
@@ -258,14 +258,14 @@ impl RuleSetGenerator {
continue;
}
- let mut constraint = link.get_constraint().clone_box();
+ let mut constraint = link.get_constraint().clone();
if platform_requirement_filter.is_ignored(link.get_target()) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(link.get_target(), constraint, false)
.unwrap_or(fallback);
@@ -274,7 +274,7 @@ impl RuleSetGenerator {
let conflicts = self
.pool
.borrow_mut()
- .what_provides(link.get_target(), Some(&*constraint));
+ .what_provides(link.get_target(), Some(&constraint));
for conflict in &conflicts {
// define the conflict rule for regular packages, for alias packages it's only needed if the name
@@ -354,14 +354,14 @@ impl RuleSetGenerator {
}
for (package_name, constraint) in request.get_requires() {
- let mut constraint = constraint.clone_box();
+ let mut constraint = constraint.clone();
if platform_requirement_filter.is_ignored(package_name) {
continue;
} else if let Some(ignore_list_filter) = platform_requirement_filter
.as_any()
.downcast_ref::<IgnoreListPlatformRequirementFilter>(
) {
- let fallback = constraint.clone_box();
+ let fallback = constraint.clone();
constraint = ignore_list_filter
.filter_constraint(package_name, constraint, true)
.unwrap_or(fallback);
@@ -370,7 +370,7 @@ impl RuleSetGenerator {
let packages: Vec<Box<dyn PackageInterface>> = self
.pool
.borrow_mut()
- .what_provides(package_name, Some(&*constraint))
+ .what_provides(package_name, Some(&constraint))
.into_iter()
.map(|p| p.clone_package_box())
.collect();
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 742a709..4daf641 100644
--- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
+++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs
@@ -8,7 +8,8 @@ use crate::dependency_resolver::Request;
use crate::package::PackageInterface;
use crate::repository::RepositoryInterface;
use indexmap::IndexMap;
-use shirabe_semver::constraint::Constraint;
+use shirabe_semver::constraint::AnyConstraint;
+use shirabe_semver::constraint::SimpleConstraint;
#[derive(Debug)]
pub struct SecurityAdvisoryPoolFilter {
@@ -64,7 +65,9 @@ impl SecurityAdvisoryPoolFilter {
continue;
}
- let package_constraint = Constraint::new("==", package.get_version());
+ let package_constraint =
+ SimpleConstraint::new("==".to_string(), package.get_version().to_string(), None)
+ .into();
for advisory in &advisory_map[&package_name] {
// advisory is PartialSecurityAdvisory or SecurityAdvisory; both have affected_versions: Box<dyn ConstraintInterface>
if advisory.affected_versions.matches(&package_constraint) {
diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs
index e4539d2..820f792 100644
--- a/crates/shirabe/src/dependency_resolver/solver.rs
+++ b/crates/shirabe/src/dependency_resolver/solver.rs
@@ -8,7 +8,7 @@ use indexmap::IndexMap;
use shirabe_php_shim::{
PhpMixed, array_pop, array_shift, array_unshift, microtime, spl_object_hash, sprintf,
};
-use shirabe_semver::constraint::ConstraintInterface;
+use shirabe_semver::constraint::AnyConstraint;
use crate::dependency_resolver::Decisions;
use crate::dependency_resolver::GenericRule;
@@ -189,8 +189,8 @@ impl Solver {
// TODO(phase-b): ConstraintInterface is a PHP class — Box<dyn ConstraintInterface>
// cannot be cloned. We borrow the original constraint and only allocate a fresh
// box when the ignore filter rewrites it.
- let mut filtered: Option<Box<dyn ConstraintInterface>> = None;
- let constraint_ref: &dyn ConstraintInterface = constraint.as_ref();
+ let mut filtered: Option<AnyConstraint> = None;
+ let constraint_ref: &AnyConstraint = constraint;
if platform_requirement_filter.is_ignored(package_name) {
continue;
} else if let Some(ignore_filter) = platform_requirement_filter
@@ -204,8 +204,7 @@ impl Solver {
let _ = &mut filtered;
}
- let active_constraint: &dyn ConstraintInterface =
- filtered.as_deref().unwrap_or(constraint_ref);
+ let active_constraint: &AnyConstraint = filtered.as_ref().unwrap_or(constraint_ref);
if self
.pool