diff --git a/README.md b/README.md index f25db7f..cd50a44 100644 --- a/README.md +++ b/README.md @@ -116,20 +116,41 @@ Panaly relies on a wide plugin system and does not provide metric collection, st Each plugin can specialize in a single task or deliver a full feature set from metric collection to storage handling and report generation. -Plugins are the most essential part of configuring a Panaly run. Each plugin has a base class that defines how it -interacts with Panaly and the features it provides. - -A plugin can extend the `Panaly\Plugin\BasePlugin` class to avoid implementing all methods individually, as the methods -are called independently and do nothing if left empty. - -The following methods are available: +Plugins are essential for configuring a Panaly run. Each plugin has a base class that defines how it interacts with +Panaly and the features it provides. A plugin must implement the `Panaly\Plugin\Plugin interface`, which defines +an `initialize` method. + +The plugin will receive the full application configuration, the specific configuration associated +with it, and the runtime configuration where metrics, storage, and reports can be added. It also has access to the +event dispatcher to register listeners/subscribers for customizations. + +A plugin example: + +```php +addMetric(new MyMetric()); + $runtimeConfiguration->addReporting(new MyReport()); + $runtimeConfiguration->addStorage(new MyStorage()); + } +} +``` -| Method | Description | -|-------------------------|------------------------------------------------------------------------------------------------------------------------------------| -| `initialize` | Mainly used to register event listeners for events triggered during a Panaly run. | -| `getAvailableMetrics` | Returns a list of `Panaly\Plugin\Plugin\Metric` implementing classes to be used as metric collectors. | -| `getAvailableStorages` | Returns a list of `Panaly\Plugin\Plugin\Storage` implementing classes that handle storage tasks for the metric collection results. | -| `getAvailableReporting` | Returns a list of `Panaly\Plugin\Plugin\Reporting` implementing classes that generate reports from the metric collection results. | ## Events diff --git a/src/Configuration/PluginLoader.php b/src/Configuration/PluginLoader.php index 84705f3..d13c66a 100644 --- a/src/Configuration/PluginLoader.php +++ b/src/Configuration/PluginLoader.php @@ -8,7 +8,6 @@ use Panaly\Plugin\Plugin; use Throwable; -use function array_walk; use function assert; class PluginLoader @@ -24,28 +23,10 @@ public function load(ConfigurationFile $configurationFile, RuntimeConfiguration throw PluginLoadingFailed::instantiationFailed($plugin->class, $e); } + $runtimeConfiguration->addPlugin($loadedPlugin); + $loadedPlugin->initialize($configurationFile, $runtimeConfiguration, $plugin->options); $runtimeConfiguration->getLogger()->debug('Plugin "' . $plugin->class . '" initialized.', $plugin->options); - - $loadedPluginMetrics = $loadedPlugin->getAvailableMetrics($plugin->options); - array_walk( - $loadedPluginMetrics, - static fn (Plugin\Metric $metric) => $runtimeConfiguration->addMetric($metric), - ); - - $loadedPluginStorages = $loadedPlugin->getAvailableStorages($plugin->options); - array_walk( - $loadedPluginStorages, - static fn (Plugin\Storage $storage) => $runtimeConfiguration->addStorage($storage), - ); - - $loadedPluginReports = $loadedPlugin->getAvailableReporting($plugin->options); - array_walk( - $loadedPluginReports, - static fn (Plugin\Reporting $reporting) => $runtimeConfiguration->addReporting($reporting), - ); - - $runtimeConfiguration->addPlugin($loadedPlugin); } } } diff --git a/src/Plugin/BasePlugin.php b/src/Plugin/BasePlugin.php index 166c3a6..17d26b8 100644 --- a/src/Plugin/BasePlugin.php +++ b/src/Plugin/BasePlugin.php @@ -15,22 +15,4 @@ public function initialize( array $options, ): void { } - - /** @inheritDoc */ - public function getAvailableMetrics(array $options): array - { - return []; - } - - /** @inheritDoc */ - public function getAvailableStorages(array $options): array - { - return []; - } - - /** @inheritDoc */ - public function getAvailableReporting(array $options): array - { - return []; - } } diff --git a/src/Plugin/Plugin.php b/src/Plugin/Plugin.php index cb5f22b..b78a18b 100644 --- a/src/Plugin/Plugin.php +++ b/src/Plugin/Plugin.php @@ -6,9 +6,6 @@ use Panaly\Configuration\ConfigurationFile; use Panaly\Configuration\RuntimeConfiguration; -use Panaly\Plugin\Plugin\Metric; -use Panaly\Plugin\Plugin\Reporting; -use Panaly\Plugin\Plugin\Storage; interface Plugin { @@ -18,25 +15,4 @@ public function initialize( RuntimeConfiguration $runtimeConfiguration, array $options, ): void; - - /** - * @param array $options - * - * @return list - */ - public function getAvailableMetrics(array $options): array; - - /** - * @param array $options - * - * @return list - */ - public function getAvailableStorages(array $options): array; - - /** - * @param array $options - * - * @return list - */ - public function getAvailableReporting(array $options): array; } diff --git a/tests/Configuration/PluginLoaderTest.php b/tests/Configuration/PluginLoaderTest.php index da16b9d..416263a 100644 --- a/tests/Configuration/PluginLoaderTest.php +++ b/tests/Configuration/PluginLoaderTest.php @@ -9,12 +9,11 @@ use Panaly\Configuration\PluginLoader; use Panaly\Configuration\RuntimeConfiguration; use Panaly\Plugin\BasePlugin; +use Panaly\Plugin\Plugin; use Panaly\Test\Fixtures\Plugin\TestPlugin; use PHPUnit\Framework\TestCase; use stdClass; -use function assert; - class PluginLoaderTest extends TestCase { public function testThatTheInstantiationOfPluginsFailsWithException(): void @@ -60,20 +59,12 @@ public function testThatThePluginsAreCorrectLoaded(): void public function testThatOptionsAreHandOverToThePlugin(): void { - $plugin = new class () extends BasePlugin { + $plugin = new class () implements Plugin { /** @var array{ - * initialize: array|null, - * metrics: array|null, - * storages: array|null, - * reporting: array|null + * initialize: array|null * } */ - public array $expectedCalls = [ - 'initialize' => null, - 'metrics' => null, - 'storages' => null, - 'reporting' => null, - ]; + public array $expectedCalls = ['initialize' => null]; public function initialize( ConfigurationFile $configurationFile, @@ -82,30 +73,6 @@ public function initialize( ): void { $this->expectedCalls['initialize'] = $options; } - - /** @inheritDoc */ - public function getAvailableMetrics(array $options): array - { - $this->expectedCalls['metrics'] = $options; - - return []; - } - - /** @inheritDoc */ - public function getAvailableStorages(array $options): array - { - $this->expectedCalls['storages'] = $options; - - return []; - } - - /** @inheritDoc */ - public function getAvailableReporting(array $options): array - { - $this->expectedCalls['reporting'] = $options; - - return []; - } }; $pluginOptions = ['foo' => 'bar']; @@ -116,23 +83,12 @@ public function getAvailableReporting(array $options): array [], ); - $runtimeConfiguration = new RuntimeConfiguration(); + $runtimeConfiguration = $this->createMock(RuntimeConfiguration::class); $loader = new PluginLoader(); $loader->load($configurationFile, $runtimeConfiguration); - $loadedPlugin = $runtimeConfiguration->getPlugins()[0]; - assert($loadedPlugin instanceof $plugin); - - self::assertIsArray($loadedPlugin->expectedCalls['initialize']); - self::assertSame($pluginOptions, $loadedPlugin->expectedCalls['initialize']); - - self::assertIsArray($loadedPlugin->expectedCalls['metrics']); - self::assertSame($pluginOptions, $loadedPlugin->expectedCalls['metrics']); - - self::assertIsArray($loadedPlugin->expectedCalls['storages']); - self::assertSame($pluginOptions, $loadedPlugin->expectedCalls['storages']); - - self::assertIsArray($loadedPlugin->expectedCalls['reporting']); - self::assertSame($pluginOptions, $loadedPlugin->expectedCalls['reporting']); + $runtimeConfiguration->expects($this->never())->method('addMetric'); + $runtimeConfiguration->expects($this->never())->method('addReporting'); + $runtimeConfiguration->expects($this->never())->method('addStorage'); } } diff --git a/tests/Fixtures/Plugin/TestPlugin.php b/tests/Fixtures/Plugin/TestPlugin.php index 5c107fd..f6f69a8 100644 --- a/tests/Fixtures/Plugin/TestPlugin.php +++ b/tests/Fixtures/Plugin/TestPlugin.php @@ -5,7 +5,9 @@ namespace Panaly\Test\Fixtures\Plugin; use InvalidArgumentException; -use Panaly\Plugin\BasePlugin; +use Panaly\Configuration\ConfigurationFile; +use Panaly\Configuration\RuntimeConfiguration; +use Panaly\Plugin\Plugin; use Panaly\Plugin\Plugin\Metric; use Panaly\Plugin\Plugin\Reporting; use Panaly\Plugin\Plugin\Storage; @@ -20,75 +22,64 @@ use const JSON_PRETTY_PRINT; use const JSON_THROW_ON_ERROR; -class TestPlugin extends BasePlugin +class TestPlugin implements Plugin { /** @inheritDoc */ - public function getAvailableMetrics(array $options): array - { - return [ - new class implements Metric { - public function getIdentifier(): string - { - return 'a_static_integer'; - } + public function initialize( + ConfigurationFile $configurationFile, + RuntimeConfiguration $runtimeConfiguration, + array $options, + ): void { + $runtimeConfiguration->addMetric(new class implements Metric { + public function getIdentifier(): string + { + return 'a_static_integer'; + } - public function getDefaultTitle(): string - { - return 'I am a default title'; - } + public function getDefaultTitle(): string + { + return 'I am a default title'; + } - public function calculate(array $options): Value - { - return new IntegerValue(12); - } - }, - ]; - } + public function calculate(array $options): Value + { + return new IntegerValue(12); + } + }); - /** @inheritDoc */ - public function getAvailableStorages(array $options): array - { - return [ - new class implements Storage { - public function getIdentifier(): string - { - return 'single_json'; - } + $runtimeConfiguration->addStorage(new class implements Storage { + public function getIdentifier(): string + { + return 'single_json'; + } - public function store(Result $result, array $options): void - { - $file = __DIR__ . '/../../../' . ($options['file'] ?? 'panaly-single-json-result.json'); + public function store(Result $result, array $options): void + { + $file = __DIR__ . '/../../../' . ($options['file'] ?? 'panaly-single-json-result.json'); - if ( - file_put_contents( - $file, - json_encode($result->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), - ) === false - ) { - throw new InvalidArgumentException( - 'The file "' . $file . '" configured in "file" option is not writable.', - ); - } + if ( + file_put_contents( + $file, + json_encode($result->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), + ) === false + ) { + throw new InvalidArgumentException( + 'The file "' . $file . '" configured in "file" option is not writable.', + ); } - }, - ]; - } + } + }); - /** @inheritDoc */ - public function getAvailableReporting(array $options): array - { - return [ - new class implements Reporting { - public function getIdentifier(): string - { - return 'symfony_dump'; - } + $runtimeConfiguration->addReporting(new class implements Reporting { + public function getIdentifier(): string + { + return 'symfony_dump'; + } - public function report(Result $result, array $options): void - { - VarDumper::dump($result); - } - }, - ]; + public function report(Result $result, array $options): void + { + VarDumper::dump($result); + } + }); } }