aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-rpc/php/stubs/Composer/Package
AgeCommit message (Collapse)Author
2026-08-07fix(plugin): make proxy stub property access an explicit errornsfisis
A proxy stub declares none of the real class's instance properties, and the `__get`/`__set` forwarders were emitted only for classes that declare a public one. Every other property access therefore got PHP's own answer for an undeclared property — null on a read, a dynamic property on a write — so plugin code reading state the entity holds ran on with null and failed somewhere else entirely, or not at all. Emit the forwarders on every root stub, add `__isset`/`__unset` alongside them so `isset()` cannot answer false silently either, and serve all four from one dispatcher that answers the state the Rust-side entity exposes and rejects every other name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07feat(plugin): cross alias packages over RPC as proxy stubsnsfisis
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>
2026-08-06feat(plugin): widen the RPC surface to LibraryInstaller-based pluginsnsfisis
An installer that extends LibraryInstaller reaches for the Composer object graph in ways the proxy did not answer: the download manager and the config, the writable repository methods, a React promise as its own return value, and `new Package(...)` from its supports() path. * `Composer::getConfig`/`getDownloadManager` are dispatched, and both classes become generated proxy stubs. Their reads and mutators answer from the Rust entity; the surfaces needing stubs of their own (ConfigSourceInterface, DownloaderInterface) stay explicit errors. * The download manager's futures are driven to completion and handed back as already-settled React promises, since PHP declares a non-nullable PromiseInterface there. A promise a plugin returns is drained the same way: settled yields its value, rejected re-raises, pending is an explicit error. * Proxy stubs now carry the real class's constructor and ask the Rust side to allocate the entity; reviving a stub for an existing entity binds the handle without running it. Classes Rust cannot build name themselves in the error. * The package proxy covers `Package`'s own setters, `CompletePackage`'s metadata, `RootPackage`'s root-only state, and `BasePackage::$id`. Link values and release dates still have no wire image, so the methods carrying them remain explicit errors.
2026-08-06feat(plugin): run plugin-provided installers through the RPC workernsfisis
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>
2026-08-04feat(plugin): generate proxy stubs for the package and repository graphnsfisis
Emit the eleven stubs a subscriber plugin's object-graph calls reach (BasePackage through RootPackage, the installed-repository hierarchy, RepositoryManager, InstallationManager). The generator learns the member kinds these classes need: builtin interfaces contribute no closure entries, public static properties are materialized, public instance properties forward through __get/__set, __toString forwards like a plain method, __clone throws (proxy clone semantics are still an open design question), and a subclass stub may add interfaces to its inherited surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>