- Add module for generating component documentation.
- - Allow activating/deactivating optional install elements
-
- Allow handling various Horde package locations (horde/, horde/framework/, Horde_SQL -> horde/framework/SQL)
- Allow linking files during the installation.
private $_environment;
/**
+ * The tree for this run.
+ *
+ * @var Components_Helper_Tree
+ */
+ private $_tree;
+
+ /**
+ * The output handler.
+ *
+ * @param Component_Output
+ */
+ private $_output;
+
+ /**
* The list of channels already installed.
*
* @var array
*
* @param Components_Pear_InstallLocation $environment The environment we
* establish the tree for.
+ * @param Components_Helper_Tree $tree The tree for this run.
+ * @param Component_Output $output The output handler.
+ * @param array $options Options for this installation.
*/
public function __construct(
- Components_Pear_InstallLocation $environment
+ Components_Pear_InstallLocation $environment,
+ Components_Helper_Tree $tree,
+ Components_Output $output,
+ array $options
) {
$this->_environment = $environment;
+ $this->_tree = $tree;
+ $this->_output = $output;
+ $this->_options = $options;
+ }
+
+ /**
+ * Install a package into the environment.
+ *
+ * @param Components_Pear_Package $package The package that should be installed.
+ * @param string $reason Optional reason for adding the package.
+ *
+ * @return NULL
+ */
+ public function install(
+ Components_Pear_Package $package,
+ $reason = ''
+ ) {
+ $this->_installDependencies(
+ $package->getDependencyHelper(),
+ sprintf(' [required by %s]', $package->getName())
+ );
+ $this->_installHordePackageOnce($package->getPackageXml(), $reason);
+ }
+
+ /**
+ * Install a list of dependencies.
+ *
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param string $reason Optional reason for adding the dependencies.
+ *
+ * @return NULL
+ */
+ private function _installDependencies(
+ Components_Pear_Dependencies $dependencies,
+ $reason = ''
+ ) {
+ $this->_installChannels($dependencies, $reason);
+ $this->_installExternalPackages($dependencies, $reason);
+ $this->_installHordeDependencies($dependencies, $reason);
}
/**
* environment. The channels are only going to be installed once during the
* installation run represented by this instance.
*
- * @param array $channels The channels to install.
- * @param string $reason Optional reason for adding the channels.
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param string $reason Optional reason for adding the channels.
*
* @return NULL
*/
- public function installChannelsOnce(array $channels, $reason = '')
- {
- foreach ($channels as $channel) {
+ private function _installChannels(
+ Components_Pear_Dependencies $dependencies,
+ $reason = ''
+ ) {
+ foreach ($dependencies->listAllChannels() as $channel) {
if (!in_array($channel, $this->_installed_channels)) {
- $this->_environment->provideChannel($channel, $reason);
+ if (empty($this->_options['pretend'])) {
+ $this->_environment->provideChannel($channel, $reason);
+ } else {
+ $this->_output->ok(
+ sprintf('Would install channel %s%s.', $channel, $reason)
+ );
+ }
$this->_installed_channels[] = $channel;
}
}
}
/**
+ * Ensure that the external dependencies are available within the
+ * installation environment.
+ *
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param string $reason Optional reason for adding the package.
+ *
+ * @return NULL
+ */
+ private function _installExternalPackages(
+ Components_Pear_Dependencies $dependencies,
+ $reason = ''
+ ) {
+ foreach (
+ $dependencies->listExternalDependencies(
+ $this->_options['include'], $this->_options['exclude']
+ ) as $dependency
+ ) {
+ // Refrain from installing optional pecl packages
+ if ($dependency->isPackage()) {
+ $this->_installExternalPackageOnce(
+ $dependency, $reason
+ );
+ }
+ }
+ }
+
+ /**
* Ensure that the external package is available within the installation
* environment. The package is only going to be installed once during the
* installation run represented by this instance.
*
- * @param string $package The package that should be installed.
- * @param string $channel The channel of the package.
- * @param string $reason Optional reason for adding the package.
- * @param array $to_add The local packages currently being added.
+ * @param Components_Pear_Dependency $dependency The package dependency.
+ * @param string $reason Optional reason for adding the package.
+ * @param array $to_add The local packages currently being added.
*
* @return NULL
*/
- public function installExternalPackageOnce($channel, $package, $reason = '', array &$to_add = null)
- {
- $key = $channel . '/' . $package;
- if (!in_array($key, $this->_installed_packages)) {
+ private function _installExternalPackageOnce(
+ Components_Pear_Dependency $dependency,
+ $reason = '',
+ array &$to_add = null
+ ) {
+ if (!in_array($dependency->key(), $this->_installed_packages)) {
if (empty($to_add)) {
- $to_add = array($key);
+ $to_add = array($dependency->key());
}
- foreach ($this->_environment->identifyRequiredLocalDependencies($channel, $package) as $required) {
- $rkey = $required['channel'] . '/' . $required['name'];
- if (in_array($rkey, $to_add)) {
+ foreach (
+ $this->_environment->identifyRequiredLocalDependencies(
+ $dependency, $this->_options['include'], $this->_options['exclude']
+ ) as $required
+ ) {
+ if (in_array($required->key(), $to_add)) {
continue;
}
- $to_add[] = $rkey;
- $rreason = sprintf(' [required by %s]', $package);
- $this->installExternalPackageOnce(
- $required['channel'], $required['name'], $rreason, &$to_add
+ $to_add[] = $required->key();
+ $this->_installExternalPackageOnce(
+ $required, sprintf(' [required by %s]', $dependency->name()), &$to_add
);
}
- $this->_environment->addPackageFromPackage(
- $channel, $package, $reason
- );
- $this->_installed_packages[] = $key;
+ if (empty($this->_options['pretend'])) {
+ $this->_environment->addPackageFromPackage(
+ $dependency, $reason
+ );
+ } else {
+ $this->_output->ok(
+ sprintf(
+ 'Would install external package %s%s.',
+ $dependency->key(),
+ $reason
+ )
+ );
+ }
+ $this->_installed_packages[] = $dependency->key();
}
}
-
+
+ /**
+ * Ensure that the horde package is available within the installation
+ * environment. The package is only going to be installed once during the
+ * installation run represented by this instance.
+ *
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param string $reason Optional reason for adding the package.
+ *
+ * @return NULL
+ */
+ private function _installHordeDependencies(
+ Components_Pear_Dependencies $dependencies,
+ $reason = ''
+ ) {
+ foreach (
+ $this->_tree->getChildren(
+ $dependencies->listHordeDependencies(
+ $this->_options['include'], $this->_options['exclude']
+ )
+ ) as $child
+ ) {
+ if (in_array($child->getName(), $this->_installed_packages)) {
+ continue;
+ }
+ $this->_installed_packages[] = $child->getName();
+ $this->install($child, $reason);
+ }
+ }
+
/**
* Ensure that the horde package is available within the installation
* environment. The package is only going to be installed once during the
*
* @return NULL
*/
- public function installHordePackageOnce($package_file, $reason = '')
+ private function _installHordePackageOnce($package_file, $reason = '')
{
- if (!in_array($package_file, $this->_installed_packages)) {
+ if (empty($this->_options['pretend'])) {
$this->_environment->addPackageFromSource(
$package_file, $reason
);
- $this->_installed_packages[] = $package_file;
+ } else {
+ $this->_output->ok(
+ sprintf(
+ 'Would install package %s%s.',
+ $package_file,
+ $reason
+ )
+ );
}
}
}
\ No newline at end of file
private $_output;
/**
+ * The tree for this run.
+ *
+ * @var Components_Helper_Tree
+ */
+ private $_tree;
+
+ /**
* The list of dependencies already displayed.
*
* @var array
/**
* Constructor.
*
- * @param Component_Output $output The output handler.
+ * @param Component_Output $output The output handler.
+ * @param Components_Helper_Tree $tree The tree for this run.
*/
- public function __construct(Components_Output $output)
- {
+ public function __construct(
+ Components_Output $output,
+ Components_Helper_Tree $tree
+ ) {
$this->_output = $output;
+ $this->_tree = $tree;
if ($this->_output->isVerbose()) {
- $output->bold('List contains optional dependencies!');
+ $output->bold('The list contains optional dependencies!');
} else {
- $output->bold('List only contains required dependencies!');
+ $output->bold('The list only contains required dependencies!');
}
$output->blue('Dependencies on PEAR itself are not displayed.');
$output->bold('');
}
/**
+ * List the dependency tree for this package.
+ *
+ * @param Components_Pear_Package $package The package that should be installed.
+ * @param int $level The current list level.
+ * @param string $parent The name of the parent element.
+ *
+ * @return NULL
+ */
+ public function listTree(
+ Components_Pear_Package $package,
+ $level = 0,
+ $parent = '',
+ $required = true
+ ) {
+ if ($this->_listHordePackage($package, $level, $parent, $required)) {
+ $this->_listExternalPackages($package->getDependencyHelper(), $level + 1);
+ $this->_listHordeDependencies($package->getDependencyHelper(), $level + 1);
+ }
+ }
+
+ /**
* List a Horde component as dependency.
*
* @param Components_Pear_Package $package The package that should be listed.
* @param int $level The current list level.
* @param string $parent Name of the parent element.
- * @param boolean $reqired Is this a required element?
*
* @return boolean True in case listing should continue.
*/
- public function listHordePackage(
+ private function _listHordePackage(
Components_Pear_Package $package,
$level,
- $parent,
- $required
+ $parent
) {
- if (!$this->_output->isVerbose() && !$required) {
- return false;
- }
- $key = $package->getName() . '@pear.horde.org';
+ $key = $package->getName() . '/pear.horde.org';
if (!$this->_output->isQuiet()) {
if (in_array($key, array_keys($this->_displayed_dependencies))) {
if (empty($this->_displayed_dependencies[$key])) {
}
/**
- * List an external package as dependency.
+ * List the horde dependencies.
*
- * @param array $dependency The dependency that should be listed.
- * @param int $level The current list level.
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param int $level The current list level.
*
* @return NULL
*/
- public function listExternalPackage(array $dependency, $level)
- {
- // Showing PEAR does not make much sense.
- if ($dependency['name'] == 'PEAR'
- && $dependency['channel'] == 'pear.php.net') {
- return;
+ private function _listHordeDependencies(
+ Components_Pear_Dependencies $dependencies,
+ $level
+ ) {
+ if ($this->_output->isVerbose()) {
+ $list = $dependencies->listAllHordeDependencies();
+ } else {
+ $list = $dependencies->listRequiredHordeDependencies();
+ }
+ foreach ($this->_tree->getChildren($list) as $child) {
+ $this->listTree($child, $level, $child->getName());
}
+ }
- $key = $dependency['name'] . '@' . $dependency['channel'];
- if (!$this->_output->isQuiet()) {
- $this->_output->yellow(
- Horde_String::pad(
- $this->_listLevel($level) . '|_'
- . $dependency['name'], 40
- )
- . Horde_String::pad(' [' . $dependency['channel'] . ']', 20)
- . ' (EXTERNAL) ***STOP***'
- );
+ /**
+ * List an external package as dependency.
+ *
+ * @param Components_Pear_Dependencies $dependencies The package dependencies.
+ * @param int $level The current list level.
+ *
+ * @return NULL
+ */
+ private function _listExternalPackages(
+ Components_Pear_Dependencies $dependencies,
+ $level
+ ) {
+ if ($this->_output->isVerbose()) {
+ $list = $dependencies->listAllExternalDependencies();
} else {
- $this->_quiet_list[$key] = array(
- 'channel' => $dependency['channel'],
- 'name' => $dependency['name'],
- 'color' => 'yellow'
- );
+ $list = $dependencies->listRequiredExternalDependencies();
+ }
+ foreach ($list as $dependency) {
+ if ($dependency->isPearBase()) {
+ // Showing PEAR does not make much sense.
+ continue;
+ }
+
+ if (!$this->_output->isQuiet()) {
+ $this->_output->yellow(
+ Horde_String::pad(
+ $this->_listLevel($level) . '|_'
+ . $dependency->name(), 40
+ )
+ . Horde_String::pad(' [' . $dependency->channelOrType() . ']', 20)
+ . ' (EXTERNAL) ***STOP***'
+ );
+ } else {
+ $this->_quiet_list[$dependency->key()] = array(
+ 'channel' => $dependency->channelOrType(),
+ 'name' => $dependency->name(),
+ 'color' => 'yellow'
+ );
+ }
}
}
/**
* Install the tree of packages into the specified environment.
*
- * @param string $package_file Path to the package file representing the element
- * at the root of the dependency tree.
+ * @param string $package_file Path to the package file representing the element
+ * at the root of the dependency tree.
+ * @param Component_Output $output The output handler.
+ * @param array $options Options for this installation.
*
* @return NULL
*/
- public function installTreeInEnvironment($package_file) {
- $this->_getHordeChildElement($package_file)
- ->installInTree(
- new Components_Helper_InstallationRun($this->_environment)
- );
+ public function installTreeInEnvironment(
+ $package_file,
+ Components_Output $output,
+ array $options)
+ {
+ $run = new Components_Helper_InstallationRun($this->_environment, $this, $output, $options);
+ $run->install($this->_getHordeChildElement($package_file));
}
/**
$package_file,
Components_Output $output
) {
- $run = new Components_Helper_ListRun($output);
- $this->_getHordeChildElement($package_file)
- ->listDependencies($run, 0);
+ $run = new Components_Helper_ListRun($output, $this);
+ $run->listTree($this->_getHordeChildElement($package_file));
$run->finish();
}
*
* @param array $dependencies The dependencies of a package to be
* transformed in elements.
- * @return array The list of children elements.
+ * @return array The list of children.
*/
public function getChildren(array $dependencies)
{
$children = array();
foreach ($dependencies as $dependency) {
$package_file = $this->_root_path . DIRECTORY_SEPARATOR
- . $dependency['name'] . DIRECTORY_SEPARATOR . 'package.xml';
+ . $dependency->name() . DIRECTORY_SEPARATOR . 'package.xml';
if (!file_exists($package_file)) {
$package_file = $this->_root_path . DIRECTORY_SEPARATOR
- . 'framework' . DIRECTORY_SEPARATOR . $dependency['name']
+ . 'framework' . DIRECTORY_SEPARATOR . $dependency->name()
. DIRECTORY_SEPARATOR . 'package.xml';
}
- $children[] = $this->_getHordeChildElement(
- $package_file,
- isset($dependency['optional']) && $dependency['optional'] == 'no'
+ $children[$dependency->key()] = $this->_getHordeChildElement(
+ $package_file
);
}
return $children;
*
* @param string $package_file Path to the package file representing the
* element at the root of the dependency tree.
- * @param boolean $required Is this a required element?
- * @return NULL
+ *
+ * @return Components_Pear_Package The child package.
*/
- private function _getHordeChildElement($package_file, $required = true)
+ private function _getHordeChildElement($package_file)
{
- return new Components_Helper_Tree_Element(
- $this->_factory->createPackageForEnvironment(
- $package_file, $this->_environment
- ),
- $package_file,
- $required,
- $this
+ return $this->_factory->createPackageForEnvironment(
+ $package_file, $this->_environment
);
}
+++ /dev/null
-<?php
-/**
- * Components_Helper_Tree_Element:: provides utility methods for a single
- * element of the tree.
- *
- * PHP version 5
- *
- * @category Horde
- * @package Components
- * @author Gunnar Wrobel <wrobel@pardus.de>
- * @license http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link http://pear.horde.org/index.php?package=Components
- */
-
-/**
- * Components_Helper_Tree_Element:: provides utility methods for a single
- * element of the tree.
- *
- * 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 <wrobel@pardus.de>
- * @license http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link http://pear.horde.org/index.php?package=Components
- */
-class Components_Helper_Tree_Element
-{
- /**
- * The package represented by this element.
- *
- * @var Components_Pear_Package
- */
- private $_package;
-
- /**
- * The path to the package file defining this element.
- *
- * @var string
- */
- private $_package_file;
-
- /**
- * Is this a required element?
- *
- * @var boolean
- */
- private $_required;
-
- /**
- * The parent tree for this child.
- *
- * @var Components_Helper_Tree
- */
- private $_tree;
-
- /**
- * Constructor.
- *
- * @param Components_Pear_Package $package The root of the dependency tree.
- * @param string $package_file The path to the package file.
- * @param boolean $required Is this a required element?
- * @param Components_Helper_Tree $tree The parent tree for this child.
- */
- public function __construct(
- Components_Pear_Package $package,
- $package_file,
- $required,
- Components_Helper_Tree $tree
- ) {
- $this->_package = $package;
- $this->_package_file = $package_file;
- $this->_required = $required;
- $this->_tree = $tree;
- }
-
- /**
- * Install the tree of packages into the environment.
- *
- * @param Components_Helper_InstallationRun $run The current installation run.
- * @param array $visited The packages already visited.
- * @param string $reason Optional reason for adding the package.
- *
- * @return NULL
- */
- public function installInTree(
- Components_Helper_InstallationRun $run,
- array $visited = array(),
- $reason = ''
- ) {
- if (in_array($this->_package_file, $visited)) {
- return;
- }
- $visited[] = $this->_package_file;
- $new_reason = sprintf(' [required by %s]', $this->_package->getName());
- $run->installChannelsOnce($this->_package->listAllRequiredChannels(), $new_reason);
- foreach ($this->_package->listAllExternalDependencies() as $dependency) {
- // Refrain from installing optional pecl packages
- if (isset($dependency['optional'])
- && $dependency['optional'] != 'no'
- && $dependency['channel'] == 'pecl.php.net') {
- continue;
- }
- $run->installExternalPackageOnce(
- $dependency['channel'], $dependency['name'], $new_reason
- );
- }
- foreach (
- $this->_tree->getChildren(
- $this->_package->listAllHordeDependencies()
- ) as $child
- ) {
- $child->installInTree($run, $visited, $new_reason);
- }
- $run->installHordePackageOnce($this->_package_file, $reason);
- }
-
- /**
- * List the dependency tree for this package.
- *
- * @param Components_Helper_ListRun $run The current listing run.
- * @param int $level The current list level.
- * @param string $parent The name of the parent element.
- *
- * @return NULL
- */
- public function listDependencies(
- Components_Helper_ListRun $run,
- $level,
- $parent = ''
- ) {
- if ($run->listHordePackage($this->_package, $level, $parent, $this->_required)) {
- foreach ($this->_package->listAllExternalDependencies() as $dependency) {
- $run->listExternalPackage($dependency, $level + 1);
- }
- foreach (
- $this->_tree->getChildren(
- $this->_package->listAllHordeDependencies()
- ) as $child
- ) {
- $child->listDependencies($run, $level + 1, $this->_package->getName());
- }
- }
- }
-
-}
\ No newline at end of file
*/
public function getOptionGroupDescription()
{
- return 'This module installs a Horde element including its dependencies.';
+ return 'This module installs a Horde component including its dependencies.';
}
/**
'help' => 'Location of static channel XML descriptions. These files need to be named CHANNEL.channel.xml (e.g. pear.php.net.channel.xml). Specifying this path allows you to avoid accessing the network for installing new channels. If this is not specified but SOURCEPATH is given then SOURCEPATH will be checked for such channel XML files.'
)
),
+ new Horde_Argv_Option(
+ '-I',
+ '--include',
+ array(
+ 'action' => 'store',
+ 'help' => 'The list of optional dependencies that should be included in the installation. You can either specify packages by name (e.g. PEAR), by a combination of channel and name (e.g. pear.php.net/PEAR), a channel name (e.g. channel:pear.php.net), or all packages by the special keyword ALL. Several entries need to be separated by ",". The default for this option is "ALL".',
+ 'default' => 'ALL',
+ 'dest' => 'include',
+ )
+ ),
+ new Horde_Argv_Option(
+ '-E',
+ '--exclude',
+ array(
+ 'action' => 'store',
+ 'help' => 'The list of optional dependencies that should be excluded during the installation. You can either specify packages by name (e.g. PEAR), by a combination of channel and name (e.g. pear.php.net/PEAR), a channel name (e.g. channel:pear.php.net), or all packages by the special keyword ALL. Several entries need to be separated by ",". The default for this option is "channel:pecl.php.net".',
+ 'default' => 'channel:pecl.php.net',
+ 'dest' => 'exclude',
+ )
+ ),
+ new Horde_Argv_Option(
+ '-P',
+ '--pretend',
+ array(
+ 'action' => 'store_true',
+ 'help' => 'Just indicate what would be installed.',
+ )
+ ),
);
}
--- /dev/null
+<?php
+/**
+ * Components_Pear_Dependencies:: provides dependency handling mechanisms.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Components
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Pear_Dependencies:: provides dependency handling mechanisms.
+ *
+ * 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 <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+class Components_Pear_Dependencies
+{
+ /**
+ * The package.
+ *
+ * @param Components_Pear_Package
+ */
+ private $_package;
+
+ /**
+ * This helper will handle the dependencies for the package provided here.
+ *
+ * @param Components_Pear_Package
+ *
+ * @return NULL
+ */
+ public function setPackage(Components_Pear_Package $package)
+ {
+ $this->_package = $package;
+ }
+
+ /**
+ * Return the PEAR package for this package.
+ *
+ * @return Components_Pear_Package
+ */
+ public function getPackage()
+ {
+ if ($this->_package === null) {
+ throw new Component_Exception('You need to set the package first!');
+ }
+ return $this->_package;
+ }
+
+ /**
+ * Return all channels required for the package and its dependencies.
+ *
+ * @return array The list of channels.
+ */
+ public function listAllChannels()
+ {
+ $channel = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ if (isset($dependency['channel'])) {
+ $channel[] = $dependency['channel'];
+ }
+ }
+ $channel[] = $this->getPackage()->getChannel();
+ return array_unique($channel);
+ }
+
+ /**
+ * Return all dependencies required for this package.
+ *
+ * @return array The list of required dependencies.
+ */
+ public function listAllRequiredDependencies()
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if ($d->isRequired()) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return all Horde dependencies required for this package.
+ *
+ * @return array The list of Horde dependencies.
+ */
+ public function listAllHordeDependencies()
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if ($d->isHorde()) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return the Horde dependencies required for this package.
+ *
+ * @param string $include Optional dependencies to include.
+ * @param string $exclude Optional dependencies to exclude.
+ *
+ * @return array The list of Horde dependencies.
+ */
+ public function listHordeDependencies($include, $exclude)
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if ($d->isHorde()
+ && ($d->isRequired()
+ || ($d->matches($include) && !$d->matches($exclude))
+ )
+ ) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return the Horde dependencies absolutely required for this package.
+ *
+ * @return array The list of Horde dependencies.
+ */
+ public function listRequiredHordeDependencies()
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if ($d->isHorde() && $d->isRequired()) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return all external non Horde package dependencies required for this package.
+ *
+ * @return array The list of external dependencies.
+ */
+ public function listAllExternalDependencies()
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if (!$d->isHorde() && !$d->isPhp()) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return the external non Horde package dependencies for this package.
+ *
+ * @param string $include Optional dependencies to include.
+ * @param string $exclude Optional dependencies to exclude.
+ *
+ * @return array The list of external dependencies.
+ */
+ public function listExternalDependencies($include, $exclude)
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if (!$d->isHorde() && !$d->isPhp() && $d->isPackage()
+ && ($d->isRequired()
+ || ($d->matches($include) && !$d->matches($exclude))
+ )
+ ) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ /**
+ * Return the required external dependencies.
+ *
+ * @return array The list of external dependencies.
+ */
+ public function listRequiredExternalDependencies()
+ {
+ $dependencies = array();
+ foreach ($this->_getDependencies() as $dependency) {
+ $d = new Components_Pear_Dependency($dependency);
+ if (!$d->isHorde() && !$d->isPhp() && $d->isRequired()) {
+ $dependencies[$d->key()] = $d;
+ }
+ }
+ return $dependencies;
+ }
+
+ private function _getDependencies()
+ {
+ $dependencies = $this->getPackage()->getDependencies();
+ if (empty($dependencies)) {
+ return array();
+ }
+ return $dependencies;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Components_Pear_Dependency:: wraps PEAR dependency information.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Components
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+
+/**
+ * Components_Pear_Dependency:: wraps PEAR dependency information.
+ *
+ * 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 <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Components
+ */
+class Components_Pear_Dependency
+{
+ /**
+ * The name of the dependency.
+ *
+ * @var string
+ */
+ private $_name = '';
+
+ /**
+ * The channel of the dependency.
+ *
+ * @var string
+ */
+ private $_channel = '';
+
+ /**
+ * The type of the dependency.
+ *
+ * @var string
+ */
+ private $_type = '';
+
+ /**
+ * Indicates if this is an optional dependency.
+ *
+ * @var boolean
+ */
+ private $_optional = true;
+
+ /**
+ * Indicates if this is a package dependency.
+ *
+ * @var boolean
+ */
+ private $_package = false;
+
+ /**
+ * Constructor.
+ *
+ * @param array $dependency The dependency information.
+ */
+ public function __construct($dependency)
+ {
+ if (isset($dependency['name'])) {
+ $this->_name = $dependency['name'];
+ }
+ if (isset($dependency['channel'])) {
+ $this->_channel = $dependency['channel'];
+ }
+ if (isset($dependency['optional'])
+ && $dependency['optional'] == 'no') {
+ $this->_optional = false;
+ }
+ if (isset($dependency['type'])) {
+ $this->_type = $dependency['type'];
+ }
+ if (isset($dependency['type'])
+ && $dependency['type'] == 'pkg') {
+ $this->_package = true;
+ }
+ }
+
+ /**
+ * Is the dependency required?
+ *
+ * @return boolen True if the dependency is required.
+ */
+ public function isRequired()
+ {
+ if (!$this->_package) {
+ return false;
+ }
+ return !$this->_optional;
+ }
+
+ /**
+ * Is this a pacakge dependency?
+ *
+ * @return boolen True if the dependency is a package.
+ */
+ public function isPackage()
+ {
+ return $this->_package;
+ }
+
+ /**
+ * Is the dependency a Horde dependency?
+ *
+ * @return boolen True if it is a Horde dependency.
+ */
+ public function isHorde()
+ {
+ if (empty($this->_channel)) {
+ return false;
+ }
+ if ($this->_channel != 'pear.horde.org') {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Is this the PHP dependency?
+ *
+ * @return boolen True if it is the PHP dependency.
+ */
+ public function isPhp()
+ {
+ if ($this->_type != 'php') {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Is this a PHP extension dependency?
+ *
+ * @return boolen True if it is a PHP extension dependency.
+ */
+ public function isExtension()
+ {
+ if ($this->_type != 'ext') {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Is the dependency the PEAR base package?
+ *
+ * @return boolen True if it is the PEAR base package.
+ */
+ public function isPearBase()
+ {
+ if ($this->_name == 'PEAR' && $this->_channel == 'pear.php.net') {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Does the dependency match the given selector?
+ *
+ * @param string $selector The selector.
+ *
+ * @return boolen True if the dependency matches.
+ */
+ public function matches($selector)
+ {
+ $selectors = split(',', $selector);
+ if (in_array('ALL', $selectors)) {
+ return true;
+ }
+ foreach ($selectors as $selector) {
+ if (empty($selector)) {
+ continue;
+ }
+ if (strpos($selector, '/') !== false) {
+ list($channel, $name) = split('/', $selector, 2);
+ if ($this->_channel == $channel && $this->_name == $name) {
+ return true;
+ }
+ continue;
+ }
+ if (substr($selector, 0, 8) == 'channel:') {
+ if ($this->_channel == substr($selector, 8)) {
+ return true;
+ }
+ continue;
+ }
+ if ($this->_name == $selector) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the package name for the dependency
+ *
+ * @return string The package name.
+ */
+ public function name()
+ {
+ return $this->_name;
+ }
+
+ /**
+ * Return the package channel for the dependency
+ *
+ * @return string The package channel.
+ */
+ public function channel()
+ {
+ return $this->_channel;
+ }
+
+ /**
+ * Return the package channel or the type description for the dependency.
+ *
+ * @return string The package channel.
+ */
+ public function channelOrType()
+ {
+ if ($this->isExtension()) {
+ return 'PHP Extension';
+ } else {
+ return $this->_channel;
+ }
+ }
+
+ /**
+ * Return the key for the dependency
+ *
+ * @return string The uniqe key for this dependency.
+ */
+ public function key()
+ {
+ return $this->_channel . '/' . $this->_name;
+ }
+}
*
* @param string $config_file The path to the configuration file.
*
- * @return NULL
+ * @return Components_Pear_InstallLocation The PEAR environment
*/
public function createInstallLocation($config_file)
{
$install_location = $this->_dependencies->createInstance('Components_Pear_InstallLocation');
+ $install_location->setFactory($this);
$install_location->setLocation(
dirname($config_file),
basename($config_file)
* @param string $package_file The path of the package XML file.
* @param Components_Pear_InstallLocation $environment The PEAR environment.
*
- * @return NULL
+ * @return Components_Pear_Package The PEAR package.
*/
public function createPackageForEnvironment(
$package_file,
Components_Pear_InstallLocation $environment
) {
- $package = $this->_dependencies->createInstance('Components_Pear_Package');
- $package->setFactory($this);
- $package->setEnvironment($environment);
+ $package = $this->_createPackage($environment);
$package->setPackageXml($package_file);
return $package;
}
* @param string $package_file The path of the package XML file.
* @param string $config_file The path to the configuration file.
*
- * @return NULL
+ * @return Components_Pear_Package The PEAR package.
*/
public function createPackageForInstallLocation($package_file, $config_file)
{
- $package = $this->_dependencies->createInstance('Components_Pear_Package');
- $package->setFactory($this);
- $package->setEnvironment($this->createInstallLocation($config_file));
- $package->setPackageXml($package_file);
- return $package;
+ return $this->createPackageForEnvironment(
+ $package_file, $this->createInstallLocation($config_file)
+ );
}
/**
*
* @param string $package_file The path of the package XML file.
*
- * @return NULL
+ * @return Components_Pear_Package The PEAR package.
*/
public function createPackageForDefaultLocation($package_file)
{
+ return $this->createPackageForEnvironment(
+ $package_file, $this->_dependencies->getInstance('Components_Pear_InstallLocation')
+ );
+ }
+
+ /**
+ * Create a package representation for a specific PEAR environment based on a *.tgz archive.
+ *
+ * @param string $package_file The path of the package *.tgz file.
+ * @param Components_Pear_InstallLocation $environment The environment for the package file.
+ *
+ * @return Components_Pear_Package The PEAR package.
+ */
+ public function createTgzPackageForInstallLocation(
+ $package_file,
+ Components_Pear_InstallLocation $environment
+ ) {
+ $package = $this->_createPackage($environment);
+ $package->setPackageTgz($package_file);
+ return $package;
+ }
+
+ /**
+ * Create a generic package representation for a specific PEAR environment.
+ *
+ * @param Components_Pear_InstallLocation $environment The PEAR environment.
+ *
+ * @return Components_Pear_Package The generic PEAR package.
+ */
+ private function _createPackage(Components_Pear_InstallLocation $environment)
+ {
$package = $this->_dependencies->createInstance('Components_Pear_Package');
$package->setFactory($this);
- $package->setEnvironment($this->_dependencies->getInstance('Components_Pear_InstallLocation'));
- $package->setPackageXml($package_file);
+ $package->setEnvironment($environment);
return $package;
}
public function createTreeHelper($config_file, $root_path, array $options)
{
$environment = $this->_dependencies->createInstance('Components_Pear_InstallLocation');
+ $environment->setFactory($this);
$environment->setLocation(
dirname($config_file),
basename($config_file)
}
/**
+ * Return the PEAR Package representation based on a local *.tgz archive.
+ *
+ * @param string $package_tgz_path Path to the *.tgz file.
+ * @param Components_Pear_InstallLocation $environment The PEAR environment.
+ *
+ * @return PEAR_PackageFile
+ */
+ public function getPackageFileFromTgz(
+ $package_tgz_path,
+ Components_Pear_InstallLocation $environment
+ )
+ {
+ $pkg = new PEAR_PackageFile($environment->getPearConfig());
+ return Components_Exception_Pear::catchError(
+ $pkg->fromTgzFile($package_tgz_path, PEAR_VALIDATE_NORMAL)
+ );
+ }
+
+ /**
* Create a new PEAR Package representation.
*
* @param string $package_xml_dir Path to the parent directory of the package.xml file.
)
);
}
+
+ /**
+ * Create a package dependency helper.
+ *
+ * @param Components_Pear_Package $package The package.
+ *
+ * @return Components_Pear_Dependencies The dependency helper.
+ */
+ public function createDependencies(Components_Pear_Package $package)
+ {
+ $dependencies = $this->_dependencies->createInstance('Components_Pear_Dependencies');
+ $dependencies->setPackage($package);
+ return $dependencies;
+ }
}
\ No newline at end of file
private $_output;
/**
+ * The factory for PEAR class instances.
+ *
+ * @param Components_Pear_Factory
+ */
+ private $_factory;
+
+ /**
* The base directory for the PEAR install location.
*
* @param string
*
* @param Component_Output $output The output handler.
*/
- public function __construct(Components_Output $output)
- {
+ public function __construct(Components_Output $output) {
$this->_output = $output;
}
/**
+ * Define the factory that creates our PEAR dependencies.
+ *
+ * @param Components_Pear_Factory
+ *
+ * @return NULL
+ */
+ public function setFactory(Components_Pear_Factory $factory)
+ {
+ $this->_factory = $factory;
+ }
+
+ /**
* Set the path to the install location.
*
* @param string $base_directory The base directory for the PEAR install location.
}
/**
- * Identify any dependencies we need when installing via downloaded packages.
- *
- * @param string $channel The channel name for the package.
- * @param string $package The name of the package of the path of the tarball.
- *
- * @return array The added packages.
- */
- public function identifyRequiredLocalDependencies($channel, $package)
- {
- if ($local = $this->_identifyMatchingLocalPackage($package)) {
- $dependencies = array();
- $pkg = new PEAR_PackageFile($this->getPearConfig());
- $pkg = $pkg->fromTgzFile($local, PEAR_VALIDATE_NORMAL);
- $deps = $pkg->getDeps();
- if (empty($deps)) {
- return array();
- }
- foreach ($deps as $dependency) {
- if ($dependency['type'] != 'pkg') {
- continue;
- }
- if (isset($dependency['optional']) && $dependency['optional'] == 'no') {
- $dependencies[] = $dependency;
- }
- }
- return $dependencies;
- }
- return array();
- }
-
- /**
- * Add a package based on a package name or package tarball.
+ * Add an external dependency based on a package name or package tarball.
*
- * @param string $channel The channel name for the package.
+ * @param Components_Pear_Dependency $dependency The package dependency.
* @param string $package The name of the package of the path of the tarball.
* @param string $reason Optional reason for adding the package.
*
* @return NULL
*/
- public function addPackageFromPackage($channel, $package, $reason = '')
- {
+ public function addPackageFromPackage(
+ Components_Pear_Dependency $dependency,
+ $reason = ''
+ ) {
$installer = $this->getInstallationHandler();
$this->_output->ok(
sprintf(
- 'About to add package %s/%s%s',
- $channel,
- $package,
+ 'About to add external package %s%s',
+ $dependency->key(),
$reason
)
);
- if ($local = $this->_identifyMatchingLocalPackage($package)) {
+ if ($local = $this->_identifyMatchingLocalPackage($dependency->name())) {
ob_start();
Components_Exception_Pear::catchError(
$installer->doInstall(
} else {
$this->_output->warn(
sprintf(
- 'Adding package %s via network.',
- $package
+ 'Adding external package %s via network.',
+ $dependency->key()
)
);
ob_start();
$installer->doInstall(
'install',
array(
- 'channel' => $channel,
+ 'channel' => $dependency->channel(),
),
- array($package)
+ array($dependency->name())
)
);
$this->_output->pear(ob_get_clean());
}
$this->_output->ok(
sprintf(
- 'Successfully added package %s/%s%s',
- $channel,
- $package,
+ 'Successfully added external package %s%s',
+ $dependency->key(),
$reason
)
);
}
+ /**
+ * Identify any dependencies we need when installing via downloaded packages.
+ *
+ * @param Components_Pear_Dependency $dependency The package dependency.
+ * @param string $include Optional dependencies to include.
+ * @param string $exclude Optional dependencies to exclude.
+ *
+ * @return array The added packages.
+ */
+ public function identifyRequiredLocalDependencies(
+ Components_Pear_Dependency $dependency, $include, $exclude
+ ) {
+ if ($local = $this->_identifyMatchingLocalPackage($dependency->name())) {
+ $this->_checkSetup();
+ return $this->_factory
+ ->createTgzPackageForInstallLocation($local, $this)
+ ->getDependencyHelper()
+ ->listExternalDependencies($include, $exclude);
+ }
+ return array();
+ }
+
+ /**
+ * Identify a dependency that is available via a downloaded *.tgz archive.
+ *
+ * @param string $package The package name.
+ *
+ * @return string A path to the local archive if it was found.
+ */
private function _identifyMatchingLocalPackage($package)
{
if (empty($this->_source_directory)) {
}
return false;
}
+
+ /**
+ * Validate that the required instance parameters are set.
+ *
+ * @return NULL
+ *
+ * @throws Components_Exception In case some settings are missing.
+ */
+ private function _checkSetup()
+ {
+ if ($this->_factory === null) {
+ throw new Components_Exception('You need to set the factory, the environment and the path to the package file first!');
+ }
+ }
+
}
private $_package_xml_path;
/**
+ * The path to the package *.tgz file.
+ *
+ * @param string
+ */
+ private $_package_tgz_path;
+
+ /**
* The package representation.
*
* @param PEAR_PackageFile_v2
}
/**
+ * Return the path to the package.xml.
+ *
+ * @return string
+ */
+ public function getPackageXml()
+ {
+ if ($this->_package_xml_path === null) {
+ throw new Component_Exception('You need to set the package.xml path first!');
+ }
+ return $this->_package_xml_path;
+ }
+
+ /**
+ * Define the package to work on.
+ *
+ * @param string $package_tgz_path Path to the *.tgz file.
+ *
+ * @return NULL
+ */
+ public function setPackageTgz($package_tgz_path)
+ {
+ $this->_package_tgz_path = $package_tgz_path;
+ }
+
+ /**
* Return the PEAR Package representation.
*
* @return PEAR_PackageFile
{
$this->_checkSetup();
if ($this->_package_file === null) {
- $this->_package_file = $this->_factory->getPackageFile(
- $this->_package_xml_path,
- $this->getEnvironment()
- );
+ if (!empty($this->_package_xml_path)) {
+ $this->_package_file = $this->_factory->getPackageFile(
+ $this->_package_xml_path,
+ $this->getEnvironment()
+ );
+ } else {
+ $this->_package_file = $this->_factory->getPackageFileFromTgz(
+ $this->_package_tgz_path,
+ $this->getEnvironment()
+ );
+ }
}
return $this->_package_file;
}
private function _checkSetup()
{
if ($this->_environment === null
- || $this->_package_xml_path === null
+ || ($this->_package_xml_path === null
+ && $this->_package_tgz_path === null)
|| $this->_factory === null) {
throw new Components_Exception('You need to set the factory, the environment and the path to the package file first!');
}
}
/**
+ * Return the channel for the package.
+ *
+ * @return string The package channel.
+ */
+ public function getChannel()
+ {
+ return $this->_getPackageFile()->getChannel();
+ }
+
+ /**
* Return the description for this package.
*
* @return string The package description.
}
/**
- * Return all channels required for this package and its dependencies.
+ * Return the dependencies for the package.
*
- * @return array The list of channels.
+ * @return array The list of dependencies.
*/
- public function listAllRequiredChannels()
+ public function getDependencies()
{
- $dependencies = array();
- foreach ($this->_getPackageFile()->getDeps() as $dependency) {
- if (isset($dependency['channel'])) {
- $dependencies[] = $dependency['channel'];
- }
- }
- $dependencies[] = $this->_getPackageFile()->getChannel();
- return array_unique($dependencies);
- }
-
- /**
- * Return all channels required for this package and its dependencies.
- *
- * @return array The list of channels.
- */
- public function listAllExternalDependencies()
- {
- $dependencies = array();
- foreach ($this->_getPackageFile()->getDeps() as $dependency) {
- if (isset($dependency['channel']) && $dependency['channel'] != 'pear.horde.org') {
- $dependencies[] = $dependency;
- }
- }
- return $dependencies;
- }
+ return $this->_getPackageFile()->getDeps();
+ }
/**
- * Return all channels required for this package and its dependencies.
+ * Return the dependency helper for the package.
*
- * @return array The list of channels.
+ * @return Components_Pear_Dependencies The dependency helper.
*/
- public function listAllHordeDependencies()
+ public function getDependencyHelper()
{
- $dependencies = array();
- foreach ($this->_getPackageFile()->getDeps() as $dependency) {
- if (isset($dependency['channel']) && $dependency['channel'] == 'pear.horde.org') {
- $dependencies[] = $dependency;
- }
- }
- return $dependencies;
- }
+ $this->_checkSetup();
+ return $this->_factory->createDependencies($this);
+ }
/**
* Generate a snapshot of the package using the provided version number.
private $_factory;
/**
+ * The output handler.
+ *
+ * @param Component_Output
+ */
+ private $_output;
+
+ /**
* Constructor.
*
* @param Components_Config $config The configuration for the current
* job.
* @param Components_Pear_Factory $factory The factory for PEAR
* dependencies.
+ * @param Component_Output $output The output handler.
*/
public function __construct(
Components_Config $config,
- Components_Pear_Factory $factory
+ Components_Pear_Factory $factory,
+ Components_Output $output
) {
$this->_config = $config;
$this->_factory = $factory;
+ $this->_output = $output;
}
public function run()
);
$tree->getEnvironment()->provideChannel('pear.horde.org');
$tree->installTreeInEnvironment(
- realpath($arguments[0]) . DIRECTORY_SEPARATOR . 'package.xml'
+ realpath($arguments[0]) . DIRECTORY_SEPARATOR . 'package.xml',
+ $this->_output,
+ $options
);
}
}
{
$this->given('the default Components setup')
->when('calling the package with the list dependencies option and a path to a Horde framework component')
- ->then('the non-Horde dependencies of the component will be listed')
+ ->then('the non-Horde dependencies of the component will not be listed')
->and('the Horde dependencies of the component will be listed');
}
{
$this->given('the default Components setup')
->when('calling the package with the list dependencies option, the nocolor option and a path to a Horde framework component')
- ->then('the non-Horde dependencies of the component will be listed')
+ ->then('the non-Horde dependencies of the component will not be listed')
->and('the Horde dependencies of the component will be listed');
}
{
$this->given('the default Components setup')
->when('calling the package with the quiet list dependencies option and a path to a Horde framework component')
- ->then('the non-Horde dependencies of the component will be listed')
+ ->then('the non-Horde dependencies of the component will not be listed')
->and('the Horde dependencies of the component will be listed');
}
}
\ No newline at end of file
/**
* @scenario
*/
+ public function theTheIOptionListsThePackagesToBeInstalledWhenPretendHasBeenSelected()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, the pretend option and a path to a Horde framework component')
+ ->then('the dummy PEAR package will be listed')
+ ->and('the non-Horde dependencies of the component would be installed')
+ ->and('the Horde dependencies of the component would be installed')
+ ->and('the component will be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToAvoidIncludingAllOptionalPackages()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', '', '')
+ ->then('the Optional package will not be listed')
+ ->and('the Console_Getopt package will not be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToIncludeSpecificChannels()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', 'channel:pear.php.net,channel:pear.horde.org', '')
+ ->then('the Optional package will be listed')
+ ->and('the Console_Getopt package will be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToIncludeSpecificPackages()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', 'Console_Getopt,Optional', '')
+ ->then('the Optional package will be listed')
+ ->and('the Console_Getopt package will be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToExcludeAllOptionalPackages()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', 'channel:pear.horde.org,channel:pear.php.net', 'ALL')
+ ->then('the Optional package will not be listed')
+ ->and('the Console_Getopt package will not be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToExcludeSpecificChannels()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', 'channel:pear.php.net,channel:pear.horde.org', 'channel:pecl.php.net')
+ ->then('the Optional package will be listed')
+ ->and('the Console_Getopt package will be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
+ public function theTheIOptionAllowsToExcludeSpecificPackages()
+ {
+ $this->given('the default Components setup')
+ ->when('calling the package with the install option, a path to a Horde framework component, and the following include/exclude options', 'ALL', 'pecl.php.net/PECL')
+ ->then('the Optional package will be listed')
+ ->and('the Console_Getopt package will be listed')
+ ->and('the PECL will package will not be listed');
+ }
+
+ /**
+ * @scenario
+ */
public function theTheIOptionInstallsThePackageFromTheCurrentTree()
{
$this->given('the default Components setup')
);
$world['output'] = $this->_callUnstrictComponents();
break;
+ case 'calling the package with the install option, the pretend option and a path to a Horde framework component':
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--channelxmlpath=' . dirname(__FILE__) . '/fixture/channels',
+ '--sourcepath=' . dirname(__FILE__) . '/fixture/packages',
+ '--pretend',
+ '--install=' . $this->_getTemporaryDirectory() . DIRECTORY_SEPARATOR . '.pearrc',
+ dirname(__FILE__) . '/fixture/framework/Install'
+ );
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
+ case 'calling the package with the install option, a path to a Horde framework component, and the following include/exclude options':
+ $_SERVER['argv'] = array(
+ 'horde-components',
+ '--channelxmlpath=' . dirname(__FILE__) . '/fixture/channels',
+ '--sourcepath=' . dirname(__FILE__) . '/fixture/packages',
+ '--pretend',
+ '--include=' . $arguments[0],
+ '--exclude=' . $arguments[1],
+ '--install=' . $this->_getTemporaryDirectory() . DIRECTORY_SEPARATOR . '.pearrc',
+ dirname(__FILE__) . '/fixture/framework/Install'
+ );
+ $world['output'] = $this->_callUnstrictComponents();
+ break;
case 'calling the package with the list dependencies option and a path to a Horde framework component':
$_SERVER['argv'] = array(
'horde-components',
)
);
break;
+ case 'the dummy PEAR package will be listed':
+ $this->assertContains(
+ 'Would install external package pear.php.net/PEAR',
+ $world['output']
+ );
+ break;
+ case 'the non-Horde dependencies of the component would be installed':
+ $this->assertContains(
+ 'Would install external package pear.php.net/Console_Getopt',
+ $world['output']
+ );
+ break;
+ case 'the PECL will package will be listed':
+ $this->assertContains(
+ 'Would install external package pecl.php.net/PECL',
+ $world['output']
+ );
+ break;
+ case 'the PECL will package will not be listed':
+ $this->assertNotContains(
+ 'Would install external package pecl.php.net/PECL',
+ $world['output']
+ );
+ break;
+ case 'the Console_Getopt package will be listed':
+ $this->assertContains(
+ 'Would install external package pear.php.net/Console_Getopt',
+ $world['output']
+ );
+ break;
+ case 'the Console_Getopt package will not be listed':
+ $this->assertNotContains(
+ 'Would install external package pear.php.net/Console_Getopt',
+ $world['output']
+ );
+ break;
+ case 'the Horde dependencies of the component would be installed':
+ $trimmed = strtr($world['output'], array(' ' => '', "\n" => ''));
+ $this->assertRegExp(
+ '#Wouldinstallpackage.*Dependency/package.xml#',
+ $trimmed
+ );
+ break;
+ case 'the Optional package will be listed':
+ $trimmed = strtr($world['output'], array(' ' => '', "\n" => ''));
+ $this->assertRegExp(
+ '#Wouldinstallpackage.*Optional/package.xml#',
+ $trimmed
+ );
+ break;
+ case 'the Optional package will not be listed':
+ $trimmed = strtr($world['output'], array(' ' => '', "\n" => ''));
+ $this->assertNotRegExp(
+ '#Wouldinstallpackage.*Optional/package.xml#',
+ $trimmed
+ );
+ break;
+ case 'the component will be listed':
+ $trimmed = strtr($world['output'], array(' ' => '', "\n" => ''));
+ $this->assertRegExp(
+ '#Wouldinstallpackage.*Install/package.xml#',
+ $trimmed
+ );
+ break;
case 'the CI configuration will be installed.':
$this->assertTrue(
file_exists(
$world['output']
);
break;
+ case 'the non-Horde dependencies of the component will not be listed':
+ $this->assertNotContains(
+ 'Console_Getopt',
+ $world['output']
+ );
+ break;
case 'the non-Horde dependencies of the component will be listed':
$this->assertContains(
'Console_Getopt',
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>Dependency</name>
- <channel>pear.php.net</channel>
+ <channel>pear.horde.org</channel>
<summary>Test fixture.</summary>
<description>A dummy package.xml used for testing the Components package.</description>
<lead>
<pearinstaller>
<min>1.7.0</min>
</pearinstaller>
- <package>
- <name>Console_Getopt</name>
- <channel>pear.php.net</channel>
- </package>
</required>
<optional>
<package>
- <name>Install</name>
+ <name>Optional</name>
<channel>pear.horde.org</channel>
</package>
+ <package>
+ <name>Console_Getopt</name>
+ <channel>pear.php.net</channel>
+ </package>
</optional>
</dependencies>
<phprelease>
--- /dev/null
+<?php
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Optional</name>
+ <channel>pear.horde.org</channel>
+ <summary>Test fixture.</summary>
+ <description>A dummy package.xml used for testing the Components package.</description>
+ <lead>
+ <name>Gunnar Wrobel</name>
+ <user>wrobel</user>
+ <email>p@rdus.de</email>
+ <active>yes</active>
+ </lead>
+ <date>2010-08-22</date>
+ <time>21:12:03</time>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+ <notes>
+* Initial release
+ </notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <dir name="lib">
+ <file name="Optional.php" role="php" />
+ </dir> <!-- /lib -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.0.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ <package>
+ <name>Console_Getopt</name>
+ <channel>pear.php.net</channel>
+ </package>
+ </required>
+ <optional>
+ <package>
+ <name>PECL</name>
+ <channel>pecl.php.net</channel>
+ </package>
+ </optional>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install as="Optional.php" name="lib/Optional.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2010-08-22</date>
+ <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+ <notes>
+* Initial release
+ </notes>
+ </release>
+ </changelog>
+</package>