Skip to content

Commit 938e3bc

Browse files
authored
Chore: Add Rector with safe rule bucket and CI refactor check (#247)
Introduces Rector for automated refactoring, wired up via: - rector.php config targeting src/ and tests/ with PHP 8.3 level set plus CODE_QUALITY, DEAD_CODE, EARLY_RETURN, and INSTANCEOF sets. Rules with BC risk or behavioural shifts (readonly, explicit bool compare, empty() rewrites, type-hint additions, random_int swaps) are explicitly skipped. - composer refactor / refactor:check scripts. - Checks / Refactor CI job running rector in dry-run. - Safe-bucket refactor applied across the codebase: strict_types declarations, #[\Override] attributes, str_contains / str_starts_with, null-coalescing, match over switch where safe, dead code removal, and docblock cleanup.
1 parent 288c943 commit 938e3bc

31 files changed

Lines changed: 250 additions & 623 deletions

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,34 @@ jobs:
4848
- name: PHPStan
4949
run: composer analyze
5050

51+
refactor:
52+
name: Checks / Refactor
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v6
56+
57+
- uses: shivammathur/setup-php@v2
58+
with:
59+
php-version: '8.3'
60+
extensions: swoole
61+
coverage: none
62+
63+
- name: Get composer cache directory
64+
id: composer-cache
65+
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
66+
67+
- uses: actions/cache@v5
68+
with:
69+
path: ${{ steps.composer-cache.outputs.dir }}
70+
key: composer-${{ hashFiles('composer.lock') }}
71+
restore-keys: composer-
72+
73+
- name: Install dependencies
74+
run: composer install --prefer-dist --no-progress --no-interaction --ignore-platform-req=ext-opentelemetry
75+
76+
- name: Rector (dry run)
77+
run: composer refactor:check
78+
5179
unit:
5280
name: Tests / Unit / PHP ${{ matrix.php }}
5381
runs-on: ubuntu-latest

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
"format": "vendor/bin/pint",
2626
"format:check": "vendor/bin/pint --test",
2727
"analyze": "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit 512M",
28+
"refactor": "vendor/bin/rector process",
29+
"refactor:check": "vendor/bin/rector process --dry-run",
2830
"test": "vendor/bin/phpunit --configuration phpunit.xml"
2931
},
3032
"require": {
@@ -54,6 +56,7 @@
5456
"laravel/pint": "1.*",
5557
"phpstan/phpstan": "^2.0",
5658
"phpunit/phpunit": "^9.5.25",
59+
"rector/rector": "^2.0",
5760
"swoole/ide-helper": "4.8.3"
5861
}
5962
}

composer.lock

Lines changed: 64 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rector.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector;
6+
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
7+
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
8+
use Rector\CodeQuality\Rector\Ternary\SwitchNegatedTernaryRector;
9+
use Rector\Config\RectorConfig;
10+
use Rector\DeadCode\Rector\Cast\RecastingRemovalRector;
11+
use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector;
12+
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
13+
use Rector\Php70\Rector\FuncCall\RandomFunctionRector;
14+
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
15+
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
16+
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
17+
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
18+
use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
19+
use Rector\Set\ValueObject\LevelSetList;
20+
use Rector\Set\ValueObject\SetList;
21+
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByParentCallTypeRector;
22+
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector;
23+
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;
24+
25+
return RectorConfig::configure()
26+
->withPaths([
27+
__DIR__ . '/src',
28+
__DIR__ . '/tests',
29+
])
30+
->withPhpSets(php83: true)
31+
->withSets([
32+
LevelSetList::UP_TO_PHP_83,
33+
SetList::CODE_QUALITY,
34+
SetList::DEAD_CODE,
35+
SetList::EARLY_RETURN,
36+
SetList::INSTANCEOF,
37+
])
38+
->withImportNames(importShortClasses: false, removeUnusedImports: true)
39+
->withSkip([
40+
// BC breaks in a published library
41+
ReadOnlyPropertyRector::class,
42+
ReadOnlyClassRector::class,
43+
44+
// Changes truthy semantics — "0", null, "" behave differently
45+
ExplicitBoolCompareRector::class,
46+
SimplifyEmptyCheckOnEmptyArrayRector::class,
47+
48+
// Can throw TypeError on previously-working callers (library is public API)
49+
TypedPropertyFromAssignsRector::class,
50+
TypedPropertyFromStrictConstructorRector::class,
51+
ParamTypeByParentCallTypeRector::class,
52+
53+
// Different distribution and failure mode than rand()
54+
RandomFunctionRector::class,
55+
56+
// Subtle casting/control-flow shifts — apply manually
57+
RecastingRemovalRector::class,
58+
FlipTypeControlToUseExclusiveTypeRector::class,
59+
SwitchNegatedTernaryRector::class,
60+
StringClassNameToClassConstantRector::class,
61+
62+
// Promoted properties / nullable defaults — BC shape changes for library
63+
ClassPropertyAssignToConstructorPromotionRector::class,
64+
RestoreDefaultNullToNullableTypePropertyRector::class,
65+
66+
// empty() replacement rarely covers every falsy case Rector's type info misses
67+
DisallowedEmptyRuleFixerRector::class,
68+
69+
// Throws TypeError when args are objects/arrays — review per-call
70+
NullToStrictStringFuncCallArgRector::class,
71+
]);

src/Http/Adapter.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Utopia\Http;
46

57
use Utopia\DI\Container;

0 commit comments

Comments
 (0)