mirror of
https://github.com/php/php-src.git
synced 2024-11-28 20:34:29 +08:00
Added error codes for the PEAR_Dependency class
Changed the dependency API to have a reference to an error message string as first arg to all check methods
This commit is contained in:
parent
5ca953b10f
commit
40ac4a2d68
@ -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();
|
||||
|
@ -27,6 +27,12 @@
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user