aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--crates/shirabe/src/command/create_project_command.rs2
-rw-r--r--crates/shirabe/src/command/reinstall_command.rs11
-rw-r--r--crates/shirabe/src/dependency_resolver/local_repo_transaction.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/lock_transaction.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/operation.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/any_operation.rs92
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/install_operation.rs29
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs25
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs25
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/operation_interface.rs31
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/solver_operation.rs12
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs29
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/update_operation.rs33
-rw-r--r--crates/shirabe/src/dependency_resolver/transaction.rs80
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs6
-rw-r--r--crates/shirabe/src/installer.rs54
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs196
-rw-r--r--crates/shirabe/src/installer/package_event.rs16
-rw-r--r--crates/shirabe/tests/dependency_resolver/solver_test.rs14
-rw-r--r--crates/shirabe/tests/dependency_resolver/transaction_test.rs7
-rw-r--r--crates/shirabe/tests/repository/filesystem_repository_test.rs4
21 files changed, 275 insertions, 403 deletions
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs
index 8ea4f07f..fdc01391 100644
--- a/crates/shirabe/src/command/create_project_command.rs
+++ b/crates/shirabe/src/command/create_project_command.rs
@@ -1002,7 +1002,7 @@ impl CreateProjectCommand {
let mut installed_repo = InstalledArrayRepository::new()?;
im.execute(
&mut installed_repo,
- vec![std::rc::Rc::new(InstallOperation::new(package.clone()))],
+ vec![InstallOperation::new(package.clone()).into()],
true,
true,
false,
diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs
index c2c3ab18..bf10aeed 100644
--- a/crates/shirabe/src/command/reinstall_command.rs
+++ b/crates/shirabe/src/command/reinstall_command.rs
@@ -6,8 +6,7 @@ use crate::command::base_command::base_command_initialize;
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::dependency_resolver::Transaction;
-use crate::dependency_resolver::operation::InstallOperation;
-use crate::dependency_resolver::operation::OperationInterface;
+use crate::dependency_resolver::operation::AnyOperation;
use crate::dependency_resolver::operation::UninstallOperation;
use crate::io::IOInterfaceImmutable;
use crate::package::base_package;
@@ -175,7 +174,7 @@ impl Command for ReinstallCommand {
let mut install_order = indexmap::IndexMap::new();
for (index, op) in install_operations.iter().enumerate() {
- if let Some(install_op) = op.as_any().downcast_ref::<InstallOperation>()
+ if let AnyOperation::Install(install_op) = op
&& install_op.get_package().as_alias().is_none()
{
install_order.insert(install_op.get_package().get_name(), index);
@@ -241,10 +240,8 @@ impl Command for ReinstallCommand {
indexmap::IndexMap::new(),
);
- let uninstall_operations: Vec<std::rc::Rc<dyn OperationInterface>> = uninstall_operations
- .into_iter()
- .map(|op| std::rc::Rc::new(op) as std::rc::Rc<dyn OperationInterface>)
- .collect();
+ let uninstall_operations: Vec<AnyOperation> =
+ uninstall_operations.into_iter().map(Into::into).collect();
{
let mut local_repo_ref = local_repo.borrow_mut();
let repo = local_repo_ref
diff --git a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
index e592741e..a3443b93 100644
--- a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/DependencyResolver/LocalRepoTransaction.php
use super::Transaction;
-use crate::dependency_resolver::operation::OperationInterface;
+use crate::dependency_resolver::operation::AnyOperation;
use crate::repository::InstalledRepositoryInterface;
use crate::repository::RepositoryInterface;
@@ -23,7 +23,7 @@ impl LocalRepoTransaction {
})
}
- pub fn get_operations(&self) -> &Vec<std::rc::Rc<dyn OperationInterface>> {
+ pub fn get_operations(&self) -> &Vec<AnyOperation> {
self.inner.get_operations()
}
diff --git a/crates/shirabe/src/dependency_resolver/lock_transaction.rs b/crates/shirabe/src/dependency_resolver/lock_transaction.rs
index d78db851..a9086983 100644
--- a/crates/shirabe/src/dependency_resolver/lock_transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/lock_transaction.rs
@@ -235,9 +235,7 @@ impl LockTransaction {
used_aliases
}
- pub fn get_operations(
- &self,
- ) -> &Vec<std::rc::Rc<dyn crate::dependency_resolver::operation::OperationInterface>> {
+ pub fn get_operations(&self) -> &Vec<crate::dependency_resolver::operation::AnyOperation> {
self.inner.get_operations()
}
}
diff --git a/crates/shirabe/src/dependency_resolver/operation.rs b/crates/shirabe/src/dependency_resolver/operation.rs
index 720c5a0a..b0db094a 100644
--- a/crates/shirabe/src/dependency_resolver/operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation.rs
@@ -1,15 +1,15 @@
+pub mod any_operation;
pub mod install_operation;
pub mod mark_alias_installed_operation;
pub mod mark_alias_uninstalled_operation;
-pub mod operation_interface;
pub mod solver_operation;
pub mod uninstall_operation;
pub mod update_operation;
+pub use any_operation::*;
pub use install_operation::*;
pub use mark_alias_installed_operation::*;
pub use mark_alias_uninstalled_operation::*;
-pub use operation_interface::*;
pub use solver_operation::*;
pub use uninstall_operation::*;
pub use update_operation::*;
diff --git a/crates/shirabe/src/dependency_resolver/operation/any_operation.rs b/crates/shirabe/src/dependency_resolver/operation/any_operation.rs
new file mode 100644
index 00000000..6675b280
--- /dev/null
+++ b/crates/shirabe/src/dependency_resolver/operation/any_operation.rs
@@ -0,0 +1,92 @@
+//! ref: composer/src/Composer/DependencyResolver/Operation/OperationInterface.php
+//!
+//! PHP's `OperationInterface` is not ported as a trait. Operations are only ever constructed by the
+//! dependency resolver, so a plugin has no way to inject an implementation of its own and the set is
+//! closed. The shared implementations PHP puts on `SolverOperation` (`getOperationType()`,
+//! `__toString()`) live here.
+
+use crate::dependency_resolver::operation::{
+ InstallOperation, MarkAliasInstalledOperation, MarkAliasUninstalledOperation, SolverOperation,
+ UninstallOperation, UpdateOperation,
+};
+use crate::package::PackageInterfaceHandle;
+
+/// Any solver operation.
+#[derive(Debug, Clone)]
+pub enum AnyOperation {
+ Install(InstallOperation),
+ Update(UpdateOperation),
+ Uninstall(UninstallOperation),
+ MarkAliasInstalled(MarkAliasInstalledOperation),
+ MarkAliasUninstalled(MarkAliasUninstalledOperation),
+}
+
+impl AnyOperation {
+ pub fn get_operation_type(&self) -> &'static str {
+ match self {
+ Self::Install(_) => InstallOperation::TYPE,
+ Self::Update(_) => UpdateOperation::TYPE,
+ Self::Uninstall(_) => UninstallOperation::TYPE,
+ Self::MarkAliasInstalled(_) => MarkAliasInstalledOperation::TYPE,
+ Self::MarkAliasUninstalled(_) => MarkAliasUninstalledOperation::TYPE,
+ }
+ }
+
+ pub fn show(&self, lock: bool) -> String {
+ match self {
+ Self::Install(op) => op.show(lock),
+ Self::Update(op) => op.show(lock),
+ Self::Uninstall(op) => op.show(lock),
+ Self::MarkAliasInstalled(op) => op.show(lock),
+ Self::MarkAliasUninstalled(op) => op.show(lock),
+ }
+ }
+
+ /// The package the operation results in. PHP spells this out at every call site as
+ /// `$op instanceof UpdateOperation ? $op->getTargetPackage() : $op->getPackage()`.
+ pub fn get_target_package(&self) -> PackageInterfaceHandle {
+ match self {
+ Self::Install(op) => op.get_package(),
+ Self::Update(op) => op.get_target_package(),
+ Self::Uninstall(op) => op.get_package(),
+ Self::MarkAliasInstalled(op) => op.get_package().into(),
+ Self::MarkAliasUninstalled(op) => op.get_package().into(),
+ }
+ }
+}
+
+impl std::fmt::Display for AnyOperation {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.show(false))
+ }
+}
+
+impl From<InstallOperation> for AnyOperation {
+ fn from(op: InstallOperation) -> Self {
+ Self::Install(op)
+ }
+}
+
+impl From<UpdateOperation> for AnyOperation {
+ fn from(op: UpdateOperation) -> Self {
+ Self::Update(op)
+ }
+}
+
+impl From<UninstallOperation> for AnyOperation {
+ fn from(op: UninstallOperation) -> Self {
+ Self::Uninstall(op)
+ }
+}
+
+impl From<MarkAliasInstalledOperation> for AnyOperation {
+ fn from(op: MarkAliasInstalledOperation) -> Self {
+ Self::MarkAliasInstalled(op)
+ }
+}
+
+impl From<MarkAliasUninstalledOperation> for AnyOperation {
+ fn from(op: MarkAliasUninstalledOperation) -> Self {
+ Self::MarkAliasUninstalled(op)
+ }
+}
diff --git a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs
index ef492393..05349c2d 100644
--- a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs
@@ -1,10 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/InstallOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::SolverOperation;
use crate::package::PackageInterfaceHandle;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct InstallOperation {
pub(crate) package: PackageInterfaceHandle,
}
@@ -18,6 +17,10 @@ impl InstallOperation {
self.package.clone()
}
+ pub fn show(&self, lock: bool) -> String {
+ Self::format(self.package.clone(), lock)
+ }
+
pub fn format(package: PackageInterfaceHandle, lock: bool) -> String {
format!(
"{}<info>{}</info> (<comment>{}</comment>)",
@@ -32,28 +35,6 @@ impl SolverOperation for InstallOperation {
const TYPE: &'static str = "install";
}
-impl OperationInterface for InstallOperation {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn get_operation_type(&self) -> String {
- Self::TYPE.to_string()
- }
-
- fn show(&self, lock: bool) -> String {
- Self::format(self.package.clone(), lock)
- }
-
- fn as_install_operation(&self) -> Option<&InstallOperation> {
- Some(self)
- }
-
- fn get_package(&self) -> PackageInterfaceHandle {
- self.package.clone()
- }
-}
-
impl std::fmt::Display for InstallOperation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.show(false))
diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs
index 28bf511a..72066204 100644
--- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs
@@ -1,10 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::SolverOperation;
use crate::package::AliasPackageHandle;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct MarkAliasInstalledOperation {
pub(crate) package: AliasPackageHandle,
}
@@ -17,22 +16,8 @@ impl MarkAliasInstalledOperation {
pub fn get_package(&self) -> AliasPackageHandle {
self.package.clone()
}
-}
-
-impl SolverOperation for MarkAliasInstalledOperation {
- const TYPE: &'static str = "markAliasInstalled";
-}
-
-impl OperationInterface for MarkAliasInstalledOperation {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
- fn get_operation_type(&self) -> String {
- Self::TYPE.to_string()
- }
-
- fn show(&self, _lock: bool) -> String {
+ pub fn show(&self, _lock: bool) -> String {
format!(
"Marking <info>{}</info> (<comment>{}</comment>) as installed, alias of <info>{}</info> (<comment>{}</comment>)",
self.package.get_pretty_name(),
@@ -44,10 +29,10 @@ impl OperationInterface for MarkAliasInstalledOperation {
.get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev),
)
}
+}
- fn get_package(&self) -> crate::package::PackageInterfaceHandle {
- self.package.clone().into()
- }
+impl SolverOperation for MarkAliasInstalledOperation {
+ const TYPE: &'static str = "markAliasInstalled";
}
impl std::fmt::Display for MarkAliasInstalledOperation {
diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs
index 3c0de332..4e4000df 100644
--- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs
@@ -1,10 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::SolverOperation;
use crate::package::AliasPackageHandle;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct MarkAliasUninstalledOperation {
pub(crate) package: AliasPackageHandle,
}
@@ -17,22 +16,8 @@ impl MarkAliasUninstalledOperation {
pub fn get_package(&self) -> AliasPackageHandle {
self.package.clone()
}
-}
-
-impl SolverOperation for MarkAliasUninstalledOperation {
- const TYPE: &'static str = "markAliasUninstalled";
-}
-
-impl OperationInterface for MarkAliasUninstalledOperation {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
- fn get_operation_type(&self) -> String {
- Self::TYPE.to_string()
- }
-
- fn show(&self, _lock: bool) -> String {
+ pub fn show(&self, _lock: bool) -> String {
format!(
"Marking <info>{}</info> (<comment>{}</comment>) as uninstalled, alias of <info>{}</info> (<comment>{}</comment>)",
self.package.get_pretty_name(),
@@ -44,10 +29,10 @@ impl OperationInterface for MarkAliasUninstalledOperation {
.get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev),
)
}
+}
- fn get_package(&self) -> crate::package::PackageInterfaceHandle {
- self.package.clone().into()
- }
+impl SolverOperation for MarkAliasUninstalledOperation {
+ const TYPE: &'static str = "markAliasUninstalled";
}
impl std::fmt::Display for MarkAliasUninstalledOperation {
diff --git a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs
deleted file mode 100644
index 30ed8eb5..00000000
--- a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-//! ref: composer/src/Composer/DependencyResolver/Operation/OperationInterface.php
-
-use crate::dependency_resolver::operation::InstallOperation;
-use crate::dependency_resolver::operation::UninstallOperation;
-use crate::dependency_resolver::operation::UpdateOperation;
-
-pub trait OperationInterface: std::fmt::Display + std::fmt::Debug {
- fn as_any(&self) -> &dyn std::any::Any;
-
- fn get_operation_type(&self) -> String;
-
- fn show(&self, lock: bool) -> String;
-
- fn as_install_operation(&self) -> Option<&InstallOperation> {
- None
- }
-
- fn as_update_operation(&self) -> Option<&UpdateOperation> {
- None
- }
-
- fn as_uninstall_operation(&self) -> Option<&UninstallOperation> {
- None
- }
-
- /// PHP duck-typed accessor. Only InstallOperation/UninstallOperation/MarkAlias*Operation
- /// expose this; UpdateOperation has getInitialPackage()/getTargetPackage() instead.
- fn get_package(&self) -> crate::package::PackageInterfaceHandle {
- todo!("get_package is not available on this operation type")
- }
-}
diff --git a/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs b/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs
index 2710ec50..eb9c6315 100644
--- a/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/solver_operation.rs
@@ -1,11 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/SolverOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
-
-pub trait SolverOperation: OperationInterface {
+/// PHP's abstract `SolverOperation` carries the per-class `TYPE` constant and the
+/// `getOperationType()` / `__toString()` implementations shared by every operation. Only the
+/// constant remains here; the shared implementations live on
+/// [`AnyOperation`](crate::dependency_resolver::operation::AnyOperation).
+pub trait SolverOperation {
const TYPE: &'static str;
-
- fn get_operation_type(&self) -> &str {
- Self::TYPE
- }
}
diff --git a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs
index d2dd6651..2fd35af5 100644
--- a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs
@@ -1,10 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/UninstallOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::SolverOperation;
use crate::package::PackageInterfaceHandle;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct UninstallOperation {
pub(crate) package: PackageInterfaceHandle,
}
@@ -18,6 +17,10 @@ impl UninstallOperation {
self.package.clone()
}
+ pub fn show(&self, lock: bool) -> String {
+ Self::format(self.package.clone(), lock)
+ }
+
pub fn format(package: PackageInterfaceHandle, _lock: bool) -> String {
format!(
"Removing <info>{}</info> (<comment>{}</comment>)",
@@ -31,28 +34,6 @@ impl SolverOperation for UninstallOperation {
const TYPE: &'static str = "uninstall";
}
-impl OperationInterface for UninstallOperation {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn get_operation_type(&self) -> String {
- Self::TYPE.to_string()
- }
-
- fn show(&self, lock: bool) -> String {
- Self::format(self.package.clone(), lock)
- }
-
- fn as_uninstall_operation(&self) -> Option<&UninstallOperation> {
- Some(self)
- }
-
- fn get_package(&self) -> PackageInterfaceHandle {
- self.package.clone()
- }
-}
-
impl std::fmt::Display for UninstallOperation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.show(false))
diff --git a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
index 76b17189..a06a9cdc 100644
--- a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
+++ b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs
@@ -1,11 +1,10 @@
//! ref: composer/src/Composer/DependencyResolver/Operation/UpdateOperation.php
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::SolverOperation;
use crate::package::PackageInterfaceHandle;
use crate::package::version::VersionParser;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct UpdateOperation {
pub(crate) initial_package: PackageInterfaceHandle,
pub(crate) target_package: PackageInterfaceHandle,
@@ -27,6 +26,14 @@ impl UpdateOperation {
self.target_package.clone()
}
+ pub fn show(&self, lock: bool) -> String {
+ Self::format(
+ self.initial_package.clone(),
+ self.target_package.clone(),
+ lock,
+ )
+ }
+
pub fn format(
initial_package: PackageInterfaceHandle,
target_package: PackageInterfaceHandle,
@@ -78,28 +85,6 @@ impl SolverOperation for UpdateOperation {
const TYPE: &'static str = "update";
}
-impl OperationInterface for UpdateOperation {
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
-
- fn get_operation_type(&self) -> String {
- Self::TYPE.to_string()
- }
-
- fn show(&self, lock: bool) -> String {
- Self::format(
- self.initial_package.clone(),
- self.target_package.clone(),
- lock,
- )
- }
-
- fn as_update_operation(&self) -> Option<&UpdateOperation> {
- Some(self)
- }
-}
-
impl std::fmt::Display for UpdateOperation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.show(false))
diff --git a/crates/shirabe/src/dependency_resolver/transaction.rs b/crates/shirabe/src/dependency_resolver/transaction.rs
index 07564ed0..4abe85d4 100644
--- a/crates/shirabe/src/dependency_resolver/transaction.rs
+++ b/crates/shirabe/src/dependency_resolver/transaction.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/DependencyResolver/Transaction.php
+use crate::dependency_resolver::operation::AnyOperation;
use crate::dependency_resolver::operation::InstallOperation;
use crate::dependency_resolver::operation::MarkAliasInstalledOperation;
use crate::dependency_resolver::operation::MarkAliasUninstalledOperation;
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::UninstallOperation;
use crate::dependency_resolver::operation::UpdateOperation;
use crate::package::AliasPackageHandle;
@@ -21,7 +21,7 @@ use shirabe_php_shim::{
#[derive(Debug, Clone)]
pub struct Transaction {
/// @var OperationInterface[]
- pub(crate) operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ pub(crate) operations: Vec<AnyOperation>,
/// Packages present at the beginning of the transaction
/// @var PackageInterface[]
@@ -64,7 +64,7 @@ impl Transaction {
this
}
- pub fn get_operations(&self) -> &Vec<std::rc::Rc<dyn OperationInterface>> {
+ pub fn get_operations(&self) -> &Vec<AnyOperation> {
&self.operations
}
@@ -108,8 +108,8 @@ impl Transaction {
}
/// @return OperationInterface[]
- pub(crate) fn calculate_operations(&mut self) -> Vec<std::rc::Rc<dyn OperationInterface>> {
- let mut operations: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ pub(crate) fn calculate_operations(&mut self) -> Vec<AnyOperation> {
+ let mut operations: Vec<AnyOperation> = vec![];
let mut present_package_map: IndexMap<String, PackageInterfaceHandle> = IndexMap::new();
let mut remove_map: IndexMap<String, PackageInterfaceHandle> = IndexMap::new();
@@ -163,7 +163,7 @@ impl Transaction {
if present_alias_map.contains(&alias_key) {
remove_alias_map.shift_remove(&alias_key);
} else {
- operations.push(std::rc::Rc::new(MarkAliasInstalledOperation::new(alias)));
+ operations.push(MarkAliasInstalledOperation::new(alias).into());
}
} else if let Some(source) = present_package_map.get(&package.get_name()).cloned() {
// do we need to update?
@@ -187,14 +187,12 @@ impl Transaction {
|| package.get_source_reference() != present.get_source_reference()
|| abandoned_or_replacement_changed
{
- operations.push(std::rc::Rc::new(UpdateOperation::new(
- source.clone(),
- package.clone(),
- )));
+ operations
+ .push(UpdateOperation::new(source.clone(), package.clone()).into());
}
remove_map.shift_remove(&package.get_name());
} else {
- operations.push(std::rc::Rc::new(InstallOperation::new(package.clone())));
+ operations.push(InstallOperation::new(package.clone()).into());
remove_map.shift_remove(&package.get_name());
}
}
@@ -202,16 +200,10 @@ impl Transaction {
for (_name, package) in remove_map {
// PHP: array_unshift($operations, new Operation\UninstallOperation($package));
- array_unshift(
- &mut operations,
- std::rc::Rc::new(UninstallOperation::new(package))
- as std::rc::Rc<dyn OperationInterface>,
- );
+ array_unshift(&mut operations, UninstallOperation::new(package).into());
}
for (_name_version, package) in remove_alias_map {
- operations.push(std::rc::Rc::new(MarkAliasUninstalledOperation::new(
- package,
- )));
+ operations.push(MarkAliasUninstalledOperation::new(package).into());
}
let operations = self.move_plugins_to_front(operations);
@@ -279,29 +271,22 @@ impl Transaction {
///
/// @param OperationInterface[] $operations
/// @return OperationInterface[] reordered operation list
- fn move_plugins_to_front(
- &self,
- mut operations: Vec<std::rc::Rc<dyn OperationInterface>>,
- ) -> Vec<std::rc::Rc<dyn OperationInterface>> {
- let mut dl_modifying_plugins_no_deps: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
- let mut dl_modifying_plugins_with_deps: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ fn move_plugins_to_front(&self, mut operations: Vec<AnyOperation>) -> Vec<AnyOperation> {
+ let mut dl_modifying_plugins_no_deps: Vec<AnyOperation> = vec![];
+ let mut dl_modifying_plugins_with_deps: Vec<AnyOperation> = vec![];
let mut dl_modifying_plugin_requires: Vec<String> = vec![];
- let mut plugins_no_deps: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
- let mut plugins_with_deps: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ let mut plugins_no_deps: Vec<AnyOperation> = vec![];
+ let mut plugins_with_deps: Vec<AnyOperation> = vec![];
let mut plugin_requires: Vec<String> = vec![];
let mut to_remove: Vec<usize> = vec![];
for idx in (0..operations.len()).rev() {
let op = &operations[idx];
- let package: PackageInterfaceHandle = if let Some(install_op) =
- op.as_ref().as_any().downcast_ref::<InstallOperation>()
- {
- install_op.get_package().clone()
- } else if let Some(update_op) = op.as_ref().as_any().downcast_ref::<UpdateOperation>() {
- update_op.get_target_package().clone()
- } else {
- continue;
+ let package: PackageInterfaceHandle = match op {
+ AnyOperation::Install(install_op) => install_op.get_package(),
+ AnyOperation::Update(update_op) => update_op.get_target_package(),
+ _ => continue,
};
let extra = package.get_extra();
@@ -373,7 +358,7 @@ impl Transaction {
}
// PHP: array_merge($dlModifyingPluginsNoDeps, $dlModifyingPluginsWithDeps, $pluginsNoDeps, $pluginsWithDeps, $operations)
- let mut result: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ let mut result: Vec<AnyOperation> = vec![];
result.extend(dl_modifying_plugins_no_deps);
result.extend(dl_modifying_plugins_with_deps);
result.extend(plugins_no_deps);
@@ -387,23 +372,14 @@ impl Transaction {
///
/// @param OperationInterface[] $operations
/// @return OperationInterface[] reordered operation list
- fn move_uninstalls_to_front(
- &self,
- mut operations: Vec<std::rc::Rc<dyn OperationInterface>>,
- ) -> Vec<std::rc::Rc<dyn OperationInterface>> {
- let mut uninst_ops: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ fn move_uninstalls_to_front(&self, mut operations: Vec<AnyOperation>) -> Vec<AnyOperation> {
+ let mut uninst_ops: Vec<AnyOperation> = vec![];
let mut to_remove: Vec<usize> = vec![];
for (idx, op) in operations.iter().enumerate() {
- let is_uninstall = op
- .as_ref()
- .as_any()
- .downcast_ref::<UninstallOperation>()
- .is_some()
- || op
- .as_ref()
- .as_any()
- .downcast_ref::<MarkAliasUninstalledOperation>()
- .is_some();
+ let is_uninstall = matches!(
+ op,
+ AnyOperation::Uninstall(_) | AnyOperation::MarkAliasUninstalled(_)
+ );
if is_uninstall {
uninst_ops.push(op.clone());
to_remove.push(idx);
@@ -415,7 +391,7 @@ impl Transaction {
operations.remove(idx);
}
- let mut result: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ let mut result: Vec<AnyOperation> = vec![];
result.extend(uninst_ops);
result.extend(operations);
result
diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
index 1f1d9619..abc8aad8 100644
--- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
+++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
@@ -4,7 +4,7 @@ use crate::autoload::ClassLoader;
use crate::composer::PartialComposerHandle;
use crate::composer::PartialComposerWeakHandle;
use crate::dependency_resolver::Transaction;
-use crate::dependency_resolver::operation::OperationInterface;
+use crate::dependency_resolver::operation::AnyOperation;
use crate::event_dispatcher::Event;
use crate::event_dispatcher::EventInterface;
use crate::event_dispatcher::EventSubscriberInterface;
@@ -205,8 +205,8 @@ impl EventDispatcher {
event_name: &str,
dev_mode: bool,
local_repo: Box<dyn RepositoryInterface>,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
- operation: std::rc::Rc<dyn OperationInterface>,
+ operations: Vec<AnyOperation>,
+ operation: AnyOperation,
) -> anyhow::Result<i64> {
let composer = self.composer();
assert!(
diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs
index cfe2432c..3cdb046b 100644
--- a/crates/shirabe/src/installer.rs
+++ b/crates/shirabe/src/installer.rs
@@ -55,7 +55,7 @@ use crate::dependency_resolver::Request;
use crate::dependency_resolver::SecurityAdvisoryPoolFilter;
use crate::dependency_resolver::Solver;
use crate::dependency_resolver::UpdateAllowTransitiveDeps;
-use crate::dependency_resolver::operation::OperationInterface;
+use crate::dependency_resolver::operation::AnyOperation;
use crate::downloader::DownloadManagerInterface;
use crate::downloader::TransportException;
use crate::event_dispatcher::EventDispatcherInterface;
@@ -754,14 +754,14 @@ impl Installer {
let platform_dev_reqs =
self.extract_platform_requirements(&self.package.get_dev_requires());
- let mut installs_updates: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
- let mut uninstalls: Vec<std::rc::Rc<dyn OperationInterface>> = vec![];
+ let mut installs_updates: Vec<AnyOperation> = vec![];
+ let mut uninstalls: Vec<AnyOperation> = vec![];
if !lock_transaction.get_operations().is_empty() {
let mut install_names: Vec<String> = vec![];
let mut update_names: Vec<String> = vec![];
let mut uninstall_names: Vec<String> = vec![];
for operation in lock_transaction.get_operations() {
- if let Some(io) = operation.as_install_operation() {
+ if let AnyOperation::Install(io) = operation {
installs_updates.push(operation.clone());
install_names.push(format!(
"{}:{}",
@@ -771,7 +771,7 @@ impl Installer {
crate::package::DisplayMode::SourceRefIfDev
)
));
- } else if let Some(uo) = operation.as_update_operation() {
+ } else if let AnyOperation::Update(uo) = operation {
// when mirrors/metadata from a package gets updated we do not want to list it as an
// update in the output as it is only an internal lock file metadata update
if self.update_mirrors
@@ -791,7 +791,7 @@ impl Installer {
crate::package::DisplayMode::SourceRefIfDev
)
));
- } else if let Some(uo) = operation.as_uninstall_operation() {
+ } else if let AnyOperation::Uninstall(uo) = operation {
uninstalls.push(operation.clone());
uninstall_names.push(uo.get_package().get_pretty_name().to_string());
}
@@ -837,29 +837,20 @@ impl Installer {
}
}
- let sort_by_name = |a: &std::rc::Rc<dyn OperationInterface>,
- b: &std::rc::Rc<dyn OperationInterface>|
- -> i64 {
- let a_name: String = if let Some(uo) = a.as_update_operation() {
- uo.get_target_package().get_name().to_string()
- } else {
- a.get_package().get_name().to_string()
- };
- let b_name: String = if let Some(uo) = b.as_update_operation() {
- uo.get_target_package().get_name().to_string()
- } else {
- b.get_package().get_name().to_string()
- };
- strcmp(&a_name, &b_name)
+ let sort_by_name = |a: &AnyOperation, b: &AnyOperation| -> i64 {
+ strcmp(
+ &a.get_target_package().get_name(),
+ &b.get_target_package().get_name(),
+ )
};
usort(&mut uninstalls, &sort_by_name);
usort(&mut installs_updates, &sort_by_name);
- let mut merged: Vec<std::rc::Rc<dyn OperationInterface>> = uninstalls;
+ let mut merged: Vec<AnyOperation> = uninstalls;
merged.extend(installs_updates);
for operation in &merged {
// collect suggestions
- if let Some(io) = operation.as_install_operation() {
+ if let AnyOperation::Install(io) = operation {
self.suggested_packages_reporter
.borrow_mut()
.add_suggestions_from_package(io.get_package());
@@ -872,17 +863,13 @@ impl Installer {
.get("lock")
.as_bool()
.unwrap_or(false)
- && (strpos(&operation.get_operation_type(), "Alias").is_none()
- || self.io.is_debug())
+ && (strpos(operation.get_operation_type(), "Alias").is_none() || self.io.is_debug())
{
let mut source_repo = String::new();
if self.io.is_very_verbose()
- && strpos(&operation.get_operation_type(), "Alias").is_none()
+ && strpos(operation.get_operation_type(), "Alias").is_none()
{
- let operation_pkg = match operation.as_update_operation() {
- Some(uo) => uo.get_target_package(),
- None => operation.get_package(),
- };
+ let operation_pkg = operation.get_target_package();
if let Some(repo) = operation_pkg.get_repository() {
source_repo = format!(" from {}", repo.get_repo_name());
}
@@ -1212,21 +1199,21 @@ impl Installer {
let mut updates: Vec<String> = vec![];
let mut uninstalls: Vec<String> = vec![];
for operation in local_repo_transaction.get_operations() {
- if let Some(io) = operation.as_install_operation() {
+ if let AnyOperation::Install(io) = operation {
installs.push(format!(
"{}:{}",
io.get_package().get_pretty_name(),
io.get_package()
.get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev)
));
- } else if let Some(uo) = operation.as_update_operation() {
+ } else if let AnyOperation::Update(uo) = operation {
updates.push(format!(
"{}:{}",
uo.get_target_package().get_pretty_name(),
uo.get_target_package()
.get_full_pretty_version(true, crate::package::DisplayMode::SourceRefIfDev)
));
- } else if let Some(uo) = operation.as_uninstall_operation() {
+ } else if let AnyOperation::Uninstall(uo) = operation {
uninstalls.push(uo.get_package().get_pretty_name().to_string());
}
}
@@ -1298,8 +1285,7 @@ impl Installer {
} else {
for operation in local_repo_transaction.get_operations() {
// output op, but alias op only in debug verbosity
- if strpos(&operation.get_operation_type(), "Alias").is_none() || self.io.is_debug()
- {
+ if strpos(operation.get_operation_type(), "Alias").is_none() || self.io.is_debug() {
self.io
.write_error(&format!(" - {}", operation.show(false)));
}
diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs
index 2d60997c..4eb905ed 100644
--- a/crates/shirabe/src/installer/installation_manager.rs
+++ b/crates/shirabe/src/installer/installation_manager.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Installer/InstallationManager.php
+use crate::dependency_resolver::operation::AnyOperation;
use crate::dependency_resolver::operation::InstallOperation;
use crate::dependency_resolver::operation::MarkAliasInstalledOperation;
use crate::dependency_resolver::operation::MarkAliasUninstalledOperation;
-use crate::dependency_resolver::operation::OperationInterface;
use crate::dependency_resolver::operation::UninstallOperation;
use crate::dependency_resolver::operation::UpdateOperation;
use crate::downloader::FileDownloader;
@@ -240,7 +240,7 @@ impl InstallationManager {
pub fn execute(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
download_only: bool,
@@ -253,18 +253,16 @@ impl InstallationManager {
let _ = (dev_mode, run_scripts, download_only);
for operation in operations {
let trace = shirabe_php_shim::strip_tags(&operation.to_string());
- match operation.get_operation_type().as_str() {
- "install" => {
- let op = operation.as_install_operation().expect("install operation");
+ match operation {
+ AnyOperation::Install(op) => {
let package = op.get_package();
mock.installed.push(package.clone());
mock.trace.push(trace);
repo.add_package(PackageInterfaceHandle::dup(&package));
}
- "update" => {
- let op = operation.as_update_operation().expect("update operation");
- let initial = op.get_initial_package().clone();
- let target = op.get_target_package().clone();
+ AnyOperation::Update(op) => {
+ let initial = op.get_initial_package();
+ let target = op.get_target_package();
mock.updated.push((initial.clone(), target.clone()));
mock.trace.push(trace);
repo.remove_package(initial);
@@ -272,38 +270,26 @@ impl InstallationManager {
repo.add_package(PackageInterfaceHandle::dup(&target));
}
}
- "uninstall" => {
- let op = operation
- .as_uninstall_operation()
- .expect("uninstall operation");
+ AnyOperation::Uninstall(op) => {
let package = op.get_package();
mock.uninstalled.push(package.clone());
mock.trace.push(trace);
repo.remove_package(package);
}
- "markAliasInstalled" => {
- let op = operation
- .as_any()
- .downcast_ref::<MarkAliasInstalledOperation>()
- .expect("markAliasInstalled operation");
- let package = op.get_package();
- mock.installed.push(package.clone().into());
+ AnyOperation::MarkAliasInstalled(op) => {
+ let package: PackageInterfaceHandle = op.get_package().into();
+ mock.installed.push(package.clone());
mock.trace.push(trace);
- if !repo.has_package(package.clone().into()) {
- repo.add_package(PackageInterfaceHandle::dup(&package.into()));
+ if !repo.has_package(package.clone()) {
+ repo.add_package(PackageInterfaceHandle::dup(&package));
}
}
- "markAliasUninstalled" => {
- let op = operation
- .as_any()
- .downcast_ref::<MarkAliasUninstalledOperation>()
- .expect("markAliasUninstalled operation");
- let package = op.get_package();
- mock.uninstalled.push(package.clone().into());
+ AnyOperation::MarkAliasUninstalled(op) => {
+ let package: PackageInterfaceHandle = op.get_package().into();
+ mock.uninstalled.push(package.clone());
mock.trace.push(trace);
- repo.remove_package(package.into());
+ repo.remove_package(package);
}
- other => panic!("unknown operation type: {}", other),
}
}
return Ok(());
@@ -333,7 +319,7 @@ impl InstallationManager {
}),
);
- let all_operations: Vec<std::rc::Rc<dyn OperationInterface>> = operations.clone();
+ let all_operations: Vec<AnyOperation> = operations.clone();
// The concurrent operation chains share the repository; each chain borrows it only in
// synchronous sections, never across an await.
@@ -343,18 +329,15 @@ impl InstallationManager {
let result: anyhow::Result<()> = (|| -> anyhow::Result<()> {
// execute operations in batches to make sure download-modifying-plugins are installed
// before the other packages get downloaded
- let mut batches: Vec<IndexMap<i64, std::rc::Rc<dyn OperationInterface>>> = vec![];
- let mut batch: IndexMap<i64, std::rc::Rc<dyn OperationInterface>> = IndexMap::new();
+ let mut batches: Vec<IndexMap<i64, AnyOperation>> = vec![];
+ let mut batch: IndexMap<i64, AnyOperation> = IndexMap::new();
for (index, operation) in operations.into_iter().enumerate() {
let index = index as i64;
- let package: Option<PackageInterfaceHandle> =
- if let Some(update) = operation.as_update_operation() {
- Some(update.get_target_package())
- } else {
- operation
- .as_install_operation()
- .map(|install| install.get_package())
- };
+ let package: Option<PackageInterfaceHandle> = match &operation {
+ AnyOperation::Update(update) => Some(update.get_target_package()),
+ AnyOperation::Install(install) => Some(install.get_package()),
+ _ => None,
+ };
if let Some(package) = package
&& package.get_type() == "composer-plugin"
{
@@ -423,7 +406,7 @@ impl InstallationManager {
async fn download_and_execute_batch(
&self,
repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
- operations: IndexMap<i64, std::rc::Rc<dyn OperationInterface>>,
+ operations: IndexMap<i64, AnyOperation>,
cleanup_promises: &mut IndexMap<
i64,
Box<
@@ -435,7 +418,7 @@ impl InstallationManager {
dev_mode: bool,
run_scripts: bool,
download_only: bool,
- all_operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ all_operations: Vec<AnyOperation>,
) -> anyhow::Result<()> {
let mut promises: Vec<
std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>>>>,
@@ -445,24 +428,15 @@ impl InstallationManager {
let op_type = operation.get_operation_type();
// ignoring alias ops as they don't need to execute anything at this stage
- if !["update", "install", "uninstall"].contains(&op_type.as_str()) {
+ if !["update", "install", "uninstall"].contains(&op_type) {
continue;
}
- let package: PackageInterfaceHandle;
- let initial_package: Option<PackageInterfaceHandle>;
- if op_type == "update" {
- // @var UpdateOperation $operation
- let update_op = operation
- .as_update_operation()
- .expect("op_type == \"update\" implies UpdateOperation");
- package = update_op.get_target_package();
- initial_package = Some(update_op.get_initial_package());
- } else {
- // @var InstallOperation|MarkAliasInstalledOperation|MarkAliasUninstalledOperation|UninstallOperation $operation
- package = operation.get_package();
- initial_package = None;
- }
+ let package = operation.get_target_package();
+ let initial_package: Option<PackageInterfaceHandle> = match operation {
+ AnyOperation::Update(update_op) => Some(update_op.get_initial_package()),
+ _ => None,
+ };
let installer = self.get_installer(&package.get_type())?;
// PHP: $cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage) {
@@ -474,7 +448,6 @@ impl InstallationManager {
>,
> = {
let installer = installer.clone();
- let op_type = op_type.clone();
let package = package.clone();
let initial_package = initial_package.clone();
Box::new(move || {
@@ -488,14 +461,13 @@ impl InstallationManager {
}
let installer = installer.clone();
- let op_type = op_type.clone();
let package = package.clone();
let initial_package = initial_package.clone();
let fut: std::pin::Pin<
Box<dyn std::future::Future<Output = anyhow::Result<()>>>,
> = Box::pin(async move {
installer
- .cleanup(&op_type, package, initial_package)
+ .cleanup(op_type, package, initial_package)
.await
.map(|_| ())
});
@@ -530,17 +502,14 @@ impl InstallationManager {
// execute operations in batches to make sure every plugin is installed in the
// right order and activated before the packages depending on it are installed
- let mut batches: Vec<IndexMap<i64, std::rc::Rc<dyn OperationInterface>>> = vec![];
- let mut batch: IndexMap<i64, std::rc::Rc<dyn OperationInterface>> = IndexMap::new();
+ let mut batches: Vec<IndexMap<i64, AnyOperation>> = vec![];
+ let mut batch: IndexMap<i64, AnyOperation> = IndexMap::new();
for (index, operation) in operations {
- let package: Option<PackageInterfaceHandle> =
- if let Some(update) = operation.as_update_operation() {
- Some(update.get_target_package())
- } else {
- operation
- .as_install_operation()
- .map(|install| install.get_package())
- };
+ let package: Option<PackageInterfaceHandle> = match &operation {
+ AnyOperation::Update(update) => Some(update.get_target_package()),
+ AnyOperation::Install(install) => Some(install.get_package()),
+ _ => None,
+ };
if let Some(package) = package {
let pkg_type = package.get_type();
if pkg_type == "composer-plugin" || pkg_type == "composer-installer" {
@@ -579,7 +548,7 @@ impl InstallationManager {
async fn execute_batch(
&self,
repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
- operations: IndexMap<i64, std::rc::Rc<dyn OperationInterface>>,
+ operations: IndexMap<i64, AnyOperation>,
cleanup_promises: &IndexMap<
i64,
Box<
@@ -590,7 +559,7 @@ impl InstallationManager {
>,
dev_mode: bool,
run_scripts: bool,
- all_operations: &[std::rc::Rc<dyn OperationInterface>],
+ all_operations: &[AnyOperation],
) -> anyhow::Result<()> {
let mut promises: Vec<
std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>> + '_>>,
@@ -600,7 +569,7 @@ impl InstallationManager {
let op_type = operation.get_operation_type();
// ignoring alias ops as they don't need to execute anything
- if !["update", "install", "uninstall"].contains(&op_type.as_str()) {
+ if !["update", "install", "uninstall"].contains(&op_type) {
// output alias ops in debug verbosity as they have no output otherwise
if self.io.is_debug() {
self.io.write_error3(
@@ -609,23 +578,11 @@ impl InstallationManager {
io_interface::NORMAL,
);
}
- match op_type.as_str() {
- "markAliasInstalled" => {
- let op = operation
- .as_any()
- .downcast_ref::<MarkAliasInstalledOperation>()
- .expect(
- "op_type == \"markAliasInstalled\" implies MarkAliasInstalledOperation",
- );
+ match &operation {
+ AnyOperation::MarkAliasInstalled(op) => {
self.mark_alias_installed(&mut **repo.borrow_mut(), op);
}
- "markAliasUninstalled" => {
- let op = operation
- .as_any()
- .downcast_ref::<MarkAliasUninstalledOperation>()
- .expect(
- "op_type == \"markAliasUninstalled\" implies MarkAliasUninstalledOperation",
- );
+ AnyOperation::MarkAliasUninstalled(op) => {
self.mark_alias_uninstalled(&mut **repo.borrow_mut(), op);
}
_ => {}
@@ -634,20 +591,13 @@ impl InstallationManager {
continue;
}
- let package: PackageInterfaceHandle;
- let initial_package: Option<PackageInterfaceHandle>;
- if op_type == "update" {
- let update_op = operation
- .as_update_operation()
- .expect("op_type == \"update\" implies UpdateOperation");
- package = update_op.get_target_package();
- initial_package = Some(update_op.get_initial_package());
- } else {
- package = operation.get_package();
- initial_package = None;
- }
+ let package = operation.get_target_package();
+ let initial_package: Option<PackageInterfaceHandle> = match &operation {
+ AnyOperation::Update(update_op) => Some(update_op.get_initial_package()),
+ _ => None,
+ };
- let event_name = match op_type.as_str() {
+ let event_name = match op_type {
"install" => PackageEvents::PRE_PACKAGE_INSTALL,
"update" => PackageEvents::PRE_PACKAGE_UPDATE,
"uninstall" => PackageEvents::PRE_PACKAGE_UNINSTALL,
@@ -658,13 +608,7 @@ impl InstallationManager {
// TODO(phase-c): dispatch_package_event takes Box<dyn RepositoryInterface>/Vec<Box<...>>
// but we hold a RefCell'd &mut dyn here. Needs structural rework (likely shared Rc
// on repo and ops).
- let _ = (
- event_name,
- dev_mode,
- &repo,
- &all_operations,
- operation.as_ref(),
- );
+ let _ = (event_name, dev_mode, &repo, &all_operations, &operation);
}
let installer = self.get_installer(&package.get_type())?;
@@ -679,29 +623,23 @@ impl InstallationManager {
promises.push(Box::pin(async move {
let chain_result: anyhow::Result<()> = async {
installer
- .prepare(&op_type, package.clone(), initial_package.clone())
+ .prepare(op_type, package.clone(), initial_package.clone())
.await?;
- match op_type.as_str() {
- "install" => {
- let op = operation
- .as_install_operation()
- .expect("op_type == \"install\" implies InstallOperation");
+ match &operation {
+ AnyOperation::Install(op) => {
self.install(repo, op).await?;
}
- "update" => {
- let op = operation
- .as_update_operation()
- .expect("op_type == \"update\" implies UpdateOperation");
+ AnyOperation::Update(op) => {
self.update(repo, op).await?;
}
- "uninstall" => {
- let op = operation
- .as_uninstall_operation()
- .expect("op_type == \"uninstall\" implies UninstallOperation");
+ AnyOperation::Uninstall(op) => {
self.uninstall(repo, op).await?;
}
- _ => unreachable!("op_type is one of install/update/uninstall"),
+ AnyOperation::MarkAliasInstalled(_)
+ | AnyOperation::MarkAliasUninstalled(_) => {
+ unreachable!("alias operations were skipped above")
+ }
}
if let Some(cleanup) = cleanup_promises.get(&index)
@@ -718,7 +656,7 @@ impl InstallationManager {
if let Err(e) = chain_result {
self.io.write_error(&format!(
" <error>{} of {} failed</error>",
- shirabe_php_shim::ucfirst(&op_type),
+ shirabe_php_shim::ucfirst(op_type),
package.get_pretty_name()
));
return Err(e);
@@ -727,7 +665,7 @@ impl InstallationManager {
// PHP: ->then(fn() => $repo->write($devMode, $this)) persists the repository after each op.
repo.borrow_mut().write(dev_mode, self);
- let event_name_post = match op_type.as_str() {
+ let event_name_post = match op_type {
"install" => PackageEvents::POST_PACKAGE_INSTALL,
"update" => PackageEvents::POST_PACKAGE_UPDATE,
"uninstall" => PackageEvents::POST_PACKAGE_UNINSTALL,
@@ -1087,7 +1025,7 @@ pub trait InstallationManagerInterface: std::fmt::Debug {
fn execute(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
download_only: bool,
@@ -1129,7 +1067,7 @@ impl InstallationManagerInterface for InstallationManager {
fn execute(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
download_only: bool,
diff --git a/crates/shirabe/src/installer/package_event.rs b/crates/shirabe/src/installer/package_event.rs
index 6661e0d1..28a8a2ea 100644
--- a/crates/shirabe/src/installer/package_event.rs
+++ b/crates/shirabe/src/installer/package_event.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Installer/PackageEvent.php
use crate::composer::ComposerWeakHandle;
-use crate::dependency_resolver::operation::OperationInterface;
+use crate::dependency_resolver::operation::AnyOperation;
use crate::event_dispatcher::Event;
use crate::event_dispatcher::EventInterface;
use crate::io::IOInterface;
@@ -16,8 +16,8 @@ pub struct PackageEvent {
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
local_repo: Box<dyn RepositoryInterface>,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
- operation: std::rc::Rc<dyn OperationInterface>,
+ operations: Vec<AnyOperation>,
+ operation: AnyOperation,
}
impl PackageEvent {
@@ -27,8 +27,8 @@ impl PackageEvent {
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
local_repo: Box<dyn RepositoryInterface>,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
- operation: std::rc::Rc<dyn OperationInterface>,
+ operations: Vec<AnyOperation>,
+ operation: AnyOperation,
) -> Self {
Self {
inner: Event::new(event_name, vec![], IndexMap::new()),
@@ -61,12 +61,12 @@ impl PackageEvent {
self.local_repo.as_ref()
}
- pub fn get_operations(&self) -> &Vec<std::rc::Rc<dyn OperationInterface>> {
+ pub fn get_operations(&self) -> &Vec<AnyOperation> {
&self.operations
}
- pub fn get_operation(&self) -> &dyn OperationInterface {
- self.operation.as_ref()
+ pub fn get_operation(&self) -> &AnyOperation {
+ &self.operation
}
}
diff --git a/crates/shirabe/tests/dependency_resolver/solver_test.rs b/crates/shirabe/tests/dependency_resolver/solver_test.rs
index 7a507da3..be8df4db 100644
--- a/crates/shirabe/tests/dependency_resolver/solver_test.rs
+++ b/crates/shirabe/tests/dependency_resolver/solver_test.rs
@@ -4,6 +4,7 @@ use crate::test_case::{get_alias_package, get_package, get_version_constraint};
use indexmap::IndexMap;
use shirabe::dependency_resolver::PolicyInterface;
use shirabe::dependency_resolver::default_policy::DefaultPolicy;
+use shirabe::dependency_resolver::operation::AnyOperation;
use shirabe::dependency_resolver::pool::Pool;
use shirabe::dependency_resolver::request::Request;
use shirabe::dependency_resolver::solver_problems_exception::SolverProblemsException;
@@ -140,7 +141,7 @@ fn check_solver_result_repo_set(
let mut result_readable: Vec<(String, String)> = Vec::new();
let mut result_ids: Vec<(String, Vec<usize>)> = Vec::new();
for operation in transaction.get_operations() {
- if let Some(update) = operation.as_update_operation() {
+ if let AnyOperation::Update(update) = operation {
let from = update.get_initial_package();
let to = update.get_target_package();
result_readable.push((
@@ -149,15 +150,14 @@ fn check_solver_result_repo_set(
));
result_ids.push(("update".to_string(), vec![from.ptr_id(), to.ptr_id()]));
} else {
- let op_type = operation.get_operation_type();
- let job = match op_type.as_str() {
+ let job = match operation.get_operation_type() {
"markAliasInstalled" => "markAliasInstalled",
"markAliasUninstalled" => "markAliasUninstalled",
"uninstall" => "remove",
"install" => "install",
other => panic!("Unexpected operation: {}", other),
};
- let package = operation.get_package();
+ let package = operation.get_target_package();
result_readable.push((job.to_string(), package.get_unique_name()));
result_ids.push((job.to_string(), vec![package.ptr_id()]));
}
@@ -2521,7 +2521,7 @@ fn test_learn_positive_literal() {
];
let mut result: Vec<(String, String)> = Vec::new();
for operation in transaction.get_operations() {
- if let Some(update) = operation.as_update_operation() {
+ if let AnyOperation::Update(update) = operation {
result.push((
"update".to_string(),
format!(
@@ -2535,9 +2535,9 @@ fn test_learn_positive_literal() {
let job = if op_type == "uninstall" {
"remove".to_string()
} else {
- op_type
+ op_type.to_string()
};
- result.push((job, operation.get_package().get_unique_name()));
+ result.push((job, operation.get_target_package().get_unique_name()));
}
}
assert_eq!(expected, result);
diff --git a/crates/shirabe/tests/dependency_resolver/transaction_test.rs b/crates/shirabe/tests/dependency_resolver/transaction_test.rs
index 99f31c38..3b1006ea 100644
--- a/crates/shirabe/tests/dependency_resolver/transaction_test.rs
+++ b/crates/shirabe/tests/dependency_resolver/transaction_test.rs
@@ -2,6 +2,7 @@
use crate::test_case::{get_alias_package, get_package, get_version_constraint};
use indexmap::IndexMap;
+use shirabe::dependency_resolver::operation::AnyOperation;
use shirabe::dependency_resolver::transaction::Transaction;
use shirabe::package::Link;
use shirabe::package::handle::PackageInterfaceHandle;
@@ -62,15 +63,15 @@ impl PartialEq for OperationEntry {
fn check_transaction_operations(transaction: &Transaction, expected: Vec<OperationEntry>) {
let mut result: Vec<OperationEntry> = vec![];
for operation in transaction.get_operations() {
- if let Some(update) = operation.as_update_operation() {
+ if let AnyOperation::Update(update) = operation {
result.push(OperationEntry::Update {
from: update.get_initial_package(),
to: update.get_target_package(),
});
} else {
result.push(OperationEntry::Job {
- job: operation.get_operation_type(),
- package: operation.get_package(),
+ job: operation.get_operation_type().to_string(),
+ package: operation.get_target_package(),
});
}
}
diff --git a/crates/shirabe/tests/repository/filesystem_repository_test.rs b/crates/shirabe/tests/repository/filesystem_repository_test.rs
index f2cdb670..054a6d7c 100644
--- a/crates/shirabe/tests/repository/filesystem_repository_test.rs
+++ b/crates/shirabe/tests/repository/filesystem_repository_test.rs
@@ -3,7 +3,7 @@
use crate::test_case::{get_alias_package, get_package};
use indexmap::IndexMap;
use serial_test::serial;
-use shirabe::dependency_resolver::operation::OperationInterface;
+use shirabe::dependency_resolver::operation::AnyOperation;
use shirabe::installed_versions::InstalledVersions;
use shirabe::installer::{InstallationManagerInterface, InstallerInterface};
use shirabe::io::IOInterface;
@@ -106,7 +106,7 @@ mockall::mock! {
fn execute(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- operations: Vec<std::rc::Rc<dyn OperationInterface>>,
+ operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
download_only: bool,