From d9437b180788f19012282a2bab66e7ff6cc576b1 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Sun, 22 Mar 2026 09:52:43 +0100 Subject: [PATCH] Add Cache Meta Extension documentation --- resources/docs/cache-meta-extension.md | 50 +++++++++++++++++++ .../DocumentationMenuFactory.php | 1 + 2 files changed, 51 insertions(+) create mode 100644 resources/docs/cache-meta-extension.md diff --git a/resources/docs/cache-meta-extension.md b/resources/docs/cache-meta-extension.md new file mode 100644 index 000000000..b779f3235 --- /dev/null +++ b/resources/docs/cache-meta-extension.md @@ -0,0 +1,50 @@ +Rector caches processed files and skips them on subsequent runs if nothing has changed. By default, cache invalidation is based on file content, Rector configuration, registered rules, and Rector version. + +But what if your rule depends on **external state** — a database schema, an API response, a config file outside `rector.php`, or an environment variable? Rector has no way of knowing that state changed, so it serves stale cache results. + +The `CacheMetaExtensionInterface` solves this. It lets you provide custom metadata that Rector includes in its cache key computation. When your metadata hash changes, Rector re-processes all files. + +## 1. Implement the Interface + +Create a class that implements `CacheMetaExtensionInterface`: + +```php +use Rector\Caching\Contract\CacheMetaExtensionInterface; + +final class DatabaseSchemaCacheExtension implements CacheMetaExtensionInterface +{ + public function getKey(): string + { + return 'database-schema'; + } + + public function getHash(): string + { + // return a hash that represents the current state + return sha1(file_get_contents(__DIR__ . '/schema.sql')); + } +} +``` + +The `getKey()` method returns a unique identifier for this metadata source. The `getHash()` method returns a value representing the current state — when it changes, the cache is invalidated. + +## 2. Register in `rector.php` + +```php +use Rector\Config\RectorConfig; + +return RectorConfig::configure() + ->withRules([...]) + ->withCacheMetaExtension(DatabaseSchemaCacheExtension::class); +``` + +
+ +## Use Cases + +Here are some practical examples of when to use a cache meta extension: + +* **External config files** — hash a YAML/JSON config that your rule reads +* **Database schema** — hash migration files or a schema dump +* **Environment variables** — hash environment values that affect rule behavior +* **API versioning** — hash an API version string that your rule depends on diff --git a/src/Documentation/DocumentationMenuFactory.php b/src/Documentation/DocumentationMenuFactory.php index b2b737009..2cba6fdfa 100644 --- a/src/Documentation/DocumentationMenuFactory.php +++ b/src/Documentation/DocumentationMenuFactory.php @@ -50,6 +50,7 @@ public function create(): array ], 'Testing and CI' => [ $this->documentationMenuItemFactory->createSection('cache-in-ci', 'Cache in CI'), + $this->documentationMenuItemFactory->createSection('cache-meta-extension', 'Cache Meta Extension', true), $this->documentationMenuItemFactory->createSection('debugging', 'Debugging'), $this->documentationMenuItemFactory->createSection( 'troubleshooting-parallel',