Skip to content

Commit 67ff6ef

Browse files
committed
[Console] Undeprecate list-rules command, restore loaded rules listing
1 parent 33926fa commit 67ff6ef

1 file changed

Lines changed: 84 additions & 5 deletions

File tree

‎src/Console/Command/ListRulesCommand.php‎

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,112 @@
44

55
namespace Rector\Console\Command;
66

7+
use Nette\Utils\Json;
8+
use Rector\ChangesReporting\Output\ConsoleOutputFormatter;
9+
use Rector\Configuration\Option;
10+
use Rector\Contract\Rector\RectorInterface;
11+
use Rector\PostRector\Contract\Rector\PostRectorInterface;
12+
use Rector\Skipper\SkipCriteriaResolver\SkippedClassResolver;
713
use Symfony\Component\Console\Command\Command;
814
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Input\InputOption;
916
use Symfony\Component\Console\Output\OutputInterface;
1017
use Symfony\Component\Console\Style\SymfonyStyle;
1118

1219
final class ListRulesCommand extends Command
1320
{
21+
/**
22+
* @param RectorInterface[] $rectors
23+
*/
1424
public function __construct(
15-
private readonly SymfonyStyle $symfonyStyle
25+
private readonly SymfonyStyle $symfonyStyle,
26+
private readonly SkippedClassResolver $skippedClassResolver,
27+
private readonly array $rectors
1628
) {
1729
parent::__construct();
1830
}
1931

2032
protected function configure(): void
2133
{
2234
$this->setName('list-rules');
23-
$this->setDescription('[DEPRECATED] Show loaded Rectors');
35+
$this->setDescription('Show loaded Rectors');
2436

2537
$this->setAliases(['show-rules']);
38+
39+
$this->addOption(
40+
Option::OUTPUT_FORMAT,
41+
null,
42+
InputOption::VALUE_REQUIRED,
43+
'Select output format',
44+
ConsoleOutputFormatter::NAME
45+
);
46+
47+
$this->addOption(Option::ONLY, null, InputOption::VALUE_REQUIRED, 'Fully qualified rule class name');
2648
}
2749

2850
protected function execute(InputInterface $input, OutputInterface $output): int
2951
{
30-
$this->symfonyStyle->error(
31-
'The "list-rules" command is deprecated and no longer provided. Run Rector with the set or rules you desire instead.'
52+
$rectorClasses = $this->resolveRectorClasses();
53+
54+
$skippedClasses = $this->getSkippedRectorClasses();
55+
56+
$outputFormat = $input->getOption(Option::OUTPUT_FORMAT);
57+
if ($outputFormat === 'json') {
58+
$data = [
59+
'rectors' => $rectorClasses,
60+
'skipped-rectors' => $skippedClasses,
61+
];
62+
63+
echo Json::encode($data, pretty: true) . PHP_EOL;
64+
return Command::SUCCESS;
65+
}
66+
67+
$this->symfonyStyle->title('Loaded Rector rules');
68+
$this->symfonyStyle->listing($rectorClasses);
69+
70+
if ($skippedClasses !== []) {
71+
$this->symfonyStyle->title('Skipped Rector rules');
72+
$this->symfonyStyle->listing($skippedClasses);
73+
}
74+
75+
$this->symfonyStyle->newLine();
76+
$this->symfonyStyle->note(sprintf('Loaded %d rules', count($rectorClasses)));
77+
78+
return Command::SUCCESS;
79+
}
80+
81+
/**
82+
* @return array<class-string<RectorInterface>>
83+
*/
84+
private function resolveRectorClasses(): array
85+
{
86+
$customRectors = array_filter(
87+
$this->rectors,
88+
static fn (RectorInterface $rector): bool => ! $rector instanceof PostRectorInterface
3289
);
3390

34-
return Command::FAILURE;
91+
$rectorClasses = array_map(static fn (RectorInterface $rector): string => $rector::class, $customRectors);
92+
sort($rectorClasses);
93+
94+
return array_unique($rectorClasses);
95+
}
96+
97+
/**
98+
* @return array<class-string>
99+
*/
100+
private function getSkippedRectorClasses(): array
101+
{
102+
$skippedRectorClasses = [];
103+
104+
foreach ($this->skippedClassResolver->resolve() as $rectorClass => $fileList) {
105+
// ignore specific skips
106+
if ($fileList !== null) {
107+
continue;
108+
}
109+
110+
$skippedRectorClasses[] = $rectorClass;
111+
}
112+
113+
return $skippedRectorClasses;
35114
}
36115
}

0 commit comments

Comments
 (0)