From: Gunnar Wrobel
Date: Sun, 3 Oct 2010 17:42:44 +0000 (+0200)
Subject: Refactor the dependency setup and add a draft for the distibute module.
X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=be3dccb87a7e307703b25a03095cb86be3786aac;p=horde.git
Refactor the dependency setup and add a draft for the distibute module.
---
diff --git a/components/lib/Components.php b/components/lib/Components.php
index c6da6a1bb..3d6db5b06 100644
--- a/components/lib/Components.php
+++ b/components/lib/Components.php
@@ -47,10 +47,9 @@ class Components
&& $parameters['dependencies'] instanceOf Components_Dependencies) {
$dependencies = $parameters['dependencies'];
} else {
- $dependencies = new Components_Dependencies_Injector(
- $config
- );
+ $dependencies = new Components_Dependencies_Injector();
}
+ $dependencies->initConfig($config);
$modules = self::_prepareModules($dependencies);
$config->handleModules($modules);
try {
diff --git a/components/lib/Components/Dependencies.php b/components/lib/Components/Dependencies.php
index 229f907f9..57c6c458c 100644
--- a/components/lib/Components/Dependencies.php
+++ b/components/lib/Components/Dependencies.php
@@ -30,6 +30,29 @@
interface Components_Dependencies
{
/**
+ * Initial configuration setup.
+ *
+ * @param Components_Config $config The configuration.
+ *
+ * @return NULL
+ */
+ public function initConfig(Components_Config $config);
+
+ /**
+ * Returns the continuous integration setup handler.
+ *
+ * @return Components_Runner_CiSetup The CI setup handler.
+ */
+ public function getRunnerCiSetup();
+
+ /**
+ * Returns the distribution handler for a package.
+ *
+ * @return Components_Runner_Distribute The distribution handler.
+ */
+ public function getRunnerDistribute();
+
+ /**
* Returns the installer for a package.
*
* @return Components_Runner_Installer The installer.
diff --git a/components/lib/Components/Dependencies/Injector.php b/components/lib/Components/Dependencies/Injector.php
index 0cc4ca64e..a043534cb 100644
--- a/components/lib/Components/Dependencies/Injector.php
+++ b/components/lib/Components/Dependencies/Injector.php
@@ -33,16 +33,45 @@ implements Components_Dependencies
{
/**
* Constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct(new Horde_Injector_TopLevel());
+ }
+
+ /**
+ * Initial configuration setup.
*
* @param Components_Config $config The configuration.
+ *
+ * @return NULL
*/
- public function __construct(Components_Config $config)
+ public function initConfig(Components_Config $config)
{
- parent::__construct(new Horde_Injector_TopLevel());
$this->setInstance('Components_Config', $config);
}
/**
+ * Returns the continuous integration setup handler.
+ *
+ * @return Components_Runner_CiSetup The CI setup handler.
+ */
+ public function getRunnerCiSetup()
+ {
+ return $this->getInstance('Components_Runner_CiSetup');
+ }
+
+ /**
+ * Returns the distribution handler for a package.
+ *
+ * @return Components_Runner_Distribute The distribution handler.
+ */
+ public function getRunnerDistribute()
+ {
+ return $this->getInstance('Components_Runner_Distribute');
+ }
+
+ /**
* Returns the installer for a package.
*
* @return Components_Runner_Installer The installer.
diff --git a/components/lib/Components/Module/Distribute.php b/components/lib/Components/Module/Distribute.php
new file mode 100644
index 000000000..c60f32f4c
--- /dev/null
+++ b/components/lib/Components/Module/Distribute.php
@@ -0,0 +1,93 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Module_Distribute:: prepares a distribution package for a
+ * component.
+ *
+ * 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
+ * @author Gunnar Wrobel
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+class Components_Module_Distribute
+extends Components_Module_Base
+{
+ /**
+ * Return the title for the option group representing this module.
+ *
+ * @return string The group title.
+ */
+ public function getOptionGroupTitle()
+ {
+ return 'Distribute';
+ }
+
+ /**
+ * Return the description for the option group representing this module.
+ *
+ * @return string The group description.
+ */
+ public function getOptionGroupDescription()
+ {
+ return 'This module prepares a distribution package (e.g. RPM, APT, Ebuild, ...) from a component.';
+ }
+
+ /**
+ * Return the options for this module.
+ *
+ * @return array The group options.
+ */
+ public function getOptionGroupOptions()
+ {
+ return array(
+ new Horde_Argv_Option(
+ '-D',
+ '--distribute',
+ array(
+ 'action' => 'store',
+ 'help' => 'Prepare the component package in the specified DISTRIBUTE location'
+ )
+ ),
+ new Horde_Argv_Option(
+ '-t',
+ '--template',
+ array(
+ 'action' => 'store',
+ 'help' => 'Location of a template that will be rewritten into the final package definition.'
+ )
+ ),
+ );
+ }
+
+ /**
+ * Determine if this module should act. Run all required actions if it has
+ * been instructed to do so.
+ *
+ * @return NULL
+ */
+ public function handle(Components_Config $config)
+ {
+ $options = $config->getOptions();
+ if (!empty($options['distribute'])) {
+ $this->_dependencies->getRunnerDistribute()->run();
+ }
+ }
+}
diff --git a/components/lib/Components/Runner/Distribute.php b/components/lib/Components/Runner/Distribute.php
new file mode 100644
index 000000000..e437e36ac
--- /dev/null
+++ b/components/lib/Components/Runner/Distribute.php
@@ -0,0 +1,67 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Runner_Distribute:: prepares a distribution package for a
+ * component.
+ *
+ * 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
+ * @author Gunnar Wrobel
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+class Components_Runner_Distribute
+{
+ /**
+ * The configuration for the current job.
+ *
+ * @var Components_Config
+ */
+ private $_config;
+
+ /**
+ * The package handler.
+ *
+ * @var Components_Pear_Package
+ */
+ private $_package;
+
+ /**
+ * Constructor.
+ *
+ * @param Components_Config $config The configuration for the current job.
+ * @param Components_Pear_Package $package Package handler.
+ */
+ public function __construct(
+ Components_Config $config,
+ Components_Pear_Package $package
+ ) {
+ $this->_config = $config;
+ $this->_package = $package;
+ }
+
+ public function run()
+ {
+ $options = $this->_config->getOptions();
+ $arguments = $this->_config->getArguments();
+ $location = realpath($options['distribute']);
+
+ }
+}
diff --git a/components/package.xml b/components/package.xml
index 14c4f057f..9f94f2cc7 100644
--- a/components/package.xml
+++ b/components/package.xml
@@ -24,8 +24,8 @@
jan@horde.org
yes
- 2010-09-06
-
+ 2010-10-03
+
0.0.1
0.0.1
@@ -57,20 +57,22 @@
+
+
+
+
-
-
-
+
@@ -80,9 +82,7 @@
-
-
-
+
@@ -100,9 +100,15 @@
+
+
+
+
+
+
@@ -112,6 +118,7 @@
+
@@ -169,9 +176,13 @@
+
+
+
+
@@ -184,6 +195,8 @@
+
+
@@ -197,7 +210,7 @@
alpha
alpha
- 2010-09-06
+ 2010-10-03
LGPL
* Initial release
diff --git a/components/test/Components/Autoload.php b/components/test/Components/Autoload.php
index b347717c8..2fde5e569 100644
--- a/components/test/Components/Autoload.php
+++ b/components/test/Components/Autoload.php
@@ -30,6 +30,10 @@ if (!spl_autoload_functions()) {
);
}
+if (!class_exists('Components')) {
+ set_include_path(dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'lib' . PATH_SEPARATOR . get_include_path());
+}
+
/** Catch strict standards */
error_reporting(E_ALL | E_STRICT);
@@ -38,4 +42,5 @@ error_reporting(E_ALL | E_STRICT);
require_once dirname(__FILE__) . '/StoryTestCase.php';
/** Load stubs */
+require_once dirname(__FILE__) . '/Stub/Cli.php';
require_once dirname(__FILE__) . '/Stub/Parser.php';
diff --git a/components/test/Components/Integration/Components/Module/CiSetupTest.php b/components/test/Components/Integration/Components/Module/CiSetupTest.php
new file mode 100644
index 000000000..9c8cc0ed5
--- /dev/null
+++ b/components/test/Components/Integration/Components/Module/CiSetupTest.php
@@ -0,0 +1,97 @@
+
+ * @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 Components 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 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_CiSetupTest
+extends Components_StoryTestCase
+{
+ /**
+ * @scenario
+ */
+ public function theCisetupModuleAddsTheCOptionInTheHelpOutput()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the help option')
+ ->then('the help will contain the option', '-c\s*CISETUP,\s*--cisetup=CISETUP');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theCisetupModuleAddsTheCapitalCOptionInTheHelpOutput()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the help option')
+ ->then('the help will contain the option', '-C\s*CIPREBUILD,\s*--ciprebuild=CIPREBUILD');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theCisetupOptionsFailsWithoutAValidPearrcOption()
+ {
+ $this->given('the default Components setup')
+ ->when(
+ 'calling the package with the cisetup option and paths',
+ 'test',
+ dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/simple'
+ )
+ ->then('the call will fail with', 'You are required to set the path to a PEAR environment for this package');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theCisetupOptionCreatesATemplateBaseCiConfigurationForAComponent()
+ {
+ $this->given('the default Components setup')
+ ->when(
+ 'calling the package with the cisetup, pearrc options and path',
+ dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/simple'
+ )
+ ->then('the CI configuration will be installed.');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theCisetupOptionCreatesATemplateBaseCiBuildScriptForAComponent()
+ {
+ $this->given('the default Components setup')
+ ->when(
+ 'calling the package with the ciprebuild, pearrc options and path',
+ dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/simple'
+ )
+ ->then('the CI build script will be installed.');
+ }
+}
\ No newline at end of file
diff --git a/components/test/Components/Integration/ComponentsTest.php b/components/test/Components/Integration/ComponentsTest.php
index 6941070be..0068dc29c 100644
--- a/components/test/Components/Integration/ComponentsTest.php
+++ b/components/test/Components/Integration/ComponentsTest.php
@@ -78,7 +78,43 @@ extends Components_StoryTestCase
/**
* @scenario
*/
- public function theThePOptionProvidesAnUpdatedPackageXml()
+ 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')
diff --git a/components/test/Components/StoryTestCase.php b/components/test/Components/StoryTestCase.php
index 01fd6a228..a35312690 100644
--- a/components/test/Components/StoryTestCase.php
+++ b/components/test/Components/StoryTestCase.php
@@ -74,12 +74,7 @@ extends PHPUnit_Extensions_Story_TestCase
'--help',
dirname(__FILE__) . '/fixture/empty'
);
- ob_start();
- $parameters = array();
- $parameters['cli']['parser']['class'] = 'Components_Stub_Parser';
- Components::main($parameters);
- $world['output'] = ob_get_contents();
- ob_end_clean();
+ $world['output'] = $this->_callStrictComponents();
break;
case 'calling the package with the packagexml option and a Horde element':
$_SERVER['argv'] = array(
@@ -87,29 +82,52 @@ extends PHPUnit_Extensions_Story_TestCase
'--packagexml',
dirname(__FILE__) . '/fixture/simple'
);
- ob_start();
- $parameters = array();
- $parameters['cli']['parser']['class'] = 'Components_Stub_Parser';
- $old_errorreporting = error_reporting(E_ALL & ~E_STRICT);
- Components::main($parameters);
- error_reporting($old_errorreporting);
- $world['output'] = ob_get_contents();
- ob_end_clean();
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
+ case 'calling the package with the packagexml option and the path':
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--packagexml',
+ $arguments[0]
+ );
+ $world['output'] = $this->_callStrictComponents();
+ break;
+ case 'calling the package with the cisetup option and paths':
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--cisetup=' . $arguments[0],
+ $arguments[1]
+ );
+ $world['output'] = $this->_callStrictComponents();
+ break;
+ case 'calling the package with the cisetup, pearrc options and path':
+ $tmp = $this->_getTemporaryDirectory();
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--cisetup=' . $tmp,
+ '--pearrc=' . $tmp . DIRECTORY_SEPARATOR . '.pearrc',
+ $arguments[0]
+ );
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
+ case 'calling the package with the ciprebuild, pearrc options and path':
+ $tmp = $this->_getTemporaryDirectory();
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--ciprebuild=' . $tmp,
+ '--pearrc=' . $tmp . DIRECTORY_SEPARATOR . '.pearrc',
+ $arguments[0]
+ );
+ $world['output'] = $this->_callUnstrictComponents();
break;
case 'calling the package with the install option and a Horde element':
$_SERVER['argv'] = array(
'horde-components',
+ '--channelxmlpath=' . dirname(__FILE__) . '/fixture/channels',
'--install=' . $this->_getTemporaryDirectory(),
dirname(__FILE__) . '/../../'
);
- ob_start();
- $parameters = array();
- $parameters['cli']['parser']['class'] = 'Components_Stub_Parser';
- $old_errorreporting = error_reporting(E_ALL & ~E_STRICT);
- Components::main($parameters);
- error_reporting($old_errorreporting);
- $world['output'] = ob_get_contents();
- ob_end_clean();
+ $world['output'] = $this->_callUnstrictComponents();
break;
default:
return $this->notImplemented($action);
@@ -158,6 +176,12 @@ extends PHPUnit_Extensions_Story_TestCase
$world['output']
);
break;
+ case 'the help will contain the option':
+ $this->assertRegExp(
+ '/' . $arguments[0] . '/',
+ $world['output']
+ );
+ break;
case 'the new package.xml of the Horde element will be printed.':
$this->assertRegExp(
'//',
@@ -180,7 +204,6 @@ extends PHPUnit_Extensions_Story_TestCase
);
break;
case 'the non-Horde dependencies of the Horde element will get installed from the network.':
- var_dump($world['output']);
$this->assertTrue(
file_exists(
$this->_temp_dir . DIRECTORY_SEPARATOR
@@ -212,6 +235,28 @@ extends PHPUnit_Extensions_Story_TestCase
)
);
break;
+ case 'the CI configuration will be installed.':
+ $this->assertTrue(
+ file_exists(
+ $this->_temp_dir . DIRECTORY_SEPARATOR
+ . 'config.xml'
+ )
+ );
+ break;
+ case 'the CI build script will be installed.':
+ $this->assertTrue(
+ file_exists(
+ $this->_temp_dir . DIRECTORY_SEPARATOR
+ . 'build.xml'
+ )
+ );
+ break;
+ case 'the call will fail with':
+ $this->assertContains(
+ $arguments[0],
+ $world['output']
+ );
+ break;
default:
return $this->notImplemented($action);
}
@@ -241,5 +286,42 @@ extends PHPUnit_Extensions_Story_TestCase
reset($objects);
rmdir($dir);
}
- }
+ }
+
+ private function _callStrictComponents(array $parameters = array())
+ {
+ return $this->_callComponents($parameters, array($this, '_callStrict'));
+ }
+
+ private function _callUnstrictComponents(array $parameters = array())
+ {
+ return $this->_callComponents($parameters, array($this, '_callUnstrict'));
+ }
+
+ private function _callComponents(array $parameters, $callback)
+ {
+ ob_start();
+ $parameters['cli']['parser']['class'] = 'Components_Stub_Parser';
+ $parameters['dependencies'] = new Components_Dependencies_Injector();
+ $parameters['dependencies']->setInstance(
+ 'Horde_Cli',
+ new Components_Stub_Cli()
+ );
+ call_user_func_array($callback, array($parameters));
+ $output = ob_get_contents();
+ ob_end_clean();
+ return $output;
+ }
+
+ private function _callUnstrict(array $parameters)
+ {
+ $old_errorreporting = error_reporting(E_ALL & ~E_STRICT);
+ $this->_callStrict($parameters);
+ error_reporting($old_errorreporting);
+ }
+
+ private function _callStrict(array $parameters)
+ {
+ Components::main($parameters);
+ }
}
\ No newline at end of file
diff --git a/components/test/Components/Stub/Cli.php b/components/test/Components/Stub/Cli.php
new file mode 100644
index 000000000..f6564d189
--- /dev/null
+++ b/components/test/Components/Stub/Cli.php
@@ -0,0 +1,30 @@
+getMessage();
+ }
+ $this->writeln($this->red('===================='));
+ $this->writeln();
+ $this->writeln($this->red(_("Fatal Error:")));
+ $this->writeln($this->red($error));
+ $this->writeln();
+ $this->writeln((string)$backtrace);
+ $this->writeln($this->red('===================='));
+ }
+}
\ No newline at end of file
diff --git a/components/test/Components/Stub/Parser.php b/components/test/Components/Stub/Parser.php
index 082b79542..b8efead9f 100644
--- a/components/test/Components/Stub/Parser.php
+++ b/components/test/Components/Stub/Parser.php
@@ -2,9 +2,22 @@
class Components_Stub_Parser
extends Horde_Argv_Parser
{
+ /**
+ * Print a usage message incorporating $msg to stderr and exit.
+ * If you override this in a subclass, it should not return -- it
+ * should either exit or raise an exception.
+ *
+ * @param string $msg
+ */
+ public function parserError($msg)
+ {
+ $this->printUsage();
+ $this->parserExit(2, sprintf("%s: error: %s\n", $this->getProgName(), $msg));
+ }
+
public function parserExit($status = 0, $msg = null)
{
if ($msg)
- fwrite(STDERR, $msg);
+ echo $msg;
}
}
\ No newline at end of file