* @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.
*
* @return NULL
*/
- public function installExternalPackageOnce($channel, $package, $reason = '')
+ public function installExternalPackageOnce($channel, $package, $reason = '', array &$to_add = null)
{
$key = $channel . '/' . $package;
if (!in_array($key, $this->_installed_packages)) {
+ if (empty($to_add)) {
+ $to_add = array($key);
+ }
+ foreach ($this->_environment->identifyRequiredLocalDependencies($channel, $package) as $required) {
+ $rkey = $required['channel'] . '/' . $required['name'];
+ if (in_array($rkey, $to_add)) {
+ continue;
+ }
+ $to_add[] = $rkey;
+ $rreason = sprintf(' [required by %s]', $package);
+ $this->installExternalPackageOnce(
+ $required['channel'], $required['name'], $rreason, &$to_add
+ );
+ }
+
$this->_environment->addPackageFromPackage(
$channel, $package, $reason
);
*
* @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())
- {
+ public function installInTree(
+ Components_Helper_InstallationRun $run,
+ array $visited = array(),
+ $reason = ''
+ ) {
if (in_array($this->_package_file, $visited)) {
return;
}
$visited[] = $this->_package_file;
- $reason = sprintf(' [required by %s]', $this->_package->getName());
- $run->installChannelsOnce($this->_package->listAllRequiredChannels(), $reason);
+ $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'])
continue;
}
$run->installExternalPackageOnce(
- $dependency['channel'], $dependency['name'], $reason
+ $dependency['channel'], $dependency['name'], $new_reason
);
}
foreach (
$this->_package->listAllHordeDependencies()
) as $child
) {
- $child->installInTree($run, $visited);
+ $child->installInTree($run, $visited, $new_reason);
}
$run->installHordePackageOnce($this->_package_file, $reason);
}
new PEAR_Frontend_CLI(),
$this->getPearConfig()
);
- $installer->setErrorHandling(PEAR_ERROR_EXCEPTION);
return $installer;
}
)
);
ob_start();
- $installer->doInstall(
- 'install',
- array('nodeps' => true),
- array($package)
+ Components_Exception_Pear::catchError(
+ $installer->doInstall(
+ 'install',
+ array('nodeps' => true),
+ array($package)
+ )
);
$this->_output->pear(ob_get_clean());
$this->_output->ok(
}
/**
+ * 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.
*
* @param string $channel The channel name for the package.
* @param string $package The name of the package of the path of the tarball.
* @param string $reason Optional reason for adding the package.
- * @param array $locals Packages currently being installed.
*
* @return NULL
*/
- public function addPackageFromPackage($channel, $package, $reason = '', array $locals = null)
+ public function addPackageFromPackage($channel, $package, $reason = '')
{
$installer = $this->getInstallationHandler();
$this->_output->ok(
sprintf(
- 'About to add package %s%s',
+ 'About to add package %s/%s%s',
+ $channel,
$package,
$reason
)
);
if ($local = $this->_identifyMatchingLocalPackage($package)) {
- if (empty($locals)) {
- $locals = array($package);
- } else {
- $locals[] = $package;
- }
- $pkg = new PEAR_PackageFile($this->getPearConfig());
- $pkg = $pkg->fromTgzFile($local, PEAR_VALIDATE_NORMAL);
- foreach ($pkg->getDeps() as $dependency) {
- if ($dependency['type'] != 'pkg') {
- continue;
- }
- if (isset($dependency['optional']) && $dependency['optional'] == 'no') {
- if (in_array($dependency['name'], $locals)) {
- continue;
- }
- $this->addPackageFromPackage($dependency['channel'], $dependency['name'], $reason, $locals);
- }
- }
ob_start();
- $installer->doInstall(
- 'install',
- array(
- 'offline' => true
- ),
- array($local)
+ Components_Exception_Pear::catchError(
+ $installer->doInstall(
+ 'install',
+ array(
+ 'offline' => true
+ ),
+ array($local)
+ )
);
$this->_output->pear(ob_get_clean());
} else {
)
);
ob_start();
- $installer->doInstall(
- 'install',
- array(
- 'channel' => $channel,
- ),
- array($package)
+ Components_Exception_Pear::catchError(
+ $installer->doInstall(
+ 'install',
+ array(
+ 'channel' => $channel,
+ ),
+ array($package)
+ )
);
$this->_output->pear(ob_get_clean());
}
$this->_output->ok(
sprintf(
- 'Successfully added package %s%s',
+ 'Successfully added package %s/%s%s',
+ $channel,
$package,
$reason
)