From 0020a39197a53a14c130ee12759e8cb9002636ef Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 27 Jun 2026 21:12:20 +0900 Subject: feat(installer): register default installers after Composer Rc is built LibraryInstaller and PluginInstaller upgrade the Composer back-reference in their constructors, so they could not be built inside Rc::new_cyclic where the weak handle is not yet upgradeable. Defer create_default_ installers until after the cyclic Rc is established, where the weak handle resolves, and implement it to register Library -> Plugin -> Metapackage with a single shared BinaryInstaller. To share one BinaryInstaller (as Composer does), LibraryInstaller's binary_installer becomes Rc> instead of an owned Box; PluginInstaller and the __set_binary_installer test seam follow. This clears "Unknown installer type: metapackage". Un-ignores the six remove tests that now pass; the remaining install/remove tests are re-labeled for the next blocker (InstallationManager::execute_batch still leaves the install/cleanup/repo.write promise chain as a todo!() stub, so package operations do not actually execute). Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/shirabe/src/installer/library_installer.rs | 71 ++++++++++++++--------- crates/shirabe/src/installer/plugin_installer.rs | 5 +- 2 files changed, 45 insertions(+), 31 deletions(-) (limited to 'crates/shirabe/src/installer') diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs index 96f38c7..26fbf0e 100644 --- a/crates/shirabe/src/installer/library_installer.rs +++ b/crates/shirabe/src/installer/library_installer.rs @@ -30,7 +30,7 @@ pub struct LibraryInstaller { pub(crate) io: std::rc::Rc>, pub(crate) r#type: Option, pub(crate) filesystem: std::rc::Rc>, - pub(crate) binary_installer: Box, + pub(crate) binary_installer: std::rc::Rc>, } impl LibraryInstaller { @@ -40,7 +40,7 @@ impl LibraryInstaller { composer: PartialComposerWeakHandle, r#type: Option, filesystem: Option>>, - binary_installer: Option, + binary_installer: Option>>, ) -> Self { let composer_rc = composer .upgrade() @@ -62,31 +62,32 @@ impl LibraryInstaller { .unwrap_or_default(), Some("/"), ); - let binary_installer: Box = match binary_installer { - Some(binary_installer) => Box::new(binary_installer), - None => { - let bin_dir = rtrim( - &composer_ref + let binary_installer: std::rc::Rc> = + match binary_installer { + Some(binary_installer) => binary_installer, + None => { + let bin_dir = rtrim( + &composer_ref + .get_config() + .borrow_mut() + .get_str("bin-dir") + .unwrap_or_default(), + Some("/"), + ); + let bin_compat = composer_ref .get_config() .borrow_mut() - .get_str("bin-dir") - .unwrap_or_default(), - Some("/"), - ); - let bin_compat = composer_ref - .get_config() - .borrow_mut() - .get_str("bin-compat") - .unwrap_or_default(); - Box::new(BinaryInstaller::new( - io.clone(), - bin_dir, - bin_compat, - Some(filesystem.clone()), - Some(vendor_dir.clone()), - )) - } - }; + .get_str("bin-compat") + .unwrap_or_default(); + std::rc::Rc::new(std::cell::RefCell::new(BinaryInstaller::new( + io.clone(), + bin_dir, + bin_compat, + Some(filesystem.clone()), + Some(vendor_dir.clone()), + ))) + } + }; Self { composer, @@ -101,7 +102,10 @@ impl LibraryInstaller { /// For testing only: swap the binary installer for a recording double, mirroring the /// constructor injection PHPUnit performs with a mocked BinaryInstaller. - pub fn __set_binary_installer(&mut self, binary_installer: Box) { + pub fn __set_binary_installer( + &mut self, + binary_installer: std::rc::Rc>, + ) { self.binary_installer = binary_installer; } @@ -109,6 +113,7 @@ impl LibraryInstaller { pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { let install_path = self.get_install_path(package.clone()).unwrap(); self.binary_installer + .borrow_mut() .install_binaries(package, &install_path, false); } @@ -317,13 +322,16 @@ impl InstallerInterface for LibraryInstaller { // remove the binaries if it appears the package files are missing if !Filesystem::is_readable(&download_path) && repo.has_package(package.clone()) { - self.binary_installer.remove_binaries(package.clone()); + self.binary_installer + .borrow_mut() + .remove_binaries(package.clone()); } let _ = self.install_code(package.clone()).await?; let install_path = self.get_install_path(package.clone()).unwrap(); self.binary_installer + .borrow_mut() .install_binaries(package.clone(), &install_path, true); if !repo.has_package(package.clone()) { repo.add_package(PackageInterfaceHandle::dup(&package)); @@ -348,11 +356,14 @@ impl InstallerInterface for LibraryInstaller { self.initialize_vendor_dir(); - self.binary_installer.remove_binaries(initial.clone()); + self.binary_installer + .borrow_mut() + .remove_binaries(initial.clone()); let _ = self.update_code(initial.clone(), target.clone()).await?; let install_path = self.get_install_path(target.clone()).unwrap(); self.binary_installer + .borrow_mut() .install_binaries(target.clone(), &install_path, true); repo.remove_package(initial.clone()); if !repo.has_package(target.clone()) { @@ -378,7 +389,9 @@ impl InstallerInterface for LibraryInstaller { let _ = self.remove_code(package.clone()).await?; let download_path = self.get_package_base_path(package.clone()); - self.binary_installer.remove_binaries(package.clone()); + self.binary_installer + .borrow_mut() + .remove_binaries(package.clone()); repo.remove_package(package.clone()); if strpos(&package.get_name(), "/").is_some_and(|pos| pos != 0) { diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs index cd4de0a..28e4e0d 100644 --- a/crates/shirabe/src/installer/plugin_installer.rs +++ b/crates/shirabe/src/installer/plugin_installer.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Installer/PluginInstaller.php use crate::composer::PartialComposerWeakHandle; -use crate::installer::BinaryInstaller; use crate::installer::BinaryPresenceInterface; use crate::installer::InstallerInterface; use crate::installer::LibraryInstaller; @@ -25,7 +24,9 @@ impl PluginInstaller { io: std::rc::Rc>, composer: PartialComposerWeakHandle, fs: Option>>, - binary_installer: Option, + binary_installer: Option< + std::rc::Rc>, + >, ) -> Self { Self { inner: LibraryInstaller::new( -- cgit v1.3.1