diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-04 03:03:10 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-04 05:43:20 +0900 |
| commit | 6cb1849473792bd73dbfb6265d363f149f687572 (patch) | |
| tree | 78f02030ac91929f449072d504673e9e6a21e2a2 /crates/shirabe/src/command | |
| parent | a02fc7d728a9973a3275a0f47604081c4439b424 (diff) | |
| download | php-shirabe-6cb1849473792bd73dbfb6265d363f149f687572.tar.gz php-shirabe-6cb1849473792bd73dbfb6265d363f149f687572.tar.zst php-shirabe-6cb1849473792bd73dbfb6265d363f149f687572.zip | |
fix(plugin): resolve review findings in the plugin activation flow
InstallationManager::execute now takes &self (the mock recorder moved
into a RefCell) and its callers hold only shared borrows: plugin
registration inside a batch re-enters the same manager handle through
Composer::getInstallationManager()->getInstallPath(), which panicked
on the RefCell re-borrow under the &mut shape — the same re-entrancy
the repository side already fixed, unreachable from the ported tests
because they call PluginInstaller::install directly like PHPUnit does.
The worker-side InstalledVersions mirror now matches the full tail of
FilesystemRepository::write: unconditional reload plus the
reflection-based selfDir/installedIsLocalDir restore. The previous
class_exists(false) guard rested on a lazy-load assumption that does
not hold in the worker (its real ClassLoader only knows the Composer
checkout's vendor dir, so a later lazy load would read the checkout's
installed.php, not the project's); the mirror is now skipped only when
the class is not autoloadable at all, i.e. no plugin runtime and hence
no observer code. Boot-time seeding stays TODO(plugin).
Also from the review: registered_plugins entries are removed only
after the deactivate/uninstall loop (PHP unsets last, and a throw must
leave the entry observable); extra.class keeps associative-array
values and fails loudly on non-strings instead of silently dropping
them; the two discarded write() results now propagate (they carry the
reload-push failure); register_package's allow-plugins skip message is
DEBUG like the addPlugin side; the loader-eviction divergence of
REGISTERED_LOADERS and the lossy UTF-8 spots carry searchable
markers; the test-only proxy downcast follows the __ naming rule; the
R-table dispatch clones the entity out instead of holding the table
borrow across the handler; the IO/PartialComposer stubs turn a
plugin-side `new NullIO()` into an explicit error instead of an
ArgumentCountError; and the empty() emulation covers float 0.0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/command')
| -rw-r--r-- | crates/shirabe/src/command/create_project_command.rs | 16 | ||||
| -rw-r--r-- | crates/shirabe/src/command/reinstall_command.rs | 4 |
2 files changed, 13 insertions, 7 deletions
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs index a907bc09..1e289b08 100644 --- a/crates/shirabe/src/command/create_project_command.rs +++ b/crates/shirabe/src/command/create_project_command.rs @@ -1008,20 +1008,26 @@ impl CreateProjectCommand { let project_installer = ProjectInstaller::new(&directory, dm.clone(), fs); let installation_manager = composer.get_installation_manager().clone(); - let mut im = installation_manager.borrow_mut(); - im.set_output_progress(!no_progress); - im.add_installer(Box::new(project_installer)); + { + let mut im = installation_manager.borrow_mut(); + im.set_output_progress(!no_progress); + im.add_installer(Box::new(project_installer)); + } let installed_repo = crate::repository::InstalledRepositoryInterfaceHandle::new( InstalledArrayRepository::new()?, ); - im.execute( + // A shared borrow: plugin registration inside execute re-enters this manager handle + // through the Composer graph. + installation_manager.borrow().execute( &installed_repo, vec![InstallOperation::new(package.clone()).into()], true, true, false, )?; - im.notify_installs(io.clone()); + installation_manager + .borrow_mut() + .notify_installs(io.clone()); // collect suggestions self.suggested_packages_reporter diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs index 0d3567a2..05543870 100644 --- a/crates/shirabe/src/command/reinstall_command.rs +++ b/crates/shirabe/src/command/reinstall_command.rs @@ -247,14 +247,14 @@ impl Command for ReinstallCommand { let repo = crate::repository::InstalledRepositoryInterfaceHandle::from_repository_handle( &local_repo, ); - installation_manager.borrow_mut().execute( + installation_manager.borrow().execute( &repo, uninstall_operations, dev_mode, true, false, )?; - installation_manager.borrow_mut().execute( + installation_manager.borrow().execute( &repo, install_operations.clone(), dev_mode, |
