aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-07 20:51:59 +0900
committernsfisis <nsfisis@gmail.com>2026-08-07 22:23:23 +0900
commitc82da84ae1a8cee23670a74a646584ab637308d1 (patch)
tree1c985827e9d85d11c1d8b5ded70f5cd424c1a60b /scripts
parent18a37a098157a98edbc8473e9c0d8dff3e8a88fa (diff)
downloadphp-shirabe-c82da84ae1a8cee23670a74a646584ab637308d1.tar.gz
php-shirabe-c82da84ae1a8cee23670a74a646584ab637308d1.tar.zst
php-shirabe-c82da84ae1a8cee23670a74a646584ab637308d1.zip
feat(installer): dispatch package eventsHEADmain
InstallationManager left both PRE_PACKAGE_* and POST_PACKAGE_* as empty stubs, so a subscriber never ran at all and the difference from upstream was silent rather than an explicit error. Operations cross the boundary as R-table entities with generated proxy stubs. Materializing them the way a Link crosses is not possible: a materialized value is revived by unserialize() on the child side, so its properties never pass through the wire decoder and a nested handle descriptor would not come back as a stub — and an operation always holds a PackageInterface. execute() now shares one Rc per operation through the whole batch pipeline, so a plugin sees one object for both the pre- and the post-event of an operation, as it does in PHP. POST_PACKAGE_* also moves out of the operation's promise chain into the post-exec callback list PHP runs after waitOnPromises(). The stub generator materializes non-public class constants verbatim now, which the operation classes need for their `protected const TYPE`: a constant has no entity behind it, so a copy in the worker cannot diverge, and keeping the declared visibility exposes nothing the real class hides. The E2E fixture added here compares the recorded events against upstream Composer. It also surfaced that upstream starts an operation's chain where it is built (a null prepare() becomes an already-fulfilled React promise whose handlers run through the immediately drained queue) while this port only drives its futures in wait_on_promises, so the repository state a pre-event observes differs; that half of the comparison is a separate `#[ignore]`d test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/plugin-stub-generator/generate-stubs5
-rw-r--r--scripts/plugin-stub-generator/src/Generator.php7
-rw-r--r--scripts/plugin-stub-generator/targets.list7
3 files changed, 13 insertions, 6 deletions
diff --git a/scripts/plugin-stub-generator/generate-stubs b/scripts/plugin-stub-generator/generate-stubs
index 934577f3..5db83a27 100755
--- a/scripts/plugin-stub-generator/generate-stubs
+++ b/scripts/plugin-stub-generator/generate-stubs
@@ -117,8 +117,9 @@ foreach ($iterator as $entry) {
}
}
-// The Rust side embeds every stub with include_str!; the two lists must not drift apart.
-$libRsText = (string) file_get_contents($libRs);
+// The Rust side embeds every stub with include_str!; the two lists must not drift apart. The
+// whitespace is squeezed out first because rustfmt wraps a long include_str! across lines.
+$libRsText = preg_replace('/\s+/', '', (string) file_get_contents($libRs));
foreach ($files as $relative => $_) {
if (!str_contains($libRsText, "include_str!(\"../php/stubs/$relative\")")) {
$problems[] = "STUB_FILES in $libRs does not embed $relative";
diff --git a/scripts/plugin-stub-generator/src/Generator.php b/scripts/plugin-stub-generator/src/Generator.php
index 12967787..dd62da60 100644
--- a/scripts/plugin-stub-generator/src/Generator.php
+++ b/scripts/plugin-stub-generator/src/Generator.php
@@ -220,12 +220,11 @@ final class Generator
}
}
+ // Constants are compile-time data with no entity behind them, so the declaration is
+ // copied verbatim, visibility included: a local copy cannot diverge from the entity,
+ // and nothing that was unreadable in the real class becomes readable here.
$constants = [];
foreach ($class->getConstants() as $constant) {
- if (!$constant->isPublic()) {
- $this->errors[] = "$fqcn declares a non-public constant; materializing it is not supported";
- continue;
- }
$constants[] = $file->verbatim($constant->getStartLine(), $constant->getEndLine());
}
diff --git a/scripts/plugin-stub-generator/targets.list b/scripts/plugin-stub-generator/targets.list
index 347680d2..411b9e3b 100644
--- a/scripts/plugin-stub-generator/targets.list
+++ b/scripts/plugin-stub-generator/targets.list
@@ -26,3 +26,10 @@ Composer\Repository\FilesystemRepository
Composer\Repository\InstalledFilesystemRepository
Composer\Repository\RepositoryManager
Composer\Installer\InstallationManager
+Composer\Installer\PackageEvent
+Composer\DependencyResolver\Operation\SolverOperation
+Composer\DependencyResolver\Operation\InstallOperation
+Composer\DependencyResolver\Operation\UpdateOperation
+Composer\DependencyResolver\Operation\UninstallOperation
+Composer\DependencyResolver\Operation\MarkAliasInstalledOperation
+Composer\DependencyResolver\Operation\MarkAliasUninstalledOperation