aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/dependency_resolver
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-11 02:39:35 +0900
committernsfisis <nsfisis@gmail.com>2026-06-11 02:39:35 +0900
commit6ae7e0d4b3eaf20e2d2cd3d000cf61ab0c9b6e83 (patch)
treee39261f4aa7314fe8c75142670c76591cdaccb92 /crates/shirabe/src/dependency_resolver
parent5d3232a80be4b989e89cc7ae4e3642cc5acae030 (diff)
downloadphp-shirabe-6ae7e0d4b3eaf20e2d2cd3d000cf61ab0c9b6e83.tar.gz
php-shirabe-6ae7e0d4b3eaf20e2d2cd3d000cf61ab0c9b6e83.tar.zst
php-shirabe-6ae7e0d4b3eaf20e2d2cd3d000cf61ab0c9b6e83.zip
feat(console): resolve phase-b TODOs in doRun and IO wiring
Wire up ConsoleIO with HelperSet/QuestionHelper, register the ErrorHandler with the IO instance, and fall back to a default output in run(). Replace resolved phase-b TODOs across the console, command, io, factory, installer, dependency_resolver, and util modules; reclassify the remaining blockers (typed Symfony command registry, stdin resource caching) as phase-c. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/dependency_resolver')
-rw-r--r--crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs6
-rw-r--r--crates/shirabe/src/dependency_resolver/rule.rs26
-rw-r--r--crates/shirabe/src/dependency_resolver/rule2_literals.rs6
-rw-r--r--crates/shirabe/src/dependency_resolver/rule_set_generator.rs48
4 files changed, 31 insertions, 55 deletions
diff --git a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
index 5b2e107..8db0f7f 100644
--- a/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
+++ b/crates/shirabe/src/dependency_resolver/multi_conflict_rule.rs
@@ -2,7 +2,7 @@
use crate::dependency_resolver::{ReasonData, Rule, RuleBase};
use anyhow::Result;
-use shirabe_php_shim::{PHP_VERSION_ID, PhpMixed, RuntimeException, hash_raw};
+use shirabe_php_shim::{PHP_VERSION_ID, RuntimeException, hash_raw};
#[derive(Debug)]
pub struct MultiConflictRule {
@@ -11,7 +11,7 @@ pub struct MultiConflictRule {
}
impl MultiConflictRule {
- pub fn new(mut literals: Vec<i64>, reason: PhpMixed, reason_data: PhpMixed) -> Result<Self> {
+ pub fn new(mut literals: Vec<i64>, reason: i64, reason_data: ReasonData) -> Result<Self> {
if literals.len() < 3 {
return Err(RuntimeException {
message: "multi conflict rule requires at least 3 literals".to_string(),
@@ -24,7 +24,7 @@ impl MultiConflictRule {
literals.sort();
Ok(Self {
- inner: RuleBase::new(reason.as_int().unwrap_or(0), ReasonData::from(reason_data)),
+ inner: RuleBase::new(reason, reason_data),
literals,
})
}
diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs
index 4e5a920..e62bb7b 100644
--- a/crates/shirabe/src/dependency_resolver/rule.rs
+++ b/crates/shirabe/src/dependency_resolver/rule.rs
@@ -42,21 +42,6 @@ pub enum ReasonData {
Fixed {
package: BasePackageHandle,
},
- /// Phase B placeholder for an arbitrary PHP-side value not yet mapped to a real variant.
- Mixed(PhpMixed),
-}
-
-impl From<PhpMixed> for ReasonData {
- fn from(value: PhpMixed) -> Self {
- // TODO(phase-b): callers should construct the appropriate variant directly;
- // this catch-all keeps the rule constructors building while reason_data threading
- // through PhpMixed in the resolver is still in transition.
- match value {
- PhpMixed::String(s) => ReasonData::String(s),
- PhpMixed::Int(i) => ReasonData::Int(i),
- other => ReasonData::Mixed(other),
- }
- }
}
// reason constants and // their reason data contents
@@ -106,8 +91,8 @@ impl Rule {
&mut self.base_mut().bitfield
}
- fn reason_data(&self) -> Option<&ReasonData> {
- self.base().reason_data.as_ref()
+ fn reason_data(&self) -> &ReasonData {
+ &self.base().reason_data
}
pub fn get_literals(&self) -> Vec<i64> {
@@ -161,8 +146,7 @@ impl Rule {
/// @phpstan-return ReasonData
pub fn get_reason_data(&self) -> &ReasonData {
- // TODO(phase-b): reason_data() returns Option; PHP getReasonData unconditional
- self.reason_data().unwrap()
+ self.reason_data()
}
pub fn get_required_package(&self) -> Option<String> {
@@ -774,7 +758,7 @@ impl std::fmt::Display for Rule {
pub struct RuleBase {
pub(crate) bitfield: i64,
pub(crate) request: Option<Request>,
- pub(crate) reason_data: Option<ReasonData>,
+ pub(crate) reason_data: ReasonData,
}
impl RuleBase {
@@ -788,7 +772,7 @@ impl RuleBase {
Self {
bitfield,
request: None,
- reason_data: Some(reason_data),
+ reason_data,
}
}
diff --git a/crates/shirabe/src/dependency_resolver/rule2_literals.rs b/crates/shirabe/src/dependency_resolver/rule2_literals.rs
index 7db9024..39e1d4e 100644
--- a/crates/shirabe/src/dependency_resolver/rule2_literals.rs
+++ b/crates/shirabe/src/dependency_resolver/rule2_literals.rs
@@ -1,7 +1,5 @@
//! ref: composer/src/Composer/DependencyResolver/Rule2Literals.php
-use shirabe_php_shim::PhpMixed;
-
use crate::dependency_resolver::{ReasonData, Rule, RuleBase};
#[derive(Debug)]
@@ -12,7 +10,7 @@ pub struct Rule2Literals {
}
impl Rule2Literals {
- pub fn new(literal1: i64, literal2: i64, reason: PhpMixed, reason_data: PhpMixed) -> Self {
+ pub fn new(literal1: i64, literal2: i64, reason: i64, reason_data: ReasonData) -> Self {
let (literal1, literal2) = if literal1 < literal2 {
(literal1, literal2)
} else {
@@ -20,7 +18,7 @@ impl Rule2Literals {
};
Self {
- inner: RuleBase::new(reason.as_int().unwrap_or(0), ReasonData::from(reason_data)),
+ inner: RuleBase::new(reason, reason_data),
literal1,
literal2,
}
diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
index 295160c..f2e7b75 100644
--- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
+++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs
@@ -53,7 +53,7 @@ impl RuleSetGenerator {
package: PackageInterfaceHandle,
providers: &[PackageInterfaceHandle],
reason: i64,
- reason_data: PhpMixed,
+ reason_data: rule::ReasonData,
) -> Option<GenericRule> {
let mut literals = vec![-package.get_id()];
@@ -65,11 +65,7 @@ impl RuleSetGenerator {
literals.push(provider.get_id());
}
- Some(GenericRule::new(
- literals,
- reason,
- rule::ReasonData::from(reason_data),
- ))
+ Some(GenericRule::new(literals, reason, reason_data))
}
/// Creates a rule to install at least one of a set of packages.
@@ -80,10 +76,10 @@ impl RuleSetGenerator {
&self,
packages: &[PackageInterfaceHandle],
reason: i64,
- reason_data: PhpMixed,
+ reason_data: rule::ReasonData,
) -> GenericRule {
let literals: Vec<i64> = packages.iter().map(|p| p.get_id()).collect();
- GenericRule::new(literals, reason, rule::ReasonData::from(reason_data))
+ GenericRule::new(literals, reason, reason_data)
}
/// Creates a rule for two conflicting packages.
@@ -95,7 +91,7 @@ impl RuleSetGenerator {
issuer: PackageInterfaceHandle,
provider: PackageInterfaceHandle,
reason: i64,
- reason_data: PhpMixed,
+ reason_data: rule::ReasonData,
) -> Option<Rule2Literals> {
// ignore self conflict
if issuer.ptr_eq(&provider) {
@@ -105,7 +101,7 @@ impl RuleSetGenerator {
Some(Rule2Literals::new(
-issuer.get_id(),
-provider.get_id(),
- PhpMixed::Int(reason),
+ reason,
reason_data,
))
}
@@ -114,7 +110,7 @@ impl RuleSetGenerator {
&self,
packages: &[PackageInterfaceHandle],
reason: i64,
- reason_data: PhpMixed,
+ reason_data: rule::ReasonData,
) -> Rule {
let literals: Vec<i64> = packages.iter().map(|p| -p.get_id()).collect();
@@ -122,13 +118,11 @@ impl RuleSetGenerator {
Rule::TwoLiterals(Rule2Literals::new(
literals[0],
literals[1],
- PhpMixed::Int(reason),
+ reason,
reason_data,
))
} else {
- Rule::MultiConflict(
- MultiConflictRule::new(literals, PhpMixed::Int(reason), reason_data).unwrap(),
- )
+ Rule::MultiConflict(MultiConflictRule::new(literals, reason, reason_data).unwrap())
}
}
@@ -175,7 +169,7 @@ impl RuleSetGenerator {
package.clone(),
&[alias_of.clone()],
rule::RULE_PACKAGE_ALIAS,
- PhpMixed::Null, // reasonData: $package (BasePackage)
+ rule::ReasonData::BasePackage(package.clone()),
);
self.add_rule(RuleSet::TYPE_PACKAGE, rule.map(Rule::Generic));
@@ -184,7 +178,7 @@ impl RuleSetGenerator {
alias_of.clone(),
&[package.clone()],
rule::RULE_PACKAGE_INVERSE_ALIAS,
- PhpMixed::Null, // reasonData: $package->getAliasOf() (BasePackage)
+ rule::ReasonData::BasePackage(alias_of.clone()),
);
self.add_rule(RuleSet::TYPE_PACKAGE, inverse_rule.map(Rule::Generic));
@@ -221,7 +215,7 @@ impl RuleSetGenerator {
package.clone(),
&possible_requires,
rule::RULE_PACKAGE_REQUIRES,
- PhpMixed::Null, // reasonData: $link (Link)
+ rule::ReasonData::Link(link.clone()),
);
self.add_rule(RuleSet::TYPE_PACKAGE, rule.map(Rule::Generic));
@@ -277,7 +271,7 @@ impl RuleSetGenerator {
package.clone(),
conflict.clone(),
rule::RULE_PACKAGE_CONFLICT,
- PhpMixed::Null, // reasonData: $link (Link)
+ rule::ReasonData::Link(link.clone()),
);
self.add_rule(RuleSet::TYPE_PACKAGE, rule.map(Rule::TwoLiterals));
}
@@ -294,8 +288,11 @@ impl RuleSetGenerator {
for (name, packages) in names_packages {
if packages.len() > 1 {
let reason = rule::RULE_PACKAGE_SAME_NAME;
- let rule =
- self.create_multi_conflict_rule(&packages, reason, PhpMixed::String(name));
+ let rule = self.create_multi_conflict_rule(
+ &packages,
+ reason,
+ rule::ReasonData::String(name),
+ );
self.add_rule(RuleSet::TYPE_PACKAGE, Some(rule));
}
}
@@ -329,15 +326,12 @@ impl RuleSetGenerator {
self.add_rules_for_package(package.clone().into(), platform_requirement_filter);
- let mut reason_data: IndexMap<String, Box<PhpMixed>> = IndexMap::new();
- reason_data.insert(
- "package".to_string(),
- Box::new(PhpMixed::Null), // reasonData: $package (BasePackage)
- );
let rule = self.create_install_one_of_rule(
&[package.clone().into()],
rule::RULE_FIXED,
- PhpMixed::Array(reason_data),
+ rule::ReasonData::Fixed {
+ package: package.clone().into(),
+ },
);
self.add_rule(RuleSet::TYPE_REQUEST, Some(Rule::Generic(rule)));
}