Skip to content

Commit

Permalink
Result cache - invalidate when scanned file changed
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 20, 2021
1 parent 67b2d1c commit 7d279fc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
3 changes: 3 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ services:
-
implement: PHPStan\Analyser\ResultCache\ResultCacheManagerFactory
arguments:
scanFileFinder: @fileFinderScan
cacheFilePath: %resultCachePath%
tempResultCachePath: %tempResultCachePath%
analysedPaths: %analysedPaths%
Expand All @@ -419,6 +420,8 @@ services:
usedLevel: %usedLevel%
cliAutoloadFile: %cliAutoloadFile%
bootstrapFiles: %bootstrapFiles%
scanFiles: %scanFiles%
scanDirectories: %scanDirectories%

-
class: PHPStan\Analyser\ResultCache\ResultCacheClearer
Expand Down
57 changes: 50 additions & 7 deletions src/Analyser/ResultCache/ResultCacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Command\Output;
use PHPStan\Dependency\ExportedNode;
use PHPStan\Dependency\ExportedNodeFetcher;
use PHPStan\File\FileFinder;
use PHPStan\File\FileReader;
use PHPStan\File\FileWriter;
use function array_fill_keys;
Expand All @@ -20,6 +21,8 @@ class ResultCacheManager

private ExportedNodeFetcher $exportedNodeFetcher;

private FileFinder $scanFileFinder;

private string $cacheFilePath;

private string $tempResultCachePath;
Expand All @@ -40,6 +43,12 @@ class ResultCacheManager
/** @var string[] */
private array $bootstrapFiles;

/** @var string[] */
private array $scanFiles;

/** @var string[] */
private array $scanDirectories;

/** @var array<string, string> */
private array $fileHashes = [];

Expand All @@ -48,6 +57,7 @@ class ResultCacheManager

/**
* @param ExportedNodeFetcher $exportedNodeFetcher
* @param FileFinder $scanFileFinder
* @param string $cacheFilePath
* @param string $tempResultCachePath
* @param string[] $analysedPaths
Expand All @@ -56,10 +66,13 @@ class ResultCacheManager
* @param string $usedLevel
* @param string|null $cliAutoloadFile
* @param string[] $bootstrapFiles
* @param string[] $scanFiles
* @param string[] $scanDirectories
* @param array<string, string> $fileReplacements
*/
public function __construct(
ExportedNodeFetcher $exportedNodeFetcher,
FileFinder $scanFileFinder,
string $cacheFilePath,
string $tempResultCachePath,
array $analysedPaths,
Expand All @@ -68,10 +81,13 @@ public function __construct(
string $usedLevel,
?string $cliAutoloadFile,
array $bootstrapFiles,
array $scanFiles,
array $scanDirectories,
array $fileReplacements
)
{
$this->exportedNodeFetcher = $exportedNodeFetcher;
$this->scanFileFinder = $scanFileFinder;
$this->cacheFilePath = $cacheFilePath;
$this->tempResultCachePath = $tempResultCachePath;
$this->analysedPaths = $analysedPaths;
Expand All @@ -80,6 +96,8 @@ public function __construct(
$this->usedLevel = $usedLevel;
$this->cliAutoloadFile = $cliAutoloadFile;
$this->bootstrapFiles = $bootstrapFiles;
$this->scanFiles = $scanFiles;
$this->scanDirectories = $scanDirectories;
$this->fileReplacements = $fileReplacements;
}

Expand All @@ -95,13 +113,13 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache not used because of debug mode.');
}
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($projectConfigArray), [], [], []);
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], []);
}
if ($onlyFiles) {
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache not used because only files were passed as analysed paths.');
}
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($projectConfigArray), [], [], []);
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], []);
}

$cacheFilePath = $this->cacheFilePath;
Expand All @@ -116,7 +134,7 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache not used because the cache file does not exist.');
}
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($projectConfigArray), [], [], []);
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], []);
}

try {
Expand All @@ -128,7 +146,7 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?

@unlink($cacheFilePath);

return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($projectConfigArray), [], [], []);
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], []);
}

if (!is_array($data)) {
Expand All @@ -137,10 +155,10 @@ public function restore(array $allAnalysedFiles, bool $debug, bool $onlyFiles, ?
$output->writeLineFormatted('Result cache not used because the cache file is corrupted.');
}

return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($projectConfigArray), [], [], []);
return new ResultCache($allAnalysedFiles, true, time(), $this->getMeta($allAnalysedFiles, $projectConfigArray), [], [], []);
}

$meta = $this->getMeta($projectConfigArray);
$meta = $this->getMeta($allAnalysedFiles, $projectConfigArray);
if ($data['meta'] !== $meta) {
if ($output->isDebug()) {
$output->writeLineFormatted('Result cache not used because the metadata do not match.');
Expand Down Expand Up @@ -529,10 +547,11 @@ private function save(
}

/**
* @param string[] $allAnalysedFiles
* @param mixed[]|null $projectConfigArray
* @return mixed[]
*/
private function getMeta(?array $projectConfigArray): array
private function getMeta(array $allAnalysedFiles, ?array $projectConfigArray): array
{
$extensions = array_values(array_filter(get_loaded_extensions(), static function (string $extension): bool {
return $extension !== 'xdebug';
Expand All @@ -558,6 +577,7 @@ private function getMeta(?array $projectConfigArray): array
'phpVersion' => PHP_VERSION_ID,
'projectConfig' => $projectConfigArray,
'analysedPaths' => $this->analysedPaths,
'scannedFiles' => $this->getScannedFiles($allAnalysedFiles),
'composerLocks' => $this->getComposerLocks(),
'composerInstalled' => $this->getComposerInstalled(),
'executedFilesHashes' => $this->getExecutedFileHashes(),
Expand Down Expand Up @@ -585,6 +605,29 @@ private function getFileHash(string $path): string
return $hash;
}

/**
* @param string[] $allAnalysedFiles
* @return array<string, string>
*/
private function getScannedFiles(array $allAnalysedFiles): array
{
$scannedFiles = $this->scanFiles;
foreach ($this->scanFileFinder->findFiles($this->scanDirectories)->getFiles() as $file) {
$scannedFiles[] = $file;
}

$scannedFiles = array_unique($scannedFiles);

$hashes = [];
foreach (array_diff($scannedFiles, $allAnalysedFiles) as $file) {
$hashes[$file] = $this->getFileHash($file);
}

ksort($hashes);

return $hashes;
}

/**
* @return array<string, string>
*/
Expand Down

0 comments on commit 7d279fc

Please sign in to comment.