Repository navigation
Expand file tree
/
Copy pathvalidate-node-rule-map.php
More file actions
67 lines (51 loc) · 2.72 KB
/
Copy pathvalidate-node-rule-map.php
File metadata and controls
67 lines (51 loc) · 2.72 KB
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
<?php
declare(strict_types=1);
use Nette\Utils\FileSystem;
use Nette\Utils\Json;
use Rector\Console\Style\SymfonyStyleFactory;
use Rector\Scripts\Finder\RectorClassFinder;
use Rector\Scripts\NodeRuleMap\NodeRuleMapFactory;
use Rector\Util\Reflection\PrivatesAccessor;
use Symfony\Component\Console\Command\Command;
require __DIR__ . '/../vendor/autoload.php';
$rootDirectory = __DIR__ . '/..';
$symfonyStyleFactory = new SymfonyStyleFactory(new PrivatesAccessor());
$symfonyStyle = $symfonyStyleFactory->create();
// extension packages move independently (dev-main), so only the in-repo core rules are validated;
// extension rules ship best-effort and the traverser falls back to is_a() resolution for any drift
$siblingNamespacePrefixes = ['Rector\\Symfony\\', 'Rector\\Doctrine\\', 'Rector\\PHPUnit\\'];
$nodeDirectories = [
$rootDirectory . '/vendor/nikic/php-parser/lib/PhpParser/Node',
$rootDirectory . '/src/PhpParser/Node',
];
$nodeRuleMapFactory = new NodeRuleMapFactory(new RectorClassFinder());
$expectedCoreMap = $nodeRuleMapFactory->create([$rootDirectory . '/rules'], $nodeDirectories);
$committedMap = Json::decode(FileSystem::read($rootDirectory . '/config/node-rule-map.json'), true);
if (! is_array($committedMap)) {
$symfonyStyle->error('The committed config/node-rule-map.json is not valid.');
exit(Command::FAILURE);
}
// keep only core rules from the committed map
$committedCoreMap = [];
foreach ($committedMap as $nodeClass => $ruleClasses) {
$coreRuleClasses = array_filter($ruleClasses, static fn (string $ruleClass): bool => array_all($siblingNamespacePrefixes, fn (string $siblingNamespacePrefix): bool => ! str_starts_with($ruleClass, $siblingNamespacePrefix)));
$committedCoreMap[$nodeClass] = array_values($coreRuleClasses);
}
if (Json::encode($committedCoreMap) === Json::encode($expectedCoreMap)) {
$symfonyStyle->success('The core rules in config/node-rule-map.json are up to date.');
exit(Command::SUCCESS);
}
$symfonyStyle->error(
'The core rules in config/node-rule-map.json are out of date. Run "composer build-node-rule-map" and commit the result.'
);
// report the first differing node classes to make the fix obvious
foreach ($expectedCoreMap as $nodeClass => $expectedRuleClasses) {
$committedRuleClasses = $committedCoreMap[$nodeClass] ?? [];
if ($committedRuleClasses === $expectedRuleClasses) {
continue;
}
$symfonyStyle->writeln('<comment>' . $nodeClass . '</comment>');
$symfonyStyle->writeln(' missing: ' . implode(', ', array_values(array_diff($expectedRuleClasses, $committedRuleClasses))));
$symfonyStyle->writeln(' unexpected: ' . implode(', ', array_values(array_diff($committedRuleClasses, $expectedRuleClasses))));
}
exit(Command::FAILURE);