Skip to content

Commit

Permalink
Allow --rule option to take short rule names
Browse files Browse the repository at this point in the history
.. but throw an exception if the name is ambiguous
  • Loading branch information
cweiske committed Nov 26, 2024
1 parent 193ecc4 commit 5849c7e
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/Configuration/OnlyRuleResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Rector\Contract\Rector\RectorInterface;
use Rector\Exception\Configuration\RectorRuleNotFoundException;
use Rector\Exception\Configuration\RectorRuleNameAmbigiousException;

/**
* @see \Rector\Tests\Configuration\OnlyRuleResolverTest
Expand Down Expand Up @@ -38,6 +39,27 @@ public function resolve(string $rule): string
}
}

//allow short rule names if there are not duplicates
$matching = [];
foreach ($this->rectors as $rector) {
if (str_ends_with($rector::class, '\\' . $rule)) {
$matching[] = $rector::class;
}
}
$matching = array_unique($matching);

if (count($matching) == 1) {
return $matching[0];
} elseif (count($matching) > 1) {
sort($matching);
$message = sprintf(
'Short rule name "%s" is ambiguous. Specify the full rule name:' . PHP_EOL
. '- ' . implode(PHP_EOL . '- ', $matching),
$rule
);
throw new RectorRuleNameAmbigiousException($message);
}

if (strpos($rule, '\\') === false) {
$message = sprintf(
'Rule "%s" was not found.%sThe rule has no namespace. Make sure to escape the backslashes, and add quotes around the rule name: --only="My\\Rector\\Rule"',
Expand Down
11 changes: 11 additions & 0 deletions src/Exception/Configuration/RectorRuleNameAmbigiousException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Rector\Exception\Configuration;

use Exception;

final class RectorRuleNameAmbigiousException extends Exception
{
}
29 changes: 29 additions & 0 deletions tests/Configuration/OnlyRuleResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Rector\Configuration\OnlyRuleResolver;
use Rector\Contract\Rector\RectorInterface;
use Rector\Exception\Configuration\RectorRuleNameAmbigiousException;
use Rector\Exception\Configuration\RectorRuleNotFoundException;
use Rector\Testing\PHPUnit\AbstractLazyTestCase;

Expand Down Expand Up @@ -76,4 +77,32 @@ public function testResolveNotFound(): void

$this->resolver->resolve('This\\Rule\\Does\\Not\\Exist');
}

public function testResolveShortOk(): void
{
$this->assertEquals(
\Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector::class,
$this->resolver->resolve('RemoveUnusedPrivateMethodRector'),
);
}

public function testResolveShortOkTwoLevels(): void
{
$this->assertEquals(
\Rector\DeadCode\Rector\Assign\RemoveDoubleAssignRector::class,
$this->resolver->resolve('Assign\\RemoveDoubleAssignRector'),
);
}

public function testResolveShortAmbiguous(): void
{
$this->expectExceptionMessage(
'Short rule name "RemoveDoubleAssignRector" is ambiguous. Specify the full rule name:' . PHP_EOL
. '- Rector\\DeadCode\\Rector\\Assign\\RemoveDoubleAssignRector' . PHP_EOL
. '- Rector\\Tests\\Configuration\\Source\\RemoveDoubleAssignRector'
);
$this->expectException(RectorRuleNameAmbigiousException::class);

$this->resolver->resolve('RemoveDoubleAssignRector');
}
}
28 changes: 28 additions & 0 deletions tests/Configuration/Source/RemoveDoubleAssignRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rector\Tests\Configuration\Source;

use PhpParser\Node;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* Dummy rector with same class name as an official one
*/
class RemoveDoubleAssignRector extends AbstractRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Test short rule name conflicts', []);
}

public function getNodeTypes(): array
{
return [];
}

public function refactor(Node $node): ?Node
{
return $node;
}
}
3 changes: 2 additions & 1 deletion tests/Configuration/config/only_rule_resolver_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\Assign\RemoveDoubleAssignRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\Tests\Configuration\Source\RemoveDoubleAssignRector as RemoveDoubleAssignRectorTest;

return RectorConfig::configure()
->withRules([RemoveDoubleAssignRector::class, RemoveUnusedPrivateMethodRector::class]);
->withRules([RemoveDoubleAssignRector::class, RemoveDoubleAssignRectorTest::class, RemoveUnusedPrivateMethodRector::class]);

0 comments on commit 5849c7e

Please sign in to comment.