diff options
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/decisions.rs | 34 | ||||
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/problem.rs | 21 | ||||
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/request.rs | 8 | ||||
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/rule.rs | 8 | ||||
| -rw-r--r-- | crates/shirabe/src/dependency_resolver/solver.rs | 18 |
5 files changed, 27 insertions, 62 deletions
diff --git a/crates/shirabe/src/dependency_resolver/decisions.rs b/crates/shirabe/src/dependency_resolver/decisions.rs index 3b82883..81f0088 100644 --- a/crates/shirabe/src/dependency_resolver/decisions.rs +++ b/crates/shirabe/src/dependency_resolver/decisions.rs @@ -11,7 +11,6 @@ pub struct Decisions { pub(crate) pool: std::rc::Rc<std::cell::RefCell<Pool>>, pub(crate) decision_map: IndexMap<i64, i64>, pub(crate) decision_queue: Vec<(i64, std::rc::Rc<std::cell::RefCell<Rule>>)>, - iterator_cursor: Option<usize>, } impl std::fmt::Debug for Decisions { @@ -32,7 +31,6 @@ impl Decisions { pool, decision_map: IndexMap::new(), decision_queue: Vec::new(), - iterator_cursor: None, } } @@ -154,33 +152,6 @@ impl Decisions { self.decision_queue.len() } - pub fn rewind(&mut self) { - if self.decision_queue.is_empty() { - self.iterator_cursor = None; - } else { - self.iterator_cursor = Some(self.decision_queue.len() - 1); - } - } - - pub fn current(&self) -> Option<&(i64, std::rc::Rc<std::cell::RefCell<Rule>>)> { - self.iterator_cursor - .and_then(|cursor| self.decision_queue.get(cursor)) - } - - pub fn key(&self) -> Option<usize> { - self.iterator_cursor - } - - pub fn next(&mut self) { - self.iterator_cursor = self - .iterator_cursor - .and_then(|cursor| if cursor > 0 { Some(cursor - 1) } else { None }); - } - - pub fn valid(&self) -> bool { - self.iterator_cursor.is_some() && self.current().is_some() - } - pub fn is_empty(&self) -> bool { self.decision_queue.is_empty() } @@ -227,6 +198,11 @@ impl Decisions { str } + + // Reverse iteration: newest-first. + pub fn iter(&self) -> impl Iterator<Item = &(i64, std::rc::Rc<std::cell::RefCell<Rule>>)> { + self.decision_queue.iter().rev() + } } impl fmt::Display for Decisions { diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs index 47cf3b5..7841946 100644 --- a/crates/shirabe/src/dependency_resolver/problem.rs +++ b/crates/shirabe/src/dependency_resolver/problem.rs @@ -92,7 +92,6 @@ 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<&AnyConstraint>) = match reason_data { rule::ReasonData::RootRequire { package_name, @@ -144,27 +143,23 @@ impl Problem { rule::ReasonData::RootRequire { package_name, .. } => package_name.clone(), _ => String::new(), }, - rule::RULE_FIXED => { - // TODO(phase-b): reason_data for RULE_FIXED is `array{package: BasePackage}`. - // PHP: (string) $rule->getReasonData()['package'] - match rule.get_reason_data() { - rule::ReasonData::Fixed { package } => package.get_pretty_string(), - _ => String::new(), - } - } + rule::RULE_FIXED => match rule.get_reason_data() { + rule::ReasonData::Fixed { package } => package.get_unique_name(), + _ => String::new(), + }, rule::RULE_PACKAGE_CONFLICT | rule::RULE_PACKAGE_REQUIRES => { - // TODO(phase-b): reason_data is a Link. let source = rule.get_source_package(pool).unwrap(); let link_pretty = match rule.get_reason_data() { rule::ReasonData::Link(link) => link.get_pretty_string(source.clone()), _ => String::new(), }; - format!("{}//{}", source.get_pretty_string(), link_pretty) + format!("{}//{}", source.get_unique_name(), link_pretty) } rule::RULE_PACKAGE_SAME_NAME | rule::RULE_PACKAGE_ALIAS | rule::RULE_PACKAGE_INVERSE_ALIAS => { - // TODO(phase-b): convert ReasonData to PhpMixed for php_to_string + // TODO(phase-c): PHP returns (string) $rule->getReasonData(), but the alias rules' + // reason_data is still a placeholder pending the RuleSetGenerator reason_data wiring. format!("{:?}", rule.get_reason_data()) } rule::RULE_LEARNED => implode( @@ -807,7 +802,7 @@ impl Problem { } if pool.is_security_removed_package_version(package_name, constraint) { - // TODO(phase-b): get_matching_security_advisories needs Vec<PackageInterfaceHandle> + // TODO(phase-c): get_matching_security_advisories needs Vec<PackageInterfaceHandle> // and SecurityAdvisory.inner.advisory_id is on the private inner field. // Convert packages to PackageInterfaceHandle and adjust SecurityAdvisory accessor first. let _ = repository_set; diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs index 88957f2..83efb9b 100644 --- a/crates/shirabe/src/dependency_resolver/request.rs +++ b/crates/shirabe/src/dependency_resolver/request.rs @@ -28,13 +28,15 @@ impl Request { pub const UPDATE_LISTED_WITH_TRANSITIVE_DEPS: i64 = UPDATE_LISTED_WITH_TRANSITIVE_DEPS; } -/// Represents the value of updateAllowTransitiveDependencies, which is false|UPDATE_* in PHP. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum UpdateAllowTransitiveDeps { - /// Corresponds to PHP false (initial value) + /// Corresponds to PHP false. False, + /// \Composer\DependencyResolver\Request::UPDATE_ONLY_LISTED UpdateOnlyListed, + /// \Composer\DependencyResolver\Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE UpdateListedWithTransitiveDepsNoRootRequire, + /// \Composer\DependencyResolver\Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS UpdateListedWithTransitiveDeps, } diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs index 7804b99..4e5a920 100644 --- a/crates/shirabe/src/dependency_resolver/rule.rs +++ b/crates/shirabe/src/dependency_resolver/rule.rs @@ -229,7 +229,9 @@ impl Rule { if PlatformRepository::is_platform_package(link.get_target()) { return false; } - // TODO(phase-b): Request::get_locked_repository() signature + // TODO(phase-c): request.get_locked_repository() exists, but its get_packages() + // returns Result while is_caused_by_lock returns bool; resolving needs the bool + // chain (also via Problem/SolverProblemsException, itself phase-c) to carry Result. let locked_repo: Option<()> = todo!("request.get_locked_repository()"); if let Some(_locked_repo) = locked_repo { let packages: Vec<BasePackageHandle> = todo!("locked_repo.get_packages()"); @@ -269,7 +271,9 @@ impl Rule { if PlatformRepository::is_platform_package(package_name) { return false; } - // TODO(phase-b): Request::get_locked_repository() signature + // TODO(phase-c): request.get_locked_repository() exists, but its get_packages() + // returns Result while is_caused_by_lock returns bool; resolving needs the bool + // chain (also via Problem/SolverProblemsException, itself phase-c) to carry Result. let locked_repo: Option<()> = todo!("request.get_locked_repository()"); if let Some(_locked_repo) = locked_repo { let packages: Vec<BasePackageHandle> = todo!("locked_repo.get_packages()"); diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs index 3d2113e..03dd575 100644 --- a/crates/shirabe/src/dependency_resolver/solver.rs +++ b/crates/shirabe/src/dependency_resolver/solver.rs @@ -239,10 +239,8 @@ impl Solver { self.io .write_error3("Generating rules", true, crate::io::DEBUG); let mut rule_set_generator = RuleSetGenerator::new(self.policy.clone(), self.pool.clone()); - // TODO(phase-b): get_rules_for takes Option<Rc<dyn PlatformRequirementFilterInterface>>; - // PHP passes the filter directly. Forwarding `None` here keeps the call typecheckable. - let _ = platform_requirement_filter.as_ref(); - self.rules = rule_set_generator.get_rules_for(request, None)?; + self.rules = + rule_set_generator.get_rules_for(request, Some(platform_requirement_filter.clone()))?; drop(rule_set_generator); self.check_for_root_require_problems(request, platform_requirement_filter.as_ref())?; self.decisions = Decisions::new(self.pool.clone()); @@ -667,22 +665,12 @@ impl Solver { seen.insert(literal.abs(), true); } - // TODO(phase-b): Decisions does not expose an `iter()` matching PHP's foreach. - // Walk the decision queue directly through offsets to avoid borrowing issues - // (we still need to call back into `&self` while iterating). - let mut offset = 0_usize; - while offset < self.decisions.count() { - let decision_literal = self.decisions.at_offset(offset).0; - - offset += 1; - + for (decision_literal, why) in self.decisions.iter() { // skip literals that are not in this rule if !seen.contains_key(&decision_literal.abs()) { continue; } - let why = self.decisions.at_offset(offset - 1).1.clone(); - problem.add_rule(why.clone()); self.analyze_unsolvable_rule(&mut problem, why.clone(), &mut rule_seen); |
