diff --git a/src/Analyser/ResultCache/ResultCacheClearer.php b/src/Analyser/ResultCache/ResultCacheClearer.php index d511a3fa92..03d7b43671 100644 --- a/src/Analyser/ResultCache/ResultCacheClearer.php +++ b/src/Analyser/ResultCache/ResultCacheClearer.php @@ -4,7 +4,6 @@ use Symfony\Component\Finder\Finder; use function dirname; -use function is_file; use function unlink; class ResultCacheClearer @@ -17,11 +16,11 @@ public function __construct(private string $cacheFilePath, private string $tempR public function clear(): string { $dir = dirname($this->cacheFilePath); - if (!is_file($this->cacheFilePath)) { - return $dir; - } - @unlink($this->cacheFilePath); + $finder = new Finder(); + foreach ($finder->files()->depth(0)->name('resultCache*.php')->in($dir) as $resultCacheFile) { + @unlink($resultCacheFile->getPathname()); + } return $dir; } diff --git a/src/Analyser/ResultCache/ResultCacheManager.php b/src/Analyser/ResultCache/ResultCacheManager.php index 9631426b1b..5d7d225f6c 100644 --- a/src/Analyser/ResultCache/ResultCacheManager.php +++ b/src/Analyser/ResultCache/ResultCacheManager.php @@ -27,11 +27,13 @@ use function array_unique; use function array_values; use function count; +use function dirname; use function get_loaded_extensions; use function is_array; use function is_file; use function is_string; use function ksort; +use function md5; use function sha1; use function sort; use function sprintf; @@ -99,11 +101,10 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ? return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], [], []); } - $cacheFilePath = $this->cacheFilePath; + $cacheFilePath = $this->getCacheFilePath($resultCacheName, $projectConfigArray); if ($resultCacheName !== null) { - $tmpCacheFile = $this->tempResultCachePath . '/' . $resultCacheName . '.php'; - if (is_file($tmpCacheFile)) { - $cacheFilePath = $tmpCacheFile; + if (!is_file($cacheFilePath)) { + $cacheFilePath = $this->cacheFilePath; } } @@ -578,16 +579,13 @@ private function save( ksort($exportedNodes); - $file = $this->cacheFilePath; - if ($resultCacheName !== null) { - $file = $this->tempResultCachePath . '/' . $resultCacheName . '.php'; - } - $projectConfigArray = $meta['projectConfig']; if ($projectConfigArray !== null) { $meta['projectConfig'] = Neon::encode($projectConfigArray); } + $file = $this->getCacheFilePath($resultCacheName, $projectConfigArray); + FileWriter::write( $file, sprintf( @@ -603,6 +601,27 @@ private function save( ); } + /** + * @param mixed[]|null $projectConfig + */ + private function getCacheFilePath(?string $resultCacheName, ?array $projectConfig): string + { + if ($resultCacheName !== null) { + return $this->tempResultCachePath . '/' . $resultCacheName . '.php'; + } + + if ($projectConfig !== null && + array_key_exists('parameters', $projectConfig) && + !array_key_exists('resultCachePath', $projectConfig['parameters']) && + (!array_key_exists('tmpDir', $projectConfig['parameters']) || $projectConfig['parameters']['tmpDir'] === null) + ) { + + return dirname($this->cacheFilePath) . '/resultCache-' . md5(Neon::encode([$this->analysedPaths, ComposerHelper::getPhpStanVersion()])) . '.php'; + } + + return $this->cacheFilePath; + } + /** * @param mixed[]|null $projectConfig * @param array $dependencies diff --git a/tests/e2e/ResultCacheEndToEndTest.php b/tests/e2e/ResultCacheEndToEndTest.php index 3ba8efae97..62b6bf2d7f 100644 --- a/tests/e2e/ResultCacheEndToEndTest.php +++ b/tests/e2e/ResultCacheEndToEndTest.php @@ -10,9 +10,11 @@ use PHPUnit\Framework\TestCase; use function array_map; use function chdir; +use function count; use function escapeshellarg; use function exec; use function file_put_contents; +use function glob; use function implode; use function ksort; use function sort; @@ -136,6 +138,15 @@ public function testResultCachePath(): void $this->assertResultCache(__DIR__ . '/resultCache_1.php', sys_get_temp_dir() . '/phpstan/myResultCacheFile.php'); } + public function testSeparateResultCachePath(): void + { + $this->runPhpstan(0, __DIR__ . '/phpstan_separate_cache.neon'); + + $resultCacheFiles = glob(sys_get_temp_dir() . '/phpstan/resultCache-*.php'); + $this->assertNotFalse($resultCacheFiles); + $this->assertTrue(count($resultCacheFiles) > 0); + } + /** * @return mixed[] */ diff --git a/tests/e2e/phpstan_separate_cache.neon b/tests/e2e/phpstan_separate_cache.neon new file mode 100644 index 0000000000..72ea80c29b --- /dev/null +++ b/tests/e2e/phpstan_separate_cache.neon @@ -0,0 +1,7 @@ +# test whether a config, which does not define tmpDir or resultCachePath, will get a separate md5-hashed result cache + +includes: + - baseline.neon + +parameters: + level: 2