aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-05 02:42:02 +0900
committernsfisis <nsfisis@gmail.com>2026-06-05 02:42:02 +0900
commit9a25fcfc82b72f60facd381786ca5490acca032c (patch)
treeb34b36c19f14d57d160b8e4235a8040011bdec60 /crates/shirabe
parent886ee829cb191745167dca369045acd3125e5714 (diff)
downloadphp-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')
-rw-r--r--crates/shirabe/src/command/create_project_command.rs2
-rw-r--r--crates/shirabe/src/dependency_resolver/local_repo_transaction.rs2
-rw-r--r--crates/shirabe/src/dependency_resolver/lock_transaction.rs2
-rw-r--r--crates/shirabe/src/dependency_resolver/operation/operation_interface.rs4
-rw-r--r--crates/shirabe/src/dependency_resolver/transaction.rs41
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs4
-rw-r--r--crates/shirabe/src/installer.rs39
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs18
-rw-r--r--crates/shirabe/src/installer/package_event.rs10
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
}