]> granicus.if.org Git - php/commitdiff
Added error codes for the PEAR_Dependency class
authorStig Bakken <ssb@php.net>
Thu, 14 Nov 2002 23:23:21 +0000 (23:23 +0000)
committerStig Bakken <ssb@php.net>
Thu, 14 Nov 2002 23:23:21 +0000 (23:23 +0000)
Changed the dependency API to have a reference to an error message
string as first arg to all check methods

pear/PEAR/Common.php
pear/PEAR/Dependency.php
pear/PEAR/Installer.php

index af5ef9fc438c136203ca63029fc458ae44c2b3ea..eeabe3c0a5be7844e6bb60115e30b87cd11d0d7c 100644 (file)
@@ -764,7 +764,7 @@ class PEAR_Common extends PEAR
     function infoFromString($data)
     {
         require_once('PEAR/Dependency.php');
-        if ($error = PEAR_Dependency::checkExtension('xml')) {
+        if (PEAR_Dependency::checkExtension($error, 'xml')) {
             return $this->raiseError($error);
         }
         $xp = @xml_parser_create();
index 15ffa9f157be83945edbd8de77685f92a4fac2f7..1717c3d25c0edd3a020642de2f8e0fac8d896729 100644 (file)
 
 require_once "PEAR.php";
 
+define('PEAR_DEPENDENCY_MISSING',        -1);
+define('PEAR_DEPENDENCY_CONFLICT',       -2);
+define('PEAR_DEPENDENCY_UPGRADE_MINOR',  -3);
+define('PEAR_DEPENDENCY_UPGRADE_MAJOR',  -4);
+define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
+
 class PEAR_Dependency
 {
     function PEAR_Dependency(&$registry)
@@ -45,32 +51,33 @@ class PEAR_Dependency
     *        [name] => HTML_Common
     *    )
     */
-    function callCheckMethod($opts)
+    function callCheckMethod(&$errmsg, $opts)
     {
         $rel = isset($opts['rel']) ? $opts['rel'] : 'has';
         $req = isset($opts['version']) ? $opts['version'] : null;
         $name = isset($opts['name']) ? $opts['name'] : null;
+        $errmsg = '';
         switch ($opts['type']) {
             case 'pkg':
-                return $this->checkPackage($name, $req, $rel);
+                return $this->checkPackage($errmsg, $name, $req, $rel);
                 break;
             case 'ext':
-                return $this->checkExtension($name, $req, $rel);
+                return $this->checkExtension($errmsg, $name, $req, $rel);
                 break;
             case 'php':
-                return $this->checkPHP($req, $rel);
+                return $this->checkPHP($errmsg, $req, $rel);
                 break;
             case 'prog':
-                return $this->checkProgram($name);
+                return $this->checkProgram($errmsg, $name);
                 break;
             case 'os':
-                return $this->checkOS($name);
+                return $this->checkOS($errmsg, $name);
                 break;
             case 'sapi':
-                return $this->checkSAPI($name);
+                return $this->checkSAPI($errmsg, $name);
                 break;
             case 'zend':
-                return $this->checkZend($name);
+                return $this->checkZend($errmsg, $name);
                 break;
             default:
                 return "'{$opts['type']}' dependency type not supported";
@@ -86,7 +93,7 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkPackage($name, $req = null, $relation = 'has')
+    function checkPackage(&$errmsg, $name, $req = null, $relation = 'has')
     {
         if (substr($relation, 0, 2) == 'v.') {
             $relation = substr($relation, 2);
@@ -94,12 +101,14 @@ class PEAR_Dependency
         switch ($relation) {
             case 'has':
                 if (!$this->registry->packageExists($name)) {
-                    return "requires package `$name'";
+                    $errmsg = "requires package `$name'";
+                    return PEAR_DEPENDENCY_MISSING;
                 }
                 return false;
             case 'not':
                 if (!$this->registry->packageExists($name)) {
-                    return "conflicts with package `$name'";
+                    $errmsg = "conflicts with package `$name'";
+                    return PEAR_DEPENDENCY_CONFLICT;
                 }
                 return false;
             case 'lt':
@@ -112,12 +121,14 @@ class PEAR_Dependency
                 if (!$this->registry->packageExists($name)
                     || !version_compare("$version", "$req", $relation))
                 {
-                    return "requires package `$name' " .
-                           $this->signOperator($relation) . " $req";
+                    $errmsg = "requires package `$name' " .
+                        $this->signOperator($relation) . " $req";
+                    $code = $this->codeFromRelation($relation, $version, $req);
                 }
                 return false;
         }
-        return "Relation '$relation' with requirement '$req' is not supported (name=$name)";
+        $errmsg = "relation '$relation' with requirement '$req' is not supported (name=$name)";
+        return PEAR_DEPENDENCY_BAD_DEPENDENCY;
     }
 
     /**
@@ -129,25 +140,29 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkExtension($name, $req = null, $relation = 'has')
+    function checkExtension(&$errmsg, $name, $req = null, $relation = 'has')
     {
         // XXX (ssb): could we avoid loading the extension here?
         if (!PEAR::loadExtension($name)) {
-            return "'$name' PHP extension is not installed";
+            $errmsg = "'$name' PHP extension is not installed";
+            return PEAR_DEPENDENCY_MISSING;
         }
         if ($relation == 'has') {
             return false;
         }
+        $code = false;
         if (substr($relation, 0, 2) == 'v.') {
             $ext_ver = phpversion($name);
             $operator = substr($relation, 2);
             // Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
+            settype($req, "string");
             if (!version_compare("$ext_ver", "$req", $operator)) {
-                return "'$name' PHP extension version " .
-                        $this->signOperator($operator) . " $req is required";
+                $retval = "'$name' PHP extension version " .
+                    $this->signOperator($operator) . " $req is required";
+                $code = $this->codeFromRelation($relation, $ext_ver, $req);
             }
         }
-        return false;
+        return $code;
     }
 
     /**
@@ -157,16 +172,21 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkOS($os)
+    function checkOS(&$errmsg, $os)
     {
         // XXX Fixme: Implement a more flexible way, like
         // comma separated values or something similar to PEAR_OS
-
-        // only 'has' relation is supported
-        if ($os == PHP_OS) {
+        static $myos;
+        if (empty($myos)) {
+            include_once "OS/Guess.php";
+            $myos = new OS_Guess();
+        }
+        // only 'has' relation is currently supported
+        if ($myos->matchSignature($os)) {
             return false;
         }
-        return "'$os' operating system not supported";
+        $errmsg = "'$os' operating system not supported";
+        return PEAR_DEPENDENCY_CONFLICT;
     }
 
     /**
@@ -177,14 +197,15 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkPHP($req, $relation = 'ge')
+    function checkPHP(&$errmsg, $req, $relation = 'ge')
     {
         if (substr($relation, 0, 2) == 'v.') {
             $php_ver = phpversion();
             $operator = substr($relation, 2);
             if (!version_compare("$php_ver", "$req", $operator)) {
-                return "PHP version " . $this->signOperator($operator) .
-                       " $req is required";
+                $errmsg = "PHP version " . $this->signOperator($operator) .
+                    " $req is required";
+                return PEAR_DEPENDENCY_CONFLICT;
             }
         }
         return false;
@@ -198,7 +219,7 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkProgram($program)
+    function checkProgram(&$errmsg, $program)
     {
         // XXX FIXME honor safe mode
         $path_delim = OS_WINDOWS ? ';' : ':';
@@ -210,7 +231,8 @@ class PEAR_Dependency
                 return false;
             }
         }
-        return "'$program' program is not present in the PATH";
+        $errmsg = "'$program' program is not present in the PATH";
+        return PEAR_DEPENDENCY_MISSING;
     }
 
     /**
@@ -223,7 +245,7 @@ class PEAR_Dependency
      *                          hardcoded to 'has')
      * @return mixed bool false if no error or the error string
      */
-    function checkSAPI($name, $req = null, $relation = 'has')
+    function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
     {
         // XXX Fixme: There is no way to know if the user has or
         // not other SAPI backends installed than the installer one
@@ -234,7 +256,8 @@ class PEAR_Dependency
         if ($sapi_backend == $name) {
             return false;
         }
-        return "'$sapi_backend' SAPI backend not supported";
+        $errmsg = "'$sapi_backend' SAPI backend not supported";
+        return PEAR_DEPENDENCY_CONFLICT;
     }
 
 
@@ -246,14 +269,15 @@ class PEAR_Dependency
      *
      * @return mixed bool false if no error or the error string
      */
-    function checkZend($req, $relation = 'ge')
+    function checkZend(&$errmsg, $req, $relation = 'ge')
     {
         if (substr($relation, 0, 2) == 'v.') {
             $zend_ver = zend_version();
             $operator = substr($relation, 2);
             if (!version_compare("$zend_ver", "$req", $operator)) {
-                return "Zend version " . $this->signOperator($operator) .
-                       " $req is required";
+                $errmsg = "Zend version " . $this->signOperator($operator) .
+                    " $req is required";
+                return PEAR_DEPENDENCY_CONFLICT;
             }
         }
         return false;
@@ -276,6 +300,28 @@ class PEAR_Dependency
                 return $operator;
         }
     }
+
+
+    function codeFromRelation($relation, $version, $req)
+    {
+        $code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
+        switch ($relation) {
+            case 'gt': case 'ge': case 'eq':
+                // upgrade
+                $have_major = preg_replace('/\D.*/', '', $version);
+                $need_major = preg_replace('/\D.*/', '', $req);
+                if ($need_major > $have_major) {
+                    $code = PEAR_DEPENDENCY_UPGRADE_MAJOR;
+                } else {
+                    $code = PEAR_DEPENDENCY_UPGRADE_MINOR;
+                }
+                break;
+            case 'lt': case 'le': case 'ne':
+                $code = PEAR_DEPENDENCY_CONFLICT;
+                break;
+        }
+        return $code;
+    }
 }
 
 ?>
index 02b1e399a5ab857bec6613214088709743c3d295..21d7bf9235bf526a592163713767c0449842e676 100644 (file)
@@ -156,7 +156,6 @@ class PEAR_Installer extends PEAR_Common
     function _installFile($file, $atts, $tmp_path)
     {
         static $os;
-        ini_set("track_errors", 1);
         if (isset($atts['platform'])) {
             if (empty($os)) {
                 include_once "OS/Guess.php";
@@ -305,7 +304,12 @@ class PEAR_Installer extends PEAR_Common
 
     function addFileOperation($type, $data)
     {
-        $this->log(3, "adding to transaction: $type " . implode(" ", $data));
+        if ($type == 'chmod') {
+            $octmode = decoct($data[0]);
+            $this->log(3, "adding to transaction: $type $octmode $data[1]");
+        } else {
+            $this->log(3, "adding to transaction: $type " . implode(" ", $data));
+        }
         $this->file_operations[] = array($type, $data);
     }
 
@@ -346,7 +350,7 @@ class PEAR_Installer extends PEAR_Common
                     break;
                 case 'delete':
                     // check that directory is writable
-                    if (!is_writable(dirname($data[0]))) {
+                    if (file_exists($data[0]) && !is_writable(dirname($data[0]))) {
                         $errors[] = "permission denied ($type): $data[0]";
                     }
                     break;
@@ -370,7 +374,8 @@ class PEAR_Installer extends PEAR_Common
                     break;
                 case 'chmod':
                     @chmod($data[0], $data[1]);
-                    $this->log(3, "+ chmod $data[0] $data[1]");
+                    $octmode = decoct($data[0]);
+                    $this->log(3, "+ chmod $octmode $data[1]");
                     break;
                 case 'delete':
                     @unlink($data[0]);
@@ -779,16 +784,45 @@ class PEAR_Installer extends PEAR_Common
 
     function checkDeps(&$pkginfo)
     {
-        $deps = &new PEAR_Dependency($this->registry);
-        $errors = null;
+        $depchecker = &new PEAR_Dependency($this->registry);
+        $error = $errors = '';
+        $failed_deps = array();
         if (is_array($pkginfo['release_deps'])) {
             foreach($pkginfo['release_deps'] as $dep) {
-                if ($error = $deps->callCheckMethod($dep)) {
-                    $errors .= "\n$error";
+                $code = $depchecker->callCheckMethod($error, $dep);
+                if ($code) {
+                    $failed_deps[] = array($dep, $code, $error);
                 }
             }
-            if ($errors) {
-                return $errors;
+            $n = count($failed_deps);
+            if ($n > 0) {
+                $depinstaller =& new PEAR_Installer($this->ui);
+                $to_install = array();
+                for ($i = 0; $i < $n; $i++) {
+                    if (isset($failed_deps[$i]['type'])) {
+                        $type = $failed_deps[$i]['type'];
+                    } else {
+                        $type = 'pkg';
+                    }
+                    switch ($failed_deps[$i][1]) {
+                        case PEAR_DEPENDENCY_MISSING:
+                            if ($type == 'pkg') {
+                                // install
+                            }
+                            $errors .= "\n" . $failed_deps[$i][2];
+                            break;
+                        case PEAR_DEPENDENCY_UPGRADE_MINOR:
+                            if ($type == 'pkg') {
+                                // upgrade
+                            }
+                            $errors .= "\n" . $failed_deps[$i][2];
+                            break;
+                        default:
+                            $errors .= "\n" . $failed_deps[$i][2];
+                            break;
+                    }
+                }
+                return substr($errors, 1);
             }
         }
         return false;