From eee6cea92caf34839b319c3eac60a433d2f53b24 Mon Sep 17 00:00:00 2001 From: Gabriel Vieira <48625433+gvieira18@users.noreply.github.com> Date: Tue, 3 Nov 2026 21:03:31 -0300 Subject: [PATCH 1/2] fix(json): list only real changes in changed_files A FileDiff also records a rule that printed identical code. With --no-diffs every diff is empty, so FileDiff carries the changed state. --- .../Output/Factory/JsonOutputFactory.php | 4 ++- .../ValueObjectFactory/FileDiffFactory.php | 8 ++++- src/Parallel/ValueObject/BridgeItem.php | 2 ++ src/ValueObject/Reporting/FileDiff.php | 12 +++++-- .../Output/Factory/JsonOutputFactoryTest.php | 35 +++++++++++++++++++ tests/ValueObject/Reporting/FileDiffTest.php | 9 +++++ 6 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/ChangesReporting/Output/Factory/JsonOutputFactory.php b/src/ChangesReporting/Output/Factory/JsonOutputFactory.php index de0bf4e0d11..86158a45c31 100644 --- a/src/ChangesReporting/Output/Factory/JsonOutputFactory.php +++ b/src/ChangesReporting/Output/Factory/JsonOutputFactory.php @@ -56,7 +56,9 @@ public static function create( } // for Rector CI - $errorsJson['changed_files'][] = $filePath; + if ($fileDiff->hasChanged()) { + $errorsJson['changed_files'][] = $filePath; + } } $systemErrors = $processResult->getSystemErrors(); diff --git a/src/ChangesReporting/ValueObjectFactory/FileDiffFactory.php b/src/ChangesReporting/ValueObjectFactory/FileDiffFactory.php index 0a01e41aaae..79387cde0e2 100644 --- a/src/ChangesReporting/ValueObjectFactory/FileDiffFactory.php +++ b/src/ChangesReporting/ValueObjectFactory/FileDiffFactory.php @@ -36,6 +36,12 @@ public function createFileDiffWithLineChanges( $consoleDiff = $shouldShowDiffs ? $this->colorConsoleDiffFormatter->format($diff) : ''; // always keep the most recent diff - return new FileDiff($relativeFilePath, $diff, $consoleDiff, $rectorsWithLineChanges); + return new FileDiff( + $relativeFilePath, + $diff, + $consoleDiff, + $rectorsWithLineChanges, + $file->hasChanged() + ); } } diff --git a/src/Parallel/ValueObject/BridgeItem.php b/src/Parallel/ValueObject/BridgeItem.php index f0406a447ce..ab635b25197 100644 --- a/src/Parallel/ValueObject/BridgeItem.php +++ b/src/Parallel/ValueObject/BridgeItem.php @@ -24,4 +24,6 @@ final class BridgeItem public const string RECTOR_CLASS = 'rector_class'; public const string RECTORS_WITH_LINE_CHANGES = 'rectors_with_line_changes'; + + public const string HAS_CHANGED = 'has_changed'; } diff --git a/src/ValueObject/Reporting/FileDiff.php b/src/ValueObject/Reporting/FileDiff.php index f5c1cb5c283..5fa9b4d465b 100644 --- a/src/ValueObject/Reporting/FileDiff.php +++ b/src/ValueObject/Reporting/FileDiff.php @@ -34,7 +34,8 @@ public function __construct( private string $relativeFilePath, private string $diff, private string $diffConsoleFormatted, - private array $rectorsWithLineChanges = [] + private array $rectorsWithLineChanges = [], + private bool $hasChanged = true ) { Assert::allIsInstanceOf($rectorsWithLineChanges, RectorWithLineChange::class); } @@ -44,6 +45,11 @@ public function getDiff(): string return $this->diff; } + public function hasChanged(): bool + { + return $this->hasChanged; + } + public function getDiffConsoleFormatted(): string { return $this->diffConsoleFormatted; @@ -128,7 +134,7 @@ public function getLastLineNumber(): ?int } /** - * @return array{relative_file_path: string, diff: string, diff_console_formatted: string, rectors_with_line_changes: RectorWithLineChange[]} + * @return array{relative_file_path: string, diff: string, diff_console_formatted: string, rectors_with_line_changes: RectorWithLineChange[], has_changed: bool} */ public function jsonSerialize(): array { @@ -137,6 +143,7 @@ public function jsonSerialize(): array BridgeItem::DIFF => $this->diff, BridgeItem::DIFF_CONSOLE_FORMATTED => $this->diffConsoleFormatted, BridgeItem::RECTORS_WITH_LINE_CHANGES => $this->rectorsWithLineChanges, + BridgeItem::HAS_CHANGED => $this->hasChanged, ]; } @@ -156,6 +163,7 @@ public static function decode(array $json): self $json[BridgeItem::DIFF], $json[BridgeItem::DIFF_CONSOLE_FORMATTED], $rectorWithLineChanges, + $json[BridgeItem::HAS_CHANGED], ); } } diff --git a/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php b/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php index 5fcbac8f444..e66fc59dac8 100644 --- a/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php +++ b/tests/ChangesReporting/Output/Factory/JsonOutputFactoryTest.php @@ -70,4 +70,39 @@ public function testReportShouldAttributeEachRectorToItsLine(): void $expectedOutput = (string) file_get_contents(__DIR__ . '/../Fixtures/with_diffs.json'); $this->assertSame($expectedOutput, $actualOutput); } + + public function testReportShouldSkipUnchangedFileWithNoDiffs(): void + { + $actualOutput = JsonOutputFactory::create( + new ProcessResult( + [new SystemError('Some error message', 'some/file.php', 1)], + [ + new FileDiff( + 'some/file.php', + "--- Original\n+++ New\n@@ -38,5 +39,6 @@\nreturn true;\n}\n", + 'diff console formatted', + [new RectorWithLineChange(StrStartsWithRector::class, 38)] + ), + new FileDiff( + 'some/file_foo.php', + '', + '', + [new RectorWithLineChange(StrStartsWithRector::class, 38)] + ), + new FileDiff( + 'some/file_unchanged.php', + '', + '', + [new RectorWithLineChange(StrStartsWithRector::class, 5)], + hasChanged: false + ), + ], + 2 + ), + new Configuration(showDiffs: false) + ); + + $expectedOutput = (string) file_get_contents(__DIR__ . '/../Fixtures/without_diffs.json'); + $this->assertSame($expectedOutput, $actualOutput); + } } diff --git a/tests/ValueObject/Reporting/FileDiffTest.php b/tests/ValueObject/Reporting/FileDiffTest.php index 0cf0269cb1f..3e28451ffa4 100644 --- a/tests/ValueObject/Reporting/FileDiffTest.php +++ b/tests/ValueObject/Reporting/FileDiffTest.php @@ -9,6 +9,15 @@ final class FileDiffTest extends TestCase { + public function testDecodeShouldKeepUnchangedState(): void + { + $fileDiff = new FileDiff('some/file.php', '', '', [], hasChanged: false); + + $decodedFileDiff = FileDiff::decode($fileDiff->jsonSerialize()); + + $this->assertFalse($decodedFileDiff->hasChanged()); + } + public function testGetFirstLineNumberShouldReturnFirstLineNumberRegardingHunk(): void { $fileDiff = new FileDiff( From e06086c9be224ea26bd557bc201d7292390b421e Mon Sep 17 00:00:00 2001 From: Gabriel Vieira <48625433+gvieira18@users.noreply.github.com> Date: Tue, 3 Nov 2026 22:18:44 -0300 Subject: [PATCH 2/2] test(e2e): cover false json changed_files entries Each file prints identical code but a name importing post rector records a change, so the list must not contain it. --- e2e/applied-no-diffs-format-json/rector.php | 2 ++ .../src/AliasedSameShortName.php | 14 ++++++++++++++ .../src/AnonymousClassDocblock.php | 7 +++++++ ...obal_class_constant_twice_without_namespace.php | 3 +++ .../global_class_new_twice_without_namespace.php | 4 ++++ .../global_class_type_twice_without_namespace.php | 6 ++++++ 6 files changed, 36 insertions(+) create mode 100644 e2e/applied-no-diffs-format-json/src/AliasedSameShortName.php create mode 100644 e2e/applied-no-diffs-format-json/src/AnonymousClassDocblock.php create mode 100644 e2e/applied-no-diffs-format-json/src/global_class_constant_twice_without_namespace.php create mode 100644 e2e/applied-no-diffs-format-json/src/global_class_new_twice_without_namespace.php create mode 100644 e2e/applied-no-diffs-format-json/src/global_class_type_twice_without_namespace.php diff --git a/e2e/applied-no-diffs-format-json/rector.php b/e2e/applied-no-diffs-format-json/rector.php index f6c45db6f97..af0dc16c99b 100644 --- a/e2e/applied-no-diffs-format-json/rector.php +++ b/e2e/applied-no-diffs-format-json/rector.php @@ -13,4 +13,6 @@ $rectorConfig->rules([ RemoveAlwaysElseRector::class, ]); + + $rectorConfig->importNames(); }; diff --git a/e2e/applied-no-diffs-format-json/src/AliasedSameShortName.php b/e2e/applied-no-diffs-format-json/src/AliasedSameShortName.php new file mode 100644 index 00000000000..f46799880bf --- /dev/null +++ b/e2e/applied-no-diffs-format-json/src/AliasedSameShortName.php @@ -0,0 +1,14 @@ + */ class([]) extends ArrayIterator {}; diff --git a/e2e/applied-no-diffs-format-json/src/global_class_constant_twice_without_namespace.php b/e2e/applied-no-diffs-format-json/src/global_class_constant_twice_without_namespace.php new file mode 100644 index 00000000000..32f7a907f76 --- /dev/null +++ b/e2e/applied-no-diffs-format-json/src/global_class_constant_twice_without_namespace.php @@ -0,0 +1,3 @@ +