Skip to content

Commit 739ba4b

Browse files
authored
Merge pull request #2 from codeigniter4/rector
2 parents 761d524 + 514e81f commit 739ba4b

File tree

3 files changed

+189
-0
lines changed

3 files changed

+189
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ locally they will need to be installed. All of them are available via [Phive](ht
3939
* [Infection](https://infection.github.io/)
4040
* [PHP Coveralls](https://php-coveralls.github.io/php-coveralls/)
4141
* [PHP CS Fixer](https://cs.symfony.com/)
42+
* [Rector](https://github.com/rectorphp/rector/)
4243

4344
## Source Files
4445

@@ -120,6 +121,18 @@ running unit tests. This workflow also configures PHPUnit to report on code cove
120121
upload the results to [Coveralls.io](https://coveralls.io) (you will need a free account,
121122
but it is also fine to use this workflow without Coveralls).
122123

124+
#### Rector
125+
126+
*Requires **rector.php***
127+
128+
Rector provides automated refactoring of code, allowing you to make sweeping updates based on
129+
predefined rulesets. Rector can be highly opinionated based on its configuration file (**rector.php**)
130+
so be sure to read the documentation and figure out the best fit for you. This workflow performs
131+
a "dry run" to check for any changes that Rector would have made and fail if there are matches.
132+
133+
> Note: Rector updates rules all the time so you may want to lock your repo to the latest known working version of Rector to prevent unexpected failures
134+
> E.g. in **.github/workflows/rector.yml** supply the specific minor patch: `composer global require --dev rector/rector:0.12.4`
135+
123136
#### Unused
124137

125138
Composer Unused does one thing: checks that your code actually uses the dependencies you

src/.github/workflows/rector.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Rector
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- develop
7+
paths:
8+
- '**.php'
9+
- 'composer.**'
10+
- 'rector.php'
11+
- '.github/workflows/rector.yml'
12+
push:
13+
branches:
14+
- develop
15+
paths:
16+
- '**.php'
17+
- 'composer.**'
18+
- 'rector.php'
19+
- '.github/workflows/rector.yml'
20+
21+
jobs:
22+
build:
23+
name: PHP ${{ matrix.php-versions }} Rector Analysis
24+
runs-on: ubuntu-latest
25+
if: "!contains(github.event.head_commit.message, '[ci skip]')"
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
php-versions: ['7.3', '7.4', '8.0']
30+
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@v2
34+
35+
- name: Set up PHP
36+
uses: shivammathur/setup-php@v2
37+
with:
38+
php-version: ${{ matrix.php-versions }}
39+
tools: phpstan
40+
extensions: intl, json, mbstring, xml
41+
coverage: none
42+
env:
43+
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
45+
- name: Get composer cache directory
46+
id: composer-cache
47+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
48+
49+
- name: Cache composer dependencies
50+
uses: actions/cache@v2
51+
with:
52+
path: ${{ steps.composer-cache.outputs.dir }}
53+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }}
54+
restore-keys: ${{ runner.os }}-composer-
55+
56+
- name: Install dependencies
57+
run: |
58+
composer -q config -g github-oauth.github.com "${{ secrets.GITHUB_TOKEN }}"
59+
if [ -f composer.lock ]; then
60+
composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
61+
else
62+
composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader
63+
fi
64+
65+
- name: Analyze for refactoring
66+
run: |
67+
composer global require --dev rector/rector
68+
rector process --dry-run --no-progress-bar

src/rector.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
4+
use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
5+
use Rector\CodeQuality\Rector\For_\ForToForeachRector;
6+
use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector;
7+
use Rector\CodeQuality\Rector\FuncCall\AddPregQuoteDelimiterRector;
8+
use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector;
9+
use Rector\CodeQuality\Rector\FuncCall\SimplifyRegexPatternRector;
10+
use Rector\CodeQuality\Rector\FuncCall\SimplifyStrposLowerRector;
11+
use Rector\CodeQuality\Rector\If_\CombineIfRector;
12+
use Rector\CodeQuality\Rector\If_\ShortenElseIfRector;
13+
use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector;
14+
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
15+
use Rector\CodeQuality\Rector\Return_\SimplifyUselessVariableRector;
16+
use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector;
17+
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
18+
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
19+
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
20+
use Rector\Core\Configuration\Option;
21+
use Rector\Core\ValueObject\PhpVersion;
22+
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector;
23+
use Rector\DeadCode\Rector\MethodCall\RemoveEmptyMethodCallRector;
24+
use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector;
25+
use Rector\EarlyReturn\Rector\If_\ChangeIfElseValueAssignToEarlyReturnRector;
26+
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;
27+
use Rector\EarlyReturn\Rector\Return_\PreparedValueToEarlyReturnRector;
28+
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
29+
use Rector\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector;
30+
use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector;
31+
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
32+
use Rector\PHPUnit\Set\PHPUnitSetList;
33+
use Rector\Set\ValueObject\LevelSetList;
34+
use Rector\Set\ValueObject\SetList;
35+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
36+
37+
return static function (ContainerConfigurator $containerConfigurator): void {
38+
// Rule sets to apply
39+
$containerConfigurator->import(SetList::DEAD_CODE);
40+
$containerConfigurator->import(LevelSetList::UP_TO_PHP_73);
41+
$containerConfigurator->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD);
42+
$containerConfigurator->import(PHPUnitSetList::PHPUNIT_80);
43+
44+
$parameters = $containerConfigurator->parameters();
45+
46+
// The paths to refactor (can also be supplied with CLI arguments)
47+
$parameters->set(Option::PATHS, [
48+
__DIR__ . '/app',
49+
__DIR__ . '/tests',
50+
]);
51+
52+
// Do you need to include constants, class aliases, or a custom autoloader?
53+
$parameters->set(Option::BOOTSTRAP_FILES, [
54+
realpath(getcwd()) . '/vendor/codeigniter4/framework/system/Test/bootstrap.php',
55+
]);
56+
57+
// Set the target version for refactoring
58+
$parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_73);
59+
60+
// Auto-import fully qualified class names
61+
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
62+
63+
// Are there files or rules you need to skip?
64+
$parameters->set(Option::SKIP, [
65+
__DIR__ . '/app/Views',
66+
67+
JsonThrowOnErrorRector::class,
68+
StringifyStrNeedlesRector::class,
69+
70+
// Note: requires php 8
71+
RemoveUnusedPromotedPropertyRector::class,
72+
73+
// Ignore tests that might make calls without a result
74+
RemoveEmptyMethodCallRector::class => [
75+
__DIR__ . '/tests',
76+
],
77+
78+
// May load view files directly when detecting classes
79+
StringClassNameToClassConstantRector::class,
80+
81+
// May be uninitialized on purpose
82+
AddDefaultValueForUndefinedVariableRector::class,
83+
]);
84+
85+
// Additional rules to apply
86+
$services = $containerConfigurator->services();
87+
$services->set(SimplifyUselessVariableRector::class);
88+
$services->set(RemoveAlwaysElseRector::class);
89+
$services->set(CountArrayToEmptyArrayComparisonRector::class);
90+
$services->set(ForToForeachRector::class);
91+
$services->set(ChangeNestedForeachIfsToEarlyContinueRector::class);
92+
$services->set(ChangeIfElseValueAssignToEarlyReturnRector::class);
93+
$services->set(SimplifyStrposLowerRector::class);
94+
$services->set(CombineIfRector::class);
95+
$services->set(SimplifyIfReturnBoolRector::class);
96+
$services->set(InlineIfToExplicitIfRector::class);
97+
$services->set(PreparedValueToEarlyReturnRector::class);
98+
$services->set(ShortenElseIfRector::class);
99+
$services->set(SimplifyIfElseToTernaryRector::class);
100+
$services->set(UnusedForeachValueToArrayKeysRector::class);
101+
$services->set(ChangeArrayPushToArrayAssignRector::class);
102+
$services->set(UnnecessaryTernaryExpressionRector::class);
103+
$services->set(AddPregQuoteDelimiterRector::class);
104+
$services->set(SimplifyRegexPatternRector::class);
105+
$services->set(FuncGetArgsToVariadicParamRector::class);
106+
$services->set(MakeInheritedMethodVisibilitySameAsParentRector::class);
107+
$services->set(SimplifyEmptyArrayCheckRector::class);
108+
};

0 commit comments

Comments
 (0)