Skip to content

Commit c467f61

Browse files
Fix slug same class name but different set (#3534)
* Fix slug same class name but different set * [rector] Rector fixes * [rector] Rector fixes * Fix only add sets prefix when there is duplicated name * Fix only add sets prefix when there is duplicated name * [rector] Rector fixes * add test for duplicated short name to have set prefix on slug --------- Co-authored-by: GitHub Action <actions@github.com>
1 parent 3404d10 commit c467f61

4 files changed

Lines changed: 117 additions & 9 deletions

File tree

src/FileSystem/RectorFinder.php

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,10 @@ private function findInDirectoriesAndCreateRuleMetadatas(array $directories, arr
140140

141141
$ruleMetadatas = [];
142142

143-
foreach ($this->findRectorClasses($directories) as $rectorClass) {
144-
$rectorReflectionClass = new ReflectionClass($rectorClass);
143+
$findRectorClasses = $this->findRectorClasses($directories);
144+
145+
foreach ($findRectorClasses as $findRectorClass) {
146+
$rectorReflectionClass = new ReflectionClass($findRectorClass);
145147
if ($rectorReflectionClass->isAbstract()) {
146148
continue;
147149
}
@@ -171,14 +173,14 @@ private function findInDirectoriesAndCreateRuleMetadatas(array $directories, arr
171173
throw new InvalidRuleDescriptionException(
172174
sprintf(
173175
'Rule "%s" has invalid code samples:%s"%s"',
174-
$rectorClass,
176+
$findRectorClass,
175177
PHP_EOL . PHP_EOL,
176178
$throwable->getMessage()
177179
)
178180
);
179181
}
180182

181-
$ruleDefinition->setRuleClass($rectorClass);
183+
$ruleDefinition->setRuleClass($findRectorClass);
182184

183185
$currentRuleSets = $this->findRuleUsedSets($ruleDefinition, $rectorSets);
184186

@@ -187,10 +189,30 @@ private function findInDirectoriesAndCreateRuleMetadatas(array $directories, arr
187189
$ruleDefinition->getDescription(),
188190
$ruleDefinition->getCodeSamples(),
189191
$currentRuleSets,
190-
(string) $rectorReflectionClass->getFileName()
192+
(string) $rectorReflectionClass->getFileName(),
193+
$this->isDuplicatedLastName($findRectorClasses, $rectorReflectionClass->getShortName())
191194
);
192195
}
193196

194197
return $ruleMetadatas;
195198
}
199+
200+
/**
201+
* @param array<class-string<RectorInterface>> $findRectorClasses
202+
*/
203+
private function isDuplicatedLastName(array $findRectorClasses, string $lastName): bool
204+
{
205+
$count = 0;
206+
foreach ($findRectorClasses as $findRectorClass) {
207+
if (\str_ends_with($findRectorClass, '\\' . $lastName)) {
208+
++$count;
209+
210+
if ($count === 2) {
211+
return true;
212+
}
213+
}
214+
}
215+
216+
return false;
217+
}
196218
}

src/RuleFilter/ValueObject/RuleMetadata.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public function __construct(
2929
private readonly string $description,
3030
private array $codeSamples,
3131
private readonly array $sets,
32-
private readonly string $rectorRuleFilePath
32+
private readonly string $rectorRuleFilePath,
33+
private readonly bool $sameNameInDifferentSet
3334
) {
3435
Assert::isAOf($ruleClass, RectorInterface::class);
3536
Assert::allIsAOf($sets, RectorSet::class);
@@ -43,9 +44,26 @@ public function getRuleShortClass(): string
4344
public function getSlug(): string
4445
{
4546
// turn "SomeRector" to "some-rector"
46-
return str($this->getRuleShortClass())
47+
$lastSlug = str($this->getRuleShortClass())
4748
->snake('-')
4849
->toString();
50+
51+
if ($this->sameNameInDifferentSet === false) {
52+
return $lastSlug;
53+
}
54+
55+
$currentSet = current($this->sets);
56+
57+
if ($currentSet === false) {
58+
return $lastSlug;
59+
}
60+
61+
$slug = $currentSet->getSlug();
62+
if ($slug !== '') {
63+
$slug .= '-';
64+
}
65+
66+
return $slug . $lastSlug;
4967
}
5068

5169
public function getDescription(): string
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Tests\FileSystem;
6+
7+
use App\FileSystem\RectorFinder;
8+
use App\Sets\RectorSetsTreeProvider;
9+
use PHPUnit\Framework\TestCase;
10+
use Rector\Php84\Rector\Class_\DeprecatedAnnotationToDeprecatedAttributeRector;
11+
12+
final class RectorFinderTest extends TestCase
13+
{
14+
private RectorFinder $rectorFinder;
15+
16+
protected function setUp(): void
17+
{
18+
$this->rectorFinder = new RectorFinder(new RectorSetsTreeProvider());
19+
}
20+
21+
public function testFindDuplicated(): void
22+
{
23+
$foundRectors = $this->rectorFinder->find();
24+
25+
$shortNames = [];
26+
$longNames = [];
27+
foreach ($foundRectors as $ruleMetadata) {
28+
$shortNames[] = $ruleMetadata->getRuleShortClass();
29+
$longNames[] = $ruleMetadata->getRectorClass();
30+
}
31+
32+
$uniqueShortNames = array_unique($shortNames);
33+
$uniqueLongNames = array_unique($longNames);
34+
35+
$this->assertNotSame(
36+
count($uniqueShortNames),
37+
count($uniqueLongNames),
38+
'There are duplicated short class names.'
39+
);
40+
41+
// get duplicated short names and report different slug
42+
$duplicatedShortNames = array_diff_key($shortNames, $uniqueShortNames);
43+
44+
$this->assertContains(
45+
'DeprecatedAnnotationToDeprecatedAttributeRector',
46+
$duplicatedShortNames,
47+
'Expected DeprecatedAnnotationToDeprecatedAttributeRector to be one of the duplicated short names.'
48+
);
49+
50+
foreach ($foundRectors as $foundRector) {
51+
if ($foundRector->getRectorClass() === DeprecatedAnnotationToDeprecatedAttributeRector::class) {
52+
$this->assertSame(
53+
'php-php-84-deprecated-annotation-to-deprecated-attribute-rector',
54+
$foundRector->getSlug()
55+
);
56+
}
57+
58+
if ($foundRector->getRectorClass() === \Rector\Php85\Rector\Const_\DeprecatedAnnotationToDeprecatedAttributeRector::class) {
59+
$this->assertSame(
60+
'php-php-85-deprecated-annotation-to-deprecated-attribute-rector',
61+
$foundRector->getSlug()
62+
);
63+
}
64+
}
65+
}
66+
}

tests/RuleFilter/RuleFilterTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ public function testFilterBySetGroup(): void
2020
'Some description',
2121
[],
2222
[],
23-
'some-rector.php'
23+
'some-rector.php',
24+
false
2425
);
2526
$ruleMetadataCommunity = new RuleMetadata(
2627
MigrateToSimplifiedAttributeRector::class,
2728
'Some description',
2829
[],
2930
[],
30-
'some-rector.php'
31+
'some-rector.php',
32+
false,
3133
);
3234

3335
$ruleFilter = $this->make(RuleFilter::class);

0 commit comments

Comments
 (0)