diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 11d5158..5da3e14 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,6 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - # phlix-shared requires PHP ^8.3, so the matrix matches. php: ['8.3', '8.4'] steps: - uses: actions/checkout@v6 @@ -19,7 +18,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - coverage: none + coverage: pcov tools: composer:v2 - name: Install dependencies @@ -27,3 +26,9 @@ jobs: - name: Run PHPUnit run: vendor/bin/phpunit --colors=always + + - name: Run PHPStan + run: vendor/bin/phpstan analyse src --level=9 + + - name: Run PHPCS + run: vendor/bin/phpcs src --standard=PSR12 diff --git a/composer.json b/composer.json index 5bc4c9e..8b74416 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,9 @@ "detain/phlix-shared": "^0.6" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpstan/phpstan": "^2.2", + "phpunit/phpunit": "^10.0", + "squizlabs/php_codesniffer": "^4.0" }, "repositories": [ { "type": "vcs", "url": "https://github.com/detain/phlix-shared.git" } @@ -29,5 +31,9 @@ "config": { "optimize-autoloader": true, "sort-packages": true + }, + "scripts": { + "phpstan": "vendor/bin/phpstan analyse src --level=9", + "phpcs": "vendor/bin/phpcs src --standard=PSR12" } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..43a7a11 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,7 @@ + + + PSR-12 coding standard for phlix-plugin-example + src + vendor/ + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..3e639cd --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 9 + paths: + - src diff --git a/phpunit.xml b/phpunit.xml index 8cc71c9..406f480 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -14,4 +14,9 @@ src + + + + + diff --git a/src/HelloMetadataProvider.php b/src/HelloMetadataProvider.php index 8dd8df5..ca429ce 100644 --- a/src/HelloMetadataProvider.php +++ b/src/HelloMetadataProvider.php @@ -22,15 +22,15 @@ * progressively replace {@see lookup()} with real metadata lookups * against TMDB, TVDB, Fanart.tv, or any other source. * - * ## Lifecycle notes - * - * - {@see onEnable()} keeps state minimal — it only stashes the host - * container so {@see lookup()} can resolve services lazily if a - * future implementation needs them. - * - {@see subscribedEvents()} returns an empty array; this plugin does - * not listen for PSR-14 events. A real metadata provider can leave - * this empty too — Phase A's `MetadataManager` invokes providers - * directly rather than via the dispatcher. + * ## Lifecycle notes + * + * - {@see onEnable()} is a no-op for the reference plugin; it accepts + * the host container to satisfy the contract but does not retain it. + * Real plugins that need a container should store it as a property. + * - {@see subscribedEvents()} returns an empty array; this plugin does + * not listen for PSR-14 events. A real metadata provider can leave + * this empty too — Phase A's `MetadataManager` invokes providers + * directly rather than via the dispatcher. * * ## Provenance * @@ -65,15 +65,6 @@ final class HelloMetadataProvider implements LifecycleInterface */ private string $greeting; - /** - * Host container handle stashed during {@see onEnable()}. Real - * provider implementations resolve `LoggerInterface`, HTTP clients, - * or cache services through it; the example does not yet need it - * but keeping the reference makes the extension point obvious for - * authors copying this class as a starter. - */ - private ?ContainerInterface $container = null; - /** * @param string $greeting Override for the greeting returned by * {@see lookup()}. Tests pass a custom value; production @@ -87,10 +78,8 @@ public function __construct(string $greeting = self::DEFAULT_GREETING) /** * Loader hook called once when the plugin is enabled. * - * Stashes the host container so later metadata lookups can resolve - * services lazily. Real providers might also open an HTTP client or - * warm a cache here — keep it cheap; the loader is in the request - * path. + * No-op for the reference plugin. Real plugins that need the host + * container should store it as a property here. * * @param ContainerInterface $container Host PSR-11 container. * @@ -100,15 +89,14 @@ public function __construct(string $greeting = self::DEFAULT_GREETING) */ public function onEnable(ContainerInterface $container): void { - $this->container = $container; } /** * Loader hook called once when the plugin is disabled. * - * Releases the stashed container reference. Plugins that opened - * clients in {@see onEnable()} should close them here so the - * lifecycle is symmetric. + * No-op for the reference plugin. Real plugins that opened resources + * in {@see onEnable()} should close them here so the lifecycle is + * symmetric. * * @return void * @@ -116,7 +104,6 @@ public function onEnable(ContainerInterface $container): void */ public function onDisable(): void { - $this->container = null; } /**