Skip to content

Commit 78e5236

Browse files
committed
remove --only option from list-rules command, as goal is to show all rules
1 parent 1c7dcd7 commit 78e5236

4 files changed

Lines changed: 90 additions & 29 deletions

File tree

bin/list-unused-rules.php

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
declare(strict_types=1);
66

7-
use Nette\Utils\FileSystem;
8-
use Nette\Utils\Json;
9-
use Rector\Composer\InstalledPackageResolver;
7+
use Nette\Loaders\RobotLoader;
8+
use Rector\Bridge\SetRectorsResolver;
109
use Symfony\Component\Console\Input\ArrayInput;
1110
use Symfony\Component\Console\Output\ConsoleOutput;
1211
use Symfony\Component\Console\Style\SymfonyStyle;
12+
use Symfony\Component\Finder\Finder;
13+
use Symfony\Component\Finder\SplFileInfo;
14+
use Webmozart\Assert\Assert;
1315

1416
require __DIR__ . '/../vendor/autoload.php';
1517

@@ -25,34 +27,99 @@
2527
]);
2628

2729
$symfonyStyle = new SymfonyStyle(new ArrayInput([]), new ConsoleOutput());
28-
2930
$symfonyStyle->writeln(sprintf('<fg=green>Found Rector %d rules</>', count($rectorClasses)));
3031

32+
$rectorSeFinder = new RectorSetFinder();
33+
34+
$rectorSetFiles = $rectorSeFinder->find([
35+
__DIR__ . '/../config/set',
36+
__DIR__ . '/../vendor/rector/rector-symfony/config/sets',
37+
__DIR__ . '/../vendor/rector/rector-doctrine/config/sets',
38+
__DIR__ . '/../vendor/rector/rector-phpunit/config/sets',
39+
__DIR__ . '/../vendor/rector/rector-downgrade-php/config/set',
40+
]);
41+
42+
$symfonyStyle->writeln(sprintf('<fg=green>Found %d sets</>', count($rectorSetFiles)));
3143

32-
// find set files
33-
new \Nette\Utils\Finder()
44+
$usedRectorClassResolver = new UsedRectorClassResolver();
45+
$usedRectorRules = $usedRectorClassResolver->resolve($rectorSetFiles);
3446

47+
$symfonyStyle->newLine();
48+
$symfonyStyle->writeln(sprintf('<fg=yellow>Found %d used Rector rules in sets</>', count($usedRectorRules)));
49+
50+
$unusedRectorRules = array_diff($rectorClasses, $usedRectorRules);
51+
$symfonyStyle->writeln(
52+
sprintf('<fg=yellow;options=bold>Found %d Rector rules not in any set</>', count($unusedRectorRules))
53+
);
54+
55+
$symfonyStyle->newLine();
56+
$symfonyStyle->listing($unusedRectorRules);
3557

3658
final class RectorClassFinder
3759
{
3860
/**
3961
* @param string[] $dirs
40-
* @return array<class-string>
62+
* @return string[]
4163
*/
4264
public function find(array $dirs): array
4365
{
44-
$robotLoader = new \Nette\Loaders\RobotLoader();
66+
$robotLoader = new RobotLoader();
4567
$robotLoader->acceptFiles = ['*Rector.php'];
46-
$robotLoader->addDirectory(__DIR__ . '/../rules');
47-
$robotLoader->addDirectory(__DIR__ . '/../vendor/rector/rector-doctrine');
48-
$robotLoader->addDirectory(__DIR__ . '/../vendor/rector/rector-phpunit');
49-
$robotLoader->addDirectory(__DIR__ . '/../vendor/rector/rector-symfony');
50-
$robotLoader->addDirectory(__DIR__ . '/../vendor/rector/rector-downgrade-php');
51-
68+
$robotLoader->addDirectory(...$dirs);
5269

5370
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/rector-rules');
5471
$robotLoader->refresh();
5572

5673
return array_keys($robotLoader->getIndexedClasses());
5774
}
5875
}
76+
77+
final class RectorSetFinder
78+
{
79+
/**
80+
* @param string[] $configDirs
81+
* @return string[]
82+
*/
83+
public function find(array $configDirs): array
84+
{
85+
Assert::allString($configDirs);
86+
Assert::allDirectory($configDirs);
87+
88+
// find set files
89+
$finder = (new Finder())->in($configDirs)
90+
->files()
91+
->name('*.php');
92+
93+
/** @var SplFileInfo[] $setFileInfos */
94+
$setFileInfos = iterator_to_array($finder->getIterator());
95+
96+
$setFiles = [];
97+
foreach ($setFileInfos as $setFileInfo) {
98+
$setFiles[] = $setFileInfo->getRealPath();
99+
}
100+
101+
return $setFiles;
102+
}
103+
}
104+
105+
final class UsedRectorClassResolver
106+
{
107+
/**
108+
* @param string[] $rectorSetFiles
109+
* @return string[]
110+
*/
111+
public function resolve(array $rectorSetFiles): array
112+
{
113+
$setRectorsResolver = new SetRectorsResolver();
114+
$rulesConfiguration = $setRectorsResolver->resolveFromFilePathsIncludingConfiguration($rectorSetFiles);
115+
116+
$usedRectorRules = [];
117+
foreach ($rulesConfiguration as $ruleConfiguration) {
118+
$usedRectorRules[] = is_string($ruleConfiguration) ? $ruleConfiguration : array_keys($ruleConfiguration)[0];
119+
}
120+
121+
sort($usedRectorRules);
122+
123+
return array_unique($usedRectorRules);
124+
}
125+
}

composer-dependency-analyser.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
// ensure use version ^3.2.0
1818
->ignoreErrorsOnPackage('composer/pcre', [ErrorType::UNUSED_DEPENDENCY])
1919

20+
// use din /bin, but only local script
21+
->ignoreErrorsOnPackage('nette/robot-loader', [ErrorType::DEV_DEPENDENCY_IN_PROD])
22+
2023
->ignoreErrorsOnPaths([
2124
__DIR__ . '/stubs',
2225
__DIR__ . '/tests',

phpstan.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,7 @@ parameters:
354354
path: src/CustomRules/SimpleNodeDumper.php
355355

356356
- '#Method Rector\\Utils\\Rector\\RemoveRefactorDuplicatedNodeInstanceCheckRector\:\:getInstanceofNodeClass\(\) should return class\-string<PhpParser\\Node>\|null but returns class\-string#'
357+
358+
-
359+
path: bin/list-unused-rules.php
360+
identifier: symplify.multipleClassLikeInFile

src/Console/Command/ListRulesCommand.php

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
use Nette\Utils\Json;
88
use Rector\ChangesReporting\Output\ConsoleOutputFormatter;
9-
use Rector\Configuration\ConfigurationRuleFilter;
10-
use Rector\Configuration\OnlyRuleResolver;
119
use Rector\Configuration\Option;
1210
use Rector\Contract\Rector\RectorInterface;
1311
use Rector\PostRector\Contract\Rector\PostRectorInterface;
@@ -26,8 +24,6 @@ final class ListRulesCommand extends Command
2624
public function __construct(
2725
private readonly SymfonyStyle $symfonyStyle,
2826
private readonly SkippedClassResolver $skippedClassResolver,
29-
private readonly OnlyRuleResolver $onlyRuleResolver,
30-
private readonly ConfigurationRuleFilter $configurationRuleFilter,
3127
private readonly array $rectors
3228
) {
3329
parent::__construct();
@@ -53,12 +49,7 @@ protected function configure(): void
5349

5450
protected function execute(InputInterface $input, OutputInterface $output): int
5551
{
56-
$onlyRule = $input->getOption(Option::ONLY);
57-
if ($onlyRule !== null) {
58-
$onlyRule = $this->onlyRuleResolver->resolve($onlyRule);
59-
}
60-
61-
$rectorClasses = $this->resolveRectorClasses($onlyRule);
52+
$rectorClasses = $this->resolveRectorClasses();
6253

6354
$skippedClasses = $this->getSkippedCheckers();
6455

@@ -90,17 +81,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9081
/**
9182
* @return array<class-string<RectorInterface>>
9283
*/
93-
private function resolveRectorClasses(?string $onlyRule): array
84+
private function resolveRectorClasses(): array
9485
{
9586
$customRectors = array_filter(
9687
$this->rectors,
9788
static fn (RectorInterface $rector): bool => ! $rector instanceof PostRectorInterface
9889
);
9990

100-
if ($onlyRule !== null) {
101-
$customRectors = $this->configurationRuleFilter->filterOnlyRule($customRectors, $onlyRule);
102-
}
103-
10491
$rectorClasses = array_map(static fn (RectorInterface $rector): string => $rector::class, $customRectors);
10592
sort($rectorClasses);
10693

0 commit comments

Comments
 (0)