Skip to content

Commit 79d9db8

Browse files
ondrejmirtesclaude
andcommitted
Invalidate the result cache when the configured stubFiles list changes
Since 99f58fa2fa the stub file list is only recorded at save time, so adding a stub file in a config no longer invalidated the cache through the restore-time stubFiles computation. The statically configured stubFiles parameter is known without running the StubFilesExtensions, so record it in the meta and compare it on restore. The projectConfig meta entry (the Nette loader merges included config files into it) usually catches such a change too, but only as a textual config comparison: the dedicated entry compares the expanded list, is not affected by parametersNotInvalidatingCache, and names the actual cause in the verbose invalidation message. The e2e coverage adds a stub file in an included neon and expects the metadata comparison to invalidate the cache. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cAV6sztxvNeaEQ78RVFad
1 parent 6c51d2f commit 79d9db8

5 files changed

Lines changed: 43 additions & 2 deletions

File tree

‎.github/workflows/e2e-tests.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,13 @@ jobs:
679679
../bashunit -a contains 'should return non-empty-string but returns string' "$OUTPUT"
680680
mv stubs/Foo.stub.orig stubs/Foo.stub
681681
../../bin/phpstan analyse -vvv
682+
patch -b stub-files.neon < config-change.patch
683+
OUTPUT=$(../../bin/phpstan analyse -vvv 2>&1)
684+
echo "$OUTPUT"
685+
../bashunit -a contains 'Result cache not used because the metadata do not match' "$OUTPUT"
686+
../bashunit -a contains 'configStubFiles' "$OUTPUT"
687+
mv stub-files.neon.orig stub-files.neon
688+
../../bin/phpstan analyse -vvv
682689
- script: |
683690
cd e2e/nested-trait-use
684691
../../bin/phpstan analyze

‎e2e/bug-15120/config-change.patch‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--- stub-files.neon
2+
+++ stub-files.neon
3+
@@ -1,3 +1,4 @@
4+
parameters:
5+
stubFiles:
6+
- src/BazStub.php
7+
+ - stubs/Bar.stub

‎e2e/bug-15120/stubs/Bar.stub‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Bug15120;
4+
5+
class Bar
6+
{
7+
8+
/** @return non-empty-string */
9+
public function name(): string
10+
{
11+
12+
}
13+
14+
}

‎src/Analyser/ResultCache/ResultCacheManager.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use function array_filter;
3535
use function array_key_exists;
3636
use function array_keys;
37+
use function array_map;
3738
use function array_merge;
3839
use function array_unique;
3940
use function array_values;
@@ -86,6 +87,7 @@ final class ResultCacheManager
8687
* @param string[] $bootstrapFiles
8788
* @param string[] $scanFiles
8889
* @param string[] $scanDirectories
90+
* @param string[] $configStubFiles
8991
* @param list<string|non-empty-list<string>> $parametersNotInvalidatingCache
9092
* @param array<string, string> $fileReplacements
9193
* @param ExtensionsCollection<ResultCacheMetaExtension> $resultCacheMetaExtensions
@@ -117,6 +119,8 @@ public function __construct(
117119
private array $scanFiles,
118120
#[AutowiredParameter]
119121
private array $scanDirectories,
122+
#[AutowiredParameter(ref: '%stubFiles%')]
123+
private array $configStubFiles,
120124
private array $fileReplacements,
121125
#[AutowiredParameter(ref: '%resultCacheChecksProjectExtensionFilesDependencies%')]
122126
private bool $checkDependenciesOfProjectExtensionFiles,
@@ -1596,6 +1600,12 @@ private function getMeta(array $allAnalysedFiles, ?array $projectConfigArray): a
15961600
'composerInstalled' => $this->getComposerInstalled(),
15971601
'executedFilesHashes' => $this->getExecutedFileHashes(),
15981602
'phpExtensions' => $extensions,
1603+
// only the statically configured stub files - the full list including the ones
1604+
// from StubFilesExtensions is recorded at save time (see save()), because the
1605+
// extensions may only run after the bootstrapFiles. This entry catches a changed
1606+
// list in any config file, including the included ones that are not part of the
1607+
// projectConfig entry above.
1608+
'configStubFiles' => array_map(fn (string $stubFile): string => $this->fileHelper->normalizePath($stubFile), $this->configStubFiles),
15991609
'level' => $this->usedLevel,
16001610
];
16011611
}

‎src/Analyser/ResultCache/ResultCachePathTransformer.php‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,11 @@ public function relativizeProjectConfig(array $projectConfig): array
307307
*/
308308
private function transformMeta(array $meta, bool $absolutize): array
309309
{
310-
if (array_key_exists('analysedPaths', $meta) && is_array($meta['analysedPaths'])) {
311-
$meta['analysedPaths'] = $this->transformList($meta['analysedPaths'], $absolutize);
310+
foreach (['analysedPaths', 'configStubFiles'] as $listKey) {
311+
if (!array_key_exists($listKey, $meta) || !is_array($meta[$listKey])) {
312+
continue;
313+
}
314+
$meta[$listKey] = $this->transformList($meta[$listKey], $absolutize);
312315
}
313316

314317
foreach (['scannedFiles', 'composerLocks', 'executedFilesHashes', 'stubFiles'] as $key) {

0 commit comments

Comments
 (0)