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/tests | |
| 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/tests')
4 files changed, 38 insertions, 38 deletions
diff --git a/crates/shirabe/tests/autoload/autoload_generator_test.rs b/crates/shirabe/tests/autoload/autoload_generator_test.rs index 1f702e9c..9e41e3dd 100644 --- a/crates/shirabe/tests/autoload/autoload_generator_test.rs +++ b/crates/shirabe/tests/autoload/autoload_generator_test.rs @@ -38,7 +38,7 @@ impl InstallerInterface for InstallPathStubInstaller { } fn is_installed( - &mut self, + &self, _repo: &dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> bool { @@ -46,7 +46,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn download( - &mut self, + &self, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -54,7 +54,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn prepare( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -63,7 +63,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn install( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -71,7 +71,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn update( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _initial: PackageInterfaceHandle, _target: PackageInterfaceHandle, @@ -80,7 +80,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn uninstall( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -88,7 +88,7 @@ impl InstallerInterface for InstallPathStubInstaller { } async fn cleanup( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -96,7 +96,7 @@ impl InstallerInterface for InstallPathStubInstaller { Ok(None) } - fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { if package.get_type() == "metapackage" { return None; } diff --git a/crates/shirabe/tests/installer/installation_manager_test.rs b/crates/shirabe/tests/installer/installation_manager_test.rs index e24f440c..3ed2f25b 100644 --- a/crates/shirabe/tests/installer/installation_manager_test.rs +++ b/crates/shirabe/tests/installer/installation_manager_test.rs @@ -52,16 +52,16 @@ mockall::mock! { pub Installer { fn supports(&self, package_type: &str) -> bool; fn install( - &mut self, + &self, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; fn update( - &mut self, + &self, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; fn uninstall( - &mut self, + &self, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; } @@ -74,7 +74,7 @@ impl InstallerInterface for MockInstaller { } fn is_installed( - &mut self, + &self, _repo: &dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> bool { @@ -82,7 +82,7 @@ impl InstallerInterface for MockInstaller { } async fn download( - &mut self, + &self, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -90,7 +90,7 @@ impl InstallerInterface for MockInstaller { } async fn prepare( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -99,7 +99,7 @@ impl InstallerInterface for MockInstaller { } async fn install( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -107,7 +107,7 @@ impl InstallerInterface for MockInstaller { } async fn update( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, initial: PackageInterfaceHandle, target: PackageInterfaceHandle, @@ -116,7 +116,7 @@ impl InstallerInterface for MockInstaller { } async fn uninstall( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -124,7 +124,7 @@ impl InstallerInterface for MockInstaller { } async fn cleanup( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -132,7 +132,7 @@ impl InstallerInterface for MockInstaller { Ok(None) } - fn get_install_path(&mut self, _package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { None } } @@ -174,7 +174,7 @@ impl InstallerInterface for BinaryInstaller { } fn is_installed( - &mut self, + &self, _repo: &dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> bool { @@ -182,7 +182,7 @@ impl InstallerInterface for BinaryInstaller { } async fn download( - &mut self, + &self, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { @@ -190,7 +190,7 @@ impl InstallerInterface for BinaryInstaller { } async fn prepare( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -199,7 +199,7 @@ impl InstallerInterface for BinaryInstaller { } async fn install( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -207,7 +207,7 @@ impl InstallerInterface for BinaryInstaller { } async fn update( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _initial: PackageInterfaceHandle, _target: PackageInterfaceHandle, @@ -216,7 +216,7 @@ impl InstallerInterface for BinaryInstaller { } async fn uninstall( - &mut self, + &self, _repo: &mut dyn InstalledRepositoryInterface, _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { @@ -224,7 +224,7 @@ impl InstallerInterface for BinaryInstaller { } async fn cleanup( - &mut self, + &self, _type: &str, _package: PackageInterfaceHandle, _prev_package: Option<PackageInterfaceHandle>, @@ -232,17 +232,17 @@ impl InstallerInterface for BinaryInstaller { Ok(None) } - fn get_install_path(&mut self, _package: PackageInterfaceHandle) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { None } - 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 BinaryInstaller { - fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + fn ensure_binaries_presence(&self, package: PackageInterfaceHandle) { self.calls .borrow_mut() .ensure_binaries_presence diff --git a/crates/shirabe/tests/installer/library_installer_test.rs b/crates/shirabe/tests/installer/library_installer_test.rs index f2a94cbf..b9e3caa8 100644 --- a/crates/shirabe/tests/installer/library_installer_test.rs +++ b/crates/shirabe/tests/installer/library_installer_test.rs @@ -196,7 +196,7 @@ fn test_installer_creation_should_not_create_bin_directory() { #[test] fn test_is_installed() { let mut setup = set_up(); - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); let package = get_package("test/pkg", "1.0.0"); @@ -237,7 +237,7 @@ fn test_install() { .returning(|_, _| Ok(None)); set_download_manager(&setup, dm); - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); let mut repository = InstalledArrayRepository::new().unwrap(); @@ -296,7 +296,7 @@ fn test_update() { repository.add_package(initial.clone()).unwrap(); // The default Filesystem is fine; the LibraryInstaller's own filesystem performs the rename. - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); run(library.update(&mut repository, initial.clone(), target.clone())).unwrap(); @@ -344,7 +344,7 @@ fn test_uninstall() { .returning(|_, _| Ok(None)); set_download_manager(&setup, dm); - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); // PHP mocks hasPackage to return (true, false) over two calls; a real repository @@ -366,7 +366,7 @@ fn test_uninstall() { #[test] fn test_get_install_path_without_target_dir() { let mut setup = set_up(); - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); let package = get_package("Vendor/Pkg", "1.0.0"); @@ -381,7 +381,7 @@ fn test_get_install_path_without_target_dir() { #[test] fn test_get_install_path_with_target_dir() { let mut setup = set_up(); - let mut library = + let library = LibraryInstaller::new(setup.io.clone(), setup.composer.clone(), None, None, None); let package = get_package("Foo/Bar", "1.0.0"); package.__set_target_dir(Some("Some/Namespace".to_string())); diff --git a/crates/shirabe/tests/installer/metapackage_installer_test.rs b/crates/shirabe/tests/installer/metapackage_installer_test.rs index 3380befb..3c1f0efe 100644 --- a/crates/shirabe/tests/installer/metapackage_installer_test.rs +++ b/crates/shirabe/tests/installer/metapackage_installer_test.rs @@ -19,7 +19,7 @@ fn installer() -> MetapackageInstaller { #[test] fn test_install() { let package = get_package("test/pkg", "1.0.0"); - let mut installer = installer(); + let installer = installer(); let mut repository = InstalledArrayRepository::new_with_packages(vec![]).unwrap(); run(installer.install(&mut repository, package.clone())).unwrap(); @@ -31,7 +31,7 @@ fn test_install() { fn test_update() { let initial = get_package("test/initial", "1.0.0"); let target = get_package("test/target", "1.0.1"); - let mut installer = installer(); + let installer = installer(); let mut repository = InstalledArrayRepository::new_with_packages(vec![initial.clone()]).unwrap(); @@ -47,7 +47,7 @@ fn test_update() { #[test] fn test_uninstall() { let package = get_package("test/pkg", "1.0.0"); - let mut installer = installer(); + let installer = installer(); let mut repository = InstalledArrayRepository::new_with_packages(vec![package.clone()]).unwrap(); |
