chore: install rector with accept-current-state baseline
Installs rector/rector ^2.0 (v2.4.2) + driftingly/rector-laravel ^2.0 as dev-dependencies. Configures PHP 8.2 language sets + safe quality rule sets (CODE_QUALITY, DEAD_CODE, EARLY_RETURN, TYPE_DECLARATION, PRIVATIZATION) + Laravel-specific sets (LARAVEL_CODE_QUALITY, LARAVEL_COLLECTION). Dry-run baseline: 487 rule-applications across 357 files. NO changes applied in this commit — adoption is incremental via per- set sprints documented in BACKLOG.md. Top rules by volume: 103 AddClosureVoidReturnTypeWhereNoReturnRector 71 AddArrowFunctionReturnTypeRector 51 AppToResolveRector 34 ConvertStaticToSelfRector 27 ReadOnlyClassRector 18 NullToStrictStringFuncCallArgRector 16 ReturnBinaryOrToEarlyReturnRector 16 MakeModelAttributesAndScopesProtectedRector 13 RemoveUnusedVariableAssignRector 13 OptionalToNullsafeOperatorRector 13 FlipTypeControlToUseExclusiveTypeRector Composer scripts: - composer rector — DRY-RUN (default) - composer rector:apply — apply changes - composer rector:clear-cache — clear Rector cache Dry-run exits with code 2 when suggestions exist (Rector convention, not an error state). Apply-mode exits 0 on clean runs. Documentation: /dev-docs/RECTOR.md added; CLAUDE.md updated. Backlog: per-set application sprints seeded (TECH-RECTOR-01..05 + TECH-RECTOR-CI). DEAD_CODE (smallest scope) and TYPE_DECLARATION (biggest volume, will help reduce Larastan baseline) are the natural first two. Disruptive sets deliberately deferred: - LaravelLevelSetList::UP_TO_LARAVEL_* — broad bulk upgrades - SetList::NAMING — high-churn variable renames - SetList::INSTANCEOF — substantial logic changes Memory limit 2G (dry-run completed within it). No production behavior change. No code modified — Rector ran dry-run only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
94
dev-docs/RECTOR.md
Normal file
94
dev-docs/RECTOR.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Rector (automated refactoring)
|
||||
|
||||
Modernisation tool for the Crewli backend. Provides automated
|
||||
refactoring against PHP-version and Laravel-version rule sets.
|
||||
|
||||
## Running locally
|
||||
|
||||
- `composer rector` — DRY-RUN. Lists proposed changes, modifies
|
||||
nothing. Default mode for safety. Exit code is 2 when suggestions
|
||||
exist, 0 when the codebase is clean — this is Rector's convention
|
||||
and NOT an error state.
|
||||
- `composer rector:apply` — APPLIES changes. Use only inside a
|
||||
scoped reduction sprint with a planned set of rule-applications.
|
||||
- `composer rector:clear-cache` — clear Rector cache.
|
||||
|
||||
Memory: 2G default. Bump to 4G if OOM.
|
||||
|
||||
## The dry-run-then-apply model
|
||||
|
||||
Rector configuration in `rector.php` defines the rule sets that
|
||||
SHOULD apply. `composer rector` reports what WOULD change without
|
||||
modifying code. `composer rector:apply` actually performs the
|
||||
changes.
|
||||
|
||||
### Rules
|
||||
|
||||
1. **Default workflow is dry-run.** Never run `composer rector:apply`
|
||||
outside a scoped reduction sprint. Mass-applying produces
|
||||
unreviewable PRs.
|
||||
2. **One rule-set per sprint.** Pick `SetList::DEAD_CODE` (or
|
||||
similar) for one PR. Apply, review, regenerate baselines,
|
||||
commit. Then move to the next set.
|
||||
3. **Run all tests + Larastan after each apply.** Rector is
|
||||
deterministic but rule-set interactions can produce surprises
|
||||
(e.g., `TYPE_DECLARATION` may surface new Larastan errors that
|
||||
were previously hidden by dynamic typing).
|
||||
|
||||
## Currently configured rule sets
|
||||
|
||||
PHP language:
|
||||
- `withPhpSets(php82: true)` — language features up to PHP 8.2
|
||||
|
||||
Quality:
|
||||
- `SetList::CODE_QUALITY`
|
||||
- `SetList::DEAD_CODE`
|
||||
- `SetList::EARLY_RETURN`
|
||||
- `SetList::TYPE_DECLARATION`
|
||||
- `SetList::PRIVATIZATION`
|
||||
|
||||
Laravel:
|
||||
- `LaravelSetList::LARAVEL_CODE_QUALITY`
|
||||
- `LaravelSetList::LARAVEL_COLLECTION`
|
||||
|
||||
**Not yet enabled** (deferred to specific reduction sprints):
|
||||
- `LaravelLevelSetList::UP_TO_LARAVEL_*` — disruptive bulk upgrades
|
||||
- `SetList::NAMING` — reformats variable names; high churn
|
||||
- `SetList::INSTANCEOF` — substantial logic changes
|
||||
|
||||
Add a set during a reduction sprint by editing `rector.php` and
|
||||
running `composer rector` (dry-run) before applying.
|
||||
|
||||
## Adding skip-rules
|
||||
|
||||
If a specific rule produces incorrect changes for the project, add
|
||||
to `withSkip([...])` in `rector.php`:
|
||||
|
||||
```php
|
||||
->withSkip([
|
||||
SomeSpecificRule::class => [
|
||||
__DIR__ . '/app/path/to/file.php',
|
||||
],
|
||||
])
|
||||
```
|
||||
|
||||
Document the skip with a code comment in `rector.php` explaining
|
||||
why the rule is bypassed for that path.
|
||||
|
||||
## Relationship to Larastan
|
||||
|
||||
Different concerns:
|
||||
- **Larastan**: "this code is wrong" (types, null-safety, missing
|
||||
methods)
|
||||
- **Rector**: "this code can be modernised" (PHP version idioms,
|
||||
Laravel idioms, dead code, early-return patterns)
|
||||
|
||||
Both run on the same codebase. After a Rector apply-sprint,
|
||||
regenerate the Larastan baseline — Rector changes often resolve
|
||||
Larastan errors automatically.
|
||||
|
||||
## CI integration
|
||||
|
||||
Not enabled yet. When added, `composer rector` (dry-run) becomes
|
||||
a non-blocking PR comment that surfaces suggested modernisations.
|
||||
Apply happens manually, never automatically in CI.
|
||||
Reference in New Issue
Block a user