private $_modules;
/**
+ * Module provider.
+ *
+ * @var Horde_Cli_Modular_ModuleProvider
+ */
+ private $_provider;
+
+ /**
* Constructor.
*
* @param array $parameters Options for this instance.
* 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
* </pre>
*/
public function __construct(array $parameters = null)
$usage = $this->_parameters['cli']['parser']['usage'];
}
foreach ($this->getModules() as $module) {
- $usage .= '';
+ $usage .= $this->getProvider()->getModule($module)->getUsage();
}
return $usage;
}
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.
*/
);
}
}
+
+ /**
+ * 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
*
* @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
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.
* <pre>
- * -
+ * - prefix: The module class name prefix.
+ * - dependencies: Constructor argument for CLI modules.
* </pre>
*/
public function __construct(array $parameters = null)
);
}
$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
<pearinstaller>
<min>1.9.0</min>
</pearinstaller>
+ <package>
+ <name>Argv</name>
+ <channel>pear.horde.org</channel>
+ </package>
</required>
+ <optional>
+ <package>
+ <name>Test</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </optional>
</dependencies>
<phprelease>
<filelist>
/** 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
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
--- /dev/null
+<?php
+
+class Horde_Cli_Modular_Stub_Provider
+extends Horde_Cli_Modular_ModuleProvider
+{
+ public function __construct()
+ {
+ }
+}
$modular = new Horde_Cli_Modular(
array(
'modules' => array(
- 'directory' => dirname(__FILE__) . '/../fixtures/Module'
+ 'directory' => dirname(__FILE__) . '/../Stub/Module'
+ ),
+ 'provider' => array(
+ 'prefix' => 'Horde_Cli_Modular_Stub_Module_'
),
)
);
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());
}
public function testMissingModules()
{
$modular = new Horde_Cli_Modular();
- $this->assertInstanceOf('Horde_Cli_Modular_Modules', $modular->getModules());
+ $modular->getModules();
}
/**
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()
$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_'
+ ),
+ )
+ );
+ }
}
$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'));
}
}