Allow to install files with "horde" role. Tried fixing downloading
authorGunnar Wrobel <p@rdus.de>
Sun, 31 Oct 2010 10:22:24 +0000 (11:22 +0100)
committerGunnar Wrobel <p@rdus.de>
Sun, 31 Oct 2010 10:22:24 +0000 (11:22 +0100)
external dependencies from unknown channels.

PEAR is apparently not meant to bootstrap itself. The workarounds
necessary to allow creating a new Config that takes the "horde" role
into account are awkward because a nicely place "static" when
initializing the PEAR_Config.

Automatically fetching new channels fails completely at the moment as
parsing a package.xml with unkown channels does not work. Need to find
a decent solution at a later timepoint.

components/TODO
components/lib/Components/Helper/InstallationRun.php
components/lib/Components/Helper/Tree.php
components/lib/Components/Pear/InstallLocation.php
components/lib/Components/Runner/Installer.php
components/package.xml

index 922d83c..d30304e 100644 (file)
@@ -7,6 +7,9 @@
  - Allow filtering (see http://github.com/horde/horde/commit/404e8d1ea7c0bf99373aec2ce7f2534a442149b3)
    Potentially check with git if the file is relevant or not.
 
+ - Allow channel dependency detection with external/local package
+   dependencies.
+
  - Fix dependency listing with the --optional=yes/no flag
 
  - Allow downloading documentation from the wiki.
index 24a3014..d2802fb 100644 (file)
@@ -203,11 +203,26 @@ class Components_Helper_InstallationRun
             if (empty($to_add)) {
                 $to_add = array($dependency->key());
             }
-            foreach (
-                $this->_environment->identifyRequiredLocalDependencies(
-                    $dependency, $this->_options['include'], $this->_options['exclude']
-                ) as $required
-            ) {
+            $dependencies = $this->_environment->identifyRequiredLocalDependencies(
+                $dependency
+            );
+            /**
+             * @todo This section won't really work as reading the package.xml
+             * from an archive fails if the channels are unknown. So we never
+             * get here. Sigh...
+             */
+            if ($dependencies) {
+                $this->_installChannels(
+                    $dependencies, sprintf(' [required by %s]', $dependency->name())
+                );
+                $list = $dependencies->listExternalDependencies(
+                    $this->_options['include'], $this->_options['exclude']
+                );
+            } else {
+                $list = array();
+            }
+
+            foreach ($list as $required) {
                 if (in_array($required->key(), $to_add)) {
                     continue;
                 }
index a3985f1..5cf4350 100644 (file)
@@ -148,4 +148,14 @@ class Components_Helper_Tree
     {
         return $this->_environment;
     }
+
+    /**
+     * Return the root handler for the horde repository.
+     *
+     * @return Components_Helper_Root The root handler.
+     */
+    public function getRoot()
+    {
+        return $this->_root;
+    }
 }
\ No newline at end of file
index 6efd107..0b4840a 100644 (file)
@@ -189,10 +189,28 @@ class Components_Pear_InstallLocation
             );
         }
         ob_start();
-        $command_config = new PEAR_Command_Config(new PEAR_Frontend_CLI(), new stdClass);
-        $command_config->doConfigCreate(
-            'config-create', array(), array($this->_base_directory, $this->_config_file)
+        $config = Components_Exception_Pear::catchError(
+            PEAR_Config::singleton($this->_config_file, '#no#system#config#', false)
         );
+        $root = dirname($this->_config_file);
+        $config->noRegistry();
+        $config->set('php_dir', "$root/pear/php", 'user');
+        $config->set('data_dir', "$root/pear/data");
+        $config->set('www_dir', "$root/pear/www");
+        $config->set('cfg_dir', "$root/pear/cfg");
+        $config->set('ext_dir', "$root/pear/ext");
+        $config->set('doc_dir', "$root/pear/docs");
+        $config->set('test_dir', "$root/pear/tests");
+        $config->set('cache_dir', "$root/pear/cache");
+        $config->set('download_dir', "$root/pear/download");
+        $config->set('temp_dir', "$root/pear/temp");
+        $config->set('bin_dir', "$root/pear");
+        $config->writeConfigFile();
+        $config->_noRegistry = false;
+        $config->_registry['default'] = new PEAR_Registry("$root/pear/php");
+        $config->_noRegistry = true;
+        mkdir("$root/pear");
+        mkdir("$root/pear/php");
         $this->_output->pear(ob_get_clean());
         $this->_output->ok(
             sprintf(
@@ -387,16 +405,17 @@ class Components_Pear_InstallLocation
             )
         );
 
-        $hordeDir = $this->getPearConfig()->get('horde_dir');
+        $hordeDir = $this->getPearConfig()->get('horde_dir', 'user', 'pear.horde.org');
         $destDir = $this->getPearConfig()->get('php_dir');
 
         ob_start();
+        $warnings = array();
         $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']);
+                $warnings[] = 'Install file does not seem to exist: ' . $dir . '/' . $file['attribs']['name'];
                 continue;
             }
 
@@ -405,7 +424,7 @@ class Components_Pear_InstallLocation
                 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);
+                    $warnings[] = 'Could not determine install directory (role "horde") for ' . $hordeDir;
                     continue;
                 }
                 break;
@@ -434,12 +453,16 @@ class Components_Pear_InstallLocation
 
                 print 'SYMLINK: ' . $orig . ' -> ' . $dest . "\n";
                 if (!symlink($orig, $dest)) {
-                    $this->_output->warn('Could not link ' . $orig . '.');
+                    $warnings[] = 'Could not link ' . $orig . '.';
                 }
             }
         }
         $this->_output->pear(ob_get_clean());
 
+        foreach ($warnings as $warning) {
+            $this->_output->warn($warning);
+        }
+
         $this->_output->ok(
             sprintf(
                 'Successfully symlinked package %s%s',
@@ -471,6 +494,8 @@ class Components_Pear_InstallLocation
             )
         );
         if ($local = $this->_identifyMatchingLocalPackage($dependency->name())) {
+            $pkg = $this->_factory->getPackageFileFromTgz($local, $this);
+
             ob_start();
             Components_Exception_Pear::catchError(
                 $installer->doInstall(
@@ -514,22 +539,19 @@ class Components_Pear_InstallLocation
      * 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.
+     * @return Components_Pear_Dependencies The dependency helper for the local package.
      */
     public function identifyRequiredLocalDependencies(
-        Components_Pear_Dependency $dependency, $include, $exclude
+        Components_Pear_Dependency $dependency
     ) {
         if ($local = $this->_identifyMatchingLocalPackage($dependency->name())) {
             $this->_checkSetup();
             return $this->_factory
                 ->createTgzPackageForInstallLocation($local, $this)
-                ->getDependencyHelper()
-                ->listExternalDependencies($include, $exclude);
+                ->getDependencyHelper();
         }
-        return array();
+        return false;
     }
 
     /**
index a490ffe..4407e20 100644 (file)
@@ -77,7 +77,7 @@ class Components_Runner_Installer
             $environment = $options['install'];
         }
         if (empty($options['horde_dir'])) {
-            $options['horde_dir'] = $environment . DIRECTORY_SEPARATOR . 'horde';
+            $options['horde_dir'] = dirname($environment) . DIRECTORY_SEPARATOR . 'horde';
         }
         $arguments = $this->_config->getArguments();
         $tree = $this->_factory
@@ -85,7 +85,10 @@ class Components_Runner_Installer
                 $environment, realpath($arguments[0]), $options
             );
         $tree->getEnvironment()->provideChannel('pear.horde.org');
+        $tree->getEnvironment()->addPackageFromSource($tree->getRoot()->getPackageXml('Role'));
+        $tree->getEnvironment()->getPearConfig()->setChannels(array('pear.horde.org', true));
         $tree->getEnvironment()->getPearConfig()->set('horde_dir', $options['horde_dir'], 'user', 'pear.horde.org');
+        Components_Exception_Pear::catchError($tree->getEnvironment()->getPearConfig()->store());
         $tree->installTreeInEnvironment(
             realpath($arguments[0]) . DIRECTORY_SEPARATOR . 'package.xml',
             $this->_output,
index 18e9ef5..215c3e7 100644 (file)
     <channel>pear.horde.org</channel>
    </package>
    <package>
+    <name>Role</name>
+    <channel>pear.horde.org</channel>
+   </package>
+   <package>
     <name>Util</name>
     <channel>pear.horde.org</channel>
    </package>