diff options
Diffstat (limited to 'crates/shirabe')
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, |
