Description
Problem
There is currently no unified command in dev-tools to run static analysis. Each project must manually configure and execute tools like PHPStan or Psalm, which leads to:
- inconsistent workflows across repositories
- duplicated configuration effort
- lack of standardization in CI pipelines
- fragmented developer experience compared to existing commands like ecs and rector
Given that dev-tools already centralizes code style (ecs) and automated refactoring (rector), static analysis is the missing third pillar.
Proposal
Introduce a new command:
composer analyse
Alias:
dev-tools analyse
Goals
- provide a single, standardized entry point for static analysis
- align with the existing philosophy of dev-tools
- minimize per-project configuration
- support CI-friendly execution and consistent exit codes
Scope (Phase 1)
The initial implementation should focus on PHPStan as the primary engine.
Example usage:
dev-tools analyse
dev-tools analyse --level=8
dev-tools analyse --memory-limit=512M
dev-tools analyse --format=json
dev-tools analyse --configuration=phpstan.neon
Responsibilities
- run PHPStan using project or default configuration
- allow overriding analysis level via --level
- allow memory control via --memory-limit
- support different output formats (table, json, etc.)
- return proper exit codes for CI usage
Future Extension (Phase 2)
Support additional engines such as Psalm via an extensible interface:
dev-tools analyse --engine=phpstan
dev-tools analyse --engine=psalm
dev-tools analyse --engine=all
Important:
- do NOT assume PHPStan and Psalm are interchangeable
- avoid forcing a shared abstraction that hides important differences
- engine-specific flags should be handled explicitly
Expected Behavior
- running
dev-tools analyse executes static analysis with sensible defaults
- errors are clearly reported in a normalized output
- exit code is non-zero when issues are found
- CLI options override configuration when provided
Implementation Strategy
1. PHPStan wrapper (Phase 1)
use Symfony\Component\Process\Process to execute:
vendor/bin/phpstan analyse
- map CLI options directly:
--level
--memory-limit
--configuration
--error-format
2. Output handling
- stream output directly to the console
- optionally normalize or decorate output in future iterations
3. Extensible architecture
Design the command so additional engines can be added without rewriting core logic.
Requirements
- must work out-of-the-box with PHPStan installed
- must fail with a clear error message if PHPStan is missing
- must not require additional configuration for basic usage
- must be deterministic and CI-friendly
- must preserve exit codes from underlying tools
Non-goals
- replacing PHPStan or Psalm configuration systems
- forcing a unified abstraction over fundamentally different analyzers
- auto-installing dependencies
Benefits
- standardizes static analysis across projects
- reduces setup and onboarding time
- improves CI consistency
- aligns with existing dev-tools commands (ecs, rector)
- creates a foundation for future multi-engine analysis
Additional Context
PHPStan provides native support for CLI options such as level selection and memory limits, making it a natural first choice for integration. Psalm can be added later with a more explicit engine-based model rather than forcing a one-size-fits-all interface.
Acceptance Criteria
- a new command dev-tools analyse is available and executable via Composer
- the command runs PHPStan by default
- supports at least:
--level
--memory-limit
--configuration
--format (or equivalent PHPStan flag)
- returns non-zero exit code when errors are found
- prints analysis results clearly to the console
- the implementation is extensible to support additional engines (e.g. Psalm) in the future
Architecture / Isolation Requirements
- the static analysis logic must be isolated into dedicated classes instead of being implemented directly in the command
- responsibilities must be clearly separated, for example:
- one class for resolving which analysis engine to run
- one class for building the process/command arguments for PHPStan
- one class for executing the analysis process
- one class for handling and formatting output
- the command must act only as an orchestrator and must not contain core business logic
- the design must allow adding new engines (e.g. Psalm) without modifying existing core logic significantly
- the implementation must make it straightforward to extract the analysis logic into an external reusable package in the future
- the core logic must avoid tight coupling to CLI I/O so it can be reused in other contexts
Description
Problem
There is currently no unified command in dev-tools to run static analysis. Each project must manually configure and execute tools like PHPStan or Psalm, which leads to:
Given that dev-tools already centralizes code style (ecs) and automated refactoring (rector), static analysis is the missing third pillar.
Proposal
Introduce a new command:
composer analyseAlias:
dev-tools analyseGoals
Scope (Phase 1)
The initial implementation should focus on PHPStan as the primary engine.
Example usage:
Responsibilities
Future Extension (Phase 2)
Support additional engines such as Psalm via an extensible interface:
Important:
Expected Behavior
dev-tools analyseexecutes static analysis with sensible defaultsImplementation Strategy
1. PHPStan wrapper (Phase 1)
use
Symfony\Component\Process\Processto execute:vendor/bin/phpstan analyse--level--memory-limit--configuration--error-format2. Output handling
3. Extensible architecture
Design the command so additional engines can be added without rewriting core logic.
Requirements
Non-goals
Benefits
Additional Context
PHPStan provides native support for CLI options such as level selection and memory limits, making it a natural first choice for integration. Psalm can be added later with a more explicit engine-based model rather than forcing a one-size-fits-all interface.
Acceptance Criteria
--level--memory-limit--configuration--format(or equivalent PHPStan flag)Architecture / Isolation Requirements