diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-27 00:49:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-27 00:54:09 +0900 |
| commit | cc5d73c05a0abca2eebcc8a6afa0b1543ee49850 (patch) | |
| tree | 091a0d01232d927f13f3ab22700701804980f231 /crates/shirabe/src/installer | |
| parent | c5850d62beabef0a6bcc4cf6a179589c0ba8f405 (diff) | |
| download | php-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.tar.gz php-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.tar.zst php-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.zip | |
refactor(package): pass package handles by value throughout
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/installer')
| -rw-r--r-- | crates/shirabe/src/installer/binary_installer.rs | 14 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/binary_presence_interface.rs | 4 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/installation_manager.rs | 64 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/installer_interface.rs | 25 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/library_installer.rs | 128 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/metapackage_installer.rs | 55 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/noop_installer.rs | 41 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/plugin_installer.rs | 29 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/project_installer.rs | 30 | ||||
| -rw-r--r-- | crates/shirabe/src/installer/suggested_packages_reporter.rs | 24 |
10 files changed, 183 insertions, 231 deletions
diff --git a/crates/shirabe/src/installer/binary_installer.rs b/crates/shirabe/src/installer/binary_installer.rs index a555d83..64908bf 100644 --- a/crates/shirabe/src/installer/binary_installer.rs +++ b/crates/shirabe/src/installer/binary_installer.rs @@ -11,7 +11,7 @@ use shirabe_php_shim::{ use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::Platform; use crate::util::ProcessExecutor; @@ -48,11 +48,11 @@ impl BinaryInstaller { pub fn install_binaries( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, install_path: &str, warn_on_overwrite: bool, ) { - let binaries = self.get_binaries(package); + let binaries = self.get_binaries(package.clone()); if binaries.is_empty() { return; } @@ -123,7 +123,7 @@ impl BinaryInstaller { } if bin_compat == "full" { - self.install_full_binaries(&bin_path, &link, bin, package); + self.install_full_binaries(&bin_path, &link, bin, package.clone()); } else { self.install_unixy_proxy_binaries(&bin_path, &link); } @@ -134,7 +134,7 @@ impl BinaryInstaller { } } - pub fn remove_binaries(&mut self, package: &dyn PackageInterface) { + pub fn remove_binaries(&mut self, package: PackageInterfaceHandle) { self.initialize_bin_dir(); let binaries = self.get_binaries(package); @@ -192,7 +192,7 @@ impl BinaryInstaller { } /// @return string[] - pub(crate) fn get_binaries(&self, package: &dyn PackageInterface) -> Vec<String> { + pub(crate) fn get_binaries(&self, package: PackageInterfaceHandle) -> Vec<String> { package.get_binaries() } @@ -201,7 +201,7 @@ impl BinaryInstaller { bin_path: &str, link: &str, bin: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) { let mut link = link.to_string(); // add unixy support for cygwin and similar environments diff --git a/crates/shirabe/src/installer/binary_presence_interface.rs b/crates/shirabe/src/installer/binary_presence_interface.rs index 8830bab..2c4b2cc 100644 --- a/crates/shirabe/src/installer/binary_presence_interface.rs +++ b/crates/shirabe/src/installer/binary_presence_interface.rs @@ -1,7 +1,7 @@ //! ref: composer/src/Composer/Installer/BinaryPresenceInterface.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub trait BinaryPresenceInterface { - fn ensure_binaries_presence(&self, package: &dyn PackageInterface); + 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 5f312b6..95a1870 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -134,25 +134,24 @@ impl InstallationManager { pub fn is_package_installed( &mut self, repo: &dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<bool> { if let Some(alias) = package.as_alias() { let alias_of: PackageInterfaceHandle = alias.get_alias_of().into(); return Ok( - repo.has_package(package.as_rc().borrow().as_package_interface()) - && self.is_package_installed(repo, &alias_of)?, + repo.has_package(package.clone()) && self.is_package_installed(repo, alias_of)? ); } Ok(self .get_installer(&package.get_type())? - .is_installed(repo, package.as_rc().borrow().as_package_interface())) + .is_installed(repo, package.clone())) } /// Install binary for the given package. /// If the installer associated to this package doesn't handle that function, it'll do nothing. - pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) { - let installer = self.get_installer(package.get_type()); + pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + let installer = self.get_installer(&package.get_type()); let installer = match installer { Ok(i) => i, Err(_e) => { @@ -212,7 +211,7 @@ impl InstallationManager { // TODO(phase-b): instanceof downcasts for UpdateOperation/InstallOperation let is_update_or_install = false; if is_update_or_install { - let package: Option<&dyn PackageInterface> = None; + let package: Option<PackageInterfaceHandle> = None; let _ = package; let extra: IndexMap<String, PhpMixed> = IndexMap::new(); if extra @@ -307,8 +306,8 @@ impl InstallationManager { continue; } - let package: &dyn PackageInterface; - let initial_package: Option<&dyn PackageInterface>; + let package: PackageInterfaceHandle; + let initial_package: Option<PackageInterfaceHandle>; // TODO(phase-b): downcast for UpdateOperation / Install/Mark/Uninstall variants let update_op: Option<&UpdateOperation> = None; if op_type == "update" { @@ -325,7 +324,7 @@ impl InstallationManager { package = operation.get_package(); initial_package = None; } - let installer = self.get_installer(package.get_type())?; + let installer = self.get_installer(&package.get_type())?; // TODO(phase-b): closure captures installer + package; needs Rc-shared installer/package let _ = installer; @@ -349,7 +348,7 @@ impl InstallationManager { 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())?; + let installer = self.get_installer(&package.get_type())?; installer.download(package, initial_package).await?; } } @@ -450,8 +449,8 @@ impl InstallationManager { continue; } - let package: &dyn PackageInterface; - let initial_package: Option<&dyn PackageInterface>; + let package: PackageInterfaceHandle; + let initial_package: Option<PackageInterfaceHandle>; let update_op: Option<&UpdateOperation> = None; if op_type == "update" { if let Some(_u) = update_op { @@ -488,7 +487,7 @@ impl InstallationManager { let _dispatcher = self.event_dispatcher.as_ref(); let _io = self.io.as_ref(); - let installer = self.get_installer(package.get_type())?; + let installer = self.get_installer(&package.get_type())?; // TODO(phase-c-promise): PHP chains prepare()->then(install/update/uninstall)->then(cleanup // + repo.write); the single-threaded loop awaits prepare and leaves the rest as phase-b work. installer @@ -526,8 +525,8 @@ impl InstallationManager { /// Executes download operation. /// /// @phpstan-return PromiseInterface<void|null>|null - pub async fn download(&mut self, package: &dyn PackageInterface) -> Option<PhpMixed> { - let installer = self.get_installer(package.get_type()).ok()?; + pub async fn download(&mut self, package: PackageInterfaceHandle) -> Option<PhpMixed> { + let installer = self.get_installer(&package.get_type()).ok()?; let promise = installer.cleanup("install", package, None).await.ok()?; promise @@ -541,11 +540,11 @@ impl InstallationManager { repo: &mut dyn InstalledRepositoryInterface, operation: &InstallOperation, ) -> Option<PhpMixed> { - let package = operation.get_package().clone(); + let package = operation.get_package(); let package_type = package.get_type(); let installer = self.get_installer(&package_type).ok()?; - let promise = installer.install(repo, &package).await.ok()?; - self.mark_for_notification(&package); + let promise = installer.install(repo, package.clone()).await.ok()?; + self.mark_for_notification(package.clone()); promise } @@ -566,19 +565,19 @@ impl InstallationManager { let promise = if initial_type == target_type { let installer = self.get_installer(&initial_type).ok()?; - let promise = installer.update(repo, &initial, &target).await.ok()?; - self.mark_for_notification(&target); + let promise = installer.update(repo, initial, target.clone()).await.ok()?; + self.mark_for_notification(target.clone()); promise } else { // PHP: uninstall initial, then install target via the target-type installer. let _ = self .get_installer(&initial_type) .ok()? - .uninstall(repo, &initial) + .uninstall(repo, initial) .await .ok()?; let installer = self.get_installer(&target_type).ok()?; - installer.install(repo, &target).await.ok()? + installer.install(repo, target).await.ok()? }; promise @@ -592,11 +591,11 @@ impl InstallationManager { repo: &mut dyn InstalledRepositoryInterface, operation: &UninstallOperation, ) -> Option<PhpMixed> { - let package = operation.get_package().clone(); + let package = operation.get_package(); let package_type = package.get_type(); let installer = self.get_installer(&package_type).ok()?; - installer.uninstall(repo, &package).await.ok()? + installer.uninstall(repo, package).await.ok()? } /// Executes markAliasInstalled operation. @@ -607,11 +606,8 @@ impl InstallationManager { ) { let package = operation.get_package(); - if !repo.has_package(package) { - // TODO(phase-c): MarkAliasInstalledOperation::get_package() yields a borrowed - // &AliasPackage; add_package now wants a shared PackageInterfaceHandle. - let package_handle: PackageInterfaceHandle = todo!(); - repo.add_package(package_handle); + if !repo.has_package(package.clone().into()) { + repo.add_package(package.into()); } } @@ -623,14 +619,14 @@ impl InstallationManager { ) { let package = operation.get_package(); - repo.remove_package(package); + repo.remove_package(package.clone().into()); } /// Returns the installation path of a package /// /// @return string|null absolute path to install to, which does not end with a slash, or null if the package does not have anything installed on disk - pub fn get_install_path(&mut self, package: &dyn PackageInterface) -> Option<String> { - let installer = self.get_installer(package.get_type()).ok()?; + pub fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + let installer = self.get_installer(&package.get_type()).ok()?; installer.get_install_path(package) } @@ -767,7 +763,7 @@ impl InstallationManager { self.reset(); } - fn mark_for_notification(&mut self, package: &PackageInterfaceHandle) { + fn mark_for_notification(&mut self, package: PackageInterfaceHandle) { if let Some(notification_url) = package.get_notification_url() { self.notifiable_packages .entry(notification_url) diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs index 8ab7efd..3056429 100644 --- a/crates/shirabe/src/installer/installer_interface.rs +++ b/crates/shirabe/src/installer/installer_interface.rs @@ -1,6 +1,5 @@ //! ref: composer/src/Composer/Installer/InstallerInterface.php -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use shirabe_php_shim::PhpMixed; @@ -12,49 +11,49 @@ pub trait InstallerInterface: std::fmt::Debug { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool; async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String>; + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String>; fn clone_box(&self) -> Box<dyn InstallerInterface> { todo!() diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs index 17ec8d4..c1fedef 100644 --- a/crates/shirabe/src/installer/library_installer.rs +++ b/crates/shirabe/src/installer/library_installer.rs @@ -15,7 +15,6 @@ use crate::installer::BinaryInstaller; use crate::installer::BinaryPresenceInterface; use crate::installer::InstallerInterface; use crate::io::IOInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use crate::util::Filesystem; @@ -100,8 +99,8 @@ impl LibraryInstaller { } /// Make sure binaries are installed for a given package. - pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) { - let install_path = self.get_install_path(package).unwrap(); + pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + let install_path = self.get_install_path(package.clone()).unwrap(); self.binary_installer .install_binaries(package, &install_path, false); } @@ -110,8 +109,8 @@ 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(&self, package: &dyn PackageInterface) -> String { - let install_path = self.get_install_path(package).unwrap(); + 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(); if let Some(target_dir) = target_dir { @@ -135,9 +134,9 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn install_code( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -149,11 +148,11 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn update_code( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let initial_download_path = self.get_install_path(initial).unwrap(); - let target_download_path = self.get_install_path(target).unwrap(); + let initial_download_path = self.get_install_path(initial.clone()).unwrap(); + let target_download_path = self.get_install_path(target.clone()).unwrap(); if target_download_path != initial_download_path { // if the target and initial dirs intersect, we force a remove + install // to avoid the rename wiping the target dir as part of the initial dir cleanup @@ -180,9 +179,9 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn remove_code( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let download_path = self.get_package_base_path(package); + let download_path = self.get_package_base_path(package.clone()); self.get_download_manager() .borrow() @@ -229,9 +228,9 @@ impl InstallerInterface for LibraryInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - if !repo.has_package(package) { + if !repo.has_package(package.clone()) { return false; } @@ -258,12 +257,12 @@ impl InstallerInterface for LibraryInstaller { async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -274,12 +273,12 @@ impl InstallerInterface for LibraryInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -290,12 +289,12 @@ impl InstallerInterface for LibraryInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -306,35 +305,23 @@ impl InstallerInterface for LibraryInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self - .get_install_path(package.as_rc().borrow().as_package_interface()) - .unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); // remove the binaries if it appears the package files are missing - if !Filesystem::is_readable(&download_path) - && repo.has_package(package.as_rc().borrow().as_package_interface()) - { - self.binary_installer - .remove_binaries(package.as_rc().borrow().as_package_interface()); + if !Filesystem::is_readable(&download_path) && repo.has_package(package.clone()) { + self.binary_installer.remove_binaries(package.clone()); } - let _ = self - .install_code(package.as_rc().borrow().as_package_interface()) - .await?; + let _ = self.install_code(package.clone()).await?; - let install_path = self - .get_install_path(package.as_rc().borrow().as_package_interface()) - .unwrap(); - self.binary_installer.install_binaries( - package.as_rc().borrow().as_package_interface(), - &install_path, - true, - ); - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + let install_path = self.get_install_path(package.clone()).unwrap(); + self.binary_installer + .install_binaries(package.clone(), &install_path, true); + if !repo.has_package(package.clone()) { repo.add_package(package.clone()); } @@ -344,10 +331,10 @@ impl InstallerInterface for LibraryInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -358,25 +345,14 @@ impl InstallerInterface for LibraryInstaller { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - self.binary_installer - .remove_binaries(initial.as_rc().borrow().as_package_interface()); - let _ = self - .update_code( - initial.as_rc().borrow().as_package_interface(), - target.as_rc().borrow().as_package_interface(), - ) - .await?; + self.binary_installer.remove_binaries(initial.clone()); + let _ = self.update_code(initial.clone(), target.clone()).await?; - let install_path = self - .get_install_path(target.as_rc().borrow().as_package_interface()) - .unwrap(); - self.binary_installer.install_binaries( - target.as_rc().borrow().as_package_interface(), - &install_path, - true, - ); - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - if !repo.has_package(target.as_rc().borrow().as_package_interface()) { + let install_path = self.get_install_path(target.clone()).unwrap(); + self.binary_installer + .install_binaries(target.clone(), &install_path, true); + repo.remove_package(initial.clone()); + if !repo.has_package(target.clone()) { repo.add_package(target.clone()); } @@ -386,9 +362,9 @@ impl InstallerInterface for LibraryInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, @@ -396,15 +372,11 @@ impl InstallerInterface for LibraryInstaller { .into()); } - let _ = self - .remove_code(package.as_rc().borrow().as_package_interface()) - .await?; + let _ = self.remove_code(package.clone()).await?; - let download_path = - self.get_package_base_path(package.as_rc().borrow().as_package_interface()); - self.binary_installer - .remove_binaries(package.as_rc().borrow().as_package_interface()); - repo.remove_package(package.as_rc().borrow().as_package_interface()); + let download_path = self.get_package_base_path(package.clone()); + self.binary_installer.remove_binaries(package.clone()); + repo.remove_package(package.clone()); if strpos(&package.get_name(), "/").map_or(false, |pos| pos != 0) { let package_vendor_dir = dirname(&download_path); @@ -421,7 +393,7 @@ impl InstallerInterface for LibraryInstaller { Ok(None) } - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); @@ -449,7 +421,7 @@ impl InstallerInterface for LibraryInstaller { } impl BinaryPresenceInterface for LibraryInstaller { - fn ensure_binaries_presence(&self, _package: &dyn PackageInterface) { + fn ensure_binaries_presence(&self, _package: PackageInterfaceHandle) { // TODO(phase-b): trait takes &self but LibraryInstaller::ensure_binaries_presence // requires &mut self due to BinaryInstaller::install_binaries(&mut self, ...). // Revisit the trait or use interior mutability. diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs index fe41dd3..820023b 100644 --- a/crates/shirabe/src/installer/metapackage_installer.rs +++ b/crates/shirabe/src/installer/metapackage_installer.rs @@ -7,7 +7,6 @@ use crate::installer::InstallerInterface; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::io::io_interface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use anyhow::Result; @@ -33,15 +32,15 @@ impl InstallerInterface for MetapackageInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - repo.has_package(package) + repo.has_package(package.clone()) } async fn download( &self, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -49,8 +48,8 @@ impl InstallerInterface for MetapackageInstaller { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -58,8 +57,8 @@ impl InstallerInterface for MetapackageInstaller { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -67,18 +66,15 @@ impl InstallerInterface for MetapackageInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.io.write_error3( - &format!( - " - {}", - InstallOperation::format(package.as_rc().borrow().as_package_interface(), false) - ), + &format!(" - {}", InstallOperation::format(package.clone(), false)), true, io_interface::NORMAL, ); - repo.add_package(package.clone()); + repo.add_package(package); Ok(None) } @@ -86,10 +82,10 @@ impl InstallerInterface for MetapackageInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -100,18 +96,14 @@ impl InstallerInterface for MetapackageInstaller { self.io.write_error3( &format!( " - {}", - UpdateOperation::format( - initial.as_rc().borrow().as_package_interface(), - target.as_rc().borrow().as_package_interface(), - false - ) + UpdateOperation::format(initial.clone(), target.clone(), false) ), true, io_interface::NORMAL, ); - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - repo.add_package(target.clone()); + repo.remove_package(initial.clone()); + repo.add_package(target); Ok(None) } @@ -119,9 +111,9 @@ impl InstallerInterface for MetapackageInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, @@ -130,20 +122,17 @@ impl InstallerInterface for MetapackageInstaller { } self.io.write_error3( - &format!( - " - {}", - UninstallOperation::format(package.as_rc().borrow().as_package_interface(), false) - ), + &format!(" - {}", UninstallOperation::format(package.clone(), false)), true, io_interface::NORMAL, ); - repo.remove_package(package.as_rc().borrow().as_package_interface()); + repo.remove_package(package.clone()); Ok(None) } - fn get_install_path(&self, _package: &dyn PackageInterface) -> 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 12e7e95..dad5231 100644 --- a/crates/shirabe/src/installer/noop_installer.rs +++ b/crates/shirabe/src/installer/noop_installer.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Installer/NoopInstaller.php use crate::installer::InstallerInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; @@ -18,15 +17,15 @@ impl InstallerInterface for NoopInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - repo.has_package(package) + repo.has_package(package.clone()) } async fn download( &self, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -34,8 +33,8 @@ impl InstallerInterface for NoopInstaller { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -43,8 +42,8 @@ impl InstallerInterface for NoopInstaller { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -52,9 +51,9 @@ impl InstallerInterface for NoopInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { repo.add_package(package.clone()); } @@ -64,10 +63,10 @@ impl InstallerInterface for NoopInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -75,8 +74,8 @@ impl InstallerInterface for NoopInstaller { .into()); } - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - if !repo.has_package(target.as_rc().borrow().as_package_interface()) { + repo.remove_package(initial.clone()); + if !repo.has_package(target.clone()) { repo.add_package(target.clone()); } @@ -86,28 +85,28 @@ impl InstallerInterface for NoopInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, } .into()); } - repo.remove_package(package.as_rc().borrow().as_package_interface()); + repo.remove_package(package.clone()); Ok(None) } - fn get_install_path(&self, package: &dyn PackageInterface) -> 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(); Some(if let Some(dir) = target_dir { format!("{}/{}", pretty_name, dir) } else { - pretty_name.to_string() + pretty_name }) } } diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs index deadcb7..38fcb0d 100644 --- a/crates/shirabe/src/installer/plugin_installer.rs +++ b/crates/shirabe/src/installer/plugin_installer.rs @@ -6,7 +6,6 @@ use crate::installer::InstallerInterface; use crate::installer::LibraryInstaller; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::plugin::PluginManager; use crate::repository::InstalledRepositoryInterface; @@ -47,7 +46,7 @@ impl PluginInstaller { &mut self, e: anyhow::Error, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<()> { self.inner.io.write_error(&format!( "Plugin initialization failed ({}), uninstalling plugin", @@ -72,7 +71,7 @@ impl InstallerInterface for PluginInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { self.inner.is_installed(repo, package) } @@ -80,8 +79,8 @@ impl InstallerInterface for PluginInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if (r#type == "install" || r#type == "update") && !self @@ -104,8 +103,8 @@ impl InstallerInterface for PluginInstaller { async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { let extra = package.get_extra(); let class = extra.get("class").cloned().unwrap_or(PhpMixed::Null); @@ -125,7 +124,7 @@ impl InstallerInterface for PluginInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.inner.install(repo, package).await?; @@ -139,8 +138,8 @@ impl InstallerInterface for PluginInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.inner.update(repo, initial, target).await?; @@ -155,12 +154,12 @@ impl InstallerInterface for PluginInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { // TODO(plugin): uninstall package from plugin manager self.get_plugin_manager() .borrow_mut() - .uninstall_package(package.as_rc().borrow().as_package_interface()); + .uninstall_package(package.clone()); self.inner.uninstall(repo, package).await } @@ -168,13 +167,13 @@ impl InstallerInterface for PluginInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner.cleanup(r#type, package, prev_package).await } - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { self.inner.get_install_path(package) } } diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs index 129810b..6c8a279 100644 --- a/crates/shirabe/src/installer/project_installer.rs +++ b/crates/shirabe/src/installer/project_installer.rs @@ -2,7 +2,6 @@ use crate::downloader::DownloadManager; use crate::installer::InstallerInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use crate::util::Filesystem; @@ -39,15 +38,15 @@ impl InstallerInterface for ProjectInstaller { fn is_installed( &self, _repo: &dyn InstalledRepositoryInterface, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, ) -> bool { false } async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { let install_path = &self.install_path; if std::path::Path::new(install_path).exists() @@ -72,8 +71,8 @@ impl InstallerInterface for ProjectInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() @@ -84,8 +83,8 @@ impl InstallerInterface for ProjectInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() @@ -96,22 +95,19 @@ impl InstallerInterface for ProjectInstaller { async fn install( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() - .install( - package.as_rc().borrow().as_package_interface(), - &self.install_path, - ) + .install(package, &self.install_path) .await } async fn update( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - _initial: &PackageInterfaceHandle, - _target: &PackageInterfaceHandle, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Err(InvalidArgumentException { message: "not supported".to_string(), @@ -123,7 +119,7 @@ impl InstallerInterface for ProjectInstaller { async fn uninstall( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - _package: &PackageInterfaceHandle, + _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Err(InvalidArgumentException { message: "not supported".to_string(), @@ -132,7 +128,7 @@ impl InstallerInterface for ProjectInstaller { .into()) } - fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { Some(self.install_path.clone()) } } diff --git a/crates/shirabe/src/installer/suggested_packages_reporter.rs b/crates/shirabe/src/installer/suggested_packages_reporter.rs index 8faae9c..087e1b5 100644 --- a/crates/shirabe/src/installer/suggested_packages_reporter.rs +++ b/crates/shirabe/src/installer/suggested_packages_reporter.rs @@ -2,7 +2,7 @@ use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepository; use crate::repository::RepositoryInterface; use indexmap::IndexMap; @@ -41,8 +41,8 @@ impl SuggestedPackagesReporter { self } - pub fn add_suggestions_from_package(&mut self, package: &dyn PackageInterface) -> &mut Self { - let source = package.get_pretty_name().to_string(); + pub fn add_suggestions_from_package(&mut self, package: PackageInterfaceHandle) -> &mut Self { + let source = package.get_pretty_name(); for (target, reason) in package.get_suggests() { self.add_package(source.clone(), target.clone(), reason.clone()); } @@ -54,9 +54,10 @@ impl SuggestedPackagesReporter { &self, mode: i64, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) { - let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of); + let suggested_packages = + self.get_filtered_suggestions(installed_repo, only_dependents_of.clone()); let mut suggesters: IndexMap<String, IndexMap<String, String>> = IndexMap::new(); let mut suggested: IndexMap<String, IndexMap<String, String>> = IndexMap::new(); @@ -142,7 +143,7 @@ impl SuggestedPackagesReporter { pub fn output_minimalistic( &self, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) { let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of); if !suggested_packages.is_empty() { @@ -156,7 +157,7 @@ impl SuggestedPackagesReporter { fn get_filtered_suggestions( &self, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) -> Vec<IndexMap<String, String>> { let suggested_packages = self.get_packages(); let mut installed_names: Vec<String> = Vec::new(); @@ -168,13 +169,14 @@ impl SuggestedPackagesReporter { let mut source_filter: Vec<String> = Vec::new(); if let Some(only_dependents_of) = only_dependents_of { - source_filter = only_dependents_of - .get_requires() + let requires = only_dependents_of.get_requires(); + let dev_requires = only_dependents_of.get_dev_requires(); + source_filter = requires .values() - .chain(only_dependents_of.get_dev_requires().values()) + .chain(dev_requires.values()) .map(|link| link.get_target().to_string()) .collect(); - source_filter.push(only_dependents_of.get_name().to_string()); + source_filter.push(only_dependents_of.get_name()); } let mut suggestions: Vec<IndexMap<String, String>> = Vec::new(); |
