From: Gunnar Wrobel Date: Tue, 12 Oct 2010 08:06:05 +0000 (+0200) Subject: Extract the PEAR specific parts of the package.xml update process into the Pear wrappers. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=313d7b0cd5941e77d90a15f4fd87ef3355332fea;p=horde.git Extract the PEAR specific parts of the package.xml update process into the Pear wrappers. --- diff --git a/components/lib/Components/Config/Cli.php b/components/lib/Components/Config/Cli.php index 7b46ec544..3b8b76890 100644 --- a/components/lib/Components/Config/Cli.php +++ b/components/lib/Components/Config/Cli.php @@ -100,6 +100,16 @@ implements Components_Config ) ) ); + $parser->addOption( + new Horde_Argv_Option( + '-R', + '--pearrc', + array( + 'action' => 'store', + 'help' => 'the path to the configuration of the PEAR installation you want to use for all PEAR based actions (leave empty to use your system default PEAR environment).' + ) + ) + ); } /** diff --git a/components/lib/Components/Module/CiSetup.php b/components/lib/Components/Module/CiSetup.php index 1561ff0a4..f528b2a98 100644 --- a/components/lib/Components/Module/CiSetup.php +++ b/components/lib/Components/Module/CiSetup.php @@ -67,14 +67,6 @@ extends Components_Module_Base 'help' => 'the path to the PEAR installation holding the required analysis tools' ) ), - new Horde_Argv_Option( - '-R', - '--pearrc', - array( - 'action' => 'store', - 'help' => 'the path to the configuration of the PEAR installation' - ) - ), ); } diff --git a/components/lib/Components/Pear/Factory.php b/components/lib/Components/Pear/Factory.php index 6fed6c7eb..99a84ce8b 100644 --- a/components/lib/Components/Pear/Factory.php +++ b/components/lib/Components/Pear/Factory.php @@ -77,5 +77,19 @@ class Components_Pear_Factory return $package; } + /** + * Create a package representation for the default PEAR environment. + * + * @param string $package_file The path of the package XML file. + * + * @return NULL + */ + public function createPackageForDefaultLocation($package_file) + { + $package = $this->_dependencies->getInstance('Components_Pear_Package'); + $package->setEnvironment($this->_dependencies->getInstance('Components_Pear_InstallLocation')); + $package->setPackageXml($package_file); + return $package; + } } \ No newline at end of file diff --git a/components/lib/Components/Pear/Package.php b/components/lib/Components/Pear/Package.php index cadd58074..8b93d124f 100644 --- a/components/lib/Components/Pear/Package.php +++ b/components/lib/Components/Pear/Package.php @@ -56,6 +56,13 @@ class Components_Pear_Package private $_package_file; /** + * The writeable package representation. + * + * @param PEAR_PackageFileManager2 + */ + private $_package_rw_file; + + /** * Constructor. * * @param Component_Output $output The output handler. @@ -107,11 +114,9 @@ class Components_Pear_Package * * @return PEAR_PackageFile */ - public function getPackageFile() + private function _getPackageFile() { - if ($this->_environment === null || $this->_package_xml_path === null) { - throw new Components_Exception('You need to set the environment and the path to the package file first!'); - } + $this->_checkSetup(); if ($this->_package_file === null) { $config = $this->getEnvironment()->getPearConfig(); $pkg = new PEAR_PackageFile($config); @@ -124,12 +129,153 @@ class Components_Pear_Package } /** + * Return a writeable PEAR Package representation. + * + * @return PEAR_PackageFileManager2 + */ + private function _getPackageRwFile() + { + $this->_checkSetup(); + if ($this->_package_rw_file === null) { + /** + * Ensure we setup the PEAR_Config according to the PEAR environment + * the user set. + */ + $this->getEnvironment()->getPearConfig(); + + if (!class_exists('PEAR_PackageFileManager2')) { + throw new Components_Exception( + 'The Package "PEAR_PackageFileManager2" is missing in the PEAR environment. Please install it so that you can run this action.' + ); + } + + $this->_package_rw_file = PEAR_PackageFileManager2::importOptions( + $this->_package_xml_path, + array( + 'packagedirectory' => dirname($this->_package_xml_path), + 'filelistgenerator' => 'file', + 'clearcontents' => false, + 'clearchangelog' => false, + 'simpleoutput' => true, + 'ignore' => array('*~', 'conf.php', 'CVS/*'), + 'include' => '*', + 'dir_roles' => + array( + 'doc' => 'doc', + 'example' => 'doc', + 'js' => 'horde', + 'lib' => 'php', + 'migration' => 'data', + 'script' => 'script', + 'test' => 'test', + ), + ) + ); + + if ($this->_package_rw_file instanceOf PEAR_Error) { + throw new Components_Exception($this->_package_file->getMessage()); + } + } + return $this->_package_rw_file; + } + + /** + * Validate that the required parameters for providing the package definition are set. + * + * @return NULL + * + * @throws Components_Exception In case some settings are missing. + */ + private function _checkSetup() + { + if ($this->_environment === null || $this->_package_xml_path === null) { + throw new Components_Exception('You need to set the environment and the path to the package file first!'); + } + } + + /** * Return the description for this package. * * @return string The package description. */ public function getDescription() { - return $this->getPackageFile()->getDescription(); + return $this->_getPackageFile()->getDescription(); + } + + private function _getUpdatedPackageFile() + { + $package = $this->_getPackageRwFile(); + /** + * @todo: Looks like this throws away any tags we have in + * the content list. Needs to be fixed. + */ + $package->generateContents(); + + /** + * This is required to clear the + * section. + */ + $package->setPackageType('php'); + + $contents = $package->getContents(); + $files = $contents['dir']['file']; + + foreach ($files as $file) { + $components = explode('/', $file['attribs']['name'], 2); + switch ($components[0]) { + case 'doc': + case 'example': + case 'lib': + case 'test': + case 'data': + $package->addInstallAs( + $file['attribs']['name'], $components[1] + ); + break; + case 'js': + $package->addInstallAs( + $file['attribs']['name'], $file['attribs']['name'] + ); + break; + case 'migration': + $components = explode('/', $components[1]); + array_splice($components, count($components) - 1, 0, 'migration'); + $package->addInstallAs( + $file['attribs']['name'], implode('/', $components) + ); + break; + case 'script': + $filename = basename($file['attribs']['name']); + if (substr($filename, strlen($filename) - 4)) { + $filename = substr($filename, 0, strlen($filename) - 4); + } + $package->addInstallAs( + $file['attribs']['name'], $filename + ); + break; + } + } + return $package; } + + /** + * Output the updated package.xml file. + * + * @return NULL + */ + public function printUpdatedPackageFile() + { + $this->_getUpdatedPackageFile()->debugPackageFile(); + } + + /** + * Write the updated package.xml file to disk. + * + * @return NULL + */ + public function writeUpdatedPackageFile() + { + $this->_getUpdatedPackageFile()->writePackageFile(); + } } diff --git a/components/lib/Components/Runner/PearPackageXml.php b/components/lib/Components/Runner/PearPackageXml.php index 036d782b0..7d9d35bf0 100644 --- a/components/lib/Components/Runner/PearPackageXml.php +++ b/components/lib/Components/Runner/PearPackageXml.php @@ -37,121 +37,47 @@ class Components_Runner_PearPackageXml private $_config; /** - * The package handler. + * The factory for PEAR handlers. * - * @var Components_Pear_Package + * @var Components_Factory */ - private $_package; + private $_factory; /** * Constructor. * * @param Components_Config $config The configuration for the current job. - * @param Components_Pear_Package $package Package handler. + * @param Components_Pear_Factory $factory Generator for all + * required PEAR components. */ public function __construct( Components_Config $config, - Components_Pear_Package $package + Components_Pear_Factory $factory ) { $this->_config = $config; - $this->_package = $package; + $this->_factory = $factory; } public function run() { $arguments = $this->_config->getArguments(); - $package_file = $arguments[0] . '/package.xml'; - - $pear = new PEAR(); - $pear->setErrorHandling(PEAR_ERROR_DIE); - - if (!isset($GLOBALS['_PEAR_Config_instance'])) { - $GLOBALS['_PEAR_Config_instance'] = false; - } - - $package = PEAR_PackageFileManager2::importOptions( - $package_file, - array( - 'packagedirectory' => $arguments[0], - 'filelistgenerator' => 'file', - 'clearcontents' => false, - 'clearchangelog' => false, - 'simpleoutput' => true, - 'ignore' => array('*~', 'conf.php', 'CVS/*'), - 'include' => '*', - 'dir_roles' => - array( - 'doc' => 'doc', - 'example' => 'doc', - 'js' => 'horde', - 'lib' => 'php', - 'migration' => 'data', - 'script' => 'script', - 'test' => 'test', - ), - ) - ); - - if ($package instanceOf PEAR_Error) { - throw new Components_Exception($package->getMessage()); - } - /** - * @todo: Looks like this throws away any tags we have in - * the content list. Needs to be fixed. - */ - $package->generateContents(); - - /** - * This is required to clear the - * section. - */ - $package->setPackageType('php'); - - $contents = $package->getContents(); - $files = $contents['dir']['file']; - - foreach ($files as $file) { - $components = explode('/', $file['attribs']['name'], 2); - switch ($components[0]) { - case 'doc': - case 'example': - case 'lib': - case 'test': - case 'data': - $package->addInstallAs( - $file['attribs']['name'], $components[1] - ); - break; - case 'js': - $package->addInstallAs( - $file['attribs']['name'], $file['attribs']['name'] - ); - break; - case 'migration': - $components = explode('/', $components[1]); - array_splice($components, count($components) - 1, 0, 'migration'); - $package->addInstallAs( - $file['attribs']['name'], implode('/', $components) - ); - break; - case 'script': - $filename = basename($file['attribs']['name']); - if (substr($filename, strlen($filename) - 4)) { - $filename = substr($filename, 0, strlen($filename) - 4); - } - $package->addInstallAs( - $file['attribs']['name'], $filename - ); - break; - } + if (isset($options['pearrc'])) { + $package = $this->_factory->createPackageForInstallLocation( + $arguments[0] . '/package.xml', + $options['pearrc'] + ); + } else { + $package = $this->_factory->createPackageForDefaultLocation( + $arguments[0] . '/package.xml' + ); } $options = $this->_config->getOptions(); if (!empty($options['packagexml'])) { - $package->debugPackageFile(); + $package->printUpdatedPackageFile(); } if (!empty($options['updatexml'])) { - $package->writePackageFile(); + $package->writeUpdatedPackageFile(); } } diff --git a/components/test/Components/Integration/Components/Module/PearPackageXmlTest.php b/components/test/Components/Integration/Components/Module/PearPackageXmlTest.php new file mode 100644 index 000000000..e7d78eab5 --- /dev/null +++ b/components/test/Components/Integration/Components/Module/PearPackageXmlTest.php @@ -0,0 +1,115 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Components + */ + +/** + * Prepare the test setup. + */ +require_once dirname(__FILE__) . '/../../../Autoload.php'; + +/** + * Test the PearPackageXml module. + * + * 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 Components + * @subpackage UnitTests + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Components + */ +class Components_Integration_Components_Module_PearPackageXmlTest +extends Components_StoryTestCase +{ + + /** + * @scenario + */ + public function thePearpackagexmlModuleAddsThePOptionInTheHelpOutput() + { + $this->given('the default Components 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 Components setup') + ->when('calling the package with the help option') + ->then('the help will contain the "u" option.'); + } + + /** + * @scenario + */ + public function thePOptionFailsWithoutAValidPackagePath() + { + $this->given('the default Components setup') + ->when('calling the package with the packagexml option and the path', '') + ->then('the call will fail with', 'Please specify the path of the PEAR package!'); + } + + /** + * @scenario + */ + public function thePOptionFailsWithoutAValidDirectoryPath() + { + $this->given('the default Components setup') + ->when( + 'calling the package with the packagexml option and the path', + dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/DOESNOTEXIST' + ) + ->then('the call will fail with', 'specifies no directory'); + } + + /** + * @scenario + */ + public function thePOptionFailsWithoutAValidPackage() + { + $this->given('the default Components setup') + ->when( + 'calling the package with the packagexml option and the path', + dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture' + ) + ->then('the call will fail with', 'There is no package.xml at'); + } + + /** + * @scenario + */ + public function thePOptionProvidesAnUpdatedPackageXml() + { + $this->given('the default Components setup') + ->when('calling the package with the packagexml option and a Horde element') + ->then('the new package.xml of the Horde element will be printed.'); + } + + /** + * @todo Test (and fix) the reactions to three more scenarios: + * - invalid XML in the package.xml (e.g. tag missing) + * - empty file list + * - file list with just one entry. + * + * All three scenarios yield errors which are still hard to + * understand. + */ + +} \ No newline at end of file diff --git a/components/test/Components/Integration/ComponentsTest.php b/components/test/Components/Integration/ComponentsTest.php index d6e662d79..69dcd69eb 100644 --- a/components/test/Components/Integration/ComponentsTest.php +++ b/components/test/Components/Integration/ComponentsTest.php @@ -44,27 +44,6 @@ extends Components_StoryTestCase ->when('calling the package with the help option') ->then('the help will be displayed'); } - - /** - * @scenario - */ - public function thePearpackagexmlModuleAddsThePOptionInTheHelpOutput() - { - $this->given('the default Components 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 Components setup') - ->when('calling the package with the help option') - ->then('the help will contain the "u" option.'); - } - /** * @scenario */ @@ -75,60 +54,4 @@ extends Components_StoryTestCase ->then('the help will contain the "d" option.'); } - /** - * @scenario - */ - public function thePOptionFailsWithoutAValidPackagePath() - { - $this->given('the default Components setup') - ->when('calling the package with the packagexml option and the path', '') - ->then('the call will fail with', 'Please specify the path of the PEAR package!'); - } - - /** - * @scenario - */ - public function thePOptionFailsWithoutAValidDirectoryPath() - { - $this->given('the default Components setup') - ->when( - 'calling the package with the packagexml option and the path', - dirname(dirname(__FILE__)) . '/fixture/DOESNOTEXIST' - ) - ->then('the call will fail with', 'specifies no directory'); - } - - /** - * @scenario - */ - public function thePOptionFailsWithoutAValidPackage() - { - $this->given('the default Components setup') - ->when( - 'calling the package with the packagexml option and the path', - dirname(dirname(__FILE__)) . '/fixture' - ) - ->then('the call will fail with', 'There is no package.xml at'); - } - - /** - * @scenario - */ - public function thePOptionProvidesAnUpdatedPackageXml() - { - $this->given('the default Components setup') - ->when('calling the package with the packagexml option and a Horde element') - ->then('the new package.xml of the Horde element will be printed.'); - } - - /** - * @todo Test (and fix) the reactions to three more scenarios: - * - invalid XML in the package.xml (e.g. tag missing) - * - empty file list - * - file list with just one entry. - * - * All three scenarios yield errors which are still hard to - * understand. - */ - } \ No newline at end of file