diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-05 02:42:02 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-05 02:42:02 +0900 |
| commit | 9a25fcfc82b72f60facd381786ca5490acca032c (patch) | |
| tree | b34b36c19f14d57d160b8e4235a8040011bdec60 /crates/shirabe/src | |
| parent | 886ee829cb191745167dca369045acd3125e5714 (diff) | |
| download | php-shirabe-9a25fcfc82b72f60facd381786ca5490acca032c.tar.gz php-shirabe-9a25fcfc82b72f60facd381786ca5490acca032c.tar.zst php-shirabe-9a25fcfc82b72f60facd381786ca5490acca032c.zip | |
feat(dependency-resolver): share operations via Rc, drop clone_box
OperationInterface::clone_box (a todo!() trait-object clone stub) is
removed in favor of Rc<dyn OperationInterface> shared ownership. All its
methods are &self, so operations are immutable value objects that Rc can
share; pushing the same operation into multiple lists (installer's
install/uninstall splits) becomes a cheap Rc clone instead of clone_box.
Box<dyn OperationInterface> is replaced with Rc<dyn ...> across
Transaction (and its Lock/LocalRepo wrappers), Installer, PackageEvent,
InstallationManager and EventDispatcher; Box::new operation constructions
become Rc::new.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src')
9 files changed, 60 insertions, 62 deletions
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs index 076d7cd..189ccfc 100644 --- a/crates/shirabe/src/command/create_project_command.rs +++ b/crates/shirabe/src/command/create_project_command.rs @@ -919,7 +919,7 @@ impl CreateProjectCommand { let mut installed_repo = InstalledArrayRepository::new()?; im.execute( &mut installed_repo, - vec![Box::new(InstallOperation::new(package.clone()))], + vec![std::rc::Rc::new(InstallOperation::new(package.clone()))], true, true, false, diff --git a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs index 5d9c0d5..dc71562 100644 --- a/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs +++ b/crates/shirabe/src/dependency_resolver/local_repo_transaction.rs @@ -24,7 +24,7 @@ impl LocalRepoTransaction { pub fn get_operations( &self, - ) -> Vec<Box<dyn crate::dependency_resolver::operation::OperationInterface>> { + ) -> Vec<std::rc::Rc<dyn crate::dependency_resolver::operation::OperationInterface>> { // TODO(phase-b): delegate to inner transaction once operations are typed. Vec::new() } diff --git a/crates/shirabe/src/dependency_resolver/lock_transaction.rs b/crates/shirabe/src/dependency_resolver/lock_transaction.rs index aa7ae25..61f5b39 100644 --- a/crates/shirabe/src/dependency_resolver/lock_transaction.rs +++ b/crates/shirabe/src/dependency_resolver/lock_transaction.rs @@ -209,7 +209,7 @@ impl LockTransaction { pub fn get_operations( &self, - ) -> &Vec<Box<dyn crate::dependency_resolver::operation::OperationInterface>> { + ) -> &Vec<std::rc::Rc<dyn crate::dependency_resolver::operation::OperationInterface>> { self.inner.get_operations() } } diff --git a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs index 3c24ff4..51b150c 100644 --- a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs +++ b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs @@ -13,10 +13,6 @@ pub trait OperationInterface: std::fmt::Debug { fn to_string(&self) -> String; - fn clone_box(&self) -> Box<dyn OperationInterface> { - todo!() - } - fn as_install_operation(&self) -> Option<&InstallOperation> { None } diff --git a/crates/shirabe/src/dependency_resolver/transaction.rs b/crates/shirabe/src/dependency_resolver/transaction.rs index 8cf5d5b..a693356 100644 --- a/crates/shirabe/src/dependency_resolver/transaction.rs +++ b/crates/shirabe/src/dependency_resolver/transaction.rs @@ -19,7 +19,7 @@ use crate::repository::PlatformRepository; #[derive(Debug)] pub struct Transaction { /// @var OperationInterface[] - pub(crate) operations: Vec<Box<dyn OperationInterface>>, + pub(crate) operations: Vec<std::rc::Rc<dyn OperationInterface>>, /// Packages present at the beginning of the transaction /// @var PackageInterface[] @@ -63,7 +63,7 @@ impl Transaction { } /// @return OperationInterface[] - pub fn get_operations(&self) -> &Vec<Box<dyn OperationInterface>> { + pub fn get_operations(&self) -> &Vec<std::rc::Rc<dyn OperationInterface>> { &self.operations } @@ -114,8 +114,8 @@ impl Transaction { } /// @return OperationInterface[] - pub(crate) fn calculate_operations(&mut self) -> Vec<Box<dyn OperationInterface>> { - let mut operations: Vec<Box<dyn OperationInterface>> = vec![]; + pub(crate) fn calculate_operations(&mut self) -> Vec<std::rc::Rc<dyn OperationInterface>> { + let mut operations: Vec<std::rc::Rc<dyn OperationInterface>> = vec![]; let mut present_package_map: IndexMap<String, PackageInterfaceHandle> = IndexMap::new(); let mut remove_map: IndexMap<String, PackageInterfaceHandle> = IndexMap::new(); @@ -170,7 +170,7 @@ impl Transaction { remove_alias_map.shift_remove(&alias_key); } else { // TODO(phase-b): MarkAliasInstalledOperation::new expects AliasPackage by value - operations.push(Box::new(MarkAliasInstalledOperation::new(todo!( + operations.push(std::rc::Rc::new(MarkAliasInstalledOperation::new(todo!( "package as AliasPackage by value" )))); } @@ -196,14 +196,14 @@ impl Transaction { || package.get_source_reference() != present.get_source_reference() || abandoned_or_replacement_changed { - operations.push(Box::new(UpdateOperation::new( + operations.push(std::rc::Rc::new(UpdateOperation::new( source.clone(), package.clone(), ))); } remove_map.shift_remove(&package.get_name()); } else { - operations.push(Box::new(InstallOperation::new(package.clone()))); + operations.push(std::rc::Rc::new(InstallOperation::new(package.clone()))); remove_map.shift_remove(&package.get_name()); } } @@ -213,12 +213,13 @@ impl Transaction { // PHP: array_unshift($operations, new Operation\UninstallOperation($package)); array_unshift( &mut operations, - Box::new(UninstallOperation::new(package)) as Box<dyn OperationInterface>, + std::rc::Rc::new(UninstallOperation::new(package)) + as std::rc::Rc<dyn OperationInterface>, ); } for (_name_version, _package) in remove_alias_map { // TODO(phase-b): MarkAliasUninstalledOperation::new expects AliasPackage by value - operations.push(Box::new(MarkAliasUninstalledOperation::new(todo!( + operations.push(std::rc::Rc::new(MarkAliasUninstalledOperation::new(todo!( "package as AliasPackage by value" )))); } @@ -292,13 +293,13 @@ impl Transaction { /// @return OperationInterface[] reordered operation list fn move_plugins_to_front( &self, - mut operations: Vec<Box<dyn OperationInterface>>, - ) -> Vec<Box<dyn OperationInterface>> { - let mut dl_modifying_plugins_no_deps: Vec<Box<dyn OperationInterface>> = vec![]; - let mut dl_modifying_plugins_with_deps: Vec<Box<dyn OperationInterface>> = vec![]; + 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![]; let mut dl_modifying_plugin_requires: Vec<String> = vec![]; - let mut plugins_no_deps: Vec<Box<dyn OperationInterface>> = vec![]; - let mut plugins_with_deps: Vec<Box<dyn OperationInterface>> = 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 plugin_requires: Vec<String> = vec![]; // PHP: foreach (array_reverse($operations, true) as $idx => $op) @@ -392,7 +393,7 @@ impl Transaction { } // PHP: array_merge($dlModifyingPluginsNoDeps, $dlModifyingPluginsWithDeps, $pluginsNoDeps, $pluginsWithDeps, $operations) - let mut result: Vec<Box<dyn OperationInterface>> = vec![]; + let mut result: Vec<std::rc::Rc<dyn OperationInterface>> = vec![]; result.extend(dl_modifying_plugins_no_deps); result.extend(dl_modifying_plugins_with_deps); result.extend(plugins_no_deps); @@ -408,9 +409,9 @@ impl Transaction { /// @return OperationInterface[] reordered operation list fn move_uninstalls_to_front( &self, - mut operations: Vec<Box<dyn OperationInterface>>, - ) -> Vec<Box<dyn OperationInterface>> { - let mut uninst_ops: Vec<Box<dyn OperationInterface>> = vec![]; + 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![]; let mut to_remove: Vec<usize> = vec![]; for (idx, op) in operations.iter().enumerate() { let is_uninstall = op @@ -435,7 +436,7 @@ impl Transaction { operations.remove(idx); } - let mut result: Vec<Box<dyn OperationInterface>> = vec![]; + let mut result: Vec<std::rc::Rc<dyn OperationInterface>> = 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 77d016b..ea0d69a 100644 --- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs +++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs @@ -169,8 +169,8 @@ impl EventDispatcher { event_name: &str, dev_mode: bool, local_repo: Box<dyn RepositoryInterface>, - operations: Vec<Box<dyn OperationInterface>>, - operation: Box<dyn OperationInterface>, + operations: Vec<std::rc::Rc<dyn OperationInterface>>, + operation: std::rc::Rc<dyn OperationInterface>, ) -> anyhow::Result<i64> { let composer = self.composer(); assert!( diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index 95b9298..7fc3275 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -724,15 +724,15 @@ impl Installer { let platform_dev_reqs = self.extract_platform_requirements(&self.package.get_dev_requires()); - let mut installs_updates: Vec<Box<dyn OperationInterface>> = vec![]; - let mut uninstalls: Vec<Box<dyn OperationInterface>> = vec![]; + let mut installs_updates: Vec<std::rc::Rc<dyn OperationInterface>> = vec![]; + let mut uninstalls: Vec<std::rc::Rc<dyn OperationInterface>> = 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() { - installs_updates.push(operation.clone_box()); + installs_updates.push(operation.clone()); install_names.push(format!( "{}:{}", io.get_package().get_pretty_name(), @@ -752,7 +752,7 @@ impl Installer { continue; } - installs_updates.push(operation.clone_box()); + installs_updates.push(operation.clone()); update_names.push(format!( "{}:{}", uo.get_target_package().get_pretty_name(), @@ -762,7 +762,7 @@ impl Installer { ) )); } else if let Some(uo) = operation.as_uninstall_operation() { - uninstalls.push(operation.clone_box()); + uninstalls.push(operation.clone()); uninstall_names.push(uo.get_package().get_pretty_name().to_string()); } } @@ -809,24 +809,25 @@ impl Installer { } } - let sort_by_name = - |a: &Box<dyn OperationInterface>, b: &Box<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: &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) + }; usort(&mut uninstalls, &sort_by_name); usort(&mut installs_updates, &sort_by_name); - let mut merged: Vec<Box<dyn OperationInterface>> = uninstalls; + let mut merged: Vec<std::rc::Rc<dyn OperationInterface>> = uninstalls; merged.extend(installs_updates); for operation in &merged { // collect suggestions diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs index 8275b41..2fc77d9 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -169,7 +169,7 @@ impl InstallationManager { pub fn execute( &mut self, repo: &mut dyn InstalledRepositoryInterface, - operations: Vec<Box<dyn OperationInterface>>, + operations: Vec<std::rc::Rc<dyn OperationInterface>>, dev_mode: bool, run_scripts: bool, download_only: bool, @@ -200,8 +200,8 @@ impl InstallationManager { let result: Result<()> = (|| -> 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, Box<dyn OperationInterface>>> = vec![]; - let mut batch: IndexMap<i64, Box<dyn OperationInterface>> = IndexMap::new(); + let mut batches: Vec<IndexMap<i64, std::rc::Rc<dyn OperationInterface>>> = vec![]; + let mut batch: IndexMap<i64, std::rc::Rc<dyn OperationInterface>> = IndexMap::new(); for (index, operation) in operations.into_iter().enumerate() { let index = index as i64; let package: Option<PackageInterfaceHandle> = @@ -287,7 +287,7 @@ impl InstallationManager { async fn download_and_execute_batch( &mut self, repo: &mut dyn InstalledRepositoryInterface, - operations: IndexMap<i64, Box<dyn OperationInterface>>, + operations: IndexMap<i64, std::rc::Rc<dyn OperationInterface>>, cleanup_promises: &mut IndexMap< i64, Box< @@ -298,7 +298,7 @@ impl InstallationManager { dev_mode: bool, run_scripts: bool, download_only: bool, - all_operations: Vec<Box<dyn OperationInterface>>, + all_operations: Vec<std::rc::Rc<dyn OperationInterface>>, ) -> Result<()> { for (index, operation) in &operations { let op_type = operation.get_operation_type(); @@ -359,8 +359,8 @@ 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, Box<dyn OperationInterface>>> = vec![]; - let mut batch: IndexMap<i64, Box<dyn OperationInterface>> = IndexMap::new(); + let mut batches: Vec<IndexMap<i64, std::rc::Rc<dyn OperationInterface>>> = vec![]; + let mut batch: IndexMap<i64, std::rc::Rc<dyn OperationInterface>> = IndexMap::new(); for (index, operation) in operations { let package: Option<PackageInterfaceHandle> = if let Some(update) = operation.as_update_operation() { @@ -411,7 +411,7 @@ impl InstallationManager { async fn execute_batch( &mut self, repo: &mut dyn InstalledRepositoryInterface, - operations: IndexMap<i64, Box<dyn OperationInterface>>, + operations: IndexMap<i64, std::rc::Rc<dyn OperationInterface>>, cleanup_promises: &IndexMap< i64, Box< @@ -421,7 +421,7 @@ impl InstallationManager { >, dev_mode: bool, run_scripts: bool, - all_operations: &[Box<dyn OperationInterface>], + all_operations: &[std::rc::Rc<dyn OperationInterface>], ) -> Result<()> { let mut post_exec_callbacks: Vec<Box<dyn Fn()>> = vec![]; diff --git a/crates/shirabe/src/installer/package_event.rs b/crates/shirabe/src/installer/package_event.rs index 342732d..17f9113 100644 --- a/crates/shirabe/src/installer/package_event.rs +++ b/crates/shirabe/src/installer/package_event.rs @@ -14,8 +14,8 @@ pub struct PackageEvent { io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, dev_mode: bool, local_repo: Box<dyn RepositoryInterface>, - operations: Vec<Box<dyn OperationInterface>>, - operation: Box<dyn OperationInterface>, + operations: Vec<std::rc::Rc<dyn OperationInterface>>, + operation: std::rc::Rc<dyn OperationInterface>, } impl PackageEvent { @@ -25,8 +25,8 @@ impl PackageEvent { io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, dev_mode: bool, local_repo: Box<dyn RepositoryInterface>, - operations: Vec<Box<dyn OperationInterface>>, - operation: Box<dyn OperationInterface>, + operations: Vec<std::rc::Rc<dyn OperationInterface>>, + operation: std::rc::Rc<dyn OperationInterface>, ) -> Self { Self { inner: Event::new(event_name, vec![], IndexMap::new()), @@ -59,7 +59,7 @@ impl PackageEvent { self.local_repo.as_ref() } - pub fn get_operations(&self) -> &Vec<Box<dyn OperationInterface>> { + pub fn get_operations(&self) -> &Vec<std::rc::Rc<dyn OperationInterface>> { &self.operations } |
