Skip to content

Add ResultCacheMetaExtension so the result cache tracks the Drupal site - #1030

Merged
mglaman merged 1 commit into
mainfrom
audit/5-result-cache
Sep 9, 2026
Merged

Add ResultCacheMetaExtension so the result cache tracks the Drupal site#1030
mglaman merged 1 commit into
mainfrom
audit/5-result-cache

Conversation

@mglaman

@mglaman mglaman commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Part 9 of 9 in the legacy-code audit stack. The highest-impact finding from the audit: PHPStan's result cache never invalidated when the analyzed Drupal site changed.

Why

PHPStan hashes its bootstrap files, but knows nothing about the Drupal extensions, services.yml files, and config schemas our bootstrap discovers. Enabling a module, editing a services.yml, or upgrading core silently reused stale analysis results until the user ran --no-result-cache or the cache expired.

What changed

BootstrapResultCacheMetaExtension implements PHPStan's ResultCacheMetaExtension (phpstan.resultCacheMetaExtension tag). Its hash covers:

  • the discovered extension inventory — info-file path and content per module/theme/profile,
  • every consumed services.yml (path and content),
  • all *.schema.yml files in the collected schema directories,
  • \Drupal::VERSION, which catches tarball core upgrades (composer-managed upgrades are already covered by PHPStan's own composer.lock hashing).

Any change invalidates the whole result cache. The hashing runs once per analysis over a few hundred small YAML files — well under 50ms. Discovered PHP files are deliberately not hashed; PHPStan hashes analyzed files itself.

To feed the extension, ServiceMap::setDrupalServices() gains an optional second parameter recording the consumed yml paths (backwards compatible), and ConfigSchemaData exposes its schema directories.

Testing

New unit tests assert the hash is deterministic, and changes when the extension list, a services.yml's content, or a schema directory changes. The tests run in separate processes because the underlying state is static. Full suite, self-analysis, and phpcs are green.

🤖 Generated with Claude Code

@mglaman
mglaman force-pushed the audit/5-result-cache branch from 3678ba5 to 6ee0ef6 Compare August 5, 2026 16:20
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 6ee0ef6 to e89c527 Compare August 5, 2026 16:44
@mglaman
mglaman force-pushed the audit/5-result-cache branch from e89c527 to 206c73d Compare August 5, 2026 17:15
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 206c73d to 94480e0 Compare August 5, 2026 19:13
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 94480e0 to f526bdb Compare August 5, 2026 19:33
@mglaman
mglaman force-pushed the audit/5-result-cache branch from f526bdb to 648c7ea Compare September 8, 2026 17:42
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 648c7ea to 7e36bd8 Compare September 8, 2026 18:15
@mglaman
mglaman force-pushed the audit/5-result-cache branch 3 times, most recently from b33bca0 to db7e73c Compare September 8, 2026 18:59
@mglaman
mglaman force-pushed the audit/5-result-cache branch from db7e73c to ccb2d5d Compare September 8, 2026 19:11
@mglaman
mglaman force-pushed the audit/5-result-cache branch from ccb2d5d to 038a2c5 Compare September 8, 2026 19:47
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 038a2c5 to a6ae8cf Compare September 9, 2026 01:08
@mglaman
mglaman force-pushed the audit/5-result-cache branch from a6ae8cf to 2a62ce1 Compare September 9, 2026 14:24
Base automatically changed from audit/4-bc-changes to main September 9, 2026 14:39
PHPStan hashes its bootstrap files but knows nothing about the Drupal
extensions, services.yml files, and config schemas the bootstrap
discovers. Enabling a module, editing a services.yml, or upgrading core
silently reused stale results from the cache.

BootstrapResultCacheMetaExtension hashes the discovered extension
inventory (info-file paths and content), every consumed services.yml,
all config schema files, and the core version. Any change invalidates
the whole result cache. The hashing runs once per analysis and covers
a few hundred small YAML files, well under 50ms.

ServiceMap now records which services.yml paths it consumed (new
optional parameter, backwards compatible) and ConfigSchemaData exposes
its schema directories.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mglaman
mglaman force-pushed the audit/5-result-cache branch from 2a62ce1 to 0b6ba74 Compare September 9, 2026 14:39
@mglaman
mglaman marked this pull request as ready for review September 9, 2026 14:50
@mglaman
mglaman merged commit d5b72be into main Sep 9, 2026
19 of 20 checks passed
@mglaman
mglaman deleted the audit/5-result-cache branch September 9, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant