Skip to content

Commit be3e4fc

Browse files
committed
Result cache - use file hashes instead of modified times
1 parent 2f649fa commit be3e4fc

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ jobs:
308308
uses: actions/cache@v1
309309
with:
310310
path: ./tmp
311-
key: "result-cache-v1"
311+
key: "result-cache-v2"
312312

313313
- name: "PHPStan with result cache"
314314
run: |

src/Analyser/ResultCache/ResultCacheManager.php

+17-19
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
use PHPStan\File\FileReader;
88
use function array_fill_keys;
99
use function array_key_exists;
10-
use function filemtime;
1110

1211
class ResultCacheManager
1312
{
1413

15-
private const CACHE_VERSION = 'v1';
14+
private const CACHE_VERSION = 'v2-hashes';
1615

1716
/** @var string */
1817
private $cacheFilePath;
@@ -32,6 +31,9 @@ class ResultCacheManager
3231
/** @var string */
3332
private $usedLevel;
3433

34+
/** @var array<string, string> */
35+
private $fileHashes = [];
36+
3537
/**
3638
* @param string $cacheFilePath
3739
* @param string[] $allCustomConfigFiles
@@ -113,15 +115,12 @@ public function restore(array $allAnalysedFiles, bool $debug): ResultCache
113115
unset($deletedFiles[$analysedFile]);
114116

115117
$analysedFileData = $invertedDependencies[$analysedFile];
116-
$cachedModifiedTime = $analysedFileData['modifiedTime'];
118+
$cachedFileHash = $analysedFileData['fileHash'];
117119
$dependentFiles = $analysedFileData['dependentFiles'];
118120
$invertedDependenciesToReturn[$analysedFile] = $dependentFiles;
119-
$currentModifiedTime = filemtime($analysedFile);
120-
if ($currentModifiedTime === false) {
121-
$currentModifiedTime = time();
122-
}
121+
$currentFileHash = $this->getFileHash($analysedFile);
123122

124-
if ($cachedModifiedTime === $currentModifiedTime) {
123+
if ($cachedFileHash === $currentFileHash) {
125124
continue;
126125
}
127126

@@ -293,12 +292,8 @@ private function save(
293292
foreach ($dependencies as $file => $fileDependencies) {
294293
foreach ($fileDependencies as $fileDep) {
295294
if (!array_key_exists($fileDep, $invertedDependencies)) {
296-
$modifiedTime = filemtime($fileDep);
297-
if ($modifiedTime === false) {
298-
$modifiedTime = time();
299-
}
300295
$invertedDependencies[$fileDep] = [
301-
'modifiedTime' => $modifiedTime,
296+
'fileHash' => $this->getFileHash($fileDep),
302297
'dependentFiles' => [],
303298
];
304299
unset($filesNoOneIsDependingOn[$fileDep]);
@@ -316,12 +311,8 @@ private function save(
316311
continue;
317312
}
318313

319-
$modifiedTime = filemtime($file);
320-
if ($modifiedTime === false) {
321-
$modifiedTime = time();
322-
}
323314
$invertedDependencies[$file] = [
324-
'modifiedTime' => $modifiedTime,
315+
'fileHash' => $this->getFileHash($file),
325316
'dependentFiles' => [],
326317
];
327318
}
@@ -385,10 +376,17 @@ private function getConfigFiles(): array
385376

386377
private function getFileHash(string $path): string
387378
{
379+
if (array_key_exists($path, $this->fileHashes)) {
380+
return $this->fileHashes[$path];
381+
}
382+
388383
$contents = FileReader::read($path);
389384
$contents = str_replace("\r\n", "\n", $contents);
390385

391-
return sha1($contents);
386+
$hash = sha1($contents);
387+
$this->fileHashes[$path] = $hash;
388+
389+
return $hash;
392390
}
393391

394392
private function getPhpStanVersion(): string

tests/e2e/ResultCacheEndToEndTest.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ public function testResultCache(): void
4242
$lexerCode = str_replace('@param string $code', '', $lexerCode);
4343
$lexerCode = str_replace('public function startLexing($code', 'public function startLexing(\\PhpParser\\Node\\Expr\\MethodCall $code', $lexerCode);
4444
file_put_contents($lexerPath, $lexerCode);
45-
touch(__DIR__ . '/PHP-Parser/lib/PhpParser/ErrorHandler.php');
45+
46+
$errorHandlerPath = __DIR__ . '/PHP-Parser/lib/PhpParser/ErrorHandler.php';
47+
$errorHandlerContents = FileReader::read($errorHandlerPath);
48+
$errorHandlerContents .= "\n\n";
49+
file_put_contents($errorHandlerPath, $errorHandlerContents);
4650

4751
$bootstrapPath = __DIR__ . '/PHP-Parser/lib/bootstrap.php';
4852
$originalBootstrapContents = FileReader::read($bootstrapPath);

0 commit comments

Comments
 (0)