From 4f12349bd02b0d11b633453f30a5e19fffbf8b0f Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel
Date: Fri, 29 Oct 2010 11:38:41 +0200 Subject: [PATCH] Allow symlinking when installing packages from the source repository. Now the --install option of components should be capable of completely installing the horde stack starting with the new package.xml at horde/package.xml down to all PEAR dependencies. Code from the repository can be symlinked for dev mode. So this is getting nearer to a replacement for framework/bin/install_{framework,dev}. php horde/components/bin/horde-components --install=/srv/www/h4/.pearrc --symlink horde/horde Currently the "Horde" role does not work yet and I assume there are quite a few other corner cases/bugs that I will need to weed out. --- components/TODO | 12 +--- .../lib/Components/Helper/InstallationRun.php | 19 ++++- components/lib/Components/Module/Installer.php | 16 +++++ components/lib/Components/Pear/InstallLocation.php | 80 ++++++++++++++++++++++ components/lib/Components/Pear/Package.php | 10 +++ components/lib/Components/Runner/Installer.php | 4 ++ 6 files changed, 129 insertions(+), 12 deletions(-) diff --git a/components/TODO b/components/TODO index 52a72db27..922d83cd4 100644 --- a/components/TODO +++ b/components/TODO @@ -4,26 +4,20 @@ - Document usage - - Add module for generating component documentation. - - - Allow linking files during the installation. - - Allow filtering (see http://github.com/horde/horde/commit/404e8d1ea7c0bf99373aec2ce7f2534a442149b3) Potentially check with git if the file is relevant or not. - Fix dependency listing with the --optional=yes/no flag - - Allow optional installation of PECL packages + - Allow downloading documentation from the wiki. + + - Add module for generating component documentation. - Add a commit module that automatically adds a changelog entry in the notes section of the package.xml - Add a release helper module. - - Allow downloading documentation from the wiki. - - - Maybe prefix the job names of packages from the framework with Horde_ - - Allow absolute/relative paths as arguments - WWW frontend diff --git a/components/lib/Components/Helper/InstallationRun.php b/components/lib/Components/Helper/InstallationRun.php index eca2d0548..24a3014b7 100644 --- a/components/lib/Components/Helper/InstallationRun.php +++ b/components/lib/Components/Helper/InstallationRun.php @@ -51,6 +51,13 @@ class Components_Helper_InstallationRun private $_output; /** + * The options for this run. + * + * @param array + */ + private $_options; + + /** * The list of channels already installed. * * @var array @@ -270,9 +277,15 @@ class Components_Helper_InstallationRun private function _installHordePackageOnce($package_file, $reason = '') { if (empty($this->_options['pretend'])) { - $this->_environment->addPackageFromSource( - $package_file, $reason - ); + if (empty($this->_options['symlink'])) { + $this->_environment->addPackageFromSource( + $package_file, $reason + ); + } else { + $this->_environment->linkPackageFromSource( + $package_file, $reason + ); + } } else { $this->_output->ok( sprintf( diff --git a/components/lib/Components/Module/Installer.php b/components/lib/Components/Module/Installer.php index a8e4af146..760c15e20 100644 --- a/components/lib/Components/Module/Installer.php +++ b/components/lib/Components/Module/Installer.php @@ -110,6 +110,22 @@ extends Components_Module_Base 'help' => 'Just indicate what would be installed.', ) ), + new Horde_Argv_Option( + '-s', + '--symlink', + array( + 'action' => 'store_true', + 'help' => 'Symlink the files from the source repository rather than copying them to the install location. This is intended for the development mode where you want to have your edits to have a direct effect on your installation while still retaining the possibility of commiting to your repository.', + ) + ), + new Horde_Argv_Option( + '-H', + '--horde-dir', + array( + 'action' => 'store', + 'help' => 'The location of the horde installation directory. The default will be the INSTALL/horde directory', + ) + ), ); } diff --git a/components/lib/Components/Pear/InstallLocation.php b/components/lib/Components/Pear/InstallLocation.php index 7eca2d66e..6efd1075a 100644 --- a/components/lib/Components/Pear/InstallLocation.php +++ b/components/lib/Components/Pear/InstallLocation.php @@ -370,6 +370,86 @@ class Components_Pear_InstallLocation } /** + * Add a package based on a source directory. + * + * @param string $package The path to the package.xml in the source directory. + * @param string $reason Optional reason for adding the package. + * + * @return NULL + */ + public function linkPackageFromSource($package, $reason = '') + { + $this->_output->ok( + sprintf( + 'About to symlink package %s%s', + $package, + $reason + ) + ); + + $hordeDir = $this->getPearConfig()->get('horde_dir'); + $destDir = $this->getPearConfig()->get('php_dir'); + + ob_start(); + $pkg = $this->_factory->createPackageForEnvironment($package, $this); + $dir = dirname($package); + foreach ($pkg->getInstallationFilelist() as $file) { + $orig = realpath($dir . '/' . $file['attribs']['name']); + if (empty($orig)) { + $this->_output->warn('Install file does not seem to exist: ' . $dir . '/' . $file['attribs']['name']); + continue; + } + + switch ($file['attribs']['role']) { + case 'horde': + if (isset($file['attribs']['install-as'])) { + $dest = $hordeDir . '/' . $file['attribs']['install-as']; + } else { + $this->_output->warn('Could not determine install directory (role "horde") for ' . $hordeDir); + continue; + } + break; + + case 'php': + if (isset($file['attribs']['install-as'])) { + $dest = $destDir . '/' . $file['attribs']['install-as']; + } elseif (isset($file['attribs']['baseinstalldir'])) { + $dest = $destDir . $file['attribs']['baseinstalldir'] . '/' . $file['attribs']['name']; + } else { + $dest = $destDir . '/' . $file['attribs']['name']; + } + break; + + default: + $dest = null; + break; + } + + if (!is_null($dest)) { + if (file_exists($dest)) { + @unlink($dest); + } elseif (!file_exists(dirname($dest))) { + @mkdir(dirname($dest), 0777, true); + } + + print 'SYMLINK: ' . $orig . ' -> ' . $dest . "\n"; + if (!symlink($orig, $dest)) { + $this->_output->warn('Could not link ' . $orig . '.'); + } + } + } + $this->_output->pear(ob_get_clean()); + + $this->_output->ok( + sprintf( + 'Successfully symlinked package %s%s', + $package, + $reason + ) + ); + } + + /** * Add an external dependency based on a package name or package tarball. * * @param Components_Pear_Dependency $dependency The package dependency. diff --git a/components/lib/Components/Pear/Package.php b/components/lib/Components/Pear/Package.php index 8eba628f7..4454f8db9 100644 --- a/components/lib/Components/Pear/Package.php +++ b/components/lib/Components/Pear/Package.php @@ -279,6 +279,16 @@ class Components_Pear_Package } /** + * Return the list of files that should be installed for this package. + * + * @return array The file list. + */ + public function getInstallationFilelist() + { + return $this->_getPackageFile()->getInstallationFilelist(); + } + + /** * Update the content listing of the provided package. * * @param PEAR_PackageFileManager2 $package The package to update. diff --git a/components/lib/Components/Runner/Installer.php b/components/lib/Components/Runner/Installer.php index 6296aaaff..a490ffecd 100644 --- a/components/lib/Components/Runner/Installer.php +++ b/components/lib/Components/Runner/Installer.php @@ -76,12 +76,16 @@ class Components_Runner_Installer if (!$environment) { $environment = $options['install']; } + if (empty($options['horde_dir'])) { + $options['horde_dir'] = $environment . DIRECTORY_SEPARATOR . 'horde'; + } $arguments = $this->_config->getArguments(); $tree = $this->_factory ->createTreeHelper( $environment, realpath($arguments[0]), $options ); $tree->getEnvironment()->provideChannel('pear.horde.org'); + $tree->getEnvironment()->getPearConfig()->set('horde_dir', $options['horde_dir'], 'user', 'pear.horde.org'); $tree->installTreeInEnvironment( realpath($arguments[0]) . DIRECTORY_SEPARATOR . 'package.xml', $this->_output, -- 2.11.0