From: Gunnar Wrobel Date: Wed, 30 Jun 2010 19:40:46 +0000 (+0200) Subject: Working option parser. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=9eb9b37518b35d2b1ba6e1a2814f93dbe88da7e5;p=horde.git Working option parser. --- diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php b/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php index 6fc7150cd..d84295f9a 100644 --- a/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php +++ b/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php @@ -1,6 +1,6 @@ + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ + +/** + * The Horde_Qc:: class is the entry point for the various quality control / + * packaging actions provided by the package. + * + * Copyright 2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Horde + * @package Qc + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ +class Horde_Qc +{ + static public function main($parameters = array()) + { + $modules = new Horde_Qc_Modules(); + if (!isset($parameters['config'])) { + $parameters['config'] = array(); + } + $config = new Horde_Qc_Config($parameters['config']); + $modules->addModulesFromDirectory(dirname(__FILE__) . '/Qc/Module'); + $config->handleModules($modules); + foreach ($modules as $module) { + $module->handle($config->getOptions()); + } + } +} \ No newline at end of file diff --git a/framework/Qc/lib/Horde/Qc/Config.php b/framework/Qc/lib/Horde/Qc/Config.php index e4b6d76ec..923199b5f 100644 --- a/framework/Qc/lib/Horde/Qc/Config.php +++ b/framework/Qc/lib/Horde/Qc/Config.php @@ -26,15 +26,68 @@ * @author Gunnar Wrobel * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Qc -erver */ class Horde_Qc_Config { - private $configs; + /** + * The different configuration handlers. + * + * @var array + */ + private $_configs; - public function __construct(Horde_Qc_Modules $modules) + /** + * Constructor. + * + * @param array $parameters A list of named configuration parameters. + *
+     * 'cli' - (array)  See Horde_Qc_Config_Cli.
+     * 
+ */ + public function __construct( + $parameters = array() + ) { + if (!isset($parameters['cli'])) { + $parameters['cli'] = array(); + } + $this->_configs = array(); + $this->_configs[] = new Horde_Qc_Config_Cli( + $parameters['cli'] + ); + } + + /** + * Provide each configuration handler with the list of supported modules. + * + * @param Horde_Qc_Modules $modules A list of modules. + * @return NULL + */ + public function handleModules(Horde_Qc_Modules $modules) + { + foreach ($this->_configs as $config) { + $config->handleModules($modules); + } + } + + /** + * Return the options provided by the configuration hadnlers. + * + * @return array An array of options. + */ + public function getOptions() { - $this->configs[] = new Horde_Qc_Config_Cli($modules); + $options = array(); + foreach ($this->_configs as $config) { + if (count($config->getOptions()) !== 0) { + $config_options = array(); + foreach ($config->getOptions() as $name => $option) { + $config_options[$name] = $option; + } + $options = array_merge($options, $config_options); + } + } + return $options; } + } \ No newline at end of file diff --git a/framework/Qc/lib/Horde/Qc/Config/Cli.php b/framework/Qc/lib/Horde/Qc/Config/Cli.php index 3e4c72314..3a1158581 100644 --- a/framework/Qc/lib/Horde/Qc/Config/Cli.php +++ b/framework/Qc/lib/Horde/Qc/Config/Cli.php @@ -26,31 +26,98 @@ * @author Gunnar Wrobel * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Qc -erver */ class Horde_Qc_Config_Cli { + /** + * The command line argument parser. + * + * @var Horde_Argv_Parser + */ + private $_parser; + + /** + * The options parsed from the command line. + * + * @var array + */ private $_opts; + /** + * Any additional arguments parsed from the command line. + * + * @var array + */ private $_args; /** * Constructor. * - * @param Horde_Qc_Modules $modules A list of modules. + * @param array $parameters A list of named configuration parameters. + *
+     * 'parser' - (array)  Parser configuration parameters.
+     *   'class'  - (string) The class name of the parser to use.
+     * 
*/ - public function __construct(Horde_Qc_Modules $modules) - { - $parser = new Horde_Argv_Parser( + public function __construct( + $parameters = array() + ) { + if (empty($parameters['parser']['class'])) { + $parser_class = 'Horde_Argv_Parser'; + } else { + $parser_class = $parameters['parser']['class']; + } + $this->_parser = new $parser_class( array( 'usage' => '%prog ' . _("[options] PACKAGE_PATH") ) ); + } + + /** + * Load the options for the list of supported modules. + * + * @param Horde_Qc_Modules $modules A list of modules. + * @return NULL + */ + public function handleModules(Horde_Qc_Modules $modules) + { foreach ($modules as $module) { - $parser->addOptionGroup($module->getOptions()); + $this->_addOptionsFromModule($this->_parser, $module); } - list($this->_opts, $this->_args) = $parser->parseArgs(); + list($this->_opts, $this->_args) = $this->_parser->parseArgs(); + } + + /** + * Return the options parsed from the command line. + * + * @return array An array of options. + */ + public function getOptions() + { + return $this->_opts; + } + + /** + * Add an option group from the provided module to the parser. + * + * @param Horde_Argv_Parser $parser The parser. + * @param Horde_Qc_Module $module The module providing the option group. + * + * @return NULL + */ + private function _addOptionsFromModule($parser, $module) + { + $group = new Horde_Argv_OptionGroup( + $parser, + $module->getOptionGroupTitle(), + $module->getOptionGroupDescription() + ); + foreach ($module->getOptionGroupOptions() as $option) { + $group->addOption($option); + } + $parser->addOptionGroup($group); } } diff --git a/framework/Qc/lib/Horde/Qc/Module.php b/framework/Qc/lib/Horde/Qc/Module.php index feb6cf282..14beed8bb 100644 --- a/framework/Qc/lib/Horde/Qc/Module.php +++ b/framework/Qc/lib/Horde/Qc/Module.php @@ -24,27 +24,16 @@ * @author Gunnar Wrobel * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Qc -erver */ -abstract class Horde_Qc_Module +interface Horde_Qc_Module { - /** - * The parent module. - * - * @var Horde_Qc_Module - */ - private $_parent; + public function getOptionGroupTitle(); - public function __construct(Horde_Qc_Module $parent = null) - { - $this->_parent = $parent; - } + public function getOptionGroupDescription(); - abstract public function getOptions(); + public function getOptionGroupOptions(); - abstract public function validateOptions(); + public function handle(array $config); - abstract public function setup(); - - abstract public function run(); + public function run(); } \ No newline at end of file diff --git a/framework/Qc/lib/Horde/Qc/Module/PearPackageXml.php b/framework/Qc/lib/Horde/Qc/Module/PearPackageXml.php index 225102b24..ea7d5a758 100644 --- a/framework/Qc/lib/Horde/Qc/Module/PearPackageXml.php +++ b/framework/Qc/lib/Horde/Qc/Module/PearPackageXml.php @@ -26,19 +26,45 @@ * @link http://pear.horde.org/index.php?package=Qc */ class Horde_Qc_Module_PearPackageXml -extends Horde_Qc_Module +implements Horde_Qc_Module { - public function getOptions() + public function getOptionGroupTitle() + { + return 'Pear Package Xml'; + } + + public function getOptionGroupDescription() + { + return 'This module allows manipulation of the package.xml.'; + } + + public function getOptionGroupOptions() { return array( new Horde_Argv_Option( '-u', - '--update-packagexml', - array('action' => 'store_true') + '--updatexml', + array( + 'action' => 'store_true', + 'help' => 'update the package.xml for the package' + ) + ), + new Horde_Argv_Option( + '-p', + '--packagexml', + array( + 'action' => 'store_true', + 'help' => 'display an up-to-date package.xml for the package' + ) ) + ); } + public function handle(array $config) + { + } + public function run() { diff --git a/framework/Qc/lib/Horde/Qc/Modules.php b/framework/Qc/lib/Horde/Qc/Modules.php new file mode 100644 index 000000000..f52d0d6ba --- /dev/null +++ b/framework/Qc/lib/Horde/Qc/Modules.php @@ -0,0 +1,128 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ + +/** + * The Horde_Qc_Modules:: class handles a set of Qc modules. + * + * Copyright 2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Horde + * @package Qc + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ +class Horde_Qc_Modules +implements Iterator, Countable +{ + /** + * The available modules. + * + * @var array + */ + private $_modules; + + /** + * Constructor. + */ + public function __construct() + { + $this->_modules = array(); + } + + /** + * Add all modules found in the specified directory. + * + * @param string $module_directory Load the modules from this dirrectory. + * + * @return NULL + */ + public function addModulesFromDirectory( + $module_directory, + $base = 'Horde_Qc_Module_' + ) { + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($module_directory)) as $file) { + if ($file->isFile() && preg_match('/.php$/', $file->getFilename())) { + $class = $base . preg_replace("/^(.*)\.php/", '\\1', $file->getFilename()); + if (!class_exists($class)) { + require $file->getPathname(); + } + $this->_modules[$class] = new $class(); + } + } + } + + /** + * Implementation of the Iterator rewind() method. Reqinds the module list. + * + * return NULL + */ + public function rewind() + { + reset($this->_modules); + } + + /** + * Implementation of the Iterator current(). Returns the current module. + * + * @return mixed The current module. + */ + public function current() + { + return current($this->_modules); + } + + /** + * Implementation of the Iterator key() method. Returns the key of the current module. + * + * @return mixed The class name of the current module. + */ + public function key() + { + return key($this->_modules); + } + + /** + * Implementation of the Iterator next() method. Returns the next module. + * + * @return Horde_Qc_Module|null The next module or null if there are no more + * modules. + */ + public function next() + { + return next($this->_modules); + } + + /** + * Implementation of the Iterator valid() method. Indicates if the current element is a valid element. + * + * @return boolean Whether the current element is valid + */ + public function valid() + { + return key($this->_modules) !== null; + } + + /** + * Implementation of Countable count() method. Returns the number of modules. + * + * @return integer Number of modules. + */ + public function count() + { + return count($this->_modules); + } +} \ No newline at end of file diff --git a/framework/Qc/package.xml b/framework/Qc/package.xml index 4d41851ab..b3dce269a 100644 --- a/framework/Qc/package.xml +++ b/framework/Qc/package.xml @@ -46,9 +46,15 @@ - + + + + + + + @@ -83,9 +89,13 @@ + + - + + + diff --git a/framework/Qc/test/Horde/Qc/AllTests.php b/framework/Qc/test/Horde/Qc/AllTests.php index ad3f9c508..49a919fa9 100644 --- a/framework/Qc/test/Horde/Qc/AllTests.php +++ b/framework/Qc/test/Horde/Qc/AllTests.php @@ -4,11 +4,12 @@ * * PHP version 5 * - * @category Horde - * @package Qc - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Qc + * @category Horde + * @package Qc + * @subpackage UnitTests + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc */ /** @@ -24,8 +25,19 @@ if (!defined('PHPUnit_MAIN_METHOD')) { require_once 'Horde/Test/AllTests.php'; /** - * @package Horde_Qc + * Combine the tests for this package. + * + * Copyright 2007-2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Horde + * @package Qc * @subpackage UnitTests + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc */ class Horde_Qc_AllTests extends Horde_Test_AllTests { diff --git a/framework/Qc/test/Horde/Qc/Autoload.php b/framework/Qc/test/Horde/Qc/Autoload.php new file mode 100644 index 000000000..f3bdae77f --- /dev/null +++ b/framework/Qc/test/Horde/Qc/Autoload.php @@ -0,0 +1,41 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ + +if (!spl_autoload_functions()) { + spl_autoload_register( + create_function( + '$class', + '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class);' + . '$err_mask = E_ALL ^ E_WARNING;' + . '$oldErrorReporting = error_reporting($err_mask);' + . 'include "$filename.php";' + . 'error_reporting($oldErrorReporting);' + ) + ); +} + +/** Catch strict standards */ +error_reporting(E_ALL | E_STRICT); + + +/** Load the basic test definition */ +require_once dirname(__FILE__) . '/StoryTestCase.php'; + +/** Load stubs */ +require_once dirname(__FILE__) . '/Stub/Parser.php'; diff --git a/framework/Qc/test/Horde/Qc/Integration/QcTest.php b/framework/Qc/test/Horde/Qc/Integration/QcTest.php new file mode 100644 index 000000000..93e10defb --- /dev/null +++ b/framework/Qc/test/Horde/Qc/Integration/QcTest.php @@ -0,0 +1,67 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ + +/** + * Prepare the test setup. + */ +require_once dirname(__FILE__) . '/../Autoload.php'; + +/** + * Test the Qc package. + * + * Copyright 2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Horde + * @package Qc + * @subpackage UnitTests + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ +class Horde_Qc_Integration_QcTest +extends Horde_Qc_StoryTestCase +{ + /** + * @scenario + */ + public function theHelpOptionResultsInHelpOutput() + { + $this->given('the default QC package setup') + ->when('calling the package with the help option') + ->then('the help will be displayed'); + } + + /** + * @scenario + */ + public function thePearpackagexmlModuleAddsThePOptionInTheHelpOutput() + { + $this->given('the default QC package setup') + ->when('calling the package with the help option') + ->then('the help will contain the "p" option.'); + } + + /** + * @scenario + */ + public function thePearpackagexmlModuleAddsTheUOptionInTheHelpOutput() + { + $this->given('the default QC package setup') + ->when('calling the package with the help option') + ->then('the help will contain the "u" option.'); + } +} \ No newline at end of file diff --git a/framework/Qc/test/Horde/Qc/StoryTestCase.php b/framework/Qc/test/Horde/Qc/StoryTestCase.php new file mode 100644 index 000000000..8649540c2 --- /dev/null +++ b/framework/Qc/test/Horde/Qc/StoryTestCase.php @@ -0,0 +1,113 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ + +/** + * Base for story based package testing. + * + * Copyright 2010 The Horde Project (http://www.horde.org/) + * + * See the enclosed file COPYING for license information (LGPL). If you + * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. + * + * @category Horde + * @package Qc + * @subpackage UnitTests + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Qc + */ +class Horde_Qc_StoryTestCase +extends PHPUnit_Extensions_Story_TestCase +{ + /** + * Handle a "given" step. + * + * @param array &$world Joined "world" of variables. + * @param string $action The description of the step. + * @param array $arguments Additional arguments to the step. + * + * @return mixed The outcome of the step. + */ + public function runGiven(&$world, $action, $arguments) + { + switch($action) { + case 'the default QC package setup': + break; + default: + return $this->notImplemented($action); + } + } + + /** + * Handle a "when" step. + * + * @param array &$world Joined "world" of variables. + * @param string $action The description of the step. + * @param array $arguments Additional arguments to the step. + * + * @return mixed The outcome of the step. + */ + public function runWhen(&$world, $action, $arguments) + { + switch($action) { + case 'calling the package with the help option': + $_SERVER['argv'] = array('hqc', '--help', '--packagexml'); + ob_start(); + $parameters = array(); + $parameters['config']['cli']['parser']['class'] = 'Horde_Qc_Stub_Parser'; + Horde_Qc::main($parameters); + $world['output'] = ob_get_contents(); + ob_end_clean(); + break; + default: + return $this->notImplemented($action); + } + } + + /** + * Handle a "then" step. + * + * @param array &$world Joined "world" of variables. + * @param string $action The description of the step. + * @param array $arguments Additional arguments to the step. + * + * @return mixed The outcome of the step. + */ + public function runThen(&$world, $action, $arguments) + { + switch($action) { + case 'the help will be displayed': + $this->assertRegExp( + '/-h,[ ]*--help[ ]*show this help message and exit/', + $world['output'] + ); + break; + case 'the help will contain the "p" option.': + $this->assertRegExp( + '/-p,\s*--packagexml/m', + $world['output'] + ); + break; + case 'the help will contain the "u" option.': + $this->assertRegExp( + '/-u,\s*--updatexml/', + $world['output'] + ); + break; + default: + return $this->notImplemented($action); + } + } + +} \ No newline at end of file diff --git a/framework/Qc/test/Horde/Qc/Stub/Parser.php b/framework/Qc/test/Horde/Qc/Stub/Parser.php new file mode 100644 index 000000000..44303cd29 --- /dev/null +++ b/framework/Qc/test/Horde/Qc/Stub/Parser.php @@ -0,0 +1,10 @@ + + + + + ../../../lib + + +