| Age | Commit message (Collapse) | Author |
|
Replace the hand-written proxy stubs under crates/shirabe-php-rpc/php/stubs
with output of scripts/plugin-stub-generator, a deterministic emitter that
derives every stub from the Composer checkout and the classifier report.
Anything it cannot faithfully proxy (by-ref/variadic parameters, magic
methods, public properties, diverging omitted overrides, stale stub files,
a STUB_FILES entry missing in lib.rs) fails generation instead of degrading
silently, so future Composer releases surface new members as explicit
errors rather than silent gaps.
Regenerating the stubs also normalizes the hand-written inconsistencies
(uniform guarded constructors, import-based type spellings) and fixes real
gaps the review of the generated diff uncovered: the BaseIO authentication
methods now carry the real class's untyped signatures, and the previously
missing ConsoleIO::sanitize is materialized together with its private
static helper. A cargo test runs generate-stubs --check to keep the
committed stubs, the generator and the embedded list from drifting apart.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
The audit in .ken/php-shim-copying.md judged 14 functions in
shirabe-php-shim (plus php_wordwrap in shirabe-external-packages) to be
line-by-line transcriptions or structural imitations of php-src. PHP's
relicensing to 3-clause BSD makes keeping them legal, but the boundary
between BSD-derived and MIT code was invisible in the source tree.
Moving them into their own crate puts the license into the build
metadata (so NOTICE generation follows the binary), makes a reverse
dependency a compile error, and encodes the origin in the module path,
which mirrors php-src's ext tree. Each function records its origin in a
fixed-format doc comment, and a new php_src_derivation_boundary linter
fails if `php-src` appears in any Rust source outside the crate.
Public paths under shirabe_php_shim:: are unchanged: functions that are
themselves derived are re-exported with `pub use`, and the wrappers that
only validate arguments stay on the MIT side.
This also resolves the duplicate wordwrap implementation.
shirabe_php_shim::wordwrap was todo!(), so SymfonyStyle::block panicked,
while shirabe-external-packages carried its own copy. Both now go
through the single port, verified against real PHP on 13 cases covering
multi-character breaks and cut.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The reachability closure only consults @phpstan-return/@param/@var
docblocks when the native type is array/iterable/mixed/object/absent.
For a concrete wrapper class whose payload is expressed only via a
phpstan generic (PromiseInterface<Process>), the payload type was
silently dropped: Symfony\Component\Process\Process never appeared as
reached even though ProcessExecutor::executeAsync() hands one to
plugin callbacks. Treat known generic wrapper types the same as
array/iterable/mixed/object so their docblock payload is folded into
the closure.
|
|
Answers how a given class is treated at the plugin boundary, accepting a
PHP source file, a Rust source file, or a (short or fully qualified)
class name. Reads report.json and generates it first when missing. Rust
paths resolve by normalized segment matching because the snake_case
mapping is not reversible for acronyms (io_interface.rs -> IOInterface).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Decides, for every composer/composer class, how it is treated at the
plugin boundary (rust-proxy / rust-snapshot / contract / two-world /
php-native / unsupported) so that upstream updates re-classify new or
rewritten classes without re-deriving the design by hand. Rules and
category definitions live in docs/dev/plugin-class-classification.md;
the tool (PHP + nikic/PHP-Parser) implements them as a reachability
closure with direction marks, per-method pure/mutator analysis, and a
leaf-first fixed point for unreachable classes, with three small
versioned exception lists.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Benchmarks were comparing against whatever composer happened to be on
PATH instead of the pinned submodule version, and paid the HTTP/3
fallback penalty from composer/composer#12987 on every packagist
request.
|
|
Fold scripts/lint and scripts/linters/*.rb into a standalone Composer
project under scripts/linters/, matching the scripts/plugin-class-classifier/
convention. Uses no external packages, only PHP + Composer autoloading.
Verified byte-for-byte identical output against the original Ruby
implementation, both on the current repo (all linters pass) and on a
synthetic fixture exercising every violation type.
Entry point moves from `scripts/lint` to `scripts/linters/lint`.
|
|
A dead worker and a live one hitting a framing bug both surface as a
raw socket I/O error (e.g. "Broken pipe"), which doesn't say whether
the child crashed, was signaled, or is still running. Query the
child's exit status via try_wait() and attach it as anyhow::Context
so the panic message shows the root cause directly.
|
|
The earlier measurements documented in the perf notes were taken with
--no-audit to keep the security-advisories request out of the timings,
but the flag never landed in the committed script. Add it so future
runs are comparable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
regex::Regex::clone() does not share the underlying meta engine's
search-cache pool, so every fresh clone pays a ~10us warmup cost on
its first use. Two changes together eliminate this across nearly all
preg_* call sites:
- A php_regex! macro resolves PHP-style patterns to a per-call-site
&'static regex::Regex (via regex-macro's LazyLock), applied at the
majority of call sites throughout the codebase.
- Call sites still passing dynamic pattern strings go through
PATTERN_CACHE, which now stores Arc<(Regex, bool)> and hands out
Arc::clone()s instead of cloning the Regex itself.
PregPattern::resolve() returns a ResolvedPattern enum (Arc or
'static reference) rather than an owned Regex, so neither path ever
clones the Regex proper.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Lighter-weight companion to scripts/bench/create-project.sh: compares
shirabe vs composer on dependency resolution alone (require --no-install
--no-audit), skipping the download/install step that dominates
create-project's runtime.
|
|
|
|
|
|
Extends no_banned_use to cover std::any::Any, std::io::Read/Write, and
std::process::Command, and teaches the linter to allow `as _` imports
so trait methods can still be brought into scope without binding the
banned name. Fully qualifies all existing usages across the codebase.
|
|
Add a no_banned_use linter that forbids importing anyhow::Result, and
update all call sites to reference it via its fully-qualified path so
it is never confused with std::result::Result.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|