| Age | Commit message (Collapse) | Author |
|
AliasPackage, CompleteAliasPackage and RootAliasPackage now have generated
proxy stubs, so a package handed to a plugin no longer has to be a real
package: it crosses as the stub matching its concrete variant, answers
getAliasOf / setRootPackageAlias / isRootPackageAlias /
hasSelfVersionRequires, and can be constructed from plugin code.
The setters RootPackageInterface declares are routed through that interface
for every root package instead of through the base Package state. Only the
alias variant needs it -- RootAliasPackage overrides all nine to write
through to the package it aliases -- but a real RootPackage delegates to the
same base state either way, so both take one path.
An alias of an alias has no representation here, so narrowing the
constructor argument to a real package is an explicit error rather than a
silent demotion.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The link getters and setters and the release date accessors were explicit
errors for every non-empty value, because an immutable value has no entity
to point a handle at. They now cross as materialized values: the descriptor
names the real class and the constructor arguments, and each side builds a
genuine instance of its own.
The semver constraint a link holds is encoded structurally rather than
re-parsed from its string form, so the pretty strings and the conjunctive
flag survive the crossing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The fixture project pins composer/installers 2.3.0 and requires two packages
of framework-specific types, so the plugin's LibraryInstaller subclass decides
where they land. Upstream Composer and Shirabe install the same project and
the whole resulting tree is compared.
The plugin tarball is fetched by `fixtures/e2e-installers/fetch` into a
git-ignored directory and pinned by a digest over the extracted files, so the
third-party source never enters this repository and the test skips itself
while the directory is absent. The tree is staged and only moved into place
once verified, so an unverified tree is never observable under the name the
test looks for.
|
|
The fixture plugin registers an InstallerInterface implementation of its own
and installs a package of a custom type with it, recording every contract
call it receives. A fresh install produces a byte-identical project tree on
both implementations, trace included.
A second test pins the divergence a re-run and a `remove` expose: the two
implementations consult getInstaller at different points, so the trace
order — and its length once `remove` re-creates the Composer instance —
differs. It is written in full and marked ignored rather than trimmed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The pinned plugin and its real dependency tree (nine packages, fetched by
commit and verified by tree hash into the git-ignored ext/) install under
both implementations, and the list/help renderings of the plugin-provided
normalize command must match upstream byte for byte. The execution
comparison is written but ignored: NormalizeCommand builds a second,
in-process Composer instance, and the worker's proxy stubs reject native
construction of the classes that path instantiates. Stale comments about
the missing worker-side application are updated to the current facts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
A Shirabe-authored CommandProvider fixture plugin (greet) runs under both
implementations: exit codes, the command's own output, help/list rendering,
alias resolution, a validation failure, and a file recording the shared
object graph the command observed (root package, strict application FQCN,
and the exit code of the built-in about command it invoked) must match.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Run upstream Composer and Shirabe over pristine copies of a fixture
project at the same path and require composer.lock, the whole vendor tree
(including the plugin-generated GeneratedConfig.php), the plugin's IO
lines and the exit code to match byte for byte.
The plugin under test (phpstan/extension-installer 1.4.3) is downloaded by
fixtures/e2e/fetch — pinned to an upstream commit and hash-verified — into
a git-ignored directory rather than committed; the test skips while it is
absent, like the other real-PHP prerequisites. Its dependencies are
minimal stand-ins resolved from local repositories, so test runs stay
offline. A zip dist would exercise the known lossy-string byte-precision
debt in RemoteFilesystem, so the fixture serves the plugin through a path
dist until that is resolved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Wires the addPlugin subscriber branch end to end: EventSubscriberInterface
and Capable become fallible and dyn-compatible (their sole implementor is
the PHP plugin proxy, which answers getSubscribedEvents over RPC), listeners
register as Callable::PhpMethod and are invoked with a per-call event handle,
and the R table now drops entries when a child-side stub destructs. The R
table keeps its IndexMap with monotonically increasing handles, so released
handles are never reused and no generation counter is needed.
Upstream has no subscriber-plugin test, so the path is covered by a
Shirabe-owned fixture exercising all three getSubscribedEvents shapes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|