Skip to content

Commit

Permalink
Add "--only" option to process only a single rule
Browse files Browse the repository at this point in the history
The option for the "process" and "list-rules" commands applies
the single given rule only, without needing to modify
the configuration file.

The option value must be a fully classified class name:

  --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

A hint is given when the user forgot to escape the backslashes.

----

It is impossible to modify the injected "$rectors" after the
command line configuration is parsed, so I had to introduce the
ConfigurationRuleFilter singleton.

Since both ListRulesCommand and ProcessCommand make use of the
ConfigurationRuleFilter - but list-rules does not have a Configuration -
I had to make the filterOnlyRule() method public to prevent
code duplication.

Resolves rectorphp/rector#8899
  • Loading branch information
cweiske committed Nov 25, 2024
1 parent 1ec42bc commit acf0bb4
Show file tree
Hide file tree
Showing 39 changed files with 560 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ jobs:
- 'e2e/invalid-paths'
- 'e2e/applied-polyfill-php80'
- 'e2e/print-new-node'
- 'e2e/only-option'
- 'e2e/only-option-quote-double-equalnone'
- 'e2e/only-option-quote-single'
- 'e2e/only-option-quote-single-bsdouble'
- 'e2e/only-option-quote-single-equalnone'

name: End to end test - ${{ matrix.directory }}

Expand Down
6 changes: 6 additions & 0 deletions e2e/e2eTestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
$e2eCommand .= ' -a ' . $argv[2];
}

$cliOptions = 'cli-options.txt';
if (file_exists($cliOptions)) {
$e2eCommand .= ' ' . trim(file_get_contents($cliOptions));
}


exec($e2eCommand, $output, $exitCode);
$output = trim(implode("\n", $output));
$output = str_replace(__DIR__, '.', $output);
Expand Down
1 change: 1 addition & 0 deletions e2e/only-option-quote-double-equalnone/cli-options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--only "Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
7 changes: 7 additions & 0 deletions e2e/only-option-quote-double-equalnone/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require": {
"php": "^8.1"
},
"minimum-stability": "dev",
"prefer-stable": true
}
22 changes: 22 additions & 0 deletions e2e/only-option-quote-double-equalnone/expected-output.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1 file with changes
===================

1) ../only-option/src/MultiRules.php:9

---------- begin diff ----------
@@ @@
echo 'a statement';
}
}
-
- private function notUsed()
- {
- }
}
----------- end diff -----------

Applied rules:
* RemoveUnusedPrivateMethodRector


[OK] 1 file would have been changed (dry-run) by Rector
18 changes: 18 additions & 0 deletions e2e/only-option-quote-double-equalnone/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/../only-option/src',
]);

$rectorConfig->rules([
RemoveAlwaysElseRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
};
1 change: 1 addition & 0 deletions e2e/only-option-quote-single-bsdouble/cli-options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector'
7 changes: 7 additions & 0 deletions e2e/only-option-quote-single-bsdouble/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require": {
"php": "^8.1"
},
"minimum-stability": "dev",
"prefer-stable": true
}
22 changes: 22 additions & 0 deletions e2e/only-option-quote-single-bsdouble/expected-output.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1 file with changes
===================

1) ../only-option/src/MultiRules.php:9

---------- begin diff ----------
@@ @@
echo 'a statement';
}
}
-
- private function notUsed()
- {
- }
}
----------- end diff -----------

Applied rules:
* RemoveUnusedPrivateMethodRector


[OK] 1 file would have been changed (dry-run) by Rector
18 changes: 18 additions & 0 deletions e2e/only-option-quote-single-bsdouble/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/../only-option/src',
]);

$rectorConfig->rules([
RemoveAlwaysElseRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
};
1 change: 1 addition & 0 deletions e2e/only-option-quote-single-equalnone/cli-options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--only 'Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'
7 changes: 7 additions & 0 deletions e2e/only-option-quote-single-equalnone/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require": {
"php": "^8.1"
},
"minimum-stability": "dev",
"prefer-stable": true
}
22 changes: 22 additions & 0 deletions e2e/only-option-quote-single-equalnone/expected-output.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1 file with changes
===================

1) ../only-option/src/MultiRules.php:9

---------- begin diff ----------
@@ @@
echo 'a statement';
}
}
-
- private function notUsed()
- {
- }
}
----------- end diff -----------

Applied rules:
* RemoveUnusedPrivateMethodRector


[OK] 1 file would have been changed (dry-run) by Rector
18 changes: 18 additions & 0 deletions e2e/only-option-quote-single-equalnone/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/../only-option/src',
]);

$rectorConfig->rules([
RemoveAlwaysElseRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
};
1 change: 1 addition & 0 deletions e2e/only-option-quote-single/cli-options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--only='Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'
7 changes: 7 additions & 0 deletions e2e/only-option-quote-single/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require": {
"php": "^8.1"
},
"minimum-stability": "dev",
"prefer-stable": true
}
22 changes: 22 additions & 0 deletions e2e/only-option-quote-single/expected-output.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1 file with changes
===================

1) ../only-option/src/MultiRules.php:9

---------- begin diff ----------
@@ @@
echo 'a statement';
}
}
-
- private function notUsed()
- {
- }
}
----------- end diff -----------

Applied rules:
* RemoveUnusedPrivateMethodRector


[OK] 1 file would have been changed (dry-run) by Rector
18 changes: 18 additions & 0 deletions e2e/only-option-quote-single/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/../only-option/src',
]);

$rectorConfig->rules([
RemoveAlwaysElseRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
};
1 change: 1 addition & 0 deletions e2e/only-option/cli-options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
7 changes: 7 additions & 0 deletions e2e/only-option/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"require": {
"php": "^8.1"
},
"minimum-stability": "dev",
"prefer-stable": true
}
22 changes: 22 additions & 0 deletions e2e/only-option/expected-output.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1 file with changes
===================

1) src/MultiRules.php:9

---------- begin diff ----------
@@ @@
echo 'a statement';
}
}
-
- private function notUsed()
- {
- }
}
----------- end diff -----------

Applied rules:
* RemoveUnusedPrivateMethodRector


[OK] 1 file would have been changed (dry-run) by Rector
19 changes: 19 additions & 0 deletions e2e/only-option/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/src',
]);

$rectorConfig->rules([
RemoveAlwaysElseRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
};

17 changes: 17 additions & 0 deletions e2e/only-option/src/MultiRules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

final class MultiRules
{
public function doSomething()
{
if (true === false) {
return -1;
} else {
echo 'a statement';
}
}

private function notUsed()
{
}
}
13 changes: 13 additions & 0 deletions e2e/only-option/src/RemoveAlwaysElse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

class RemoveAlwaysElse
{
public function run($value)
{
if ($value) {
throw new \InvalidStateException;
} else {
return 10;
}
}
}
12 changes: 10 additions & 2 deletions src/Configuration/ConfigurationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
final readonly class ConfigurationFactory
{
public function __construct(
private SymfonyStyle $symfonyStyle
private SymfonyStyle $symfonyStyle,
private readonly OnlyRuleResolver $onlyRuleResolver,
) {
}

Expand All @@ -41,7 +42,8 @@ public function createForTests(array $paths): Configuration
false,
null,
false,
false
false,
null
);
}

Expand All @@ -62,6 +64,11 @@ public function createFromInput(InputInterface $input): Configuration

$fileExtensions = SimpleParameterProvider::provideArrayParameter(Option::FILE_EXTENSIONS);

$onlyRule = $input->getOption(Option::ONLY);
if ($onlyRule !== null) {
$onlyRule = $this->onlyRuleResolver->resolve($onlyRule);
}

$isParallel = SimpleParameterProvider::provideBoolParameter(Option::PARALLEL);
$parallelPort = (string) $input->getOption(Option::PARALLEL_PORT);
$parallelIdentifier = (string) $input->getOption(Option::PARALLEL_IDENTIFIER);
Expand Down Expand Up @@ -90,6 +97,7 @@ public function createFromInput(InputInterface $input): Configuration
$memoryLimit,
$isDebug,
$isReportingWithRealPath,
$onlyRule,
);
}

Expand Down
Loading

0 comments on commit acf0bb4

Please sign in to comment.