From 0c14afa52986ce832538cb67da32a4cb75372e42 Mon Sep 17 00:00:00 2001
From: Gunnar Wrobel
Date: Mon, 4 Oct 2010 03:37:39 +0200
Subject: [PATCH] Allow specifying the template files that should be used for
the CI setup. Splitted the CiSetup Runner in two separate runners (CiSetup,
CiPrebuild). Updated TODOs, adapted testing.
---
components/TODO | 7 +-
components/lib/Components/Config/Application.php | 66 +++++++++++
components/lib/Components/Config/Cli.php | 10 ++
components/lib/Components/Dependencies.php | 7 ++
.../lib/Components/Dependencies/Injector.php | 10 ++
components/lib/Components/Module/CiSetup.php | 5 +-
components/lib/Components/Module/Distribute.php | 8 --
components/lib/Components/Runner/CiPrebuild.php | 126 +++++++++++++++++++++
components/lib/Components/Runner/CiSetup.php | 58 ++++------
.../Integration/Components/Module/CiSetupTest.php | 26 +++++
components/test/Components/StoryTestCase.php | 40 +++++++
.../templates/hudson-component-build.xml.template | 1 +
.../templates/hudson-component-config.xml.template | 1 +
.../hudson-component-phpunit.xml.template | 1 +
14 files changed, 319 insertions(+), 47 deletions(-)
create mode 100644 components/lib/Components/Config/Application.php
create mode 100644 components/lib/Components/Runner/CiPrebuild.php
create mode 100644 components/test/Components/fixture/templates/hudson-component-build.xml.template
create mode 100644 components/test/Components/fixture/templates/hudson-component-config.xml.template
create mode 100644 components/test/Components/fixture/templates/hudson-component-phpunit.xml.template
diff --git a/components/TODO b/components/TODO
index 73f76133c..ee354f67a 100644
--- a/components/TODO
+++ b/components/TODO
@@ -4,9 +4,7 @@
- Document usage
- - Allow specifying the template file for the CI setup that should be used.
-
- - Allow offline installs
+ - Allow offline installs and testing
- Add module for an initial empty PEAR template
@@ -19,7 +17,10 @@
- Add a release helper module.
+ - Maybe prefix the job names of packages from the framework with Horde_
+
- Allow absolute/relative paths as arguments
- Fail on missing dependencies in a decent way
+ - WWW frontend
diff --git a/components/lib/Components/Config/Application.php b/components/lib/Components/Config/Application.php
new file mode 100644
index 000000000..92cdb11c4
--- /dev/null
+++ b/components/lib/Components/Config/Application.php
@@ -0,0 +1,66 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Config_Application:: provides a wrapper that provides application
+ * specific configuration values by combining defaults and options provided at
+ * runtime.
+ *
+ * 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_Config_Application
+{
+ /**
+ * The generic configuration handler.
+ *
+ * @var Components_Config
+ */
+ private $_config;
+
+ /**
+ * Constructor.
+ *
+ * @param Components_Config $config The generic configuration handler.
+ */
+ public function __construct(
+ Components_Config $config
+ ) {
+ $this->_config = $config;
+ }
+
+ /**
+ * Return the path to the template directory
+ *
+ * @return string The path to the template directory.
+ */
+ public function getTemplateDirectory()
+ {
+ $options = $this->_config->getOptions();
+ if (!isset($options['templatedir'])) {
+ return Components_Constants::getDataDirectory();
+ } else {
+ return $options['templatedir'];
+ }
+ }
+}
diff --git a/components/lib/Components/Config/Cli.php b/components/lib/Components/Config/Cli.php
index e63505717..7b46ec544 100644
--- a/components/lib/Components/Config/Cli.php
+++ b/components/lib/Components/Config/Cli.php
@@ -90,6 +90,16 @@ implements Components_Config
)
)
);
+ $parser->addOption(
+ new Horde_Argv_Option(
+ '-t',
+ '--templatedir',
+ array(
+ 'action' => 'store',
+ 'help' => 'Location of a template directory that contains template definitions (see the data directory of this package to get an impression of which templates are available).'
+ )
+ )
+ );
}
/**
diff --git a/components/lib/Components/Dependencies.php b/components/lib/Components/Dependencies.php
index 57c6c458c..6e8797b13 100644
--- a/components/lib/Components/Dependencies.php
+++ b/components/lib/Components/Dependencies.php
@@ -46,6 +46,13 @@ interface Components_Dependencies
public function getRunnerCiSetup();
/**
+ * Returns the continuous integration pre-build handler.
+ *
+ * @return Components_Runner_CiPrebuild The CI pre-build handler.
+ */
+ public function getRunnerCiPrebuild();
+
+ /**
* Returns the distribution handler for a package.
*
* @return Components_Runner_Distribute The distribution handler.
diff --git a/components/lib/Components/Dependencies/Injector.php b/components/lib/Components/Dependencies/Injector.php
index a043534cb..0437ead89 100644
--- a/components/lib/Components/Dependencies/Injector.php
+++ b/components/lib/Components/Dependencies/Injector.php
@@ -62,6 +62,16 @@ implements Components_Dependencies
}
/**
+ * Returns the continuous integration pre-build handler.
+ *
+ * @return Components_Runner_CiPrebuild The CI pre-build handler.
+ */
+ public function getRunnerCiPrebuild()
+ {
+ return $this->getInstance('Components_Runner_CiPrebuild');
+ }
+
+ /**
* Returns the distribution handler for a package.
*
* @return Components_Runner_Distribute The distribution handler.
diff --git a/components/lib/Components/Module/CiSetup.php b/components/lib/Components/Module/CiSetup.php
index 2704c6ad2..1561ff0a4 100644
--- a/components/lib/Components/Module/CiSetup.php
+++ b/components/lib/Components/Module/CiSetup.php
@@ -82,8 +82,11 @@ extends Components_Module_Base
{
$options = $config->getOptions();
//@todo Split into two different runners here
- if (!empty($options['cisetup']) | !empty($options['ciprebuild'])) {
+ if (!empty($options['cisetup'])) {
$this->_dependencies->getRunnerCiSetup()->run();
}
+ if (!empty($options['ciprebuild'])) {
+ $this->_dependencies->getRunnerCiPrebuild()->run();
+ }
}
}
diff --git a/components/lib/Components/Module/Distribute.php b/components/lib/Components/Module/Distribute.php
index c60f32f4c..36dee8648 100644
--- a/components/lib/Components/Module/Distribute.php
+++ b/components/lib/Components/Module/Distribute.php
@@ -66,14 +66,6 @@ extends Components_Module_Base
'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.'
- )
- ),
);
}
diff --git a/components/lib/Components/Runner/CiPrebuild.php b/components/lib/Components/Runner/CiPrebuild.php
new file mode 100644
index 000000000..b805f8313
--- /dev/null
+++ b/components/lib/Components/Runner/CiPrebuild.php
@@ -0,0 +1,126 @@
+
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Runner_CiPrebuild:: prepares a continuous integration setup 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_CiPrebuild
+{
+ /**
+ * The configuration for the current job.
+ *
+ * @var Components_Config
+ */
+ private $_config;
+
+ /**
+ * The application configuration.
+ *
+ * @var Components_Config_Application
+ */
+ private $_config_application;
+
+ /**
+ * The package handler.
+ *
+ * @var Components_Pear_Package
+ */
+ private $_package;
+
+ /**
+ * Constructor.
+ *
+ * @param Components_Config $config The configuration for the
+ * current job.
+ * @param Components_Config_Application $cfgapp The application
+ * configuration.
+ * @param Components_Pear_InstallLocation $location Represents the install
+ * location and its
+ * corresponding configuration.
+ * @param Components_Pear_Package $package Package handler.
+ */
+ public function __construct(
+ Components_Config $config,
+ Components_Config_Application $cfgapp,
+ Components_Pear_InstallLocation $location,
+ Components_Pear_Package $package
+ ) {
+ $this->_config = $config;
+ $this->_config_application = $cfgapp;
+ $this->_location = $location;
+ $this->_package = $package;
+ }
+
+ public function run()
+ {
+ $options = $this->_config->getOptions();
+ $arguments = $this->_config->getArguments();
+ $pkgfile = $arguments[0] . DIRECTORY_SEPARATOR . 'package.xml';
+ $name = basename($arguments[0]);
+ if (basename(dirname($arguments[0])) == 'framework') {
+ $origin = 'framework' . DIRECTORY_SEPARATOR . $name;
+ } else {
+ $origin = $name;
+ }
+ $test_path = strtr($name, '_', '/');
+
+ if (!isset($options['toolsdir'])) {
+ $options['toolsdir'] = 'php-hudson-tools/workspace/pear/pear';
+ }
+ if (!isset($options['pearrc'])) {
+ throw new Components_Exception(
+ 'You are required to set the path to a PEAR environment for this package'
+ );
+ }
+
+ $this->_location->setLocation(
+ dirname($options['pearrc']),
+ basename($options['pearrc'])
+ );
+ $this->_package->setEnvironment($this->_location);
+ $this->_package->setPackage($pkgfile);
+ $description = $this->_package->getPackageFile()->getDescription();
+
+ $in = file_get_contents(
+ $this->_config_application->getTemplateDirectory()
+ . DIRECTORY_SEPARATOR . 'hudson-component-build.xml.template',
+ 'r'
+ );
+ file_put_contents(
+ $options['ciprebuild'] . DIRECTORY_SEPARATOR . 'build.xml',
+ sprintf($in, $options['toolsdir'])
+ );
+ $in = file_get_contents(
+ $this->_config_application->getTemplateDirectory()
+ . DIRECTORY_SEPARATOR . 'hudson-component-phpunit.xml.template',
+ 'r'
+ );
+ file_put_contents(
+ $options['ciprebuild'] . DIRECTORY_SEPARATOR . 'phpunit.xml',
+ sprintf($in, $name, $test_path)
+ );
+ }
+}
diff --git a/components/lib/Components/Runner/CiSetup.php b/components/lib/Components/Runner/CiSetup.php
index 2d78cef67..190c822af 100644
--- a/components/lib/Components/Runner/CiSetup.php
+++ b/components/lib/Components/Runner/CiSetup.php
@@ -37,6 +37,13 @@ class Components_Runner_CiSetup
private $_config;
/**
+ * The application configuration.
+ *
+ * @var Components_Config_Application
+ */
+ private $_config_application;
+
+ /**
* The package handler.
*
* @var Components_Pear_Package
@@ -48,6 +55,8 @@ class Components_Runner_CiSetup
*
* @param Components_Config $config The configuration for the
* current job.
+ * @param Components_Config_Application $cfgapp The application
+ * configuration.
* @param Components_Pear_InstallLocation $location Represents the install
* location and its
* corresponding configuration.
@@ -55,12 +64,14 @@ class Components_Runner_CiSetup
*/
public function __construct(
Components_Config $config,
+ Components_Config_Application $cfgapp,
Components_Pear_InstallLocation $location,
Components_Pear_Package $package
) {
- $this->_config = $config;
- $this->_location = $location;
- $this->_package = $package;
+ $this->_config = $config;
+ $this->_config_application = $cfgapp;
+ $this->_location = $location;
+ $this->_package = $package;
}
public function run()
@@ -93,37 +104,14 @@ class Components_Runner_CiSetup
$this->_package->setPackage($pkgfile);
$description = $this->_package->getPackageFile()->getDescription();
- if (!empty($options['cisetup'])) {
- $in = file_get_contents(
- Components_Constants::getDataDirectory()
- . DIRECTORY_SEPARATOR . 'hudson-component-config.xml.template',
- 'r'
- );
- file_put_contents(
- $options['cisetup'] . DIRECTORY_SEPARATOR . 'config.xml',
- sprintf($in, $origin, 'horde', $options['toolsdir'], $description)
- );
- }
-
- if (!empty($options['ciprebuild'])) {
- $in = file_get_contents(
- Components_Constants::getDataDirectory()
- . DIRECTORY_SEPARATOR . 'hudson-component-build.xml.template',
- 'r'
- );
- file_put_contents(
- $options['ciprebuild'] . DIRECTORY_SEPARATOR . 'build.xml',
- sprintf($in, $options['toolsdir'])
- );
- $in = file_get_contents(
- Components_Constants::getDataDirectory()
- . DIRECTORY_SEPARATOR . 'hudson-component-phpunit.xml.template',
- 'r'
- );
- file_put_contents(
- $options['ciprebuild'] . DIRECTORY_SEPARATOR . 'phpunit.xml',
- sprintf($in, $name, $test_path)
- );
- }
+ $in = file_get_contents(
+ $this->_config_application->getTemplateDirectory()
+ . DIRECTORY_SEPARATOR . 'hudson-component-config.xml.template',
+ 'r'
+ );
+ file_put_contents(
+ $options['cisetup'] . DIRECTORY_SEPARATOR . 'config.xml',
+ sprintf($in, $origin, 'horde', $options['toolsdir'], $description)
+ );
}
}
diff --git a/components/test/Components/Integration/Components/Module/CiSetupTest.php b/components/test/Components/Integration/Components/Module/CiSetupTest.php
index 9c8cc0ed5..45effa7ad 100644
--- a/components/test/Components/Integration/Components/Module/CiSetupTest.php
+++ b/components/test/Components/Integration/Components/Module/CiSetupTest.php
@@ -94,4 +94,30 @@ extends Components_StoryTestCase
)
->then('the CI build script will be installed.');
}
+
+ /**
+ * @scenario
+ */
+ public function theCisetupOptionCreatesABaseCiConfigurationForAComponentFromAUserTemplate()
+ {
+ $this->given('the default Components setup')
+ ->when(
+ 'calling the package with the cisetup, pearrc, template options and path',
+ dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/simple'
+ )
+ ->then('the CI configuration will be installed according to the specified template.');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theCiprebuildOptionCreatesABaseCiConfigurationForAComponentFromAUserTemplate()
+ {
+ $this->given('the default Components setup')
+ ->when(
+ 'calling the package with the ciprebuild, pearrc, template options and path',
+ dirname(dirname(dirname(dirname(__FILE__)))) . '/fixture/simple'
+ )
+ ->then('the CI build script will be installed according to the specified template.');
+ }
}
\ No newline at end of file
diff --git a/components/test/Components/StoryTestCase.php b/components/test/Components/StoryTestCase.php
index a35312690..97045b605 100644
--- a/components/test/Components/StoryTestCase.php
+++ b/components/test/Components/StoryTestCase.php
@@ -120,6 +120,28 @@ extends PHPUnit_Extensions_Story_TestCase
);
$world['output'] = $this->_callUnstrictComponents();
break;
+ case 'calling the package with the cisetup, pearrc, template options and path':
+ $tmp = $this->_getTemporaryDirectory();
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--cisetup=' . $tmp,
+ '--pearrc=' . $tmp . DIRECTORY_SEPARATOR . '.pearrc',
+ '--templatedir=' . dirname(__FILE__) . '/fixture/templates',
+ $arguments[0]
+ );
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
+ case 'calling the package with the ciprebuild, pearrc, template options and path':
+ $tmp = $this->_getTemporaryDirectory();
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--ciprebuild=' . $tmp,
+ '--pearrc=' . $tmp . DIRECTORY_SEPARATOR . '.pearrc',
+ '--templatedir=' . dirname(__FILE__) . '/fixture/templates',
+ $arguments[0]
+ );
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
case 'calling the package with the install option and a Horde element':
$_SERVER['argv'] = array(
'horde-components',
@@ -251,6 +273,24 @@ extends PHPUnit_Extensions_Story_TestCase
)
);
break;
+ case 'the CI configuration will be installed according to the specified template.':
+ $this->assertEquals(
+ "CONFIG.XML\n",
+ file_get_contents(
+ $this->_temp_dir . DIRECTORY_SEPARATOR
+ . 'config.xml'
+ )
+ );
+ break;
+ case 'the CI build script will be installed according to the specified template.':
+ $this->assertEquals(
+ "BUILD.XML\n",
+ file_get_contents(
+ $this->_temp_dir . DIRECTORY_SEPARATOR
+ . 'build.xml'
+ )
+ );
+ break;
case 'the call will fail with':
$this->assertContains(
$arguments[0],
diff --git a/components/test/Components/fixture/templates/hudson-component-build.xml.template b/components/test/Components/fixture/templates/hudson-component-build.xml.template
new file mode 100644
index 000000000..3c5e13d2b
--- /dev/null
+++ b/components/test/Components/fixture/templates/hudson-component-build.xml.template
@@ -0,0 +1 @@
+BUILD.XML
diff --git a/components/test/Components/fixture/templates/hudson-component-config.xml.template b/components/test/Components/fixture/templates/hudson-component-config.xml.template
new file mode 100644
index 000000000..3990b142e
--- /dev/null
+++ b/components/test/Components/fixture/templates/hudson-component-config.xml.template
@@ -0,0 +1 @@
+CONFIG.XML
diff --git a/components/test/Components/fixture/templates/hudson-component-phpunit.xml.template b/components/test/Components/fixture/templates/hudson-component-phpunit.xml.template
new file mode 100644
index 000000000..ac5fb7e06
--- /dev/null
+++ b/components/test/Components/fixture/templates/hudson-component-phpunit.xml.template
@@ -0,0 +1 @@
+PHPUNIT.XML
--
2.11.0