diff options
Diffstat (limited to 'crates/shirabe')
50 files changed, 641 insertions, 521 deletions
diff --git a/crates/shirabe/src/advisory/ignored_security_advisory.rs b/crates/shirabe/src/advisory/ignored_security_advisory.rs index 1cd5f75..140c00b 100644 --- a/crates/shirabe/src/advisory/ignored_security_advisory.rs +++ b/crates/shirabe/src/advisory/ignored_security_advisory.rs @@ -4,7 +4,7 @@ use crate::advisory::SecurityAdvisory; use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug, serde::Serialize)] #[serde(rename_all = "camelCase")] @@ -19,7 +19,7 @@ impl IgnoredSecurityAdvisory { pub fn new( package_name: String, advisory_id: String, - affected_versions: Box<dyn ConstraintInterface>, + affected_versions: AnyConstraint, title: String, sources: Vec<IndexMap<String, String>>, reported_at: DateTime<Utc>, diff --git a/crates/shirabe/src/advisory/partial_security_advisory.rs b/crates/shirabe/src/advisory/partial_security_advisory.rs index 6953ef3..fe3c99e 100644 --- a/crates/shirabe/src/advisory/partial_security_advisory.rs +++ b/crates/shirabe/src/advisory/partial_security_advisory.rs @@ -7,12 +7,12 @@ use chrono::{DateTime, TimeZone, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{PhpMixed, UnexpectedValueException}; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use shirabe_semver::version_parser::VersionParser; fn serialize_constraint<S: serde::Serializer>( - c: &Box<dyn ConstraintInterface>, + c: &AnyConstraint, serializer: S, ) -> Result<S::Ok, S::Error> { serializer.serialize_str(&c.get_pretty_string()) @@ -24,7 +24,7 @@ pub struct PartialSecurityAdvisory { pub advisory_id: String, pub package_name: String, #[serde(serialize_with = "serialize_constraint")] - pub affected_versions: Box<dyn ConstraintInterface>, + pub affected_versions: AnyConstraint, } impl PartialSecurityAdvisory { @@ -35,21 +35,22 @@ impl PartialSecurityAdvisory { ) -> Result<PartialOrSecurityAdvisory> { let affected_versions_str = data["affectedVersions"].as_string().unwrap_or(""); - let constraint: Box<dyn ConstraintInterface> = - match parser.parse_constraints(affected_versions_str) { - Ok(c) => c, - Err(_) => { - let affected_version = - Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str); - match parser.parse_constraints(affected_version.as_deref().unwrap_or("")) { - Ok(c) => c, - Err(_) => Box::new(Constraint::new( - "==".to_string(), - "0.0.0-invalid-version".to_string(), - )), - } + let constraint: AnyConstraint = match parser.parse_constraints(affected_versions_str) { + Ok(c) => c, + Err(_) => { + let affected_version = + Preg::replace(r"(^[>=<^~]*[\d.]+).*", "$1", affected_versions_str); + match parser.parse_constraints(affected_version.as_deref().unwrap_or("")) { + Ok(c) => c, + Err(_) => SimpleConstraint::new( + "==".to_string(), + "0.0.0-invalid-version".to_string(), + None, + ) + .into(), } - }; + } + }; let has_full_data = data.contains_key("title") && data.contains_key("sources") @@ -93,7 +94,7 @@ impl PartialSecurityAdvisory { pub fn new( package_name: String, advisory_id: String, - affected_versions: Box<dyn ConstraintInterface>, + affected_versions: AnyConstraint, ) -> Self { Self { advisory_id, diff --git a/crates/shirabe/src/advisory/security_advisory.rs b/crates/shirabe/src/advisory/security_advisory.rs index 9787d37..edb161c 100644 --- a/crates/shirabe/src/advisory/security_advisory.rs +++ b/crates/shirabe/src/advisory/security_advisory.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::advisory::IgnoredSecurityAdvisory; use crate::advisory::PartialSecurityAdvisory; @@ -24,7 +24,7 @@ impl SecurityAdvisory { pub fn new( package_name: String, advisory_id: String, - affected_versions: Box<dyn ConstraintInterface>, + affected_versions: AnyConstraint, title: String, sources: Vec<IndexMap<String, String>>, reported_at: DateTime<Utc>, @@ -48,15 +48,15 @@ impl SecurityAdvisory { &self.inner.advisory_id } - pub fn affected_versions(&self) -> &dyn ConstraintInterface { - &*self.inner.affected_versions + pub fn affected_versions(&self) -> &AnyConstraint { + &self.inner.affected_versions } pub fn to_ignored_advisory(&self, ignore_reason: Option<String>) -> IgnoredSecurityAdvisory { IgnoredSecurityAdvisory::new( self.inner.package_name.clone(), self.inner.advisory_id.clone(), - self.inner.affected_versions.clone_box(), + self.inner.affected_versions.clone(), self.title.clone(), self.sources.clone(), self.reported_at, diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs index 7b7980a..5c9f008 100644 --- a/crates/shirabe/src/autoload/autoload_generator.rs +++ b/crates/shirabe/src/autoload/autoload_generator.rs @@ -14,8 +14,8 @@ use shirabe_php_shim::{ sprintf, str_contains, str_replace, str_starts_with, strlen, strpos, strtr, substr, substr_count, trigger_error, trim, unlink, var_export, }; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::Bound; -use shirabe_semver::constraint::ConstraintInterface; use crate::autoload::ClassLoader; use crate::config::Config; @@ -1092,7 +1092,7 @@ impl AutoloadGenerator { let mut required_extensions: IndexMap<String, String> = IndexMap::new(); let mut extension_providers: IndexMap< String, - Vec<Box<dyn shirabe_semver::constraint::ConstraintInterface>>, + Vec<shirabe_semver::constraint::AnyConstraint>, > = IndexMap::new(); for item in package_map { @@ -1110,7 +1110,7 @@ impl AutoloadGenerator { extension_providers .entry(ext) .or_insert_with(Vec::new) - .push(link.get_constraint().clone_box()); + .push(link.get_constraint().clone()); } } } diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs index c88b47b..0813df6 100644 --- a/crates/shirabe/src/command/archive_command.rs +++ b/crates/shirabe/src/command/archive_command.rs @@ -305,11 +305,11 @@ impl ArchiveCommand { ); repo_set.add_repository(Box::new(repo))?; let parser = VersionParser::new(); - let constraint: Option<Box<dyn shirabe_semver::constraint::ConstraintInterface>> = - match version.as_deref() { - Some(v) => Some(parser.parse_constraints(v)?.clone_box()), - None => None, - }; + let constraint: Option<shirabe_semver::constraint::AnyConstraint> = match version.as_deref() + { + Some(v) => Some(parser.parse_constraints(v)?.clone()), + None => None, + }; let packages = repo_set.find_packages(&package_name.to_lowercase(), constraint, 0); let package = if packages.len() > 1 { diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs index 498c589..f1ff863 100644 --- a/crates/shirabe/src/command/base_dependency_command.rs +++ b/crates/shirabe/src/command/base_dependency_command.rs @@ -6,8 +6,8 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac use shirabe_external_packages::symfony::component::console::output::OutputInterface; use shirabe_external_packages::symfony::console::formatter::OutputFormatter; use shirabe_php_shim::{InvalidArgumentException, PhpMixed, UnexpectedValueException}; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::Bound; -use shirabe_semver::constraint::ConstraintInterface; use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData}; use crate::package::CompletePackageInterface; @@ -225,13 +225,9 @@ pub trait BaseDependencyCommand: BaseCommand { } let has_constraint = text_constraint != "*"; - let constraint: Option<Box<dyn ConstraintInterface>> = if has_constraint { + let constraint: Option<AnyConstraint> = if has_constraint { let version_parser = VersionParser::new(); - Some( - version_parser - .parse_constraints(&text_constraint)? - .clone_box(), - ) + Some(version_parser.parse_constraints(&text_constraint)?.clone()) } else { None }; diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs index 83770be..74ecfc3 100644 --- a/crates/shirabe/src/command/check_platform_reqs_command.rs +++ b/crates/shirabe/src/command/check_platform_reqs_command.rs @@ -5,8 +5,8 @@ use indexmap::IndexMap; use shirabe_external_packages::symfony::component::console::input::InputInterface; use shirabe_external_packages::symfony::component::console::output::OutputInterface; use shirabe_php_shim::{PhpMixed, strip_tags}; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData}; use crate::console::input::InputOption; @@ -147,22 +147,23 @@ impl CheckPlatformReqsCommand { if !candidates.is_empty() { let mut req_results: Vec<CheckResult> = vec![]; 'candidates: for candidate in &candidates { - let candidate_constraint: Option<Box<dyn ConstraintInterface>> = + let candidate_constraint: Option<AnyConstraint> = if candidate.get_name() == require { - let mut c = Constraint::new("=", candidate.get_version()); - c.set_pretty_string(Some( - candidate.get_pretty_version().to_string(), - )); - Some(Box::new(c)) + let c = SimpleConstraint::new( + "=".to_string(), + candidate.get_version().to_string(), + Some(candidate.get_pretty_version().to_string()), + ); + Some(c.into()) } else { - let mut found: Option<Box<dyn ConstraintInterface>> = None; + let mut found: Option<AnyConstraint> = None; for (_, link) in candidate .get_provides() .iter() .chain(candidate.get_replaces().iter()) { if link.get_target() == require { - found = Some(link.get_constraint().clone_box()); + found = Some(link.get_constraint().clone()); break; } } @@ -175,7 +176,7 @@ impl CheckPlatformReqsCommand { }; for link in links { - if !link.get_constraint().matches(&*candidate_constraint) { + if !link.get_constraint().matches(&candidate_constraint) { req_results.push(CheckResult { platform_package: if candidate.get_name() == require { candidate.get_pretty_name().to_string() diff --git a/crates/shirabe/src/command/fund_command.rs b/crates/shirabe/src/command/fund_command.rs index 233eeaa..82c0c0a 100644 --- a/crates/shirabe/src/command/fund_command.rs +++ b/crates/shirabe/src/command/fund_command.rs @@ -9,7 +9,7 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac use shirabe_external_packages::symfony::component::console::output::OutputInterface; use shirabe_external_packages::symfony::console::formatter::OutputFormatter; use shirabe_php_shim::PhpMixed; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData}; @@ -64,8 +64,7 @@ impl FundCommand { ); let mut fundings: IndexMap<String, IndexMap<String, Vec<String>>> = IndexMap::new(); - let mut packages_to_load: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = - IndexMap::new(); + let mut packages_to_load: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); let mut packages_to_load_names: indexmap::IndexSet<String> = indexmap::IndexSet::new(); for package in repo.get_packages() { if package.as_any().downcast_ref::<AliasPackage>().is_some() { @@ -73,7 +72,7 @@ impl FundCommand { } packages_to_load.insert( package.get_name().to_string(), - Some(Box::new(MatchAllConstraint::new())), + Some(MatchAllConstraint::new(None).into()), ); packages_to_load_names.insert(package.get_name().to_string()); } diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs index 43d6ee8..fa25fa3 100644 --- a/crates/shirabe/src/command/package_discovery_trait.rs +++ b/crates/shirabe/src/command/package_discovery_trait.rs @@ -880,9 +880,12 @@ pub trait PackageDiscoveryTrait { }; if !link .get_constraint() - .matches(&shirabe_semver::constraint::Constraint::new( - "==", - platform_pkg.get_version(), + .matches(&shirabe_semver::constraint::AnyConstraint::Simple( + shirabe_semver::constraint::SimpleConstraint::new( + "==".to_string(), + platform_pkg.get_version().to_string(), + None, + ), )) { let mut platform_pkg_version = platform_pkg.get_pretty_version().to_string(); diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index 3eac2df..8826421 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -13,7 +13,7 @@ use shirabe_php_shim::{ date, extension_loaded, in_array, realpath, strtolower, version_compare, }; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData}; use crate::composer::PartialComposerHandle; @@ -1486,7 +1486,7 @@ impl ShowCommand { IndexMap<String, String>, )> { let name = strtolower(name); - let constraint: Option<Box<dyn ConstraintInterface>> = match &version { + let constraint: Option<AnyConstraint> = match &version { PhpMixed::String(s) => Some(self.version_parser.parse_constraints(s)?), PhpMixed::Null => None, _ => None, // already a ConstraintInterface @@ -1514,7 +1514,7 @@ impl ShowCommand { } else { repository_set.create_pool_for_package(&name, None)? }; - let matches = pool.what_provides(&name, constraint.as_deref()); + let matches = pool.what_provides(&name, constraint.as_ref()); let mut literals: Vec<i64> = Vec::new(); for package in matches.iter() { // avoid showing the 9999999-dev alias if the default branch has no branch-alias set diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs index c4ae890..4096272 100644 --- a/crates/shirabe/src/command/update_command.rs +++ b/crates/shirabe/src/command/update_command.rs @@ -178,9 +178,7 @@ impl UpdateCommand { for (package, constraint) in &reqs { let package = strtolower(package); let parsed_constraint = parser.parse_constraints(constraint)?; - // TODO(phase-b): clone_box because Box<dyn ConstraintInterface> isn't Clone. - temporary_constraints.insert(package.clone(), parsed_constraint.clone_box()); - let _ = parsed_constraint; + temporary_constraints.insert(package.clone(), parsed_constraint); // TODO(phase-b): access root_requirements[package].getConstraint() let intersected: bool = todo!("Intervals::haveIntersections check"); if let Some(_root_req) = todo!("root_requirements.get(&package)") as Option<PhpMixed> { @@ -234,10 +232,9 @@ impl UpdateCommand { matches.get(1).cloned().unwrap_or_default() ))?; if temporary_constraints.contains_key(package.get_name()) { - // TODO(phase-b): Box<dyn ConstraintInterface> isn't Clone; clone_box workaround. let existing = temporary_constraints .get(package.get_name()) - .map(|c| c.clone_box()) + .map(|c| c.clone()) .unwrap(); temporary_constraints.insert( package.get_name().to_string(), 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 diff --git a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs index f6b8091..d69773c 100644 --- a/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs +++ b/crates/shirabe/src/filter/platform_requirement_filter/ignore_list_platform_requirement_filter.rs @@ -1,10 +1,10 @@ //! ref: composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php use shirabe_external_packages::composer::pcre::Preg; -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 shirabe_semver::interval::Interval; use shirabe_semver::intervals::Intervals; @@ -41,9 +41,9 @@ impl IgnoreListPlatformRequirementFilter { pub fn filter_constraint( &self, req: &str, - constraint: Box<dyn ConstraintInterface>, + constraint: AnyConstraint, allow_upper_bound_override: bool, - ) -> anyhow::Result<Box<dyn ConstraintInterface>> { + ) -> anyhow::Result<AnyConstraint> { if !PlatformRepository::is_platform_package(req) { return Ok(constraint); } @@ -53,20 +53,26 @@ impl IgnoreListPlatformRequirementFilter { } if Preg::is_match(&self.ignore_regex, req)? { - return Ok(Box::new(MatchAllConstraint::new())); + return Ok(MatchAllConstraint::new(None).into()); } - let intervals = Intervals::get(&*constraint)?; + let intervals = Intervals::get(&constraint)?; let last = intervals.numeric.last(); if let Some(last) = last { if last.get_end().to_string() != Interval::until_positive_infinity().to_string() { - let constraint = Box::new(MultiConstraint::new( + let constraint = MultiConstraint::new( vec![ constraint, - Box::new(Constraint::new(">=", last.get_end().get_version())), + AnyConstraint::Simple(SimpleConstraint::new( + ">=".to_string(), + last.get_end().get_version().to_string(), + None, + )), ], false, - )); + None, + ) + .into(); return Ok(constraint); } } diff --git a/crates/shirabe/src/installed_versions.rs b/crates/shirabe/src/installed_versions.rs index 644cc8e..d52deac 100644 --- a/crates/shirabe/src/installed_versions.rs +++ b/crates/shirabe/src/installed_versions.rs @@ -171,7 +171,7 @@ impl InstalledVersions { let constraint = parser.parse_constraints(constraint.unwrap_or(""))?; let provided = parser.parse_constraints(&Self::get_version_ranges(package_name)?)?; - Ok(provided.matches(&*constraint)) + Ok(provided.matches(&constraint)) } /// Returns a version constraint representing all the range(s) which are installed for a given package diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index 3ccb65f..8b68a78 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -97,8 +97,8 @@ use crate::repository::RepositorySet; use crate::repository::RootPackageRepository; use crate::script::ScriptEvents; use crate::util::Platform; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; #[derive(Debug)] pub struct Installer { @@ -144,7 +144,7 @@ pub struct Installer { pub(crate) suggested_packages_reporter: SuggestedPackagesReporter, pub(crate) platform_requirement_filter: Box<dyn PlatformRequirementFilterInterface>, pub(crate) additional_fixed_repository: Option<Box<dyn RepositoryInterface>>, - pub(crate) temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + pub(crate) temporary_constraints: IndexMap<String, AnyConstraint>, } impl Installer { @@ -1049,8 +1049,7 @@ impl Installer { } for (_key, link) in &root_requires { if PlatformRepository::is_platform_package(link.get_target()) { - request - .require_name(link.get_target(), Some(link.get_constraint().clone_box()))?; + request.require_name(link.get_target(), Some(link.get_constraint().clone()))?; } } @@ -1060,8 +1059,7 @@ impl Installer { .get_platform_requirements(self.dev_mode)? { if !root_requires.contains_key(link.get_target()) { - request - .require_name(link.get_target(), Some(link.get_constraint().clone_box()))?; + request.require_name(link.get_target(), Some(link.get_constraint().clone()))?; } } drop(root_requires); @@ -1249,7 +1247,7 @@ impl Installer { let minimum_stability: String; let mut stability_flags: IndexMap<String, i64>; - let requires: IndexMap<String, Box<dyn ConstraintInterface>>; + let requires: IndexMap<String, AnyConstraint>; if for_update { minimum_stability = self.package.get_minimum_stability().to_string(); stability_flags = self.package.get_stability_flags().clone(); @@ -1263,9 +1261,9 @@ impl Installer { req_links.insert(k, v); } // Translate to constraint map for downstream uniform handling. - let mut tmp: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut tmp: IndexMap<String, AnyConstraint> = IndexMap::new(); for (k, link) in req_links { - tmp.insert(k, link.get_constraint().clone_box()); + tmp.insert(k, link.get_constraint().clone()); } requires = tmp; } else { @@ -1286,16 +1284,19 @@ impl Installer { }) .unwrap_or_default(); - let mut tmp: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut tmp: IndexMap<String, AnyConstraint> = IndexMap::new(); for package in locked_repository.unwrap().get_packages() { - let mut constraint = Constraint::new("=", package.get_version().to_string()); - constraint.set_pretty_string(Some(package.get_pretty_version().to_string())); - tmp.insert(package.get_name().to_string(), Box::new(constraint)); + let constraint = SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + Some(package.get_pretty_version().to_string()), + ); + tmp.insert(package.get_name().to_string(), constraint.into()); } requires = tmp; } - let mut root_requires: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut root_requires: IndexMap<String, AnyConstraint> = IndexMap::new(); for (req, mut constraint) in requires { // skip platform requirements from the root package to avoid filtering out existing platform packages if self.platform_requirement_filter.is_ignored(&req) { @@ -1307,7 +1308,10 @@ impl Installer { { constraint = filter .filter_constraint(&req, constraint, false) - .unwrap_or_else(|_| Box::new(Constraint::new("=", String::new()))); + .unwrap_or_else(|_| { + SimpleConstraint::new("=".to_string(), String::new().to_string(), None) + .into() + }); } root_requires.insert(req, constraint); } @@ -1327,8 +1331,7 @@ impl Installer { // TODO(phase-b): convert root_aliases (Vec<IndexMap<String, String>>) into Vec<RootAliasInput> let root_aliases_input: Vec<crate::repository::RootAliasInput> = vec![]; let _ = root_aliases; - // TODO(phase-b): temporary_constraints holds Box<dyn ConstraintInterface> which can't Clone - let temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let temporary_constraints: IndexMap<String, AnyConstraint> = IndexMap::new(); let mut repository_set = RepositorySet::new( &minimum_stability, stability_flags, @@ -1467,7 +1470,14 @@ impl Installer { .get(package.get_name()) .unwrap() .get_constraint() - .matches(&Constraint::new("=", package.get_version().to_string())) + .matches( + &SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ) { // TODO(phase-b): fix_package needs owned Box<dyn BasePackage> let _ = &package; @@ -1510,10 +1520,14 @@ impl Installer { { request.require_name( locked_package.get_name(), - Some(Box::new(Constraint::new( - "==", - locked_package.get_version().to_string(), - ))), + Some( + SimpleConstraint::new( + "==".to_string(), + locked_package.get_version().to_string(), + None, + ) + .into(), + ), )?; } } @@ -1525,7 +1539,7 @@ impl Installer { } } for (_key, link) in &links { - request.require_name(link.get_target(), Some(link.get_constraint().clone_box()))?; + request.require_name(link.get_target(), Some(link.get_constraint().clone()))?; } } Ok(()) @@ -1674,7 +1688,7 @@ impl Installer { pub fn set_temporary_constraints( &mut self, - constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + constraints: IndexMap<String, AnyConstraint>, ) -> &mut Self { self.temporary_constraints = constraints; diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs index 0d687a1..e9b5dbf 100644 --- a/crates/shirabe/src/package/alias_package.rs +++ b/crates/shirabe/src/package/alias_package.rs @@ -3,7 +3,8 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, in_array}; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::package::BasePackage; use crate::package::Link; @@ -177,18 +178,18 @@ impl AliasPackage { for link in &links { // link is self.version, but must be replacing also the replaced version if link.get_pretty_constraint().unwrap_or("") == "self.version" { - let mut constraint = Constraint::new("=", &self.version); + let constraint = SimpleConstraint::new( + "=".to_string(), + self.version.to_string(), + Some(pretty_version.clone()), + ); let new_link = Link::new( link.get_source().to_string(), link.get_target().to_string(), - Box::new(constraint.clone()), + constraint.into(), Some(link_type.to_string()), Some(pretty_version.clone()), ); - shirabe_semver::constraint::ConstraintInterface::set_pretty_string( - &mut constraint, - Some(pretty_version.clone()), - ); new_links.push(new_link); } } @@ -200,18 +201,18 @@ impl AliasPackage { if link_type == Link::TYPE_REQUIRE { self.has_self_version_requires = true; } - let mut constraint = Constraint::new("=", &self.version); + let constraint = SimpleConstraint::new( + "=".to_string(), + self.version.to_string(), + Some(pretty_version.clone()), + ); let new_link = Link::new( links[index].get_source().to_string(), links[index].get_target().to_string(), - Box::new(constraint.clone()), + constraint.into(), Some(link_type.to_string()), Some(pretty_version.clone()), ); - shirabe_semver::constraint::ConstraintInterface::set_pretty_string( - &mut constraint, - Some(pretty_version.clone()), - ); links[index] = new_link; } } diff --git a/crates/shirabe/src/package/link.rs b/crates/shirabe/src/package/link.rs index 80a98c7..d606c63 100644 --- a/crates/shirabe/src/package/link.rs +++ b/crates/shirabe/src/package/link.rs @@ -1,14 +1,14 @@ //! ref: composer/src/Composer/Package/Link.php use shirabe_php_shim::UnexpectedValueException; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::package::PackageInterface; pub struct Link { pub(crate) source: String, pub(crate) target: String, - pub(crate) constraint: Box<dyn ConstraintInterface>, + pub(crate) constraint: AnyConstraint, pub(crate) description: String, pub(crate) pretty_constraint: Option<String>, } @@ -20,7 +20,7 @@ impl Clone for Link { Self { source: self.source.clone(), target: self.target.clone(), - constraint: self.constraint.clone_box(), + constraint: self.constraint.clone(), description: self.description.clone(), pretty_constraint: self.pretty_constraint.clone(), } @@ -63,7 +63,7 @@ impl Link { pub fn new( source: String, target: String, - constraint: Box<dyn ConstraintInterface>, + constraint: AnyConstraint, description: Option<String>, pretty_constraint: Option<String>, ) -> Self { @@ -94,8 +94,8 @@ impl Link { &self.target } - pub fn get_constraint(&self) -> &dyn ConstraintInterface { - &*self.constraint + pub fn get_constraint(&self) -> &AnyConstraint { + &self.constraint } pub fn get_pretty_constraint(&self) -> anyhow::Result<&str> { @@ -117,7 +117,7 @@ impl Link { self.source, self.description, self.target, - self.constraint.__to_string(), + self.constraint.to_string(), ) } diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs index ffbe465..87d6e35 100644 --- a/crates/shirabe/src/package/loader/array_loader.rs +++ b/crates/shirabe/src/package/loader/array_loader.rs @@ -764,12 +764,10 @@ impl ArrayLoader { } }; - // TODO(phase-b): Link::new expects Box<dyn ConstraintInterface>; we have Arc<dyn ConstraintInterface + Send + Sync> - let _ = parsed_constraint; Ok(Link::new( source.to_string(), target.to_string(), - todo!("phase-b: convert Arc<dyn ConstraintInterface> to Box<dyn ConstraintInterface>"), + parsed_constraint, Some(description.to_string()), Some(pretty_constraint.to_string()), )) diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs index 59fc266..a2dd5a7 100644 --- a/crates/shirabe/src/package/loader/validating_array_loader.rs +++ b/crates/shirabe/src/package/loader/validating_array_loader.rs @@ -11,9 +11,9 @@ use shirabe_php_shim::{ is_string, json_encode, parse_url_all, php_to_string, sprintf, str_replace, strcasecmp, strtolower, strtotime, substr, trigger_error, trim, var_export, }; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchNoneConstraint; +use shirabe_semver::constraint::SimpleConstraint; use shirabe_semver::intervals::Intervals; use crate::package::loader::InvalidPackageException; @@ -877,7 +877,8 @@ impl ValidatingArrayLoader { } } - let unbound_constraint = Constraint::new("=", "10000000-dev"); + let unbound_constraint = + SimpleConstraint::new("=".to_string(), "10000000-dev".to_string(), None).into(); let link_types: Vec<&'static str> = SUPPORTED_LINK_TYPES.keys().copied().collect(); for link_type in link_types { @@ -952,11 +953,14 @@ impl ValidatingArrayLoader { } else if (self.flags & Self::CHECK_STRICT_CONSTRAINTS) != 0 && link_type == "require" && link_constraint - .as_any() - .downcast_ref::<Constraint>() + .as_constraint() .map_or(false, |c| ["==", "="].contains(&c.get_operator())) - && Constraint::new(">=", "1.0.0.0-dev") - .matches(link_constraint.as_ref()) + && AnyConstraint::from(SimpleConstraint::new( + ">=".to_string(), + "1.0.0.0-dev".to_string(), + None, + )) + .matches(&link_constraint) { self.warnings.push(format!( "{}.{} : exact version constraints ({}) should be avoided if the package follows semantic versioning", @@ -964,8 +968,8 @@ impl ValidatingArrayLoader { )); } - let compacted = Intervals::compact_constraint(link_constraint.as_ref())?; - if compacted.as_any().is::<MatchNoneConstraint>() { + let compacted = Intervals::compact_constraint(&link_constraint)?; + if compacted.is_match_none() { self.warnings.push(format!( "{}.{} : this version constraint cannot possibly match anything ({})", link_type, package, constraint_str diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs index ecd96e3..9522e55 100644 --- a/crates/shirabe/src/package/locker.rs +++ b/crates/shirabe/src/package/locker.rs @@ -967,7 +967,7 @@ impl Locker { .find_packages_with_replacers_and_providers( &link.get_target(), Some(FindPackageConstraint::Constraint( - link.get_constraint().clone_box(), + link.get_constraint().clone(), )), ) .is_empty() diff --git a/crates/shirabe/src/package/version/version_bumper.rs b/crates/shirabe/src/package/version/version_bumper.rs index a9b5a67..8cc4b5d 100644 --- a/crates/shirabe/src/package/version/version_bumper.rs +++ b/crates/shirabe/src/package/version/version_bumper.rs @@ -8,7 +8,7 @@ use crate::util::Platform; use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::{CaptureKey, Preg}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::intervals::Intervals; #[derive(Debug)] @@ -17,7 +17,7 @@ pub struct VersionBumper; impl VersionBumper { pub fn bump_requirement( &self, - constraint: &dyn ConstraintInterface, + constraint: &AnyConstraint, package: &dyn PackageInterface, ) -> Result<String> { let parser = VersionParser::new(); @@ -114,8 +114,8 @@ impl VersionBumper { } let new_constraint = parser.parse_constraints(&modified)?; - if Intervals::is_subset_of(new_constraint.as_ref(), constraint)? - && Intervals::is_subset_of(constraint, new_constraint.as_ref())? + if Intervals::is_subset_of(&new_constraint, constraint)? + && Intervals::is_subset_of(constraint, &new_constraint)? { return Ok(pretty_constraint); } diff --git a/crates/shirabe/src/package/version/version_parser.rs b/crates/shirabe/src/package/version/version_parser.rs index 46a2356..1b588bc 100644 --- a/crates/shirabe/src/package/version/version_parser.rs +++ b/crates/shirabe/src/package/version/version_parser.rs @@ -1,16 +1,16 @@ //! ref: composer/src/Composer/Package/Version/VersionParser.php use indexmap::IndexMap; -use std::sync::{Arc, LazyLock, Mutex}; +use std::sync::{LazyLock, Mutex}; use shirabe_external_packages::composer::pcre::Preg; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::semver::Semver; use shirabe_semver::version_parser::VersionParser as SemverVersionParser; use crate::repository::PlatformRepository; -static CONSTRAINTS: LazyLock<Mutex<IndexMap<String, Arc<dyn ConstraintInterface + Send + Sync>>>> = +static CONSTRAINTS: LazyLock<Mutex<IndexMap<String, AnyConstraint>>> = LazyLock::new(|| Mutex::new(IndexMap::new())); #[derive(Debug, Clone)] @@ -21,12 +21,19 @@ pub struct VersionParser { impl VersionParser { pub const DEFAULT_BRANCH_ALIAS: &'static str = "9999999-dev"; - pub fn parse_constraints( - &self, - constraints: &str, - ) -> anyhow::Result<Box<dyn ConstraintInterface>> { - // TODO(phase-b): re-introduce a memoization cache once trait objects are Send+Sync. - self.inner.parse_constraints(constraints) + pub fn parse_constraints(&self, constraints: &str) -> anyhow::Result<AnyConstraint> { + { + let cache = CONSTRAINTS.lock().unwrap(); + if let Some(cached) = cache.get(constraints) { + return Ok(cached.clone()); + } + } + let parsed = self.inner.parse_constraints(constraints)?; + CONSTRAINTS + .lock() + .unwrap() + .insert(constraints.to_string(), parsed.clone()); + Ok(parsed) } pub fn parse_name_version_pairs( diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs index 832f64c..3bd0191 100644 --- a/crates/shirabe/src/package/version/version_selector.rs +++ b/crates/shirabe/src/package/version/version_selector.rs @@ -8,8 +8,8 @@ use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{ PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, strtolower, version_compare, }; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::filter::platform_requirement_filter::IgnoreAllPlatformRequirementFilter; use crate::filter::platform_requirement_filter::IgnoreListPlatformRequirementFilter; @@ -29,7 +29,7 @@ use crate::repository::RepositorySet; #[derive(Debug)] pub struct VersionSelector { repository_set: RepositorySet, - platform_constraints: IndexMap<String, Vec<Box<dyn ConstraintInterface>>>, + platform_constraints: IndexMap<String, Vec<AnyConstraint>>, parser: Option<VersionParser>, } @@ -38,16 +38,19 @@ impl VersionSelector { repository_set: RepositorySet, platform_repo: Option<&crate::repository::PlatformRepository>, ) -> anyhow::Result<Self> { - let mut platform_constraints: IndexMap<String, Vec<Box<dyn ConstraintInterface>>> = - IndexMap::new(); + let mut platform_constraints: IndexMap<String, Vec<AnyConstraint>> = IndexMap::new(); if let Some(platform_repo) = platform_repo { for package in <PlatformRepository as RepositoryInterface>::get_packages(platform_repo) { - let constraint = Constraint::new("==", package.get_version()); + let constraint = SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ); platform_constraints .entry(package.get_name().to_string()) .or_default() - .push(Box::new(constraint)); + .push(constraint.into()); } } Ok(Self { @@ -90,7 +93,7 @@ impl VersionSelector { }; let mut candidates = self.repository_set.find_packages( &strtolower(package_name), - constraint.as_ref().map(|c| c.clone_box()), + constraint.as_ref().map(|c| c.clone()), repo_set_flags, ); @@ -142,7 +145,7 @@ impl VersionSelector { let reason; if let Some(provided_constraints) = self.platform_constraints.get(name) { for provided_constraint in provided_constraints { - if link.get_constraint().matches(provided_constraint.as_ref()) { + if link.get_constraint().matches(provided_constraint) { continue 'reqs; } let list_filter_opt = platform_requirement_filter @@ -154,10 +157,10 @@ impl VersionSelector { if list_filter.is_upper_bound_ignored(name) { let filtered_constraint = list_filter.filter_constraint( name, - link.get_constraint().clone_box(), + link.get_constraint().clone(), false, )?; - if filtered_constraint.matches(provided_constraint.as_ref()) { + if filtered_constraint.matches(provided_constraint) { continue 'reqs; } } diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs index 26e6296..77ac577 100644 --- a/crates/shirabe/src/plugin/plugin_manager.rs +++ b/crates/shirabe/src/plugin/plugin_manager.rs @@ -13,7 +13,8 @@ use shirabe_php_shim::{ is_array, is_string, ksort, preg_quote, str_replace, strrpos, strtr, substr, trigger_error, trim, var_export, var_export_str, version_compare, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::composer::PartialComposerHandle; use crate::composer::{ComposerHandle, ComposerWeakHandle}; @@ -227,9 +228,7 @@ impl PluginManager { if package.get_type() == "composer-plugin" { let requires_map = package.get_requires(); - let mut requires_composer: Option< - &dyn shirabe_semver::constraint::ConstraintInterface, - > = None; + let mut requires_composer: Option<&shirabe_semver::constraint::AnyConstraint> = None; for (_k, link) in &requires_map { if "composer-plugin-api" == link.get_target() { requires_composer = Some(link.get_constraint()); @@ -248,15 +247,17 @@ impl PluginManager { }; let current_plugin_api_version = self.get_plugin_api_version(); - let current_plugin_api_constraint = Constraint::new( - "==", + let current_plugin_api_constraint = SimpleConstraint::new( + "==".to_string(), self.version_parser - .normalize(¤t_plugin_api_version, None)?, + .normalize(¤t_plugin_api_version, None)? + .to_string(), + None, ); if requires_composer.get_pretty_string() == self.get_plugin_api_version() { self.io.write_error(&format!("<warning>The \"{}\" plugin requires composer-plugin-api {}, this *WILL* break in the future and it should be fixed ASAP (require ^{} instead for example).</warning>", package.get_name(), self.get_plugin_api_version(), self.get_plugin_api_version())); - } else if !requires_composer.matches(¤t_plugin_api_constraint) { + } else if !requires_composer.matches(¤t_plugin_api_constraint.into()) { self.io.write_error(&format!("<warning>The \"{}\" plugin {}was skipped because it requires a Plugin API version (\"{}\") that does not match your Composer installation (\"{}\"). You may need to run composer update with the \"--no-plugins\" option.</warning>", package.get_name(), if is_global_plugin || self.running_in_global_dir { "(installed globally) " } else { "" }, diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs index 4c08a63..0de9c42 100644 --- a/crates/shirabe/src/repository/advisory_provider_interface.rs +++ b/crates/shirabe/src/repository/advisory_provider_interface.rs @@ -3,7 +3,7 @@ use crate::advisory::PartialSecurityAdvisory; use crate::advisory::SecurityAdvisory; use indexmap::IndexMap; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub enum PartialOrSecurityAdvisory { @@ -31,7 +31,7 @@ pub trait AdvisoryProviderInterface { fn get_security_advisories( &self, - package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult>; } diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index f8d2e0c..fe45849 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -10,8 +10,8 @@ use shirabe_php_shim::{ Countable, InvalidArgumentException, LogicException, implode, preg_quote, spl_object_hash, strtolower, }; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::package::AliasPackage; use crate::package::BasePackage; @@ -162,7 +162,7 @@ impl RepositoryInterface for ArrayRepository { fn load_packages( &self, - package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -178,7 +178,14 @@ impl RepositoryInterface for ArrayRepository { .unwrap(); let constraint_matches = match constraint_opt { None => true, - Some(c) => c.matches(&Constraint::new("==", package.get_version())), + Some(c) => c.matches( + &SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ), }; if constraint_matches && StabilityFilter::is_package_acceptable( @@ -233,18 +240,22 @@ impl RepositoryInterface for ArrayRepository { ) -> Option<Box<dyn BasePackage>> { let name = strtolower(name); - let constraint: Box<dyn ConstraintInterface> = match constraint { + let constraint: AnyConstraint = match constraint { FindPackageConstraint::Constraint(c) => c, FindPackageConstraint::String(s) => { let version_parser = VersionParser::new(); - version_parser.parse_constraints(&s).unwrap().clone_box() + version_parser.parse_constraints(&s).unwrap().clone() } }; for package in self.get_packages() { if name == PackageInterface::get_name(package.as_ref()) { - let pkg_constraint = Constraint::new("==", package.get_version()); - if constraint.matches(&pkg_constraint) { + let pkg_constraint = SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ); + if constraint.matches(&pkg_constraint.into()) { return Some(package); } } @@ -262,22 +273,26 @@ impl RepositoryInterface for ArrayRepository { let name = strtolower(name); let mut packages = vec![]; - let constraint: Option<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = match constraint { None => None, Some(FindPackageConstraint::Constraint(c)) => Some(c), Some(FindPackageConstraint::String(s)) => { let version_parser = VersionParser::new(); - Some(version_parser.parse_constraints(&s).unwrap().clone_box()) + Some(version_parser.parse_constraints(&s).unwrap().clone()) } }; for package in self.get_packages() { if name == PackageInterface::get_name(package.as_ref()) { if constraint.is_none() - || constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("==", package.get_version())) + || constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "==".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ) { packages.push(package); } diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 4bd5442..9752bc0 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -11,9 +11,9 @@ use shirabe_php_shim::{ }; 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::MatchAllConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::advisory::PartialSecurityAdvisory; use crate::cache::Cache; @@ -327,11 +327,11 @@ impl ComposerRepository { let has_providers = self.has_providers()?; let name = strtolower(&name); - let constraint: Box<dyn ConstraintInterface> = match constraint { - PhpMixed::String(s) => self.version_parser.parse_constraints(&s)?.clone_box(), + let constraint: AnyConstraint = match constraint { + PhpMixed::String(s) => self.version_parser.parse_constraints(&s)?.clone(), _ => { // already a ConstraintInterface object passed as opaque PhpMixed - self.version_parser.parse_constraints("")?.clone_box() + self.version_parser.parse_constraints("")?.clone() } }; @@ -345,7 +345,7 @@ impl ComposerRepository { let packages = self.what_provides(&name, None, None, IndexMap::new())?; let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, Some(&*constraint), true) { + match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), _ => None, }, @@ -356,7 +356,7 @@ impl ComposerRepository { return Ok(None); } - let mut map: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = IndexMap::new(); + let mut map: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); map.insert(name.clone(), Some(constraint)); let packages = self.load_async_packages(map, None, None, IndexMap::new())?; @@ -374,7 +374,7 @@ impl ComposerRepository { self.what_provides(&provider_name, None, None, IndexMap::new())?; let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, Some(&*constraint), true) { + match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), _ => None, }, @@ -401,11 +401,9 @@ impl ComposerRepository { let has_providers = self.has_providers()?; let name = strtolower(&name); - let constraint: Option<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = match constraint { None => None, - Some(PhpMixed::String(s)) => { - Some(self.version_parser.parse_constraints(&s)?.clone_box()) - } + Some(PhpMixed::String(s)) => Some(self.version_parser.parse_constraints(&s)?.clone()), Some(_) => None, }; @@ -419,7 +417,7 @@ impl ComposerRepository { let packages = self.what_provides(&name, None, None, IndexMap::new())?; let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, constraint.as_deref(), false) { + match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, _ => vec![], }, @@ -430,7 +428,7 @@ impl ComposerRepository { return Ok(vec![]); } - let mut map: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = IndexMap::new(); + let mut map: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); map.insert(name.clone(), constraint); let result = self.load_async_packages(map, None, None, IndexMap::new())?; @@ -444,7 +442,7 @@ impl ComposerRepository { self.what_provides(&provider_name, None, None, IndexMap::new())?; let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); return Ok( - match self.filter_packages(packages_vec, constraint.as_deref(), false) { + match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, _ => vec![], }, @@ -464,7 +462,7 @@ impl ComposerRepository { fn filter_packages( &self, packages: Vec<Box<dyn BasePackage>>, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, return_first_match: bool, ) -> FindPackageReturn { if constraint.is_none() { @@ -482,9 +480,10 @@ impl ComposerRepository { let mut filtered_packages: Vec<Box<dyn BasePackage>> = Vec::new(); for package in packages.into_iter() { - let pkg_constraint = Constraint::new("==", package.get_version().to_string()); + let pkg_constraint = + SimpleConstraint::new("==".to_string(), package.get_version().to_string(), None); - if constraint.matches(&pkg_constraint) { + if constraint.matches(&pkg_constraint.into()) { if return_first_match { return FindPackageReturn::Package(package); } @@ -506,15 +505,10 @@ impl ComposerRepository { if self.lazy_providers_url.is_some() { if let Some(ref available_packages) = self.available_packages.clone() { if self.available_package_patterns.is_none() { - let mut package_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = - IndexMap::new(); + let mut package_map: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); for name in available_packages.values() { - package_map.insert( - name.clone(), - Some( - Box::new(MatchAllConstraint::new()) as Box<dyn ConstraintInterface> - ), - ); + package_map + .insert(name.clone(), Some(MatchAllConstraint::new(None).into())); } let result = @@ -715,7 +709,7 @@ impl ComposerRepository { pub fn load_packages( &mut self, - mut package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + mut package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -767,7 +761,7 @@ impl ComposerRepository { )?; let constraint = package_name_map .get(&name) - .and_then(|c| c.as_ref().map(|c| c.clone_box())); + .and_then(|c| c.as_ref().map(|c| c.clone())); for (_uid, candidate) in candidates.iter() { if candidate.get_name() != name { return Err(LogicException { @@ -780,8 +774,12 @@ impl ComposerRepository { let matches_constraint = match &constraint { None => true, Some(c) => { - let pkg_c = Constraint::new("==", candidate.get_version().to_string()); - c.matches(&pkg_c) + let pkg_c = SimpleConstraint::new( + "==".to_string(), + candidate.get_version().to_string(), + None, + ); + c.matches(&pkg_c.into()) } }; if matches_constraint { @@ -1025,7 +1023,7 @@ impl ComposerRepository { /// @inheritDoc pub fn get_security_advisories( &mut self, - mut package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + mut package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { self.load_root_server_file(Some(600))?; @@ -1059,7 +1057,7 @@ impl ComposerRepository { let repo_name = self.get_repo_name(); let create = |data: &IndexMap<String, PhpMixed>, name: &str, - package_constraint_map: &IndexMap<String, Box<dyn ConstraintInterface>>| + package_constraint_map: &IndexMap<String, AnyConstraint>| -> anyhow::Result<Option<PartialOrSecurityAdvisory>> { let advisory = PartialSecurityAdvisory::create(name, data, &semver_parser)?; let is_full = matches!(advisory, PartialOrSecurityAdvisory::Full(_)); @@ -1081,11 +1079,11 @@ impl ComposerRepository { } .into()); } - let affected_versions: &dyn ConstraintInterface = match &advisory { - PartialOrSecurityAdvisory::Partial(p) => &*p.affected_versions, + let affected_versions: &AnyConstraint = match &advisory { + PartialOrSecurityAdvisory::Partial(p) => &p.affected_versions, PartialOrSecurityAdvisory::Full(p) => p.affected_versions(), }; - let constraint = package_constraint_map.get(name).map(|c| &**c); + let constraint = package_constraint_map.get(name); if let Some(c) = constraint { if !affected_versions.matches(c) { return Ok(None); @@ -1795,7 +1793,7 @@ impl ComposerRepository { /// @param packageNames array of package name => ConstraintInterface|null - if a constraint is provided, only packages matching it will be loaded fn load_async_packages( &mut self, - mut package_names: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + mut package_names: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: Option<&IndexMap<String, i64>>, stability_flags: Option<&IndexMap<String, i64>>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -1820,7 +1818,7 @@ impl ComposerRepository { for name in names_snapshot { let constraint = package_names .get(&name) - .and_then(|c| c.as_ref().map(|c| c.clone_box())); + .and_then(|c| c.as_ref().map(|c| c.clone())); if acceptable_stabilities.is_none() || stability_flags.is_none() || StabilityFilter::is_package_acceptable( @@ -1840,11 +1838,10 @@ impl ComposerRepository { } } - let names_iter: Vec<(String, Option<Box<dyn ConstraintInterface>>)> = package_names + let names_iter: Vec<(String, Option<AnyConstraint>)> = package_names .iter() .map(|(k, v)| { - let cloned: Option<Box<dyn ConstraintInterface>> = - v.as_ref().map(|c| dyn_clone_constraint(&**c)); + let cloned: Option<AnyConstraint> = v.clone(); (k.clone(), cloned) }) .collect(); @@ -1972,7 +1969,7 @@ impl ComposerRepository { } let acceptable = ComposerRepository::is_version_acceptable_static( - constraint.as_deref(), + constraint.as_ref(), &real_name, &version, acceptable_stabilities, @@ -2093,7 +2090,7 @@ impl ComposerRepository { /// @param name package name (must be lowercased already) fn is_version_acceptable( &self, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -2110,7 +2107,7 @@ impl ComposerRepository { } fn is_version_acceptable_static( - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -2128,7 +2125,7 @@ impl ComposerRepository { fn is_version_acceptable_with_loader( loader: &ArrayLoader, - constraint: Option<&dyn ConstraintInterface>, + constraint: Option<&AnyConstraint>, name: &str, version_data: &IndexMap<String, PhpMixed>, acceptable_stabilities: Option<&IndexMap<String, i64>>, @@ -2160,7 +2157,7 @@ impl ComposerRepository { } if let Some(c) = constraint { - if !CompilingMatcher::r#match(c, Constraint::OP_EQ, version.clone()) { + if !CompilingMatcher::r#match(c, SimpleConstraint::OP_EQ, version.clone()) { continue; } } @@ -3492,7 +3489,3 @@ fn clone_root_data(rd: &RootData) -> RootData { fn dyn_clone_box(_pkg: &dyn BasePackage) -> Box<dyn BasePackage> { todo!() } - -fn dyn_clone_constraint(_c: &dyn ConstraintInterface) -> Box<dyn ConstraintInterface> { - todo!() -} diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs index b3ac1dd..6671895 100644 --- a/crates/shirabe/src/repository/composite_repository.rs +++ b/crates/shirabe/src/repository/composite_repository.rs @@ -3,7 +3,7 @@ use std::any::Any; use indexmap::IndexMap; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackage; use crate::package::PackageInterface; @@ -111,7 +111,7 @@ impl RepositoryInterface for CompositeRepository { fn load_packages( &self, - package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -121,11 +121,10 @@ impl RepositoryInterface for CompositeRepository { for repository in &self.repositories { // TODO(phase-b): manual deep clone since trait objects in maps don't derive Clone. - let name_map_cloned: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = - package_name_map - .iter() - .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone_box()))) - .collect(); + let name_map_cloned: IndexMap<String, Option<AnyConstraint>> = package_name_map + .iter() + .map(|(k, v)| (k.clone(), v.as_ref().map(|c| c.clone()))) + .collect(); let already_loaded_cloned: IndexMap< String, IndexMap<String, Box<dyn PackageInterface>>, diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index 8a0e6f6..a3cb18b 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -10,7 +10,7 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct FilterRepository { @@ -187,7 +187,7 @@ impl RepositoryInterface for FilterRepository { fn load_packages( &self, - mut package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + mut package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, @@ -272,7 +272,7 @@ impl AdvisoryProviderInterface for FilterRepository { fn get_security_advisories( &self, - mut package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + mut package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { if let Some(advisory_repo) = self.repo.as_advisory_provider() { diff --git a/crates/shirabe/src/repository/installed_array_repository.rs b/crates/shirabe/src/repository/installed_array_repository.rs index fd273b9..b089df6 100644 --- a/crates/shirabe/src/repository/installed_array_repository.rs +++ b/crates/shirabe/src/repository/installed_array_repository.rs @@ -2,7 +2,7 @@ use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackage; use crate::package::PackageInterface; @@ -114,7 +114,7 @@ impl RepositoryInterface for InstalledArrayRepository { } fn load_packages( &self, - _package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + _package_name_map: IndexMap<String, Option<AnyConstraint>>, _acceptable_stabilities: IndexMap<String, i64>, _stability_flags: IndexMap<String, i64>, _already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/installed_filesystem_repository.rs b/crates/shirabe/src/repository/installed_filesystem_repository.rs index db1428a..5c6fecf 100644 --- a/crates/shirabe/src/repository/installed_filesystem_repository.rs +++ b/crates/shirabe/src/repository/installed_filesystem_repository.rs @@ -3,7 +3,7 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::json::JsonFile; use crate::package::BasePackage; @@ -124,7 +124,7 @@ impl RepositoryInterface for InstalledFilesystemRepository { } fn load_packages( &self, - _package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + _package_name_map: IndexMap<String, Option<AnyConstraint>>, _acceptable_stabilities: IndexMap<String, i64>, _stability_flags: IndexMap<String, i64>, _already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 3163ed2..5c9e0d7 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -2,9 +2,9 @@ use indexmap::IndexMap; use shirabe_php_shim::LogicException; -use shirabe_semver::constraint::Constraint; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::MatchAllConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::package::BasePackage; use crate::package::Link; @@ -56,7 +56,7 @@ impl InstalledRepository { ) -> Vec<Box<dyn BasePackage>> { let name = name.to_lowercase(); - let constraint: Option<Box<dyn ConstraintInterface>> = match constraint { + let constraint: Option<AnyConstraint> = match constraint { None => None, Some(FindPackageConstraint::Constraint(c)) => Some(c), Some(FindPackageConstraint::String(s)) => { @@ -70,10 +70,14 @@ impl InstalledRepository { 'candidates: for candidate in repo.get_packages() { if name == candidate.get_name() { if constraint.is_none() - || constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("==", candidate.get_version())) + || constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "==".to_string(), + candidate.get_version().to_string(), + None, + ) + .into(), + ) { matches.push(candidate); } @@ -107,7 +111,7 @@ impl InstalledRepository { pub fn get_dependents( &self, needle: NeedleInput, - constraint: Option<Box<dyn ConstraintInterface>>, + constraint: Option<AnyConstraint>, invert: bool, recurse: bool, packages_found: Option<Vec<String>>, @@ -142,9 +146,7 @@ impl InstalledRepository { for needle in &needles_snapshot { if link.get_source() == needle.as_str() { if constraint.is_none() - || link - .get_constraint() - .matches(constraint.as_ref().unwrap().as_ref()) + || link.get_constraint().matches(constraint.as_ref().unwrap()) { if packages_in_tree.contains(&link.get_target().to_string()) { results.push(DependentsEntry( @@ -187,9 +189,9 @@ impl InstalledRepository { for link in links.values() { for needle in &needles { if link.get_target() == needle.as_str() { - let matches_constraint = constraint.as_ref().map_or(true, |c| { - link.get_constraint().matches(c.as_ref()) == !invert - }); + let matches_constraint = constraint + .as_ref() + .map_or(true, |c| link.get_constraint().matches(c) == !invert); if constraint.is_none() || matches_constraint { if packages_in_tree.contains(&link.get_source().to_string()) { results.push(DependentsEntry( @@ -224,8 +226,12 @@ impl InstalledRepository { if invert && needles.contains(&package.get_name().to_string()) { for link in package.get_conflicts().values() { for pkg in self.find_packages(link.get_target(), None) { - let version = Constraint::new("=", pkg.get_version()); - if link.get_constraint().matches(&version) == invert { + let version = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ); + if link.get_constraint().matches(&version.into()) == invert { results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } @@ -235,8 +241,12 @@ impl InstalledRepository { for link in package.get_conflicts().values() { if needles.contains(&link.get_target().to_string()) { for pkg in self.find_packages(link.get_target(), None) { - let version = Constraint::new("=", pkg.get_version()); - if link.get_constraint().matches(&version) == invert { + let version = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ); + if link.get_constraint().matches(&version.into()) == invert { results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } @@ -246,19 +256,21 @@ impl InstalledRepository { if invert && constraint.is_some() && needles.contains(&package.get_name().to_string()) - && constraint - .as_ref() - .unwrap() - .matches(&Constraint::new("=", package.get_version())) + && constraint.as_ref().unwrap().matches( + &SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + None, + ) + .into(), + ) { 'requires: for link in package.get_requires().values() { if PlatformRepository::is_platform_package(link.get_target()) { if self .find_package( link.get_target(), - FindPackageConstraint::Constraint( - link.get_constraint().clone_box(), - ), + FindPackageConstraint::Constraint(link.get_constraint().clone()), ) .is_some() { @@ -278,7 +290,7 @@ impl InstalledRepository { Link::new( package.get_name().to_string(), link.get_target().to_string(), - Box::new(MatchAllConstraint::new()), + MatchAllConstraint::new(None).into(), Some(Link::TYPE_REQUIRE.to_string()), Some(format!( "{} {}", @@ -297,8 +309,12 @@ impl InstalledRepository { continue; } - let mut version: Box<dyn ConstraintInterface> = - Box::new(Constraint::new("=", pkg.get_version())); + let mut version: AnyConstraint = SimpleConstraint::new( + "=".to_string(), + pkg.get_version().to_string(), + None, + ) + .into(); if link.get_target() != pkg.get_name() { let mut replaces_and_provides: IndexMap<String, Link> = @@ -308,13 +324,13 @@ impl InstalledRepository { } for prov in replaces_and_provides.values() { if link.get_target() == prov.get_target() { - version = prov.get_constraint().clone_box(); + version = prov.get_constraint().clone(); break; } } } - if !link.get_constraint().matches(version.as_ref()) { + if !link.get_constraint().matches(&version) { if let Some(root_pkg) = root_package.as_ref() { let mut root_reqs: IndexMap<String, Link> = root_pkg.get_requires(); for (k, v) in root_pkg.get_dev_requires() { @@ -350,7 +366,7 @@ impl InstalledRepository { Link::new( root_pkg.get_name().to_string(), link.get_target().to_string(), - Box::new(MatchAllConstraint::new()), + MatchAllConstraint::new(None).into(), Some(Link::TYPE_DOES_NOT_REQUIRE.to_string()), Some(format!( "but {} is installed", @@ -446,7 +462,7 @@ impl RepositoryInterface for InstalledRepository { fn load_packages( &self, - package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/lock_array_repository.rs b/crates/shirabe/src/repository/lock_array_repository.rs index 295d982..57abe56 100644 --- a/crates/shirabe/src/repository/lock_array_repository.rs +++ b/crates/shirabe/src/repository/lock_array_repository.rs @@ -9,7 +9,7 @@ use crate::repository::{ }; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct LockArrayRepository { @@ -61,7 +61,7 @@ impl RepositoryInterface for LockArrayRepository { fn load_packages( &self, - package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs index 6e8186c..93c7e31 100644 --- a/crates/shirabe/src/repository/package_repository.rs +++ b/crates/shirabe/src/repository/package_repository.rs @@ -13,7 +13,7 @@ use crate::repository::{ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; use shirabe_php_shim::{Exception, PhpMixed, RuntimeException, var_export}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; #[derive(Debug)] pub struct PackageRepository { @@ -91,7 +91,7 @@ impl AdvisoryProviderInterface for PackageRepository { fn get_security_advisories( &self, - package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { let parser = VersionParser::new(); diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index 8494e25..0b3ccb1 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -11,7 +11,8 @@ use shirabe_php_shim::{ array_slice_strs, explode, get_class, implode, in_array, is_string, sprintf, str_replace, str_starts_with, strpos, strtolower, var_export, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::composer; use crate::composer::ComposerHandle; @@ -1759,7 +1760,7 @@ impl PlatformRepository { Link::new( "ext-uuid".to_string(), "lib-uuid".to_string(), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_REPLACE.to_string()), Some(ext.get_pretty_version().to_string()), ), @@ -1824,7 +1825,7 @@ impl PlatformRepository { Link::new( format!("lib-{}", name), format!("lib-{}", replace_lower), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_REPLACE.to_string()), Some(lib.get_pretty_version().to_string()), ), @@ -1838,7 +1839,7 @@ impl PlatformRepository { Link::new( format!("lib-{}", name), format!("lib-{}", provide_lower), - Box::new(Constraint::new("=", &version)), + SimpleConstraint::new("=".to_string(), version.to_string(), None).into(), Some(Link::TYPE_PROVIDE.to_string()), Some(lib.get_pretty_version().to_string()), ), @@ -1962,10 +1963,7 @@ impl crate::repository::RepositoryInterface for PlatformRepository { fn load_packages( &self, - package_name_map: IndexMap< - String, - Option<Box<dyn shirabe_semver::constraint::ConstraintInterface>>, - >, + package_name_map: IndexMap<String, Option<shirabe_semver::constraint::AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index d18951b..4bd1f3e 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -5,18 +5,18 @@ use crate::package::PackageInterface; use crate::repository::AdvisoryProviderInterface; use indexmap::IndexMap; use shirabe_php_shim::Countable; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; pub enum FindPackageConstraint { String(String), - Constraint(Box<dyn ConstraintInterface>), + Constraint(AnyConstraint), } impl Clone for FindPackageConstraint { fn clone(&self) -> Self { match self { Self::String(s) => Self::String(s.clone()), - Self::Constraint(c) => Self::Constraint(c.clone_box()), + Self::Constraint(c) => Self::Constraint(c.clone()), } } } @@ -71,7 +71,7 @@ pub trait RepositoryInterface: Countable + std::fmt::Debug { fn load_packages( &self, - package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs index 10e3e37..e85312a 100644 --- a/crates/shirabe/src/repository/repository_manager.rs +++ b/crates/shirabe/src/repository/repository_manager.rs @@ -2,7 +2,7 @@ use indexmap::IndexMap; use shirabe_php_shim::{InvalidArgumentException, PhpMixed, json_encode}; -use shirabe_semver::constraint::ConstraintInterface; +use shirabe_semver::constraint::AnyConstraint; use crate::config::Config; use crate::event_dispatcher::EventDispatcher; @@ -51,12 +51,12 @@ impl RepositoryManager { pub fn find_package( &self, name: &str, - constraint: &dyn ConstraintInterface, + constraint: &AnyConstraint, ) -> Option<Box<dyn PackageInterface>> { for repository in &self.repositories { if let Some(package) = repository.find_package( name, - crate::repository::FindPackageConstraint::Constraint(constraint.clone_box()), + crate::repository::FindPackageConstraint::Constraint(constraint.clone()), ) { return Some(package.clone_package_box()); } @@ -67,14 +67,14 @@ impl RepositoryManager { pub fn find_packages( &self, name: &str, - constraint: &dyn ConstraintInterface, + constraint: &AnyConstraint, ) -> Vec<Box<dyn PackageInterface>> { let mut packages: Vec<Box<dyn PackageInterface>> = vec![]; for repository in self.get_repositories() { for p in repository.find_packages( name, Some(crate::repository::FindPackageConstraint::Constraint( - constraint.clone_box(), + constraint.clone(), )), ) { packages.push(p.clone_package_box()); diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs index 84b2424..84159d4 100644 --- a/crates/shirabe/src/repository/repository_set.rs +++ b/crates/shirabe/src/repository/repository_set.rs @@ -8,10 +8,10 @@ use shirabe_php_shim::{ LogicException, PhpMixed, RuntimeException, array_merge, array_merge_recursive, ksort, strtolower, }; -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::advisory::PartialSecurityAdvisory; use crate::advisory::SecurityAdvisory; @@ -79,10 +79,10 @@ pub struct RepositorySet { /// @var ConstraintInterface[] /// @phpstan-var array<string, ConstraintInterface> - pub(crate) root_requires: IndexMap<String, Box<dyn ConstraintInterface>>, + pub(crate) root_requires: IndexMap<String, AnyConstraint>, /// @var array<string, ConstraintInterface> - pub(crate) temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + pub(crate) temporary_constraints: IndexMap<String, AnyConstraint>, /// @var bool locked: bool, @@ -115,8 +115,8 @@ impl RepositorySet { stability_flags: IndexMap<String, i64>, root_aliases: Vec<RootAliasInput>, root_references: IndexMap<String, String>, - mut root_requires: IndexMap<String, Box<dyn ConstraintInterface>>, - temporary_constraints: IndexMap<String, Box<dyn ConstraintInterface>>, + mut root_requires: IndexMap<String, AnyConstraint>, + temporary_constraints: IndexMap<String, AnyConstraint>, ) -> Self { let root_aliases = Self::get_root_aliases_per_package(root_aliases); @@ -156,12 +156,12 @@ impl RepositorySet { /// @return ConstraintInterface[] an array of package name => constraint from the root package, platform requirements excluded /// @phpstan-return array<string, ConstraintInterface> - pub fn get_root_requires(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> { + pub fn get_root_requires(&self) -> &IndexMap<String, AnyConstraint> { &self.root_requires } /// @return array<string, ConstraintInterface> Runtime temporary constraints that will be used to filter packages - pub fn get_temporary_constraints(&self) -> &IndexMap<String, Box<dyn ConstraintInterface>> { + pub fn get_temporary_constraints(&self) -> &IndexMap<String, AnyConstraint> { &self.temporary_constraints } @@ -208,7 +208,7 @@ impl RepositorySet { pub fn find_packages( &self, name: &str, - constraint: Option<Box<dyn ConstraintInterface>>, + constraint: Option<AnyConstraint>, flags: i64, ) -> Vec<Box<dyn BasePackage>> { let ignore_stability = (flags & Self::ALLOW_UNACCEPTABLE_STABILITIES) != 0; @@ -220,15 +220,14 @@ impl RepositorySet { // PHP: $repository->findPackages($name, $constraint) ?: [] let constraint_clone = constraint .as_ref() - .map(|c| FindPackageConstraint::Constraint(c.clone_box())); + .map(|c| FindPackageConstraint::Constraint(c.clone())); let found = repository.find_packages(name, constraint_clone); packages.push(found); } } else { 'outer: for repository in &self.repositories { - let mut name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>> = - IndexMap::new(); - name_map.insert(name.to_string(), constraint.as_ref().map(|c| c.clone_box())); + let mut name_map: IndexMap<String, Option<AnyConstraint>> = IndexMap::new(); + name_map.insert(name.to_string(), constraint.as_ref().map(|c| c.clone())); let acceptable = if ignore_stability { // PHP: BasePackage::STABILITIES crate::package::STABILITIES @@ -290,9 +289,9 @@ impl RepositorySet { allow_partial_advisories: bool, ignore_unreachable: bool, ) -> Result<SecurityAdvisoriesResult> { - let mut map: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut map: IndexMap<String, AnyConstraint> = IndexMap::new(); for name in &package_names { - map.insert(name.clone(), Box::new(MatchAllConstraint::new())); + map.insert(name.clone(), MatchAllConstraint::new(None).into()); } let mut unreachable_repos: Vec<String> = vec![]; @@ -317,7 +316,7 @@ impl RepositorySet { allow_partial_advisories: bool, ignore_unreachable: bool, ) -> Result<SecurityAdvisoriesResult> { - let mut map: IndexMap<String, Box<dyn ConstraintInterface>> = IndexMap::new(); + let mut map: IndexMap<String, AnyConstraint> = IndexMap::new(); for package in packages { // ignore root alias versions as they are not actual package versions and should not matter when it comes to vulnerabilities if let Some(alias) = package.as_any().downcast_ref::<AliasPackage>() { @@ -327,20 +326,29 @@ impl RepositorySet { } let name = package.get_name().to_string(); if map.contains_key(&name) { - // TODO(phase-b): MultiConstraint::new signature let existing = map.shift_remove(&name).unwrap(); map.insert( name, - Box::new(MultiConstraint::new( + MultiConstraint::new( vec![ - Box::new(Constraint::new("=", package.get_version())), + AnyConstraint::Simple(SimpleConstraint::new( + "=".to_string(), + package.get_version().to_string(), + None, + )), existing, ], false, - )), + None, + ) + .into(), ); } else { - map.insert(name, Box::new(Constraint::new("=", package.get_version()))); + map.insert( + name, + SimpleConstraint::new("=".to_string(), package.get_version().to_string(), None) + .into(), + ); } } @@ -363,7 +371,7 @@ impl RepositorySet { /// @return ($allowPartialAdvisories is true ? array<string, array<PartialSecurityAdvisory|SecurityAdvisory>> : array<string, array<SecurityAdvisory>>) fn get_security_advisories_for_constraints( &self, - package_constraint_map: IndexMap<String, Box<dyn ConstraintInterface>>, + package_constraint_map: IndexMap<String, AnyConstraint>, allow_partial_advisories: bool, ignore_unreachable: bool, unreachable_repos: &mut Vec<String>, diff --git a/crates/shirabe/src/repository/root_package_repository.rs b/crates/shirabe/src/repository/root_package_repository.rs index 6213291..1487f3e 100644 --- a/crates/shirabe/src/repository/root_package_repository.rs +++ b/crates/shirabe/src/repository/root_package_repository.rs @@ -61,10 +61,7 @@ impl RepositoryInterface for RootPackageRepository { fn load_packages( &self, - package_name_map: IndexMap< - String, - Option<Box<dyn shirabe_semver::constraint::ConstraintInterface>>, - >, + package_name_map: IndexMap<String, Option<shirabe_semver::constraint::AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs index 05dd329..1ae7e40 100644 --- a/crates/shirabe/src/repository/vcs_repository.rs +++ b/crates/shirabe/src/repository/vcs_repository.rs @@ -8,7 +8,8 @@ use shirabe_php_shim::{ InvalidArgumentException, PhpMixed, array_search_mixed, count, get_class, in_array, str_replace, strpos, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::config::Config; use crate::downloader::TransportException; @@ -514,9 +515,14 @@ impl VcsRepository { }); if let Some(existing_package) = self.inner.find_package( &tag_package_name, - crate::repository::FindPackageConstraint::Constraint(Box::new( - Constraint::new("=", &version_normalized), - )), + crate::repository::FindPackageConstraint::Constraint( + SimpleConstraint::new( + "=".to_string(), + version_normalized.to_string(), + None, + ) + .into(), + ), ) { if is_very_verbose { self.io.write_error(&format!( @@ -949,10 +955,10 @@ impl VcsRepository { .to_string(); if let Some(existing_package) = self.inner.find_package( &name, - crate::repository::FindPackageConstraint::Constraint(Box::new(Constraint::new( - "=", - &version_normalized, - ))), + crate::repository::FindPackageConstraint::Constraint( + SimpleConstraint::new("=".to_string(), version_normalized.to_string(), None) + .into(), + ), ) { if is_very_verbose { self.io.write_error(&format!( diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs index b1cf921..77d35b1 100644 --- a/crates/shirabe/src/util/http_downloader.rs +++ b/crates/shirabe/src/util/http_downloader.rs @@ -10,7 +10,8 @@ use shirabe_php_shim::{ extension_loaded, file_get_contents, function_exists, implode, is_numeric, max, min, rawurldecode, stream_context_create, stripos, strpos, substr, ucfirst, }; -use shirabe_semver::constraint::Constraint; +use shirabe_semver::constraint::AnyConstraint; +use shirabe_semver::constraint::SimpleConstraint; use crate::composer; use crate::composer::ComposerHandle; @@ -715,11 +716,14 @@ impl HttpDownloader { let version_parser: VersionParser = todo!("VersionParser::new()"); let constraint = version_parser .parse_constraints(versions_value.as_string().unwrap_or(""))?; - let composer_constraint = Constraint::new( - "==", - &version_parser.normalize(&composer::get_version(), None)?, + let composer_constraint = SimpleConstraint::new( + "==".to_string(), + version_parser + .normalize(&composer::get_version(), None)? + .to_string(), + None, ); - if !constraint.matches(&composer_constraint) { + if !constraint.matches(&composer_constraint.into()) { continue; } } @@ -753,11 +757,14 @@ impl HttpDownloader { .and_then(|v| v.as_string()) .unwrap_or(""), )?; - let composer_constraint = Constraint::new( - "==", - &version_parser.normalize(&composer::get_version(), None)?, + let composer_constraint = SimpleConstraint::new( + "==".to_string(), + version_parser + .normalize(&composer::get_version(), None)? + .to_string(), + None, ); - if !constraint.matches(&composer_constraint) { + if !constraint.matches(&composer_constraint.into()) { continue; } |
