From: Gunnar Wrobel
Date: Tue, 26 Oct 2010 15:21:17 +0000 (+0200) Subject: Do not install packages twice, catch more PEAR errors, be more explicit when installi... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=f1e865a778f2736dfffed7db32d51d0fc246401e;p=horde.git Do not install packages twice, catch more PEAR errors, be more explicit when installing packages. --- diff --git a/components/lib/Components/Helper/InstallationRun.php b/components/lib/Components/Helper/InstallationRun.php index 6449042b2..24d22ed45 100644 --- a/components/lib/Components/Helper/InstallationRun.php +++ b/components/lib/Components/Helper/InstallationRun.php @@ -90,13 +90,29 @@ class Components_Helper_InstallationRun * @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 ); diff --git a/components/lib/Components/Helper/Tree/Element.php b/components/lib/Components/Helper/Tree/Element.php index c515e26ca..650cef962 100644 --- a/components/lib/Components/Helper/Tree/Element.php +++ b/components/lib/Components/Helper/Tree/Element.php @@ -82,17 +82,21 @@ class Components_Helper_Tree_Element * * @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']) @@ -101,7 +105,7 @@ class Components_Helper_Tree_Element continue; } $run->installExternalPackageOnce( - $dependency['channel'], $dependency['name'], $reason + $dependency['channel'], $dependency['name'], $new_reason ); } foreach ( @@ -109,7 +113,7 @@ class Components_Helper_Tree_Element $this->_package->listAllHordeDependencies() ) as $child ) { - $child->installInTree($run, $visited); + $child->installInTree($run, $visited, $new_reason); } $run->installHordePackageOnce($this->_package_file, $reason); } diff --git a/components/lib/Components/Pear/InstallLocation.php b/components/lib/Components/Pear/InstallLocation.php index f10960f69..511385adb 100644 --- a/components/lib/Components/Pear/InstallLocation.php +++ b/components/lib/Components/Pear/InstallLocation.php @@ -312,7 +312,6 @@ class Components_Pear_InstallLocation new PEAR_Frontend_CLI(), $this->getPearConfig() ); - $installer->setErrorHandling(PEAR_ERROR_EXCEPTION); return $installer; } @@ -335,10 +334,12 @@ class Components_Pear_InstallLocation ) ); 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( @@ -351,51 +352,66 @@ class Components_Pear_InstallLocation } /** + * 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 { @@ -406,18 +422,21 @@ class Components_Pear_InstallLocation ) ); 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 )