-
-
Notifications
You must be signed in to change notification settings - Fork 335
/
MissingInSetCommand.php
116 lines (96 loc) · 4.28 KB
/
MissingInSetCommand.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
declare(strict_types=1);
namespace Rector\Utils\Command;
use Nette\Utils\Strings;
use Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector;
use Rector\CodeQuality\Rector\FuncCall\StrvalToTypeCastRector;
use Rector\CodingStyle\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\DeadCode\Rector\ClassMethod\RemoveNullTagValueNodeRector;
use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector;
use Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector;
use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector;
use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector;
use Rector\TypeDeclaration\Rector\BooleanAnd\BinaryOpNullableToInstanceofRector;
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
use Rector\TypeDeclaration\Rector\While_\WhileNullableToInstanceofRector;
use Rector\Utils\Enum\RectorDirectoryToSetFileMap;
use Rector\Utils\Finder\RectorClassFinder;
use Rector\Utils\Finder\SetRectorClassesResolver;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
final class MissingInSetCommand extends Command
{
/**
* @var list<string>
*/
private const SKIPPED_RULES = [
ConfigurableRectorInterface::class,
DeclareStrictTypesRector::class,
// optional
BinaryOpNullableToInstanceofRector::class,
WhileNullableToInstanceofRector::class,
IntvalToTypeCastRector::class,
StrvalToTypeCastRector::class,
// changes behavior, should be applied on purpose regardless PHP 7.3 level
JsonThrowOnErrorRector::class,
// in confront with sub type safe belt detection on RemoveUseless*TagRector
RemoveNullTagValueNodeRector::class,
// personal preference, enable on purpose
ArraySpreadInsteadOfArrayMergeRector::class,
FinalizeTestCaseClassRector::class,
FinalizeClassesWithoutChildrenRector::class,
// deprecated
FinalizePublicClassConstantRector::class,
];
public function __construct(
private readonly SymfonyStyle $symfonyStyle
) {
parent::__construct();
}
protected function configure(): void
{
$this->setName('missing-in-set');
$this->setDescription('[DEV] Show rules from specific category that are not part of the set');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$hasError = false;
foreach (RectorDirectoryToSetFileMap::provide() as $rulesDirectory => $setFile) {
$classesInSetFile = SetRectorClassesResolver::resolve($setFile);
$existingRectorClasses = RectorClassFinder::find([$rulesDirectory]);
$rectorClassesNotInSetConfig = array_diff($existingRectorClasses, $classesInSetFile);
// remove deprecated and configurable rules
$rectorClassesNotInSetConfig = array_filter(
$rectorClassesNotInSetConfig,
static function (string $rectorClass): bool {
foreach (self::SKIPPED_RULES as $rule) {
if (is_a($rectorClass, $rule, true)) {
return false;
}
}
return true;
}
);
if ($rectorClassesNotInSetConfig === []) {
continue;
}
$hasError = true;
$this->symfonyStyle->title('We could not find there rules in configs');
$setRealpath = realpath($setFile);
$relativeFilePath = Strings::after($setRealpath, getcwd() . '/');
$this->symfonyStyle->writeln(' * ' . $relativeFilePath);
$this->symfonyStyle->newLine(1);
$this->symfonyStyle->listing($rectorClassesNotInSetConfig);
$this->symfonyStyle->newLine(1);
}
if ($hasError) {
return self::FAILURE;
}
$setCount = count(RectorDirectoryToSetFileMap::provide());
$this->symfonyStyle->success(sprintf('All %d sets contains the rules from their category', $setCount));
return self::SUCCESS;
}
}