Skip to content

Commit e3c4ee7

Browse files
committed
Updated Rector to commit 3893ea422afa3fb801ae64fa546c8a2cb24b0f97
rectorphp/rector-src@3893ea4 [reporting] Group unused skips by rule, skip reporting on narrowed runs (#8069)
1 parent bdd26a9 commit e3c4ee7

4 files changed

Lines changed: 53 additions & 14 deletions

File tree

src/Application/VersionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ final class VersionResolver
1919
* @api
2020
* @var string
2121
*/
22-
public const PACKAGE_VERSION = '580b374ea3638fd50cf9b98b84445cd9fe53768e';
22+
public const PACKAGE_VERSION = '3893ea422afa3fb801ae64fa546c8a2cb24b0f97';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-06-21 00:26:52';
27+
public const RELEASE_DATE = '2026-06-21 00:55:12';
2828
/**
2929
* @var int
3030
*/

src/Configuration/ConfigurationFactory.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public function createFromInput(InputInterface $input): Configuration
5353
$onlyRule = $this->onlyRuleResolver->resolve($onlyRule);
5454
}
5555
$onlySuffix = $input->getOption(\Rector\Configuration\Option::ONLY_SUFFIX);
56+
// "--only"/"--only-suffix" narrow the run, so skips outside the scope look falsely unused;
57+
// mark the run as narrowed to disable unused skip reporting and avoid false positives
58+
if ($onlyRule !== null || $onlySuffix !== null) {
59+
SimpleParameterProvider::setParameter(\Rector\Configuration\Option::IS_RUN_NARROWED, \true);
60+
}
5661
$isParallel = SimpleParameterProvider::provideBoolParameter(\Rector\Configuration\Option::PARALLEL);
5762
$parallelPort = (string) $input->getOption(\Rector\Configuration\Option::PARALLEL_PORT);
5863
$parallelIdentifier = (string) $input->getOption(\Rector\Configuration\Option::PARALLEL_IDENTIFIER);
@@ -95,6 +100,8 @@ private function resolvePaths(InputInterface $input): array
95100
$commandLinePaths = (array) $input->getArgument(\Rector\Configuration\Option::SOURCE);
96101
// give priority to command line
97102
if ($commandLinePaths !== []) {
103+
// mark the run as narrowed, so unused skip reporting can be disabled to avoid false positives
104+
SimpleParameterProvider::setParameter(\Rector\Configuration\Option::IS_RUN_NARROWED, \true);
98105
$this->setFilesWithoutExtensionParameter($commandLinePaths);
99106
return $commandLinePaths;
100107
}

src/Configuration/Option.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ final class Option
123123
* @var string
124124
*/
125125
public const REPORT_UNUSED_SKIPS = 'report_unused_skips';
126+
/**
127+
* True when the run is narrowed on the command line - via paths argument, "--only" or
128+
* "--only-suffix". Unused skip reporting is then disabled, as skips outside the narrowed scope
129+
* look falsely unused and would produce many false positives.
130+
*
131+
* @internal
132+
* @var string
133+
*/
134+
public const IS_RUN_NARROWED = 'is_run_narrowed';
126135
/**
127136
* @internal Use RectorConfig::fileExtensions() instead
128137
* @var string

src/Reporting/UnusedSkipResolver.php

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public function __construct(SkippedClassResolver $skippedClassResolver, SkippedP
3434
}
3535
/**
3636
* Resolves skips configured via "->withSkip()" that never matched any element during the run.
37-
* Rule-scoped skips are returned as "rule => path" so the user knows exactly what to remove;
38-
* global skips are returned as a plain path. Returns an empty array unless
39-
* "->reportUnusedSkips()" is enabled.
37+
* Rule-scoped skips are grouped under their rule ("rule => path", or "rule => [ path\n path ]"
38+
* for multiple paths) so the user knows exactly what to remove; global skips are returned as a
39+
* plain path. Returns an empty array unless "->reportUnusedSkips()" is enabled.
4040
*
4141
* @return string[]
4242
*/
@@ -45,32 +45,55 @@ public function resolve(ProcessResult $processResult): array
4545
if (!SimpleParameterProvider::provideBoolParameter(Option::REPORT_UNUSED_SKIPS, \false)) {
4646
return [];
4747
}
48-
// map of trackable skip path => human-readable display; skips are tracked at runtime by
49-
// their path, but rule-scoped ones are printed as "rule => path" so the user knows exactly
50-
// what to remove. Skip-everywhere rule skips (null path) are forgotten from the container
51-
// at boot, so they never reach the skipper and cannot be tracked.
52-
$skipDisplaysByPath = [];
48+
// a narrowed run (cli paths, "--only" or "--only-suffix") only touches part of the codebase,
49+
// so skips outside that scope look falsely unused - reporting them would be noise
50+
if (SimpleParameterProvider::provideBoolParameter(Option::IS_RUN_NARROWED, \false)) {
51+
return [];
52+
}
53+
// map of rule => (trackable skip path => relative display path); skips are tracked at
54+
// runtime by their path, but rule-scoped ones are printed grouped under their rule so the
55+
// user knows exactly what to remove. Skip-everywhere rule skips (null path) are forgotten
56+
// from the container at boot, so they never reach the skipper and cannot be tracked.
57+
$relativePathsByClass = [];
5358
foreach ($this->skippedClassResolver->resolve() as $rectorClass => $paths) {
5459
if ($paths === null) {
5560
continue;
5661
}
5762
// rule-scoped paths are intentional, so they are reported even as mask paths
5863
foreach ($paths as $path) {
59-
$skipDisplaysByPath[$path] = $rectorClass . ' => ' . $this->filePathHelper->relativePath($path);
64+
$relativePathsByClass[$rectorClass][$path] = $this->filePathHelper->relativePath($path);
6065
}
6166
}
6267
// global mask paths like "*/some/*" are hard to spot and report false positives, skip them
68+
$globalRelativePaths = [];
6369
foreach ($this->skippedPathsResolver->resolve() as $globalPath) {
6470
if (strpos($globalPath, '*') !== \false) {
6571
continue;
6672
}
67-
$skipDisplaysByPath[$globalPath] = $this->filePathHelper->relativePath($globalPath);
73+
$globalRelativePaths[$globalPath] = $this->filePathHelper->relativePath($globalPath);
6874
}
6975
$usedSkips = $processResult->getUsedSkips();
7076
$unusedSkips = [];
71-
foreach ($skipDisplaysByPath as $path => $skipDisplay) {
77+
// group unused rule-scoped paths under their rule, matching the "->withSkip()" config shape
78+
foreach ($relativePathsByClass as $rectorClass => $relativePaths) {
79+
$unusedRelativePaths = [];
80+
foreach ($relativePaths as $path => $relativePath) {
81+
if (!in_array($path, $usedSkips, \true)) {
82+
$unusedRelativePaths[] = $relativePath;
83+
}
84+
}
85+
if ($unusedRelativePaths === []) {
86+
continue;
87+
}
88+
if (count($unusedRelativePaths) === 1) {
89+
$unusedSkips[] = $rectorClass . ' => ' . $unusedRelativePaths[0];
90+
continue;
91+
}
92+
$unusedSkips[] = $rectorClass . ' => [ ' . implode("\n ", $unusedRelativePaths) . ' ]';
93+
}
94+
foreach ($globalRelativePaths as $path => $relativePath) {
7295
if (!in_array($path, $usedSkips, \true)) {
73-
$unusedSkips[] = $skipDisplay;
96+
$unusedSkips[] = $relativePath;
7497
}
7598
}
7699
return $unusedSkips;

0 commit comments

Comments
 (0)