diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-07-18 18:16:07 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-07-18 18:16:07 +0900 |
| commit | 307e66847dd5e00ad1890b6a64d3ac7192a03efc (patch) | |
| tree | bdd4657d350a886d7d28dcb5187395771c99943b /crates/shirabe/src/installer | |
| parent | 9b291d454b059977639db26c847af4e835cda0c3 (diff) | |
| download | php-shirabe-307e66847dd5e00ad1890b6a64d3ac7192a03efc.tar.gz php-shirabe-307e66847dd5e00ad1890b6a64d3ac7192a03efc.tar.zst php-shirabe-307e66847dd5e00ad1890b6a64d3ac7192a03efc.zip | |
perf(installation-manager): fan out package downloads via Loop::wait
InstallationManager::downloadAndExecuteBatch now matches PHP: every
update/install operation's installer->download() promise is collected
and driven concurrently through waitOnPromises()/Loop::wait instead of
being awaited one package at a time. Concurrency caps stay where PHP
puts them (HttpDownloader 12, ProcessExecutor 10 via their semaphores).
Error semantics follow PHP too: all downloads settle before the first
rejection is rethrown, rather than aborting on the first failure.
To let the collected futures and the cleanup closures own their
installer beyond the loop iteration that created them, the installer
registry becomes Vec<Rc<dyn InstallerInterface>> and get_installer
hands out clones (PHP closures capture $installer the same way), with
InstallerInterface methods taking &self across the six implementors —
the only genuinely mutable state was LibraryInstaller.vendor_dir
(canonicalized in place), now behind a RefCell.
as_plugin_installer_mut/as_binary_presence_interface lose their &mut.
The cleanup_promises entries are now the real thing: the PHP closure
including the getInstallationSource() guard and the
installer->cleanup($opType, $package, $initialPackage) call, replacing
the no-op futures (drops one TODO(phase-b) and two TODO(phase-c)).
Verified against the real network: create-project laravel/laravel
produces a vendor tree byte-identical to real Composer's (diff -rq
clean across all 109 packages including vendor/composer).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/installer')
| -rw-r--r-- | crates/shirabe/src/installer/binary_presence_interface.rs | 2 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/installation_manager.rs | 169 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/installer_interface.rs | 20 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/library_installer.rs | 48 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/metapackage_installer.rs | 16 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/noop_installer.rs | 16 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/plugin_installer.rs | 26 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/project_installer.rs | 16 |
8 files changed, 176 insertions, 137 deletions
diff --git a/crates/shirabe/src/installer/binary_presence_interface.rs b/crates/shirabe/src/installer/binary_presence_interface.rs index 8bc3ff90..2c4b2cc4 100644 --- a/crates/shirabe/src/installer/binary_presence_interface.rs +++ b/crates/shirabe/src/installer/binary_presence_interface.rs @@ -3,5 +3,5 @@ use crate::package::PackageInterfaceHandle; pub trait BinaryPresenceInterface { - fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle); + fn ensure_binaries_presence(&self, package: PackageInterfaceHandle); } diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs index a3e429b1..df8384c4 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -29,11 +29,13 @@ use shirabe_php_shim::{ /// Package operation manager. #[derive(Debug)] pub struct InstallationManager { - installers: Vec<Box<dyn InstallerInterface>>, + /// Rc rather than Box so `get_installer` can hand out shareable handles: the download/cleanup + /// futures collected for Loop::wait must own their installer beyond the loop iteration that + /// created them (PHP closures capture $installer the same way). + installers: Vec<std::rc::Rc<dyn InstallerInterface>>, /// Maps a package type to the index of its installer in `installers`. PHP caches the installer - /// instance itself; here we store an index instead to avoid sharing ownership of the boxed - /// installer. The index never dangles because both `add_installer` and `remove_installer` - /// clear the cache whenever `installers` changes. + /// instance itself; here we store an index instead. The index never dangles because both + /// `add_installer` and `remove_installer` clear the cache whenever `installers` changes. cache: IndexMap<String, usize>, notifiable_packages: IndexMap<String, Vec<PackageInterfaceHandle>>, loop_: std::rc::Rc<std::cell::RefCell<Loop>>, @@ -125,7 +127,7 @@ impl InstallationManager { /// Adds installer pub fn add_installer(&mut self, installer: Box<dyn InstallerInterface>) { - array_unshift(&mut self.installers, installer); + array_unshift(&mut self.installers, std::rc::Rc::from(installer)); self.cache = IndexMap::new(); } @@ -135,7 +137,7 @@ impl InstallationManager { let key = self .installers .iter() - .position(|inst| inst.as_ref() as *const dyn InstallerInterface as *const () == target); + .position(|inst| &**inst as *const dyn InstallerInterface as *const () == target); if let Some(k) = key { array_splice(&mut self.installers, k as i64, Some(1), vec![]); self.cache = IndexMap::new(); @@ -148,19 +150,22 @@ impl InstallationManager { /// disabling the PluginManager. This ensures that no third-party /// code is ever executed. pub fn disable_plugins(&mut self) { - for installer in self.installers.iter_mut() { - if let Some(plugin_installer) = installer.as_plugin_installer_mut() { + for installer in self.installers.iter() { + if let Some(plugin_installer) = installer.as_plugin_installer() { plugin_installer.disable_plugins(); } } } /// Returns installer for a specific package type. - pub fn get_installer(&mut self, r#type: &str) -> anyhow::Result<&mut dyn InstallerInterface> { + pub fn get_installer( + &mut self, + r#type: &str, + ) -> anyhow::Result<std::rc::Rc<dyn InstallerInterface>> { let r#type = strtolower(r#type); if let Some(&index) = self.cache.get(&r#type) { - return Ok(self.installers[index].as_mut()); + return Ok(self.installers[index].clone()); } let index = self @@ -169,7 +174,7 @@ impl InstallationManager { .position(|installer| installer.supports(&r#type)); if let Some(index) = index { self.cache.insert(r#type.clone(), index); - return Ok(self.installers[index].as_mut()); + return Ok(self.installers[index].clone()); } Err(InvalidArgumentException { @@ -416,17 +421,9 @@ impl InstallationManager { download_only: bool, all_operations: Vec<std::rc::Rc<dyn OperationInterface>>, ) -> anyhow::Result<()> { - // PHP: waitOnPromises() shows a ProgressBar while the concurrent downloads resolve. - // TODO(phase-c-promise): see the identical note in execute_batch — the single-threaded - // port downloads serially in this same loop, so only a 0% -> 100% jump is rendered after - // the loop instead of PHP's timing-driven intermediate snapshots. - let download_promise_count = operations - .values() - .filter(|op| { - let t = op.get_operation_type(); - t == "update" || t == "install" - }) - .count() as i64; + let mut promises: Vec< + std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>>>>, + > = vec![]; for (index, operation) in &operations { let op_type = operation.get_operation_type(); @@ -452,62 +449,58 @@ impl InstallationManager { } let installer = self.get_installer(&package.get_type())?; - // PHP: $cleanupPromises[$index] = function () use ($index, $installer, $type, $package) { + // PHP: $cleanupPromises[$index] = static function () use ($opType, $installer, $package, $initialPackage) { // if (null === $package->getInstallationSource()) { return \React\Promise\resolve(null); } - // return $installer->cleanup($type, $package); }; - // TODO(phase-c): the cleanup callable must capture the installer and package and invoke - // installer.cleanup(...) returning a React promise. It is a 'static closure stored in - // cleanup_promises, so installer/package must be Rc-shared (the installer registry is - // not Rc yet, see get_installer) and the promise type must be modelled. Both depend on - // the async/React-Promise rework, so a no-op future is stored instead. - let _ = installer; - let op_type_clone = op_type.clone(); + // return $installer->cleanup($opType, $package, $initialPackage); }; let cleanup: Box< dyn Fn() -> Option< std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>>>>, >, - > = Box::new(move || { - // avoid calling cleanup if the download was not even initialized for a package - // as without installation source configured nothing will work - // TODO(phase-b): if (null === $package->getInstallationSource()) return resolve(null); - let _ = &op_type_clone; - // TODO(phase-c-promise): build the real installer.cleanup() future once the installer - // can be shared into a 'static cleanup closure (Stage 2 Rc/Arc). - let fut: std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>>>> = - Box::pin(async { Ok(()) }); - Some(fut) - }); + > = { + let installer = installer.clone(); + let op_type = op_type.clone(); + let package = package.clone(); + let initial_package = initial_package.clone(); + Box::new(move || { + // avoid calling cleanup if the download was not even initialized for a package + // as without installation source configured nothing will work + if package.get_installation_source().is_none() { + let fut: std::pin::Pin< + Box<dyn std::future::Future<Output = anyhow::Result<()>>>, + > = Box::pin(async { Ok(()) }); + return Some(fut); + } + + 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) + .await + .map(|_| ()) + }); + Some(fut) + }) + }; cleanup_promises.insert(*index, cleanup); if op_type != "uninstall" { - // TODO(phase-c-promise): PHP collects every download and runs them concurrently via - // Loop::wait; the single-threaded loop awaits each serially instead. - let installer = self.get_installer(&package.get_type())?; - installer.download(package, initial_package).await?; + let installer = installer.clone(); + let package = package.clone(); + let initial_package = initial_package.clone(); + promises.push(Box::pin(async move { + installer.download(package, initial_package).await.map(|_| ()) + })); } } - if self.output_progress - && !Platform::get_env("CI").is_some_and(|v| !v.is_empty() && v != "0") - && !self.io.is_debug() - && download_promise_count > 1 - { - let bar = { - let io_ref = self.io.borrow(); - io_ref - .as_any() - .downcast_ref::<ConsoleIO>() - .map(|console_io| console_io.get_progress_bar(download_promise_count)) - }; - if let Some(mut bar) = bar { - bar.start(Some(download_promise_count))?; - bar.set_progress(download_promise_count)?; - bar.finish()?; - bar.clear()?; - if !self.io.is_decorated() { - self.io.write_error(""); - } - } + // execute all downloads first + if !promises.is_empty() { + self.wait_on_promises(promises).await?; } if download_only { @@ -1012,6 +1005,48 @@ impl InstallationManager { } } + /// PHP: waitOnPromises() creates a ProgressBar up front and Loop::wait advances it while the + /// concurrent promises resolve. + /// TODO(phase-c-promise): Loop::wait has no active-job counter to feed the bar yet, so a + /// single 0% -> 100% jump is rendered after the wait instead of PHP's timing-driven + /// intermediate snapshots. + async fn wait_on_promises( + &mut self, + promises: Vec< + std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<()>>>>, + >, + ) -> anyhow::Result<()> { + let promise_count = promises.len() as i64; + let show_progress = self.output_progress + && !Platform::get_env("CI").is_some_and(|v| !v.is_empty() && v != "0") + && !self.io.is_debug() + && promise_count > 1; + + let result = self.loop_.borrow_mut().wait(promises, None).await; + + if result.is_ok() && show_progress { + let bar = { + let io_ref = self.io.borrow(); + io_ref + .as_any() + .downcast_ref::<ConsoleIO>() + .map(|console_io| console_io.get_progress_bar(promise_count)) + }; + if let Some(mut bar) = bar { + bar.start(Some(promise_count))?; + bar.set_progress(promise_count)?; + bar.finish()?; + bar.clear()?; + // ProgressBar in non-decorated output does not output a final line-break and clear() does nothing + if !self.io.is_decorated() { + self.io.write_error(""); + } + } + } + + result + } + async fn run_cleanup( &mut self, cleanup_promises: &IndexMap< diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs index ff7708f1..3394f1e3 100644 --- a/crates/shirabe/src/installer/installer_interface.rs +++ b/crates/shirabe/src/installer/installer_interface.rs @@ -11,57 +11,57 @@ pub trait InstallerInterface: std::fmt::Debug { fn supports(&self, package_type: &str) -> bool; fn is_installed( - &mut self, + &self, repo: &dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> bool; async fn download( - &mut self, + &self, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn prepare( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn install( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn update( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn uninstall( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn cleanup( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String>; + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String>; - fn as_binary_presence_interface(&mut self) -> Option<&mut dyn BinaryPresenceInterface> { + fn as_binary_presence_interface(&self) -> Option<&dyn BinaryPresenceInterface> { None } - fn as_plugin_installer_mut(&mut self) -> Option<&mut PluginInstaller> { + fn as_plugin_installer(&self) -> Option<&PluginInstaller> { None } } diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs index c3ebad16..5baffc15 100644 --- a/crates/shirabe/src/installer/library_installer.rs +++ b/crates/shirabe/src/installer/library_installer.rs @@ -22,7 +22,9 @@ use shirabe_php_shim::{ #[derive(Debug)] pub struct LibraryInstaller { pub(crate) composer: PartialComposerWeakHandle, - pub(crate) vendor_dir: String, + /// Behind a RefCell so initialize_vendor_dir can canonicalize it through `&self` (the + /// installer instance is shared between concurrent package operations). + pub(crate) vendor_dir: std::cell::RefCell<String>, pub(crate) download_manager: Option<std::rc::Rc<std::cell::RefCell<dyn DownloadManagerInterface>>>, pub(crate) io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, @@ -93,7 +95,7 @@ impl LibraryInstaller { io, r#type, filesystem, - vendor_dir, + vendor_dir: std::cell::RefCell::new(vendor_dir), binary_installer, } } @@ -108,7 +110,7 @@ impl LibraryInstaller { } /// Make sure binaries are installed for a given package. - pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + pub fn ensure_binaries_presence(&self, package: PackageInterfaceHandle) { let install_path = self.get_install_path(package.clone()).unwrap(); self.binary_installer .borrow_mut() @@ -119,7 +121,7 @@ impl LibraryInstaller { /// /// It is used for BC as getInstallPath tends to be overridden by /// installer plugins but not getPackageBasePath - pub(crate) fn get_package_base_path(&mut self, package: PackageInterfaceHandle) -> String { + pub(crate) fn get_package_base_path(&self, package: PackageInterfaceHandle) -> String { let install_path = self.get_install_path(package.clone()).unwrap(); let target_dir = package.get_target_dir(); @@ -143,7 +145,7 @@ impl LibraryInstaller { /// @return PromiseInterface|null /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn install_code( - &mut self, + &self, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { let download_path = self.get_install_path(package.clone()).unwrap(); @@ -157,7 +159,7 @@ impl LibraryInstaller { /// @return PromiseInterface|null /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn update_code( - &mut self, + &self, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -188,7 +190,7 @@ impl LibraryInstaller { /// @return PromiseInterface|null /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn remove_code( - &mut self, + &self, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { let download_path = self.get_package_base_path(package.clone()); @@ -199,11 +201,12 @@ impl LibraryInstaller { .await } - pub(crate) fn initialize_vendor_dir(&mut self) { + pub(crate) fn initialize_vendor_dir(&self) { self.filesystem .borrow_mut() - .ensure_directory_exists(&self.vendor_dir); - self.vendor_dir = realpath(&self.vendor_dir).unwrap_or_default(); + .ensure_directory_exists(&self.vendor_dir.borrow()); + let realpath = realpath(&self.vendor_dir.borrow()).unwrap_or_default(); + *self.vendor_dir.borrow_mut() = realpath; } pub(crate) fn get_download_manager( @@ -237,7 +240,7 @@ impl InstallerInterface for LibraryInstaller { } fn is_installed( - &mut self, + &self, repo: &dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> bool { @@ -267,7 +270,7 @@ impl InstallerInterface for LibraryInstaller { } async fn download( - &mut self, + &self, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -281,7 +284,7 @@ impl InstallerInterface for LibraryInstaller { } async fn prepare( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -296,7 +299,7 @@ impl InstallerInterface for LibraryInstaller { } async fn cleanup( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -311,7 +314,7 @@ impl InstallerInterface for LibraryInstaller { } async fn install( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -339,7 +342,7 @@ impl InstallerInterface for LibraryInstaller { } async fn update( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, @@ -372,7 +375,7 @@ impl InstallerInterface for LibraryInstaller { } async fn uninstall( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -407,13 +410,14 @@ impl InstallerInterface for LibraryInstaller { Ok(None) } - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { self.initialize_vendor_dir(); + let vendor_dir = self.vendor_dir.borrow(); let base_path = format!( "{}{}", - if !self.vendor_dir.is_empty() { - format!("{}/", self.vendor_dir) + if !vendor_dir.is_empty() { + format!("{}/", vendor_dir) } else { String::new() }, @@ -432,13 +436,13 @@ impl InstallerInterface for LibraryInstaller { }) } - fn as_binary_presence_interface(&mut self) -> Option<&mut dyn BinaryPresenceInterface> { + fn as_binary_presence_interface(&self) -> Option<&dyn BinaryPresenceInterface> { Some(self) } } impl BinaryPresenceInterface for LibraryInstaller { - fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + fn ensure_binaries_presence(&self, package: PackageInterfaceHandle) { LibraryInstaller::ensure_binaries_presence(self, package); } } diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs index ae1f49bb..22abdab7 100644 --- a/crates/shirabe/src/installer/metapackage_installer.rs +++ b/crates/shirabe/src/installer/metapackage_installer.rs @@ -29,7 +29,7 @@ impl InstallerInterface for MetapackageInstaller { } fn is_installed( - &mut self, + &self, repo: &dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> bool { @@ -37,7 +37,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn download( - &mut self, + &self, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -45,7 +45,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn prepare( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -54,7 +54,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn cleanup( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -63,7 +63,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn install( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -79,7 +79,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn update( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, @@ -108,7 +108,7 @@ impl InstallerInterface for MetapackageInstaller { } async fn uninstall( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -131,7 +131,7 @@ impl InstallerInterface for MetapackageInstaller { Ok(None) } - fn get_install_path(&mut self, _package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { None } } diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs index 9b8aa087..62e5de78 100644 --- a/crates/shirabe/src/installer/noop_installer.rs +++ b/crates/shirabe/src/installer/noop_installer.rs @@ -15,7 +15,7 @@ impl InstallerInterface for NoopInstaller { } fn is_installed( - &mut self, + &self, repo: &dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> bool { @@ -23,7 +23,7 @@ impl InstallerInterface for NoopInstaller { } async fn download( - &mut self, + &self, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -31,7 +31,7 @@ impl InstallerInterface for NoopInstaller { } async fn prepare( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -40,7 +40,7 @@ impl InstallerInterface for NoopInstaller { } async fn cleanup( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -49,7 +49,7 @@ impl InstallerInterface for NoopInstaller { } async fn install( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -61,7 +61,7 @@ impl InstallerInterface for NoopInstaller { } async fn update( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, @@ -83,7 +83,7 @@ impl InstallerInterface for NoopInstaller { } async fn uninstall( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -99,7 +99,7 @@ impl InstallerInterface for NoopInstaller { Ok(None) } - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { let target_dir = package.get_target_dir(); let pretty_name = package.get_pretty_name(); diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs index 7ff5eb33..ca8864ab 100644 --- a/crates/shirabe/src/installer/plugin_installer.rs +++ b/crates/shirabe/src/installer/plugin_installer.rs @@ -38,13 +38,13 @@ impl PluginInstaller { } } - pub fn disable_plugins(&mut self) { + pub fn disable_plugins(&self) { // TODO(plugin): disable plugins via plugin manager self.get_plugin_manager().borrow_mut().disable_plugins(); } async fn rollback_install( - &mut self, + &self, e: anyhow::Error, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, @@ -78,7 +78,7 @@ impl InstallerInterface for PluginInstaller { } fn is_installed( - &mut self, + &self, repo: &dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> bool { @@ -86,7 +86,7 @@ impl InstallerInterface for PluginInstaller { } async fn prepare( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -114,7 +114,7 @@ impl InstallerInterface for PluginInstaller { } async fn download( - &mut self, + &self, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -134,7 +134,7 @@ impl InstallerInterface for PluginInstaller { } async fn install( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -148,7 +148,7 @@ impl InstallerInterface for PluginInstaller { } async fn update( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, @@ -164,7 +164,7 @@ impl InstallerInterface for PluginInstaller { } async fn uninstall( - &mut self, + &self, repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -177,7 +177,7 @@ impl InstallerInterface for PluginInstaller { } async fn cleanup( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -185,15 +185,15 @@ impl InstallerInterface for PluginInstaller { self.inner.cleanup(r#type, package, prev_package).await } - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { self.inner.get_install_path(package) } - fn as_binary_presence_interface(&mut self) -> Option<&mut dyn BinaryPresenceInterface> { - Some(&mut self.inner) + fn as_binary_presence_interface(&self) -> Option<&dyn BinaryPresenceInterface> { + Some(&self.inner) } - fn as_plugin_installer_mut(&mut self) -> Option<&mut PluginInstaller> { + fn as_plugin_installer(&self) -> Option<&PluginInstaller> { Some(self) } } diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs index 83ffbb24..0ca251c2 100644 --- a/crates/shirabe/src/installer/project_installer.rs +++ b/crates/shirabe/src/installer/project_installer.rs @@ -36,7 +36,7 @@ impl InstallerInterface for ProjectInstaller { } fn is_installed( - &mut self, + &self, _repo: &dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> bool { @@ -44,7 +44,7 @@ impl InstallerInterface for ProjectInstaller { } async fn download( - &mut self, + &self, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -69,7 +69,7 @@ impl InstallerInterface for ProjectInstaller { } async fn prepare( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -81,7 +81,7 @@ impl InstallerInterface for ProjectInstaller { } async fn cleanup( - &mut self, + &self, r#type: &str, package: PackageInterfaceHandle, prev_package: Option<PackageInterfaceHandle>, @@ -93,7 +93,7 @@ impl InstallerInterface for ProjectInstaller { } async fn install( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -104,7 +104,7 @@ impl InstallerInterface for ProjectInstaller { } async fn update( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _initial: PackageInterfaceHandle, _target: PackageInterfaceHandle, @@ -117,7 +117,7 @@ impl InstallerInterface for ProjectInstaller { } async fn uninstall( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -128,7 +128,7 @@ impl InstallerInterface for ProjectInstaller { .into()) } - fn get_install_path(&mut self, _package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { Some(self.install_path.clone()) } } |
