diff --git a/src/Configuration/OnlyRuleResolver.php b/src/Configuration/OnlyRuleResolver.php index 39a49e50872..2667ddef002 100644 --- a/src/Configuration/OnlyRuleResolver.php +++ b/src/Configuration/OnlyRuleResolver.php @@ -63,6 +63,19 @@ public function resolve(string $rule): string } if (! str_contains($rule, '\\')) { + // the shell has eaten unescaped backslashes, e.g. --only=\Rector\Some\Rule + $flattenMatching = []; + foreach ($this->rectors as $rector) { + if (str_replace('\\', '', $rector::class) === $rule) { + $flattenMatching[] = $rector::class; + } + } + + $flattenMatching = array_unique($flattenMatching); + if (count($flattenMatching) === 1) { + return $flattenMatching[0]; + } + $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"', $rule, diff --git a/tests/Configuration/OnlyRuleResolverTest.php b/tests/Configuration/OnlyRuleResolverTest.php index eae493ddd63..8af2df9fd26 100644 --- a/tests/Configuration/OnlyRuleResolverTest.php +++ b/tests/Configuration/OnlyRuleResolverTest.php @@ -63,14 +63,23 @@ public function testResolveOkSingleQuotes(): void } public function testResolveMissingBackslash(): void + { + $this->assertSame( + RemoveDoubleAssignRector::class, + $this->onlyRuleResolver->resolve('RectorDeadCodeRectorAssignRemoveDoubleAssignRector'), + 'The shell eats unescaped backslashes, resolve the flattened rule name anyway' + ); + } + + public function testResolveMissingBackslashNotFound(): void { $this->expectExceptionMessageIsOrContains( - 'Rule "RectorDeadCodeRectorAssignRemoveDoubleAssignRector" was not found.' . PHP_EOL + 'Rule "ThisRuleDoesNotExist" was not found.' . PHP_EOL . 'The rule has no namespace. Make sure to escape the backslashes, and add quotes around the rule name: --only="My\\Rector\\Rule"' ); $this->expectException(RectorRuleNotFoundException::class); - $this->onlyRuleResolver->resolve('RectorDeadCodeRectorAssignRemoveDoubleAssignRector'); + $this->onlyRuleResolver->resolve('ThisRuleDoesNotExist'); } public function testResolveNotFound(): void