aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/installer
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-06 01:50:34 +0900
committernsfisis <nsfisis@gmail.com>2026-08-06 01:50:34 +0900
commit4de018826e9dce90fd5cb78d468641478327ec99 (patch)
tree0843f7e3e8c50886c8470ace17fcb6fed937be4f /crates/shirabe/tests/installer
parentda602f1cb1d555c7826fa3d026df66b82061cda4 (diff)
downloadphp-shirabe-4de018826e9dce90fd5cb78d468641478327ec99.tar.gz
php-shirabe-4de018826e9dce90fd5cb78d468641478327ec99.tar.zst
php-shirabe-4de018826e9dce90fd5cb78d468641478327ec99.zip
feat(plugin): run plugin-provided installers through the RPC worker
A plugin can now hand an InstallerInterface implementation to InstallationManager::addInstaller across the wire, and a legacy composer-installer package is loaded as one; both are backed by a PhpInstallerProxy forwarding the whole installer contract to the entity in the PHP worker. An installer returning a real promise is an explicit error until promises can cross the boundary. InstallationManager takes installers as shared handles instead of boxes, so the object identity removeInstaller and PluginManager's registeredPlugins compare against survives registration, and holds them in a RefCell: Installer::run keeps a shared borrow of the manager for the whole run, and a plugin activated inside it registers its installer from there. The type cache keys on the installer itself, like upstream, so re-entrant registration cannot leave a stale index behind. InstallerInterface::supports is fallible for the same reason getCapabilities and getCommands are: it answers over RPC. Cloning a proxy stub clones the Rust-side entity and rebinds the copy to the fresh handle. Previously only the classes declaring __clone got a throwing body, and the rest let two stubs share (and twice release) one handle. Package entities answer with AnyPackage::dup, which already carries BasePackage::__clone and the RootAliasPackage override; the others are an explicit error. The package proxy covers the whole PackageInterface surface; only the link maps and the release date still lack a wire image for their value objects. PluginManager gains a test-only seam for the reported Plugin API version, and the three PluginInstallerTest cases that need it are ported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/tests/installer')
-rw-r--r--crates/shirabe/tests/installer/installation_manager_test.rs42
1 files changed, 21 insertions, 21 deletions
diff --git a/crates/shirabe/tests/installer/installation_manager_test.rs b/crates/shirabe/tests/installer/installation_manager_test.rs
index 8f2d7d4f..c511703e 100644
--- a/crates/shirabe/tests/installer/installation_manager_test.rs
+++ b/crates/shirabe/tests/installer/installation_manager_test.rs
@@ -67,8 +67,8 @@ mockall::mock! {
#[async_trait::async_trait(?Send)]
impl InstallerInterface for MockInstaller {
- fn supports(&self, package_type: &str) -> bool {
- MockInstaller::supports(self, package_type)
+ fn supports(&self, package_type: &str) -> anyhow::Result<bool> {
+ Ok(MockInstaller::supports(self, package_type))
}
fn is_installed(
@@ -163,12 +163,12 @@ impl BinaryInstaller {
#[async_trait::async_trait(?Send)]
impl InstallerInterface for BinaryInstaller {
- fn supports(&self, package_type: &str) -> bool {
+ fn supports(&self, package_type: &str) -> anyhow::Result<bool> {
self.calls
.borrow_mut()
.supports_args
.push(package_type.to_string());
- package_type == "library"
+ Ok(package_type == "library")
}
fn is_installed(
@@ -272,10 +272,10 @@ fn test_add_get_installer() {
.times(2)
.returning(|arg| arg == "vendor");
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(installer));
+ manager.add_installer(std::rc::Rc::new(installer));
assert!(manager.get_installer("vendor").is_ok());
assert!(manager.get_installer("unregistered").is_err());
@@ -290,7 +290,7 @@ fn test_add_remove_installer() {
.times(2)
.returning(|arg| arg == "vendor");
// The manager stores installers as Rc, so the PHP object-identity semantics (assertSame,
- // removeInstaller) map to Rc::ptr_eq on a handle registered via __add_installer.
+ // removeInstaller) map to Rc::ptr_eq on the handle the caller keeps.
let installer: std::rc::Rc<dyn InstallerInterface> = std::rc::Rc::new(installer);
let mut installer2 = MockInstaller::new();
@@ -300,15 +300,15 @@ fn test_add_remove_installer() {
.returning(|arg| arg == "vendor");
let installer2: std::rc::Rc<dyn InstallerInterface> = std::rc::Rc::new(installer2);
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.__add_installer(installer.clone());
+ manager.add_installer(installer.clone());
assert!(std::rc::Rc::ptr_eq(
&installer,
&manager.get_installer("vendor").unwrap()
));
- manager.__add_installer(installer2.clone());
+ manager.add_installer(installer2.clone());
assert!(std::rc::Rc::ptr_eq(
&installer2,
&manager.get_installer("vendor").unwrap()
@@ -352,9 +352,9 @@ fn test_install() {
.withf_st(move |package| same_handle(package, &expected))
.returning(|_| Ok(None));
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(installer));
+ manager.add_installer(std::rc::Rc::new(installer));
let operation = InstallOperation::new(package);
@@ -385,9 +385,9 @@ fn test_update_with_equal_types() {
})
.returning(|_, _| Ok(None));
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(installer));
+ manager.add_installer(std::rc::Rc::new(installer));
let operation = UpdateOperation::new(initial, target);
@@ -427,10 +427,10 @@ fn test_update_with_not_equal_types() {
.withf_st(move |package| same_handle(package, &expected_target))
.returning(|_| Ok(None));
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(lib_installer));
- manager.add_installer(Box::new(bundle_installer));
+ manager.add_installer(std::rc::Rc::new(lib_installer));
+ manager.add_installer(std::rc::Rc::new(bundle_installer));
let operation = UpdateOperation::new(initial, target);
@@ -457,9 +457,9 @@ fn test_uninstall() {
.withf_st(move |package| same_handle(package, &expected))
.returning(|_| Ok(None));
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(installer));
+ manager.add_installer(std::rc::Rc::new(installer));
let operation = UninstallOperation::new(package);
@@ -472,9 +472,9 @@ fn test_uninstall() {
fn test_install_binary() {
let set_up = set_up();
let (installer, calls) = BinaryInstaller::new();
- let mut manager =
+ let manager =
shirabe::installer::InstallationManager::new(set_up.loop_.clone(), set_up.io.clone(), None);
- manager.add_installer(Box::new(installer));
+ manager.add_installer(std::rc::Rc::new(installer));
let package = get_package("test/pkg", "1.0.0");
manager.ensure_binaries_presence(package.clone());