From 57561b2f38badf93291fed59fdbdac447a73faa6 Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Wed, 15 Dec 2010 21:14:11 +0100 Subject: [PATCH] Finish the module provider and complete the module definition. --- framework/Cli_Modular/lib/Horde/Cli/Modular.php | 75 ++++++++++- .../Cli_Modular/lib/Horde/Cli/Modular/Module.php | 38 +++++- .../lib/Horde/Cli/Modular/ModuleProvider.php | 56 +++++++-- framework/Cli_Modular/package.xml | 10 ++ .../test/Horde/Cli/Modular/Autoload.php | 1 + .../test/Horde/Cli/Modular/Stub/Module/One.php | 71 ++++++++++- .../test/Horde/Cli/Modular/Stub/Provider.php | 9 ++ .../test/Horde/Cli/Modular/Unit/ModularTest.php | 139 ++++++++++++++++++--- .../Horde/Cli/Modular/Unit/ModuleProviderTest.php | 11 +- 9 files changed, 376 insertions(+), 34 deletions(-) create mode 100644 framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Provider.php diff --git a/framework/Cli_Modular/lib/Horde/Cli/Modular.php b/framework/Cli_Modular/lib/Horde/Cli/Modular.php index ad81c3175..112472518 100644 --- a/framework/Cli_Modular/lib/Horde/Cli/Modular.php +++ b/framework/Cli_Modular/lib/Horde/Cli/Modular.php @@ -42,6 +42,13 @@ class Horde_Cli_Modular private $_modules; /** + * Module provider. + * + * @var Horde_Cli_Modular_ModuleProvider + */ + private $_provider; + + /** * Constructor. * * @param array $parameters Options for this instance. @@ -56,6 +63,11 @@ class Horde_Cli_Modular * See Horde_Cli_Modular_Modules::__construct() * (string) A class name. * (object) An instance of Horde_Cli_Modular_Modules + * - provider: Determines the module provider. Can be one of: + * (array) A parameter array. + * See Horde_Cli_Modular_ModuleProvider::__construct() + * (string) A class name. + * (object) An instance of Horde_Cli_Modular_ModuleProvider * */ public function __construct(array $parameters = null) @@ -90,7 +102,7 @@ class Horde_Cli_Modular $usage = $this->_parameters['cli']['parser']['usage']; } foreach ($this->getModules() as $module) { - $usage .= ''; + $usage .= $this->getProvider()->getModule($module)->getUsage(); } return $usage; } @@ -103,15 +115,33 @@ class Horde_Cli_Modular public function createParser() { $parser_class = $this->getParserClass(); - return new $parser_class( + $parser = new $parser_class( array( 'usage' => '%prog ' . $this->getUsage() ) ); + foreach ($this->getModules() as $module_name) { + $module = $this->getProvider()->getModule($module_name); + foreach ($module->getBaseOptions() as $option) { + $parser->addOption($option); + } + if ($module->hasOptionGroup()) { + $group = new Horde_Argv_OptionGroup( + $parser, + $module->getOptionGroupTitle(), + $module->getOptionGroupDescription() + ); + foreach ($module->getOptionGroupOptions() as $option) { + $group->addOption($option); + } + $parser->addOptionGroup($group); + } + } + return $parser; } /** - * Create the module handler. + * Return the module handler. * * @return Horde_Cli_Modular_Modules The module handler. */ @@ -148,4 +178,43 @@ class Horde_Cli_Modular ); } } + + /** + * Return the module provider. + * + * @return Horde_Cli_Modular_ModuleProvider The module provider. + */ + public function getProvider() + { + if ($this->_provider === null) { + $this->_provider = $this->_createProvider(); + } + return $this->_provider; + } + + /** + * Create the module provider. + * + * @return Horde_Cli_Modular_ModuleProvider The module provider. + */ + private function _createProvider() + { + if (is_array($this->_parameters['provider'])) { + return new Horde_Cli_Modular_ModuleProvider( + $this->_parameters['provider'] + ); + } else if ($this->_parameters['provider'] instanceOf Horde_Cli_Modular_ModuleProvider) { + return $this->_parameters['provider']; + } else if (is_string($this->_parameters['provider'])) { + return new $this->_parameters['provider'](); + } else if (empty($this->_parameters['provider'])) { + throw new Horde_Cli_Modular_Exception( + 'Missing "provider" parameter!' + ); + } else { + throw new Horde_Cli_Modular_Exception( + 'Invalid "provider" parameter!' + ); + } + } } \ No newline at end of file diff --git a/framework/Cli_Modular/lib/Horde/Cli/Modular/Module.php b/framework/Cli_Modular/lib/Horde/Cli/Modular/Module.php index 1b4837a65..d722a87cf 100644 --- a/framework/Cli_Modular/lib/Horde/Cli/Modular/Module.php +++ b/framework/Cli_Modular/lib/Horde/Cli/Modular/Module.php @@ -32,5 +32,41 @@ interface Horde_Cli_Modular_Module * * @return string The description. */ - static public function getUsage(); + public function getUsage(); + + /** + * Get a set of base options that this module adds to the CLI argument + * parser. + * + * @return array The options. + */ + public function getBaseOptions(); + + /** + * Indicate if the module provides an option group. + * + * @return boolean True if an option group should be added. + */ + public function hasOptionGroup(); + + /** + * Return the title for the option group representing this module. + * + * @return string The group title. + */ + public function getOptionGroupTitle(); + + /** + * Return the description for the option group representing this module. + * + * @return string The group description. + */ + public function getOptionGroupDescription(); + + /** + * Return the options for this module. + * + * @return array The group options. + */ + public function getOptionGroupOptions(); } \ No newline at end of file diff --git a/framework/Cli_Modular/lib/Horde/Cli/Modular/ModuleProvider.php b/framework/Cli_Modular/lib/Horde/Cli/Modular/ModuleProvider.php index 78949e799..7b27b1447 100644 --- a/framework/Cli_Modular/lib/Horde/Cli/Modular/ModuleProvider.php +++ b/framework/Cli_Modular/lib/Horde/Cli/Modular/ModuleProvider.php @@ -37,11 +37,27 @@ class Horde_Cli_Modular_ModuleProvider private $_prefix; /** + * Constructor argument for CLI modules. Likely to be a Horde_Injector + * instance. + * + * @var mixed + */ + private $_dependencies; + + /** + * A cache for initialized module instances. + * + * @var array + */ + private $_instances; + + /** * Constructor. * * @param array $parameters Options for this instance. *
-     *  - 
+     *  - prefix: The module class name prefix.
+     *  - dependencies: Constructor argument for CLI modules.
      * 
*/ public function __construct(array $parameters = null) @@ -52,29 +68,47 @@ class Horde_Cli_Modular_ModuleProvider ); } $this->_prefix = $parameters['prefix']; + if (isset($parameters['dependencies'])) { + $this->_dependencies = $parameters['dependencies']; + } + } + + /** + * Return the specified module. + * + * @param string $module The desired module. + * + * @return Horde_Cli_Modular_Module The module instance. + * + * @throws Horde_Cli_Modular_Exception In case the specified module does not + * exist. + */ + public function getModule($module) + { + if (!isset($this->_instances[$module])) { + $this->_instances[$module] = $this->createModule($module); + } + return $this->_instances[$module]; } /** - * Get the usage string for the specified module. + * Create the specified module. * * @param string $module The desired module. * - * @return string The usage description for this module. + * @return Horde_Cli_Modular_Module The module instance. * * @throws Horde_Cli_Modular_Exception In case the specified module does not * exist. */ - public function getUsage($module) + protected function createModule($module) { - if (!class_exists($this->_prefix . $module)) { + $class = $this->_prefix . $module; + if (!class_exists($class)) { throw new Horde_Cli_Modular_Exception( - sprintf( - 'Invalid module %s!', $this->_prefix . $module - ) + sprintf('Invalid module %s!', $class) ); } - return call_user_func_array( - array($this->_prefix . $module, 'getUsage'), array() - ); + return new $class(); } } \ No newline at end of file diff --git a/framework/Cli_Modular/package.xml b/framework/Cli_Modular/package.xml index ea46cb3a9..f810662d3 100644 --- a/framework/Cli_Modular/package.xml +++ b/framework/Cli_Modular/package.xml @@ -85,7 +85,17 @@ 1.9.0 + + Argv + pear.horde.org + + + + Test + pear.horde.org + + diff --git a/framework/Cli_Modular/test/Horde/Cli/Modular/Autoload.php b/framework/Cli_Modular/test/Horde/Cli/Modular/Autoload.php index a5290b218..1d77a74d0 100644 --- a/framework/Cli_Modular/test/Horde/Cli/Modular/Autoload.php +++ b/framework/Cli_Modular/test/Horde/Cli/Modular/Autoload.php @@ -27,4 +27,5 @@ require_once dirname(__FILE__) . '/TestCase.php'; /** Load stub classes */ require_once dirname(__FILE__) . '/Stub/Modules.php'; +require_once dirname(__FILE__) . '/Stub/Provider.php'; require_once dirname(__FILE__) . '/Stub/Module/One.php'; \ No newline at end of file diff --git a/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Module/One.php b/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Module/One.php index 2ad1a0a9a..d853c9c30 100644 --- a/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Module/One.php +++ b/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Module/One.php @@ -3,8 +3,77 @@ class Horde_Cli_Modular_Stub_Module_One implements Horde_Cli_Modular_Module { - static public function getUsage() + public function getUsage() { return 'Use One'; } + + /** + * Get a set of base options that this module adds to the CLI argument + * parser. + * + * @return array The options. + */ + public function getBaseOptions() + { + return array( + new Horde_Argv_Option( + '-s', + '--something', + array( + 'action' => 'store', + 'help' => 'Base option' + ) + ), + ); + } + + /** + * Indicate if the module provides an option group. + * + * @return boolean True if an option group should be added. + */ + public function hasOptionGroup() + { + return true; + } + + /** + * Return the title for the option group representing this module. + * + * @return string The group title. + */ + public function getOptionGroupTitle() + { + return 'Test Group Title'; + } + + /** + * Return the description for the option group representing this module. + * + * @return string The group description. + */ + public function getOptionGroupDescription() + { + return 'Test Group Description'; + } + + /** + * Return the options for this module. + * + * @return array The group options. + */ + public function getOptionGroupOptions() + { + return array( + new Horde_Argv_Option( + '-g', + '--group', + array( + 'action' => 'store', + 'help' => 'Group option' + ) + ), + ); + } } \ No newline at end of file diff --git a/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Provider.php b/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Provider.php new file mode 100644 index 000000000..c5c14ab30 --- /dev/null +++ b/framework/Cli_Modular/test/Horde/Cli/Modular/Stub/Provider.php @@ -0,0 +1,9 @@ + array( - 'directory' => dirname(__FILE__) . '/../fixtures/Module' + 'directory' => dirname(__FILE__) . '/../Stub/Module' + ), + 'provider' => array( + 'prefix' => 'Horde_Cli_Modular_Stub_Module_' ), ) ); @@ -49,18 +52,7 @@ extends Horde_Cli_Modular_TestCase public function testCustomParser() { - $modular = new Horde_Cli_Modular( - array( - 'cli' => array( - 'parser' => array( - 'class' => 'Horde_Test_Stub_Parser' - ) - ), - 'modules' => array( - 'directory' => dirname(__FILE__) . '/../fixtures/Module' - ), - ) - ); + $modular = $this->_getDefault(); $this->assertInstanceOf('Horde_Test_Stub_Parser', $modular->createParser()); } @@ -70,7 +62,7 @@ extends Horde_Cli_Modular_TestCase public function testMissingModules() { $modular = new Horde_Cli_Modular(); - $this->assertInstanceOf('Horde_Cli_Modular_Modules', $modular->getModules()); + $modular->getModules(); } /** @@ -79,7 +71,7 @@ extends Horde_Cli_Modular_TestCase public function testInvalidModules() { $modular = new Horde_Cli_Modular(array('modules' => 1.0)); - $this->assertInstanceOf('Horde_Cli_Modular_Modules', $modular->getModules()); + $modular->getModules(); } public function testObjectModules() @@ -117,4 +109,121 @@ extends Horde_Cli_Modular_TestCase $this->assertInstanceOf('Horde_Cli_Modular_Modules', $modular->getModules()); } + /** + * @expectedException Horde_Cli_Modular_Exception + */ + public function testMissingProviders() + { + $modular = new Horde_Cli_Modular(); + $modular->getProvider(); + } + + /** + * @expectedException Horde_Cli_Modular_Exception + */ + public function testInvalidProviders() + { + $modular = new Horde_Cli_Modular(array('provider' => 1.0)); + $modular->getProvider(); + } + + public function testObjectProviders() + { + $modular = new Horde_Cli_Modular( + array('provider' => new Horde_Cli_Modular_ModuleProvider( + array('prefix' => 'Test') + ) + ) + ); + $this->assertInstanceOf( + 'Horde_Cli_Modular_ModuleProvider', $modular->getProvider() + ); + } + + public function testStringProviders() + { + $modular = new Horde_Cli_Modular( + array( + 'provider' => 'Horde_Cli_Modular_Stub_Provider' + ) + ); + $this->assertInstanceOf( + 'Horde_Cli_Modular_ModuleProvider', $modular->getProvider() + ); + } + + public function testArrayProviders() + { + $modular = new Horde_Cli_Modular( + array( + 'provider' => array( + 'prefix' => 'Test' + ), + ) + ); + $this->assertInstanceOf( + 'Horde_Cli_Modular_ModuleProvider', $modular->getProvider() + ); + } + + public function testGeneralUsage() + { + $modular = $this->_getDefault(); + $this->assertContains( + 'GLOBAL USAGE', $modular->createParser()->formatHelp() + ); + } + + public function testBaseOption() + { + $modular = $this->_getDefault(); + $this->assertContains( + '--something=SOMETHING', $modular->createParser()->formatHelp() + ); + } + + public function testGroupTitle() + { + $modular = $this->_getDefault(); + $this->assertContains( + 'Test Group Title', $modular->createParser()->formatHelp() + ); + } + + public function testGroupDescription() + { + $modular = $this->_getDefault(); + $this->assertContains( + 'Test Group Description', $modular->createParser()->formatHelp() + ); + } + + public function testGroupOption() + { + $modular = $this->_getDefault(); + $this->assertContains( + '--group=GROUP', $modular->createParser()->formatHelp() + ); + } + + private function _getDefault() + { + return new Horde_Cli_Modular( + array( + 'cli' => array( + 'parser' => array( + 'class' => 'Horde_Test_Stub_Parser', + 'usage' => 'GLOBAL USAGE' + + ) + ), + 'modules' => array( + 'directory' => dirname(__FILE__) . '/../Stub/Module' + ), + 'provider' => array( + 'prefix' => 'Horde_Cli_Modular_Stub_Module_' + ), + ) + ); + } } diff --git a/framework/Cli_Modular/test/Horde/Cli/Modular/Unit/ModuleProviderTest.php b/framework/Cli_Modular/test/Horde/Cli/Modular/Unit/ModuleProviderTest.php index d01098295..993368fa8 100644 --- a/framework/Cli_Modular/test/Horde/Cli/Modular/Unit/ModuleProviderTest.php +++ b/framework/Cli_Modular/test/Horde/Cli/Modular/Unit/ModuleProviderTest.php @@ -51,14 +51,19 @@ extends Horde_Cli_Modular_TestCase $provider = new Horde_Cli_Modular_ModuleProvider( array('prefix' => 'INVALID') ); - $provider->getUsage('One'); + $provider->getModule('One')->getUsage('One'); } public function testUsage() { $provider = new Horde_Cli_Modular_ModuleProvider( - array('prefix' => 'Horde_Cli_Modular_Stub_Module_') + array( + 'prefix' => 'Horde_Cli_Modular_Stub_Module_', + 'dependencies' => new stdClass, + ) + ); + $this->assertEquals( + 'Use One', $provider->getModule('One')->getUsage('One') ); - $this->assertEquals('Use One', $provider->getUsage('One')); } } -- 2.11.0