tomasvotruba/phpstan-bodyscan
PHPStan Bodyscan is a PHPStan extension that scans PHP method bodies for issues and surfaces them during static analysis. It helps catch body-level code problems early and fits easily into an existing PHPStan setup.
What it is: tomasvotruba/phpstan-bodyscan is a dev-only CLI tool that scans class bodies and reports type-declaration coverage (params, returns, properties) so teams can ratchet toward higher PHPStan levels incrementally. It is not a Laravel package in the service-provider sense — there is no runtime footprint, no config publish, no facade. It is a Composer dev dependency that shells out over the codebase using PHPStan's parser/reflection layer. TPM framing: treat it as a developer-productivity / code-quality instrument, not an application dependency.
Architecture fit: Strong for teams already standardized on PHPStan. It complements rather than replaces PHPStan — PHPStan enforces correctness at a level, bodyscan quantifies how far you are from the next level and produces a work queue. Fits a "ratchet, don't big-bang" modernization strategy for legacy Laravel codebases. Poor fit if PHPStan is not already adopted; it adds a second static-analysis surface without a foundation.
Integration feasibility (0.2.0): Two changes are directly relevant to CI adoption:
app/ trees) and reduces the need for per-job php -d memory_limit overrides in CI config. Low risk, purely permissive.--json output — the highest-leverage change in this release. It converts the tool from a human-readable report into a machine-consumable metric, enabling CI gating, artifact capture, trend dashboards, and per-directory sharding. This is the feature that makes the tool governable by a platform team rather than an individual enthusiast.Neither change is breaking; 0.2.0 is additive relative to 0.1.2.
Technical risk:
phpstan/phpstan are the most likely integration failure. Validate in a scratch branch before touching the main CI pipeline.--json ships without a stated stability contract. Any dashboard built on it must tolerate schema drift.Key questions for the maintainer / spike:
php.ini / --memory-limit?--json schema versioned or documented? What is the compatibility promise?phpstan/phpstan and nikic/php-parser version ranges does 0.2.0 accept?phpstan.neon paths / excludes_analyse, or does it need a separate path list?Stack fit: Composer require-dev, PHP 8.x, works across Laravel 9–11 without version coupling. Runs as a peer to phpstan, pint, rector, and php-cs-fixer in the same CI stage. Zero production impact, zero deploy risk, no container or infra change.
Migration path: Greenfield — nothing to migrate. The only "migration" is social: getting teams to act on the output. Do not position it as a mandate in v1; position it as a visibility tool with a published baseline.
Compatibility: Confirm the PHP matrix (dev containers, CI image, and any developer on an older local PHP) and confirm no lockfile conflict with the existing PHPStan pin. Budget half a day for a dependency-resolution spike on the largest repo before committing.
Sequencing (recommended, ~4–6 weeks end-to-end):
--json, uploads the artifact, and never fails the build. Establishes history and surfaces runtime cost in CI minutes.Explicit non-goal: do not gate on absolute coverage percentage in the first quarter. It punishes legacy modules and generates the political resistance that kills these tools.
Maintenance: Low steady-state. One pinned dev dependency, one CI job. Cost is dominated by (a) the 0.x changelog review on each bump and (b) JSON schema drift if a dashboard is built on it. Mitigation: pin exact version, Dependabot with manual review, and a thin adapter layer between the raw JSON and the dashboard so schema changes are absorbed in one file.
Support & ownership: Assign to the platform / developer-experience team, not to individual feature teams. Expect low inbound volume — the tool is read-only and non-blocking by design. Documentation burden is internal: a short README on how to run it locally and interpret the report. Note that 0.2.0's release notes are terse; do not expect upstream docs to fill the gap on JSON semantics.
Scaling: The raised memory limit is the release's main scaling enabler, and it matters most for large monorepos and big app/ trees — precisely where the analysis cost is highest. Runtime scales with codebase size, so plan for sharding by directory once the repo exceeds roughly the point where the job dominates CI wall-clock. --json makes sharding tractable: run N jobs, merge artifacts. Track CI minutes as a first-class cost; static analysis jobs on large repos can quietly become the top CI consumer.
Failure modes to instrument:
composer update, blocking unrelated work. Pin and test upgrades in a branch.excludes_analyse or the path list omits modules, coverage looks better than reality. Audit the analyzed path set once per quarter.Ramp-up: Low. Any PHP developer can run it in minutes; the learning curve is in interpreting output and negotiating thresholds, not in the tooling. Budget ~2 hours per engineer for the first run and ~1 hour of team-level calibration per directory when setting ratchet targets. TPM should own the ratchet schedule and the definition of "regression," since that is a policy decision, not a technical one.
How can I help you explore Laravel packages today?