diff --git a/src/Application/ApplicationFileProcessor.php b/src/Application/ApplicationFileProcessor.php index 932593d032f..98f75c0d14e 100644 --- a/src/Application/ApplicationFileProcessor.php +++ b/src/Application/ApplicationFileProcessor.php @@ -173,7 +173,11 @@ private function processFile(File $file, Configuration $configuration): FileProc if ($fileProcessResult->getSystemErrors() !== []) { $this->changedFilesDetector->invalidateFile($file->getFilePath()); } elseif (! $configuration->isDryRun() || ! $fileProcessResult->getFileDiff() instanceof FileDiff) { - $this->changedFilesDetector->cacheFile($file->getFilePath()); + // a file clean under a subset of rules is not necessarily clean under all rules, + // caching it would hide its pending changes from the next full run + if ($configuration->getOnlyRule() === null && $configuration->getOnlySuffix() === null) { + $this->changedFilesDetector->cacheFile($file->getFilePath()); + } } return $fileProcessResult; diff --git a/tests/Application/ApplicationFileProcessor/ApplicationFileProcessorTest.php b/tests/Application/ApplicationFileProcessor/ApplicationFileProcessorTest.php new file mode 100644 index 00000000000..09c75c0c246 --- /dev/null +++ b/tests/Application/ApplicationFileProcessor/ApplicationFileProcessorTest.php @@ -0,0 +1,65 @@ +applicationFileProcessor = $this->make(ApplicationFileProcessor::class); + $this->changedFilesDetector = $this->make(ChangedFilesDetector::class); + } + + protected function tearDown(): void + { + $this->changedFilesDetector->clear(); + } + + public function testCleanFileIsCachedAsUnchanged(): void + { + $filePath = __DIR__ . '/Source/CleanFile.php'; + + $this->applicationFileProcessor->processFiles([$filePath], new Configuration(isDryRun: true)); + + $this->assertFalse($this->changedFilesDetector->hasFileChanged($filePath)); + } + + public function testOnlyRuleRunDoesNotCacheFileAsUnchanged(): void + { + $filePath = __DIR__ . '/Source/CleanFile.php'; + + $this->applicationFileProcessor->processFiles([$filePath], new Configuration( + isDryRun: true, + onlyRule: RemoveEmptyClassMethodRector::class + )); + + // a file clean under one rule is not necessarily clean under all rules + $this->assertTrue($this->changedFilesDetector->hasFileChanged($filePath)); + } + + public function testOnlySuffixRunDoesNotCacheFileAsUnchanged(): void + { + $filePath = __DIR__ . '/Source/CleanFile.php'; + + $this->applicationFileProcessor->processFiles([$filePath], new Configuration( + isDryRun: true, + onlySuffix: 'Controller.php' + )); + + $this->assertTrue($this->changedFilesDetector->hasFileChanged($filePath)); + } +} diff --git a/tests/Application/ApplicationFileProcessor/Source/CleanFile.php b/tests/Application/ApplicationFileProcessor/Source/CleanFile.php new file mode 100644 index 00000000000..4dce24c580d --- /dev/null +++ b/tests/Application/ApplicationFileProcessor/Source/CleanFile.php @@ -0,0 +1,13 @@ +