From 243a74df8f0c5f48ea2ce462987aa7a54a90d65c Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Mon, 2 Mar 2015 17:49:26 +0100 Subject: [PATCH 1/5] plugin manager --- src/Psy/Command/DemoCommand.php | 36 ++++++++++++++++ src/Psy/Plugin/AbstractPlugin.php | 68 +++++++++++++++++++++++++++++++ src/Psy/Plugin/DemoPlugin.php | 18 ++++++++ src/Psy/Plugin/Manager.php | 32 +++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 src/Psy/Command/DemoCommand.php create mode 100644 src/Psy/Plugin/AbstractPlugin.php create mode 100644 src/Psy/Plugin/DemoPlugin.php create mode 100644 src/Psy/Plugin/Manager.php diff --git a/src/Psy/Command/DemoCommand.php b/src/Psy/Command/DemoCommand.php new file mode 100644 index 000000000..c5ceb0cfb --- /dev/null +++ b/src/Psy/Command/DemoCommand.php @@ -0,0 +1,36 @@ +setName('demo') + ->setDefinition(array( + new InputOption('message', 'm', InputOption::VALUE_REQUIRED, 'Message to send.'), + )) + ->setDescription('Sample command just for testing.') + ->setHelp( + <<getOption('message'); + $output->writeln(sprintf('Received message "%s". ', $message)); + } +} diff --git a/src/Psy/Plugin/AbstractPlugin.php b/src/Psy/Plugin/AbstractPlugin.php new file mode 100644 index 000000000..c3b7fba88 --- /dev/null +++ b/src/Psy/Plugin/AbstractPlugin.php @@ -0,0 +1,68 @@ +getShortName()); + } + + /** + * @param array $configuration + * + * @return array + */ + final public static function getConfiguration($configuration = array()) + { + return array_merge_recursive( + $configuration, + array( + 'commands' => static::getCommands(), + 'presenters' => static::getPresenters(), + 'matchers' => static::getMatchers(), + // if any more parts of the config are exposed publicly, remember to add here with the static ref. + ) + ); + } + + // any publicly exposed configuration piece below here ↓ + + /** + * @return array + */ + public static function getCommands() + { + // add your own commands + return array(); + } + + /** + * @return array + */ + public static function getPresenters() + { + // add your own presenters + return array(); + } + + /** + * @return array + */ + public static function getMatchers() + { + // add your own presenters + return array(); + } +} diff --git a/src/Psy/Plugin/DemoPlugin.php b/src/Psy/Plugin/DemoPlugin.php new file mode 100644 index 000000000..d8451685b --- /dev/null +++ b/src/Psy/Plugin/DemoPlugin.php @@ -0,0 +1,18 @@ + Date: Tue, 3 Mar 2015 12:32:12 +0100 Subject: [PATCH 2/5] added manager configuration load in the configuration class --- src/Psy/Configuration.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Psy/Configuration.php b/src/Psy/Configuration.php index 3cb934d0b..0d4cbe71c 100644 --- a/src/Psy/Configuration.php +++ b/src/Psy/Configuration.php @@ -16,6 +16,7 @@ use Psy\ExecutionLoop\Loop; use Psy\Output\OutputPager; use Psy\Output\ShellOutput; +use Psy\Plugin\Manager; use Psy\Presenter\PresenterManager; use Psy\Readline\GNUReadline; use Psy\Readline\Libedit; @@ -74,6 +75,9 @@ class Configuration */ public function __construct(array $config = array()) { + // ask the plugin manager for configurations + $config = Manager::getConfiguration($config); + // explicit configFile option if (isset($config['configFile'])) { $this->configFile = $config['configFile']; From c9b34d8b9e4debf77416af2f396f1959bbd1ce2f Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Tue, 3 Mar 2015 13:44:04 +0100 Subject: [PATCH 3/5] Added parameter that forbids plugin discovery --- src/Psy/Configuration.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Psy/Configuration.php b/src/Psy/Configuration.php index 0d4cbe71c..6517a7bf6 100644 --- a/src/Psy/Configuration.php +++ b/src/Psy/Configuration.php @@ -34,9 +34,10 @@ class Configuration 'defaultIncludes', 'useReadline', 'usePcntl', 'codeCleaner', 'pager', 'loop', 'configDir', 'dataDir', 'runtimeDir', 'manualDbFile', 'requireSemicolons', 'historySize', 'eraseDuplicates', 'tabCompletion', - 'tabCompletionMatchers', + 'tabCompletionMatchers', 'registerPlugins', ); + private $registerPlugins = true; private $defaultIncludes; private $configDir; private $dataDir; @@ -75,9 +76,6 @@ class Configuration */ public function __construct(array $config = array()) { - // ask the plugin manager for configurations - $config = Manager::getConfiguration($config); - // explicit configFile option if (isset($config['configFile'])) { $this->configFile = $config['configFile']; @@ -100,6 +98,27 @@ public function __construct(array $config = array()) // go go gadget, config! $this->loadConfig($config); $this->init(); + + // ask the plugin manager for configurations + if ($this->getRegisterPlugins()) { + $this->loadConfig(Manager::getConfiguration($config)); + } + } + + /** + * @param $bool + */ + public function setRegisterPlugins($bool) + { + $this->registerPlugins = $bool; + } + + /** + * @return bool + */ + public function getRegisterPlugins() + { + return $this->registerPlugins; } /** From d44d77328d874c6e0b0fdf9635bec46a286436f6 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Tue, 3 Mar 2015 14:03:19 +0100 Subject: [PATCH 4/5] boolean enforcer added to bolean parameter --- src/Psy/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Psy/Configuration.php b/src/Psy/Configuration.php index 6517a7bf6..2761f4264 100644 --- a/src/Psy/Configuration.php +++ b/src/Psy/Configuration.php @@ -110,7 +110,7 @@ public function __construct(array $config = array()) */ public function setRegisterPlugins($bool) { - $this->registerPlugins = $bool; + $this->registerPlugins = (bool) $bool; } /** From f1d761001741ebb7ca8d1e83e1a92e24527ceb14 Mon Sep 17 00:00:00 2001 From: Marc Garcia Date: Tue, 3 Mar 2015 16:38:22 +0100 Subject: [PATCH 5/5] Added testing, refactored a little bit the configuration building services --- src/Psy/Command/DemoCommand.php | 36 ---------- src/Psy/Configuration.php | 4 +- src/Psy/Plugin/AbstractPlugin.php | 26 ++----- src/Psy/Plugin/DemoPlugin.php | 18 ----- src/Psy/Plugin/Manager.php | 32 --------- src/Psy/Plugin/PluginManager.php | 63 +++++++++++++++++ test/Psy/Test/Plugin/ManagerTest.php | 101 +++++++++++++++++++++++++++ test/Psy/Test/Plugin/PluginStub.php | 44 ++++++++++++ 8 files changed, 214 insertions(+), 110 deletions(-) delete mode 100644 src/Psy/Command/DemoCommand.php delete mode 100644 src/Psy/Plugin/DemoPlugin.php delete mode 100644 src/Psy/Plugin/Manager.php create mode 100644 src/Psy/Plugin/PluginManager.php create mode 100644 test/Psy/Test/Plugin/ManagerTest.php create mode 100644 test/Psy/Test/Plugin/PluginStub.php diff --git a/src/Psy/Command/DemoCommand.php b/src/Psy/Command/DemoCommand.php deleted file mode 100644 index c5ceb0cfb..000000000 --- a/src/Psy/Command/DemoCommand.php +++ /dev/null @@ -1,36 +0,0 @@ -setName('demo') - ->setDefinition(array( - new InputOption('message', 'm', InputOption::VALUE_REQUIRED, 'Message to send.'), - )) - ->setDescription('Sample command just for testing.') - ->setHelp( - <<getOption('message'); - $output->writeln(sprintf('Received message "%s". ', $message)); - } -} diff --git a/src/Psy/Configuration.php b/src/Psy/Configuration.php index 2761f4264..d864193f3 100644 --- a/src/Psy/Configuration.php +++ b/src/Psy/Configuration.php @@ -16,7 +16,7 @@ use Psy\ExecutionLoop\Loop; use Psy\Output\OutputPager; use Psy\Output\ShellOutput; -use Psy\Plugin\Manager; +use Psy\Plugin\PluginManager; use Psy\Presenter\PresenterManager; use Psy\Readline\GNUReadline; use Psy\Readline\Libedit; @@ -101,7 +101,7 @@ public function __construct(array $config = array()) // ask the plugin manager for configurations if ($this->getRegisterPlugins()) { - $this->loadConfig(Manager::getConfiguration($config)); + $this->loadConfig(PluginManager::getConfiguration($config)); } } diff --git a/src/Psy/Plugin/AbstractPlugin.php b/src/Psy/Plugin/AbstractPlugin.php index c3b7fba88..93a8e5c02 100644 --- a/src/Psy/Plugin/AbstractPlugin.php +++ b/src/Psy/Plugin/AbstractPlugin.php @@ -6,35 +6,17 @@ abstract class AbstractPlugin { public static function register() { - Manager::register(new static(), static::getName()); + PluginManager::register(new static(), static::getName()); } /** * @return string - */ - final public static function getName() - { - $class = new \ReflectionClass(get_called_class()); - - return preg_replace('#Plugin$#', '', $class->getShortName()); - } - - /** - * @param array $configuration * - * @return array + * @throws \Exception */ - final public static function getConfiguration($configuration = array()) + public static function getName() { - return array_merge_recursive( - $configuration, - array( - 'commands' => static::getCommands(), - 'presenters' => static::getPresenters(), - 'matchers' => static::getMatchers(), - // if any more parts of the config are exposed publicly, remember to add here with the static ref. - ) - ); + throw new \Exception('Missing plugin name'); } // any publicly exposed configuration piece below here ↓ diff --git a/src/Psy/Plugin/DemoPlugin.php b/src/Psy/Plugin/DemoPlugin.php deleted file mode 100644 index d8451685b..000000000 --- a/src/Psy/Plugin/DemoPlugin.php +++ /dev/null @@ -1,18 +0,0 @@ -setAccessible(true); + $prop->setValue('Psy\Plugin\Manager', array()); + } + + public function testRegisterMultiplePlugins() + { + $mockedPlugin = $this->getMock('Psy\Plugin\AbstractPlugin'); + PluginManager::register($mockedPlugin, 'mock1'); + PluginManager::register($mockedPlugin, 'mock2'); + + $prop = new \ReflectionProperty('Psy\Plugin\PluginManager', 'plugins'); + $prop->setAccessible(true); + $plugins = $prop->getValue('Psy\Plugin\PluginManager'); + $this->assertArrayHasKey('mock1', $plugins); + $this->assertArrayHasKey('mock2', $plugins); + } + + public function testConfigurationWithSinglePlugin() + { + $commands = array( + 'cmd1', 'cmd2', + ); + + $presenters = array( + 'presenter1', 'presenter2', + ); + + $matchers = array( + 'matcher1', 'matcher2', + ); + + $stub = new PluginStub(); + $stub->setCommands($commands); + $stub->setPresenters($presenters); + $stub->setMatchers($matchers); + + PluginManager::register($stub, 'mock'); + + $config = PluginManager::getConfiguration(); + $this->assertArraySubset($commands, $config['commands']); + $this->assertArraySubset($presenters, $config['presenters']); + $this->assertArraySubset($matchers, $config['matchers']); + } + + public function testConfigurationWithMultiplePlugins() + { + $commands1 = array( + 'cmd1', 'cmd2', + ); + + $presenters1 = array( + 'presenter1', 'presenter2', + ); + + $matchers1 = array( + 'matcher1', 'matcher2', + ); + + $stub1 = new PluginStub(); + $stub1->setCommands($commands1); + $stub1->setPresenters($presenters1); + $stub1->setMatchers($matchers1); + + PluginManager::register($stub1, 'mock1'); + + $commands2 = array( + 'cmd3', 'cmd4', + ); + + $presenters2 = array( + 'presenter3', 'presenter4', + ); + + $matchers2 = array( + 'matcher3', 'matcher4', + ); + + $stub2 = new PluginStub(); + $stub2->setCommands($commands2); + $stub2->setPresenters($presenters2); + $stub2->setMatchers($matchers2); + + PluginManager::register($stub2, 'mock2'); + + $config = PluginManager::getConfiguration(); + $this->assertArraySubset($commands1, $config['commands']); + $this->assertArraySubset($presenters1, $config['presenters']); + $this->assertArraySubset($matchers1, $config['matchers']); + } +} diff --git a/test/Psy/Test/Plugin/PluginStub.php b/test/Psy/Test/Plugin/PluginStub.php new file mode 100644 index 000000000..3dc5436ec --- /dev/null +++ b/test/Psy/Test/Plugin/PluginStub.php @@ -0,0 +1,44 @@ +