Skip to content

Commit

Permalink
[DX] Add MissingInSetCommand, to verify what rules are not part of th…
Browse files Browse the repository at this point in the history
…eir sets (#2594)

* cleanup paths

* make utils single level for easier maintenacne and same pattern as packages

* add MissingInSetCommand

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
TomasVotruba and actions-user committed Jun 30, 2022
1 parent 82b2467 commit 143f743
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 54 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"rules"
],
"Rector\\Core\\": "src",
"Rector\\Compiler\\": "utils/compiler/src"
"Rector\\Utils\\": "utils"
},
"files": [
"src/functions/node_helper.php",
Expand All @@ -100,7 +100,7 @@
"rules-tests"
],
"Rector\\Core\\Tests\\": "tests",
"Rector\\RuleDocGenerator\\": "utils/rule-doc-generator/src",
"Rector\\RuleDocGenerator\\": "utils/RuleDocGenerator/src",
"E2e\\Parallel\\Reflection\\Resolver\\": [
"e2e/parallel-reflection-resolver/src/",
"e2e/no-parallel-reflection-resolver/src"
Expand Down
3 changes: 3 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
use Rector\PSR4\Composer\PSR4NamespaceMatcher;
use Rector\PSR4\Contract\PSR4AutoloadNamespaceMatcherInterface;
use Rector\Utils\Command\MissingInSetCommand;
use Symfony\Component\Console\Application;
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
Expand Down Expand Up @@ -216,4 +217,6 @@

$services->set(DynamicSourceLocatorProvider::class)
->factory([service(PHPStanServicesFactory::class), 'createDynamicSourceLocatorProvider']);

$services->set(MissingInSetCommand::class);
};
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ public function correctItemsByAttributeClass(array|Array_ $items, string $attrib
return $items;
}

$constructorClassMethodReflection = $attributeClassReflection->getConstructor();
$extendedMethodReflection = $attributeClassReflection->getConstructor();

$parametersAcceptor = ParametersAcceptorSelector::selectSingle(
$constructorClassMethodReflection->getVariants()
);
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($extendedMethodReflection->getVariants());

foreach ($items as $name => $item) {
foreach ($parametersAcceptor->getParameters() as $parameterReflection) {
Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -666,3 +666,5 @@ parameters:
-
message: '#New objects with "\$fullyQualifiedObjectType" name are overridden\. This can lead to unwanted bugs, please pick a different name to avoid it#'
path: packages/NodeTypeResolver/PhpDocNodeVisitor/NameImportingPhpDocNodeVisitor.php

- '#Class has a static method must so must contains "Static" in its name#'
35 changes: 7 additions & 28 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
use Rector\CodingStyle\Rector\MethodCall\PreferThisOrSelfMethodCallRector;
use Rector\CodingStyle\ValueObject\ReturnArrayClassMethodToYield;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\StmtsAwareInterface\RemoveJustPropertyFetchRector;
use Rector\Nette\Set\NetteSetList;
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\Php81\Rector\Class_\MyCLabsClassToEnumRector;
use Rector\Php81\Rector\Class_\SpatieEnumClassToEnumRector;
use Rector\PHPUnit\Set\PHPUnitSetList;
use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector;
use Rector\Set\ValueObject\LevelSetList;
Expand Down Expand Up @@ -43,8 +40,6 @@
new ReturnArrayClassMethodToYield('PHPUnit\Framework\TestCase', '*provide*'),
]);

// $rectorConfig->rule(RemoveJustPropertyFetchRector::class);

$rectorConfig->paths([
__DIR__ . '/bin',
__DIR__ . '/src',
Expand All @@ -68,29 +63,13 @@
__DIR__ . '/rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php',
],

MyCLabsClassToEnumRector::class,
SpatieEnumClassToEnumRector::class,

// test paths
'*/tests/**/Fixture/*',
'*/rules-tests/**/Fixture/*',
'*/packages-tests/**/Fixture/*',
'*/tests/**/Fixture*/*',
'*/rules-tests/**/Fixture*/*',
'*/packages-tests/**/Fixture*/*',
// source
'*/tests/**/Source/*',
'*/rules-tests/**/Source/*',
'*/packages-tests/**/Source/*',
'*/tests/**/Source*/*',
'*/rules-tests/**/Source*/*',
'*/packages-tests/**/Source*/*',
'*/tests/**/Expected/*',
'*/rules-tests/**/Expected/*',
'*/packages-tests/**/Expected/*',
'*/tests/**/Expected*/*',
'*/rules-tests/**/Expected*/*',
'*/packages-tests/**/Expected*/*',
// tests
'**/Fixture*',
'**/Fixture/*',
'**/Source*',
'**/Source/*',
'**/Expected/*',
'**/Expected*',
__DIR__ . '/tests/PhpUnit/MultipleFilesChangedTrait/MultipleFilesChangedTraitTest.php',

// to keep original API from PHPStan untouched
Expand Down
2 changes: 1 addition & 1 deletion rule-doc-generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

use Rector\RuleDocGenerator\Category\RectorCategoryInferer;
use Rector\Utils\RuleDocGenerator\Category\RectorCategoryInferer;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $rectorConfig): void {
Expand Down
2 changes: 1 addition & 1 deletion scoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use Isolated\Symfony\Component\Finder\Finder;
use Nette\Utils\DateTime;
use Nette\Utils\Strings;
use Rector\Compiler\Unprefixer;
use Rector\Core\Application\VersionResolver;
use Rector\Utils\Compiler\Unprefixer;

require_once __DIR__ . '/vendor/autoload.php';

Expand Down
100 changes: 100 additions & 0 deletions utils/Command/MissingInSetCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

declare(strict_types=1);

namespace Rector\Utils\Command;

use Nette\Loaders\RobotLoader;
use Nette\Utils\FileSystem;
use Nette\Utils\Strings;
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 array<string, string>
*/
private const SETS_TO_RULES_DIRECTORIES = [
__DIR__ . '/../../config/set/code-quality.php' => __DIR__ . '/../../rules/CodeQuality/Rector',
__DIR__ . '/../../config/set/coding-style.php' => __DIR__ . '/../../rules/CodingStyle/Rector',
__DIR__ . '/../../config/set/dead-code.php' => __DIR__ . '/../../rules/DeadCode/Rector',
__DIR__ . '/../../config/set/early-return.php' => __DIR__ . '/../../rules/EarlyReturn/Rector',
];

/**
* @see https://regex101.com/r/HuWjgn/1
* @var string
*/
private const SHORT_CLASS_REGEX = '#(?<short_class_name>\w+)::class#m';

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
{
foreach (self::SETS_TO_RULES_DIRECTORIES as $setFile => $rulesDirectory) {
$shortClassesInSetFile = $this->resolveShortClassesFromSetFile($setFile);
$existingShortRectorClasses = $this->findShortRectorClasses($rulesDirectory);

$shortRectorClassesNotInSetConfig = array_diff($existingShortRectorClasses, $shortClassesInSetFile);

if ($shortRectorClassesNotInSetConfig === []) {
continue;
}

$title = sprintf('In "%s" config we could not find', $setFile);
$this->symfonyStyle->title($title);
$this->symfonyStyle->listing($shortRectorClassesNotInSetConfig);
$this->symfonyStyle->newLine(2);
}

return self::SUCCESS;
}

/**
* @return string[]
*/
private function resolveShortClassesFromSetFile(string $setFile): array
{
$setFileContents = FileSystem::read($setFile);
$matches = Strings::matchAll($setFileContents, self::SHORT_CLASS_REGEX);

$shortClasses = [];
foreach ($matches as $match) {
$shortClasses[] = $match['short_class_name'];
}

return $shortClasses;
}

/**
* @return string[]
*/
private function findShortRectorClasses(string $rulesDirectory): array
{
$robotLoader = new RobotLoader();
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/rector-missing-in-set');
$robotLoader->addDirectory($rulesDirectory);
$robotLoader->rebuild();

$existingRectorClasses = array_keys($robotLoader->getIndexedClasses());
$existingRectorShortClasses = [];
foreach ($existingRectorClasses as $existingRectorClass) {
$existingRectorShortClasses[] = (string) Strings::after($existingRectorClass, '\\', -1);
}

return $existingRectorShortClasses;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Rector\Compiler;
namespace Rector\Utils\Compiler;

use Nette\Utils\Strings;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Rector\RuleDocGenerator\Category;
namespace Rector\Utils\RuleDocGenerator\Category;

use Nette\Utils\Strings;
use Rector\Core\Exception\ShouldNotHappenException;
Expand Down
16 changes: 0 additions & 16 deletions utils/compiler/config/config.php

This file was deleted.

0 comments on commit 143f743

Please sign in to comment.