aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/dependency_resolver
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
-rw-r--r--crates/shirabe/src/dependency_resolver/decisions.rs34
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs21
-rw-r--r--crates/shirabe/src/dependency_resolver/request.rs8
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs8
-rw-r--r--crates/shirabe/src/dependency_resolver/solver.rs18
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);