]> granicus.if.org Git - php/commitdiff
merge downloader code into HEAD - it works
authorGreg Beaver <cellog@php.net>
Thu, 4 Dec 2003 02:11:40 +0000 (02:11 +0000)
committerGreg Beaver <cellog@php.net>
Thu, 4 Dec 2003 02:11:40 +0000 (02:11 +0000)
fix bug found in uninstall

pear/PEAR/Command/Install.php
pear/PEAR/Installer.php
pear/package-PEAR.xml

index 9cac11a05859c2e8ce0a023a20fe2890d56d128c..38443ce855eecdb7bf1fc6ef85c0bcc3e2acc579 100644 (file)
@@ -251,6 +251,7 @@ package if needed.
 
     function doInstall($command, $options, $params)
     {
+        require_once 'PEAR/Downloader.php';
         if (empty($this->installer)) {
             $this->installer = &new PEAR_Installer($this->ui);
         }
@@ -260,7 +261,7 @@ package if needed.
         if ($command == 'upgrade-all') {
             include_once "PEAR/Remote.php";
             $options['upgrade'] = true;
-            $remote = new PEAR_Remote($this->config);
+            $remote = &new PEAR_Remote($this->config);
             $state = $this->config->get('preferred_state');
             if (empty($state) || $state == 'any') {
                 $latest = $remote->call("package.listLatestReleases");
@@ -288,21 +289,18 @@ package if needed.
                 $this->ui->outputData(array('data' => "Will upgrade $package"), $command);
             }
         }
+        $this->downloader = &new PEAR_Downloader($this->ui, $options, $this->config);
         $errors = array();
         $downloaded = array();
-        $this->installer->download($params, $options, $this->config, $downloaded,
-                                   $errors);
-        if ($command != 'upgrade-all') {
-            for ($i = 0; $i < count($params); $i++) {
-                $params[$i] = $this->installer->extractDownloadFileName($params[$i], $_tmp);
-            }
-        }
+        $this->downloader->download($params);
+        $errors = $this->downloader->getErrorMsgs();
         if (count($errors)) {
             $err['data'] = array($errors);
             $err['headline'] = 'Install Errors';
             $this->ui->outputData($err);
             return $this->raiseError("$command failed");
         }
+        $downloaded = $this->downloader->getDownloadedPackages();
         $this->installer->sortPkgDeps($downloaded);
         foreach ($downloaded as $pkg) {
             $bn = basename($pkg['file']);
@@ -346,7 +344,7 @@ package if needed.
                 $newparams[] = $info;
             }
         }
-        PEAR_Common::sortPkgDeps($newparams, true);
+        $this->installer->sortPkgDeps($newparams, true);
         $params = array();
         foreach($newparams as $info) {
             $params[] = $info['info']['package'];
@@ -377,7 +375,7 @@ package if needed.
     function doBundle($command, $options, $params)
     {
         if (empty($this->installer)) {
-            $this->installer = &new PEAR_Installer($this->ui);
+            $this->installer = &new PEAR_Downloader($this->ui);
         }
         $installer = &$this->installer;
         if (sizeof($params) < 1) {
@@ -461,5 +459,7 @@ package if needed.
     // }}}
     }
 
+    // }}}
+
 }
 ?>
index 1b7f5e4d747a75fdba9a2e301d894d651d27a1d1..4e22964e6407a3377c67a19a557aaeea19f367f9 100644 (file)
@@ -23,6 +23,7 @@
 require_once 'PEAR/Common.php';
 require_once 'PEAR/Registry.php';
 require_once 'PEAR/Dependency.php';
+require_once 'PEAR/Downloader.php';
 require_once 'System.php';
 
 define('PEAR_INSTALLER_OK',       1);
@@ -43,8 +44,9 @@ define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2);
  * @since PHP 4.0.2
  * @author Stig Bakken <ssb@php.net>
  * @author Martin Jansen <mj@php.net>
+ * @author Greg Beaver <cellog@php.net>
  */
-class PEAR_Installer extends PEAR_Common
+class PEAR_Installer extends PEAR_Downloader
 {
     // {{{ properties
 
@@ -528,26 +530,6 @@ class PEAR_Installer extends PEAR_Common
         $this->file_operations = array();
     }
 
-    // }}}
-    // {{{ getPackageDownloadUrl()
-
-    function getPackageDownloadUrl($package, $version = null)
-    {
-        if ($version) {
-            $package .= "-$version";
-        }
-        if ($this === null || $this->config === null) {
-            $package = "http://pear.php.net/get/$package";
-        } else {
-            $package = "http://" . $this->config->get('master_server') .
-                "/get/$package";
-        }
-        if (!extension_loaded("zlib")) {
-            $package .= '?uncompress=yes';
-        }
-        return $package;
-    }
-
     // }}}
     // {{{ mkDirHier($dir)
 
@@ -572,106 +554,6 @@ class PEAR_Installer extends PEAR_Common
         return $path;
     }
 
-    // }}}
-    // {{{ extractDownloadFileName($pkgfile, &$version)
-
-    function extractDownloadFileName($pkgfile, &$version)
-    {
-        if (@is_file($pkgfile)) {
-            return $pkgfile;
-        }
-        // regex defined in Common.php
-        if (preg_match(PEAR_COMMON_PACKAGE_DOWNLOAD_PREG, $pkgfile, $m)) {
-            $version = (isset($m[3])) ? $m[3] : null;
-            return $m[1];
-        }
-        $version = null;
-        return $pkgfile;
-    }
-
-    // }}}
-    // {{{ _downloadFile()
-    /**
-     * @param string filename to download
-     * @param PEAR_Config Configuration object
-     * @param array options returned from Console_GetOpt
-     * @param array empty array to populate with error messages, if any
-     * @param string version/state
-     * @param string original value passed to command-line
-     * @param string preferred state (snapshot/devel/alpha/beta/stable)
-     * @return null|PEAR_Error|string
-     * @access private
-     */
-    function _downloadFile($pkgfile, &$config, $options, &$errors, $version,
-                           $origpkgfile, $state)
-    {
-        // {{{ check the package filename, and whether it's already installed
-        $need_download = false;
-        if (preg_match('#^(http|ftp)://#', $pkgfile)) {
-            $need_download = true;
-        } elseif (!@is_file($pkgfile)) {
-            if ($this->validPackageName($pkgfile)) {
-                if ($this->registry->packageExists($pkgfile)) {
-                    if (empty($options['upgrade']) && empty($options['force'])) {
-                        $errors[] = "$pkgfile already installed";
-                        return;
-                    }
-                }
-                $pkgfile = $this->getPackageDownloadUrl($pkgfile, $version);
-                $need_download = true;
-            } else {
-                if (strlen($pkgfile)) {
-                    $errors[] = "Could not open the package file: $pkgfile";
-                } else {
-                    $errors[] = "No package file given";
-                }
-                return;
-            }
-        }
-        // }}}
-
-        // {{{ Download package -----------------------------------------------
-        if ($need_download) {
-            $downloaddir = $config->get('download_dir');
-            if (empty($downloaddir)) {
-                if (PEAR::isError($downloaddir = System::mktemp('-d'))) {
-                    return $downloaddir;
-                }
-                $this->log(3, '+ tmp dir created at ' . $downloaddir);
-            }
-            $callback = $this->ui ? array(&$this, '_downloadCallback') : null;
-            $this->pushErrorHandling(PEAR_ERROR_RETURN);
-            $file = $this->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback);
-            $this->popErrorHandling();
-            if (PEAR::isError($file)) {
-                if ($this->validPackageName($origpkgfile)) {
-                    include_once 'PEAR/Remote.php';
-                    $remote = new PEAR_Remote($config);
-                    if (!PEAR::isError($info = $remote->call('package.info',
-                          $origpkgfile))) {
-                        if (!count($info['releases'])) {
-                            return $this->raiseError('Package ' . $origpkgfile .
-                            ' has no releases');
-                        } else {
-                            return $this->raiseError('No releases of preferred state "'
-                            . $state . '" exist for package ' . $origpkgfile .
-                            '.  Use ' . $origpkgfile . '-state to install another' .
-                            ' state (like ' . $origpkgfile .'-beta)',
-                            PEAR_INSTALLER_ERROR_NO_PREF_STATE);
-                        }
-                    } else {
-                        return $pkgfile;
-                    }
-                } else {
-                    return $this->raiseError($file);
-                }
-            }
-            $pkgfile = $file;
-        }
-        // }}}
-        return $pkgfile;
-    }
-
     // }}}
     // {{{ download()
 
@@ -693,269 +575,19 @@ class PEAR_Installer extends PEAR_Common
      * @param false private recursion variable
      * @param false private recursion variable
      * @param false private recursion variable
+     * @deprecated in favor of PEAR_Downloader
      */
     function download($packages, $options, &$config, &$installpackages,
                       &$errors, $installed = false, $willinstall = false, $state = false)
     {
-        // recognized options:
-        // - onlyreqdeps   : install all required dependencies as well
-        // - alldeps       : install all dependencies, including optional
-        //
-        // {{{ determine preferred state, installroot, etc
-        if (!$willinstall) {
-            $willinstall = array();
-        }
-        if (!$state) {
-            $state = $config->get('preferred_state');
-            if (!$state) {
-                // don't inadvertantly use a non-set preferred_state
-                $state = null;
-            }
-        }
-        $mywillinstall = array();
-        $php_dir = $config->get('php_dir');
-        if (isset($options['installroot'])) {
-            if (substr($options['installroot'], -1) == DIRECTORY_SEPARATOR) {
-                $options['installroot'] = substr($options['installroot'], 0, -1);
-            }
-            $php_dir = $this->_prependPath($php_dir, $options['installroot']);
-            $this->installroot = $options['installroot'];
-        } else {
-            $this->installroot = '';
-        }
-        // }}}
-        $this->registry = &new PEAR_Registry($php_dir);
-
-        // {{{ download files in this list if necessary
-        foreach($packages as $pkgfile) {
-            if (!is_file($pkgfile)) {
-                $origpkgfile = $pkgfile;
-                $pkgfile = $this->extractDownloadFileName($pkgfile, $version);
-                if (preg_match('#^(http|ftp)://#', $pkgfile)) {
-                    $pkgfile = $this->_downloadFile($pkgfile, $config, $options,
-                                                    $errors, $version, $origpkgfile,
-                                                    $state);
-                    if (PEAR::isError($pkgfile)) {
-                        return $pkgfile;
-                    }
-                    $tempinfo = $this->infoFromAny($pkgfile);
-                    if (isset($options['alldeps']) || isset($options['onlyreqdeps'])) {
-                        // ignore dependencies if there are any errors
-                        if (!PEAR::isError($tempinfo)) {
-                            $mywillinstall[strtolower($tempinfo['package'])] = @$tempinfo['release_deps'];
-                        }
-                    }
-                    $installpackages[] = array('pkg' => $tempinfo['package'],
-                                               'file' => $pkgfile, 'info' => $tempinfo);
-                    continue;
-                }
-                if (!$this->validPackageName($pkgfile)) {
-                    return $this->raiseError("Package name '$pkgfile' not valid");
-                }
-                // ignore packages that are installed unless we are upgrading
-                $curinfo = $this->registry->packageInfo($pkgfile);
-                if ($this->registry->packageExists($pkgfile) && empty($options['upgrade']) && empty($options['force'])) {
-                    $this->log(0, "Package '{$curinfo['package']}' already installed, skipping");
-                    continue;
-                }
-                // Retrieve remote release list
-                include_once 'PEAR/Remote.php';
-                $curver = $curinfo['version'];
-                $remote = &new PEAR_Remote($config);
-                $releases = $remote->call('package.info', $pkgfile, 'releases');
-                if (!count($releases)) {
-                    return $this->raiseError("No releases found for package '$pkgfile'");
-                }
-                // Want a specific version/state
-                if ($version !== null) {
-                    // Passed Foo-1.2
-                    if ($this->validPackageVersion($version)) {
-                        if (!isset($releases[$version])) {
-                            return $this->raiseError("No release with version '$version' found for '$pkgfile'");
-                        }
-                    // Passed Foo-alpha
-                    } elseif (in_array($version, $this->getReleaseStates())) {
-                        $state = $version;
-                        $version = 0;
-                        foreach ($releases as $ver => $inf) {
-                            if ($inf['state'] == $state && version_compare("$version", "$ver") < 0) {
-                                $version = $ver;
-                            }
-                        }
-                        if ($version == 0) {
-                            return $this->raiseError("No release with state '$state' found for '$pkgfile'");
-                        }
-                    // invalid postfix passed
-                    } else {
-                        return $this->raiseError("Invalid postfix '-$version', be sure to pass a valid PEAR ".
-                                                 "version number or release state");
-                    }
-                // Guess what to download
-                } else {
-                    $states = $this->betterStates($state, true);
-                    $possible = false;
-                    $version = 0;
-                    foreach ($releases as $ver => $inf) {
-                        if (in_array($inf['state'], $states) && version_compare("$version", "$ver") < 0) {
-                            $version = $ver;
-                        }
-                    }
-                    if ($version == 0 && !isset($options['force'])) {
-                        return $this->raiseError('No release with state equal to: \'' . implode(', ', $states) .
-                                                 "' found for '$pkgfile'");
-                    } elseif ($version == 0) {
-                        $this->log(0, "Warning: $pkgfile is state '$inf[state]' which is less stable " .
-                                      "than state '$state'");
-                    }
-                }
-                // Check if we haven't already the version
-                if (empty($options['force'])) {
-                    if ($curinfo['version'] == $version) {
-                        $this->log(0, "Package '{$curinfo['package']}-{$curinfo['version']}' already installed, skipping");
-                        continue;
-                    } elseif (version_compare("$version", "{$curinfo['version']}") < 0) {
-                        $this->log(0, "Already got '{$curinfo['package']}-{$curinfo['version']}' greater than requested '$version', skipping");
-                        continue;
-                    }
-                }
-                $pkgfile = $this->_downloadFile($pkgfile, $config, $options,
-                                                $errors, $version, $origpkgfile,
-                                                $state);
-                if (PEAR::isError($pkgfile)) {
-                    return $pkgfile;
-                }
-            } // end is_file()
-            $tempinfo = $this->infoFromAny($pkgfile);
-            if (isset($options['alldeps']) || isset($options['onlyreqdeps'])) {
-                // ignore dependencies if there are any errors
-                if (!PEAR::isError($tempinfo)) {
-                    $mywillinstall[strtolower($tempinfo['package'])] = @$tempinfo['release_deps'];
-                }
-            }
-            $installpackages[] = array('pkg' => $tempinfo['package'],
-                                       'file' => $pkgfile, 'info' => $tempinfo);
-        } // end foreach($packages)
-        // }}}
-
-        // {{{ extract dependencies from downloaded files and then download
-        // them if necessary
-        if (isset($options['alldeps']) || isset($options['onlyreqdeps'])) {
-            include_once "PEAR/Remote.php";
-            $remote = new PEAR_Remote($config);
-            if (!$installed) {
-                $installed = $this->registry->listPackages();
-                array_walk($installed, create_function('&$v,$k','$v = strtolower($v);'));
-                $installed = array_flip($installed);
-            }
-            $deppackages = array();
-            // {{{ construct the list of dependencies for each file
-            foreach ($mywillinstall as $package => $alldeps) {
-                if (!is_array($alldeps)) {
-                    continue;
-                }
-                foreach($alldeps as $info) {
-                    if ($info['type'] != 'pkg') {
-                        continue;
-                    }
-                    if (!isset($options['alldeps']) && isset($info['optional']) &&
-                          $info['optional'] == 'yes') {
-                        // skip optional deps
-                        $this->log(0, "skipping Package $package optional dependency $info[name]");
-                        continue;
-                    }
-                    // {{{ get releases
-                    $releases = $remote->call('package.info', $info['name'], 'releases');
-                    if (PEAR::isError($releases)) {
-                        return $releases;
-                    }
-                    if (!count($releases)) {
-                        if (!isset($installed[strtolower($info['name'])])) {
-                            $errors[] = "Package $package dependency $info[name] ".
-                                        "has no releases";
-                        }
-                        continue;
-                    }
-                    $found = false;
-                    $save = $releases;
-                    while(count($releases) && !$found) {
-                        if (!empty($state) && $state != 'any') {
-                            list($release_version,$release) = each($releases);
-                            if ($state != $release['state'] &&
-                                !in_array($release['state'], $this->betterStates($state)))
-                            {
-                                // drop this release - it ain't stable enough
-                                array_shift($releases);
-                            } else {
-                                $found = true;
-                            }
-                        } else {
-                            $found = true;
-                        }
-                    }
-                    if (!count($releases) && !$found) {
-                        $get = array();
-                        foreach($save as $release) {
-                            $get = array_merge($get,
-                                $this->betterStates($release['state'], true));
-                        }
-                        $savestate = array_shift($get);
-                        $errors[] = "Release for $package dependency $info[name] " .
-                            "has state '$savestate', requires $state";
-                        continue;
-                    }
-                    if (in_array(strtolower($info['name']), $willinstall) ||
-                          isset($mywillinstall[strtolower($info['name'])])) {
-                        // skip upgrade check for packages we will install
-                        continue;
-                    }
-                    if (!isset($installed[strtolower($info['name'])])) {
-                        // check to see if we can install the specific version required
-                        if ($info['rel'] == 'eq') {
-                            $deppackages[] = $info['name'] . '-' . $info['version'];
-                            continue;
-                        }
-                        // skip upgrade check for packages we don't have installed
-                        $deppackages[] = $info['name'];
-                        continue;
-                    }
-                    // }}}
-
-                    // {{{ see if a dependency must be upgraded
-                    $inst_version = $this->registry->packageInfo($info['name'], 'version');
-                    if (!isset($info['version'])) {
-                        // this is a rel='has' dependency, check against latest
-                        if (version_compare($release_version, $inst_version, 'le')) {
-                            continue;
-                        } else {
-                            $deppackages[] = $info['name'];
-                            continue;
-                        }
-                    }
-                    if (version_compare($info['version'], $inst_version, 'le')) {
-                        // installed version is up-to-date
-                        continue;
-                    }
-                    $deppackages[] = $info['name'];
-                    // }}}
-                } // foreach($alldeps
-            }
-            // }}} foreach($willinstall
-
-            if (count($deppackages)) {
-                // check dependencies' dependencies
-                // combine the list of packages to install
-                $temppack = array();
-                foreach($installpackages as $p) {
-                    $temppack[] = strtolower($p['info']['package']);
-                }
-                foreach($deppackages as $pack) {
-                    $temppack[] = strtolower($pack);
-                }
-                $willinstall = array_merge($willinstall, $temppack);
-                $this->download($deppackages, $options, $config, $installpackages,
-                                $errors, $installed, $willinstall, $state);
-            }
-        } // }}} if --alldeps or --onlyreqdeps
+        // trickiness: initialize here
+        parent::PEAR_Downloader($this->ui, $options, $config);
+        $ret = parent::download($packages);
+        $errors = $this->getErrorMsgs();
+        $installpackages = $this->getDownloadedPackages();
+        trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
+                      "in favor of PEAR_Downloader class", E_USER_WARNING);
+        return $ret;
     }
 
     // }}}
@@ -1400,36 +1032,6 @@ class PEAR_Installer extends PEAR_Common
         return false;
     }
 
-    // }}}
-    // {{{ _downloadCallback()
-
-    function _downloadCallback($msg, $params = null)
-    {
-        switch ($msg) {
-            case 'saveas':
-                $this->log(1, "downloading $params ...");
-                break;
-            case 'done':
-                $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes');
-                break;
-            case 'bytesread':
-                static $bytes;
-                if (empty($bytes)) {
-                    $bytes = 0;
-                }
-                if (!($bytes % 10240)) {
-                    $this->log(1, '.', false);
-                }
-                $bytes += $params;
-                break;
-            case 'start':
-                $this->log(1, "Starting to download {$params[0]} (".number_format($params[1], 0, '', ',')." bytes)");
-                break;
-        }
-        if (method_exists($this->ui, '_downloadCallback'))
-            $this->ui->_downloadCallback($msg, $params);
-    }
-
     // }}}
     // {{{ _buildCallback()
 
index 59fccc5a17bd4cf49269cf0106062e8f051e347e..0e044db31d61dfa4fe6844d6e086decc2082d2d6 100644 (file)
@@ -58,6 +58,8 @@ PEAR Installer:
 * Bug #248 --force command does not work as expected
 * Bug #293 [Patch] PEAR_Error not calling static method callbacks for error-handler
 * Bug #324 pear -G gives Fatal Error (PHP-GTK not installed, but error is at engine level)
+* Moved download code into its own class
+* Fully unit tested the installer and downloader, plus PEAR_Common
 
     </notes>
     <provides type="class" name="OS_Guess" />
@@ -85,6 +87,7 @@ PEAR Installer:
         <file role="php" name="Common.php"/>
         <file role="php" name="Config.php"/>
         <file role="php" name="Dependency.php"/>
+        <file role="php" name="Downloader.php"/>
         <dir name="Frontend">
           <file role="php" name="CLI.php"/>
         </dir>