Update to PEAR 1.7.2, Image_Canvas 0.3.1, Image_Color 1.0.3, Image_Graph 0.7.2, XML_Parser 1.3.1.

Removed PHP_Compat, and references to it.
Removed ionCube/Zend/mmCache compatibility checks in test.php script.
Changed minimum PHP requirement to 5.0 in test.php script.
This commit is contained in:
anubis
2009-01-04 19:22:54 -05:00
parent 60b674c776
commit fae6352bf2
384 changed files with 34150 additions and 44524 deletions

View File

@@ -14,9 +14,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Auth.php,v 1.21 2005/04/13 04:29:15 cellog Exp $
* @version CVS: $Id: Auth.php,v 1.31 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -34,9 +34,9 @@ require_once 'PEAR/Config.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -50,8 +50,9 @@ class PEAR_Command_Auth extends PEAR_Command_Common
'shortcut' => 'li',
'function' => 'doLogin',
'options' => array(),
'doc' => '
Log in to the remote server. To use remote functions in the installer
'doc' => '<channel name>
Log in to a remote channel server. If <channel name> is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging
@@ -106,13 +107,23 @@ password from your user configuration.',
function doLogin($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
// If a parameter is supplied, use that as the channel to log in to
if (isset($params[0])) {
$channel = $params[0];
} else {
$channel = $this->config->get('default_channel');
}
$chan = $reg->getChannel($channel);
$server = $this->config->get('preferred_mirror');
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror', null, $channel);
$remote = &$this->config->getRemote();
$username = $this->config->get('username');
$username = $this->config->get('username', null, $channel);
if (empty($username)) {
$username = @$_ENV['USER'];
$username = isset($_ENV['USER']) ? $_ENV['USER'] : null;
}
$this->ui->outputData("Logging in to $server.", $command);
@@ -124,9 +135,14 @@ password from your user configuration.',
);
$username = trim($username);
$password = trim($password);
$this->config->set('username', $username);
$this->config->set('password', $password);
$ourfile = $this->config->getConfFile('user');
if (!$ourfile) {
$ourfile = $this->config->getConfFile('system');
}
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
if ($chan->supportsREST()) {
$ok = true;
@@ -137,7 +153,11 @@ password from your user configuration.',
}
if ($ok === true) {
$this->ui->outputData("Logged in.", $command);
$this->config->store();
// avoid changing any temporary settings changed with -d
$ourconfig = new PEAR_Config($ourfile, $ourfile);
$ourconfig->set('username', $username, 'user', $channel);
$ourconfig->set('password', $password, 'user', $channel);
$ourconfig->store();
} else {
return $this->raiseError("Login failed!");
}
@@ -166,6 +186,9 @@ password from your user configuration.',
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror');
$this->ui->outputData("Logging out from $server.", $command);
$this->config->remove('username');

View File

@@ -4,8 +4,9 @@
<shortcut>li</shortcut>
<function>doLogin</function>
<options />
<doc>
Log in to the remote server. To use remote functions in the installer
<doc>&lt;channel name&gt;
Log in to a remote channel server. &lt;channel name&gt; is not supplied,
the default channel is used. To use remote functions in the installer
that require any kind of privileges, you need to log in first. The
username and password you enter here will be stored in your per-user
PEAR configuration (~/.pearrc on Unix-like systems). After logging

View File

@@ -15,9 +15,9 @@
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Build.php,v 1.12 2005/04/13 04:29:36 cellog Exp $
* @version CVS: $Id: Build.php,v 1.14 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -35,9 +35,9 @@ require_once 'PEAR/Command/Common.php';
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/

View File

@@ -16,9 +16,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Channels.php,v 1.42 2005/05/11 19:44:16 cellog Exp $
* @version CVS: $Id: Channels.php,v 1.57 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
@@ -34,9 +34,9 @@ require_once 'PEAR/Command/Common.php';
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
@@ -132,8 +132,13 @@ alias.
'function' => 'doDiscover',
'shortcut' => 'di',
'options' => array(),
'doc' => '<package>
List the files in an installed package.
'doc' => '[<channel.xml>|<channel name>]
Initialize a channel from its server and create a local channel.xml.
If <channel name> is in the format "<username>:<password>@<channel>" then
<username> and <password> will be set as the login username/password for
<channel>. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system\'s process list.
'
),
);
@@ -185,133 +190,24 @@ List the files in an installed package.
function doUpdateAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$savechannel = $this->config->get('default_channel');
if (isset($options['channel'])) {
if (!$reg->channelExists($options['channel'])) {
return $this->raiseError('Unknown channel "' . $options['channel'] . '"');
}
$this->config->set('default_channel', $options['channel']);
} else {
$this->config->set('default_channel', 'pear.php.net');
}
$remote = &$this->config->getRemote();
$channels = $remote->call('channel.listAll');
if (PEAR::isError($channels)) {
$this->config->set('default_channel', $savechannel);
return $channels;
}
if (!is_array($channels) || isset($channels['faultCode'])) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError("Incorrect channel listing returned from channel '$chan'");
}
if (!count($channels)) {
$data = 'no updates available';
}
$dl = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
$channels = $reg->getChannels();
$success = true;
foreach ($channels as $channel) {
$channel = $channel[0];
$save = $channel;
if ($reg->channelExists($channel, true)) {
$this->ui->outputData("Updating channel \"$channel\"", $command);
$test = $reg->getChannel($channel, true);
if (!$test) {
$this->ui->outputData("Channel '$channel' is corrupt in registry!", $command);
$lastmodified = false;
if ($channel->getName() != '__uri') {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doUpdate('channel-update',
$options,
array($channel->getName()));
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
$success = false;
} else {
$lastmodified = $test->lastModified();
$success &= $err;
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $test->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$test->getName() . '"', $command);
continue;
}
if (!$contents) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!$info) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_ChannelFile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\" " .
'is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . ' from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->updateChannel($channel, $lastmodified);
} else {
if ($reg->isAlias($channel)) {
$temp = &$reg->getChannel($channel);
$temp->setAlias($temp->getName(), true); // set the alias to the channel name
if ($reg->channelExists($temp->getName())) {
$this->ui->outputData('ERROR: existing channel "' . $temp->getName() .
'" is aliased to "' . $channel . '" already and cannot be ' .
're-aliased to "' . $temp->getName() . '" because a channel with ' .
'that name or alias already exists! Please re-alias and try ' .
'again.', $command);
continue;
}
}
$this->ui->outputData("Adding new channel \"$channel\"", $command);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $channel . '/channel.xml',
$this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$channel . '"', $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_Channelfile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\"" .
' is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . '" from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->addChannel($channel, $lastmodified);
}
}
$this->config->set('default_channel', $savechannel);
$this->ui->outputData('update-channels complete', $command);
return true;
return $success;
}
function doInfo($command, $options, $params)
@@ -323,29 +219,30 @@ List the files in an installed package.
$channel = strtolower($params[0]);
if ($reg->channelExists($channel)) {
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
} else {
if (strpos($channel, '://')) {
$downloader = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
$tmpdir = $this->config->get('temp_dir');
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('Cannot open "' . $channel . '"');
return $this->raiseError('Cannot open "' . $channel .
'" (' . $loc->getMessage() . ')');
} else {
$contents = implode('', file($loc));
}
} else {
$fp = @fopen($params[0], 'r');
if (!$fp) {
if (@file_exists($params[0])) {
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
if (!$fp) {
return $this->raiseError('Cannot open "' . $params[0] . '"');
} else {
return $this->raiseError('Unknown channel "' . $channel . '"');
}
} else {
return $this->raiseError('Unknown channel "' . $channel . '"');
}
$contents = '';
while (!feof($fp)) {
@@ -431,7 +328,7 @@ List the files in an installed package.
$data['data'][] = array($mirror['attribs']['host']);
$d['mirrors'] = $data;
}
foreach ($mirrors as $mirror) {
foreach ($mirrors as $i => $mirror) {
$data['data'] = array();
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
@@ -469,7 +366,7 @@ List the files in an installed package.
} else {
$data['data'][] = array('No supported protocols');
}
$d['mirrorprotocols'] = $data;
$d['mirrorprotocols' . $i] = $data;
}
}
$this->ui->outputData($d, 'channel-info');
@@ -522,22 +419,38 @@ List the files in an installed package.
}
if (strpos($params[0], '://')) {
$downloader = &$this->getDownloader();
if (!class_exists('System')) {
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
$tmpdir = System::mktemp(array('-d'));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError('channel-add: Cannot open "' . $params[0] . '"');
return $this->raiseError('channel-add: Cannot open "' . $params[0] .
'" (' . $loc->getMessage() . ')');
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
} else {
$lastmodified = false;
$fp = @fopen($params[0], 'r');
$lastmodified = $fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError('channel-add: cannot open "' . $params[0] . '"');
}
@@ -588,10 +501,23 @@ List the files in an installed package.
function doUpdate($command, $options, $params)
{
if (!class_exists('System')) {
$tmpdir = $this->config->get('temp_dir');
if (!file_exists($tmpdir)) {
require_once 'System.php';
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = System::mkdir(array('-p', $tmpdir));
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError('channel-add: temp_dir does not exist: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
}
if (!is_writable($tmpdir)) {
return $this->raiseError('channel-add: temp_dir is not writable: "' .
$tmpdir .
'" - You can change this location with "pear config-set temp_dir"');
}
$tmpdir = System::mktemp(array('-d'));
$reg = &$this->config->getRegistry();
if (sizeof($params) != 1) {
return $this->raiseError("No channel file specified");
@@ -600,7 +526,10 @@ List the files in an installed package.
if ((!file_exists($params[0]) || is_dir($params[0]))
&& $reg->channelExists(strtolower($params[0]))) {
$c = $reg->getChannel(strtolower($params[0]));
$this->ui->outputData('Retrieving channel.xml from remote server');
if (PEAR::isError($c)) {
return $this->raiseError($c);
}
$this->ui->outputData("Updating channel \"$params[0]\"", $command);
$dl = &$this->getDownloader(array());
// if force is specified, use a timestamp of "1" to force retrieval
$lastmodified = isset($options['force']) ? false : $c->lastModified();
@@ -610,11 +539,11 @@ List the files in an installed package.
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
return $this->raiseError('Cannot retrieve channel.xml for channel "' .
$c->getName() . '"');
$c->getName() . '" (' . $contents->getMessage() . ')');
}
list($contents, $lastmodified) = $contents;
if (!$contents) {
$this->ui->outputData("Channel $params[0] channel.xml is up to date");
$this->ui->outputData("Channel \"$params[0]\" is up to date");
return;
}
$contents = implode('', file($contents));
@@ -645,13 +574,17 @@ List the files in an installed package.
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError("Cannot open " . $params[0]);
return $this->raiseError("Cannot open " . $params[0] .
' (' . $loc->getMessage() . ')');
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
} else {
$fp = @fopen($params[0], 'r');
$fp = false;
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
}
if (!$fp) {
return $this->raiseError("Cannot open " . $params[0]);
}
@@ -729,9 +662,9 @@ List the files in an installed package.
'already aliased to "' . strtolower($params[1]) . '", cannot re-alias');
}
$chan = &$reg->getChannel($params[0]);
if (!$chan) {
if (PEAR::isError($chan)) {
return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] .
'" information');
'" information (' . $chan->getMessage() . ')');
}
// make it a local alias
if (!$chan->setAlias(strtolower($params[1]), true)) {
@@ -743,28 +676,62 @@ List the files in an installed package.
strtolower($params[1]) . '"');
}
/**
* The channel-discover command
*
* @param string $command command name
* @param array $options option_name => value
* @param array $params list of additional parameters.
* $params[0] should contain a string with either:
* - <channel name> or
* - <username>:<password>@<channel name>
* @return null|PEAR_Error
*/
function doDiscover($command, $options, $params)
{
$reg = &$this->config->getRegistry();
if (sizeof($params) != 1) {
return $this->raiseError("No channel server specified");
}
if ($reg->channelExists($params[0])) {
if ($reg->isAlias($params[0])) {
return $this->raiseError("A channel alias named \"$params[0]\" " .
'already exists, aliasing channel "' . $reg->channelName($params[0])
// Look for the possible input format "<username>:<password>@<channel>"
if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) {
$username = $matches[1];
$password = $matches[2];
$channel = $matches[3];
} else {
$channel = $params[0];
}
if ($reg->channelExists($channel)) {
if ($reg->isAlias($channel)) {
return $this->raiseError("A channel alias named \"$channel\" " .
'already exists, aliasing channel "' . $reg->channelName($channel)
. '"');
} else {
return $this->raiseError("Channel \"$params[0]\" is already initialized");
return $this->raiseError("Channel \"$channel\" is already initialized");
}
}
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->doAdd($command, $options, array('http://' . $params[0] . '/channel.xml'));
$err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml'));
$this->popErrorHandling();
if (PEAR::isError($err)) {
return $this->raiseError("Discovery of channel \"$params[0]\" failed");
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
$err->getMessage() . ')');
}
$this->ui->outputData("Discovery of channel \"$params[0]\" succeeded", $command);
// Store username/password if they were given
// Arguably we should do a logintest on the channel here, but since
// that's awkward on a REST-based channel (even "pear login" doesn't
// do it for those), and XML-RPC is deprecated, it's fairly pointless.
if (isset($username)) {
$this->config->set('username', $username, 'user', $channel);
$this->config->set('password', $password, 'user', $channel);
$this->config->store();
$this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command);
}
$this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command);
}
}
?>

View File

@@ -86,8 +86,13 @@ alias.
<function>doDiscover</function>
<shortcut>di</shortcut>
<options />
<doc>&lt;package&gt;
List the files in an installed package.
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Initialize a channel from its server and create a local channel.xml.
If &lt;channel name&gt; is in the format &quot;&lt;username&gt;:&lt;password&gt;@&lt;channel&gt;&quot; then
&lt;username&gt; and &lt;password&gt; will be set as the login username/password for
&lt;channel&gt;. Use caution when passing the username/password in this way, as
it may allow other users on your computer to briefly view your username/
password via the system's process list.
</doc>
</channel-discover>
</commands>
</commands>

View File

@@ -14,9 +14,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.29 2005/04/13 04:29:58 cellog Exp $
* @version CVS: $Id: Common.php,v 1.36 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -33,9 +33,9 @@ require_once 'PEAR.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -74,7 +74,7 @@ class PEAR_Command_Common extends PEAR
var $_deps_type_trans = array(
'pkg' => 'package',
'extension' => 'extension',
'ext' => 'extension',
'php' => 'PHP',
'prog' => 'external program',
'ldlib' => 'external library for linking',
@@ -145,7 +145,12 @@ class PEAR_Command_Common extends PEAR
if (isset($shortcuts[$command])) {
$command = $shortcuts[$command];
}
return @$this->commands[$command]['options'];
if (isset($this->commands[$command]) &&
isset($this->commands[$command]['options'])) {
return $this->commands[$command]['options'];
} else {
return null;
}
}
// }}}
@@ -192,12 +197,19 @@ class PEAR_Command_Common extends PEAR
function getHelp($command)
{
$config = &PEAR_Config::singleton();
$help = @$this->commands[$command]['doc'];
if (!isset($this->commands[$command])) {
return "No such command \"$command\"";
}
$help = null;
if (isset($this->commands[$command]['doc'])) {
$help = $this->commands[$command]['doc'];
}
if (empty($help)) {
// XXX (cox) Fallback to summary if there is no doc (show both?)
if (!$help = @$this->commands[$command]['summary']) {
if (!isset($this->commands[$command]['summary'])) {
return "No help for command \"$command\"";
}
$help = $this->commands[$command]['summary'];
}
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
foreach($matches[0] as $k => $v) {
@@ -223,7 +235,7 @@ class PEAR_Command_Common extends PEAR
$help = "Options:\n";
foreach ($this->commands[$command]['options'] as $k => $v) {
if (isset($v['arg'])) {
if ($v['arg']{0} == '(') {
if ($v['arg'][0] == '(') {
$arg = substr($v['arg'], 1, -1);
$sapp = " [$arg]";
$lapp = "[=$arg]";
@@ -236,9 +248,9 @@ class PEAR_Command_Common extends PEAR
}
if (isset($v['shortopt'])) {
$s = $v['shortopt'];
@$help .= " -$s$sapp, --$k$lapp\n";
$help .= " -$s$sapp, --$k$lapp\n";
} else {
@$help .= " --$k$lapp\n";
$help .= " --$k$lapp\n";
}
$p = " ";
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
@@ -254,19 +266,21 @@ class PEAR_Command_Common extends PEAR
function run($command, $options, $params)
{
$func = @$this->commands[$command]['function'];
if (empty($func)) {
if (empty($this->commands[$command]['function'])) {
// look for shortcuts
foreach (array_keys($this->commands) as $cmd) {
if (@$this->commands[$cmd]['shortcut'] == $command) {
$command = $cmd;
$func = @$this->commands[$command]['function'];
if (empty($func)) {
if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) {
if (empty($this->commands[$cmd]['function'])) {
return $this->raiseError("unknown command `$command'");
} else {
$func = $this->commands[$cmd]['function'];
}
$command = $cmd;
break;
}
}
} else {
$func = $this->commands[$command]['function'];
}
return $this->$func($command, $options, $params);
}
@@ -274,4 +288,4 @@ class PEAR_Command_Common extends PEAR
// }}}
}
?>
?>

View File

@@ -14,9 +14,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Config.php,v 1.48 2005/09/24 04:25:33 cellog Exp $
* @version CVS: $Id: Config.php,v 1.56 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -33,9 +33,9 @@ require_once 'PEAR/Command/Common.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -155,8 +155,14 @@ and uninstall).
function doConfigShow($command, $options, $params)
{
if (is_array($params)) {
$layer = isset($params[0]) ? $params[0] : NULL;
} else {
$layer = NULL;
}
// $params[0] -> the layer
if ($error = $this->_checkLayer(@$params[0])) {
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-show:$error");
}
$keys = $this->config->getKeys();
@@ -170,7 +176,7 @@ and uninstall).
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
foreach ($keys as $key) {
$type = $this->config->getType($key);
$value = $this->config->get($key, @$params[0], $channel);
$value = $this->config->get($key, $layer, $channel);
if ($type == 'password' && $value) {
$value = '********';
}
@@ -184,7 +190,7 @@ and uninstall).
foreach ($this->config->getLayers() as $layer) {
$data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer));
}
$this->ui->outputData($data, $command);
return true;
}
@@ -194,27 +200,38 @@ and uninstall).
function doConfigGet($command, $options, $params)
{
// $params[0] -> the parameter
// $params[1] -> the layer
if ($error = $this->_checkLayer(@$params[1])) {
return $this->raiseError("config-get:$error");
if (!is_array($params)) {
$args_cnt = 0;
} else {
$args_cnt = count($params);
}
$channel = isset($options['channel']) ? $options['channel'] :
$this->config->get('default_channel');
switch ($args_cnt) {
case 1:
$config_key = $params[0];
$layer = NULL;
break;
case 2:
$config_key = $params[0];
$layer = $params[1];
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-get:$error");
}
break;
case 0:
default:
return $this->raiseError("config-get expects 1 or 2 parameters");
}
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
if (sizeof($params) < 1 || sizeof($params) > 2) {
return $this->raiseError("config-get expects 1 or 2 parameters");
} else {
if (count($params) == 1) {
$layer = null;
} else {
$layer = $params[1];
}
$this->ui->outputData($this->config->get($params[0], $layer, $channel), $command);
}
$this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
return true;
}
@@ -231,7 +248,7 @@ and uninstall).
$failmsg .= "config-set expects 2 or 3 parameters";
return PEAR::raiseError($failmsg);
}
if ($error = $this->_checkLayer(@$params[2])) {
if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
$failmsg .= $error;
return PEAR::raiseError("config-set:$failmsg");
}
@@ -333,10 +350,14 @@ and uninstall).
$config->noRegistry();
$config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user');
$config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data");
$config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www");
$config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg");
$config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext");
$config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs");
$config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests");
$config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache");
$config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download");
$config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp");
$config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
$config->writeConfigFile();
$this->_showConfig($config);
@@ -372,7 +393,7 @@ and uninstall).
array(ucfirst($layer) . ' Configuration File', 'Filename' ,
$config->getConfFile($layer));
}
$this->ui->outputData($data, 'config-show');
return true;
}

View File

@@ -14,9 +14,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Install.php,v 1.109 2005/10/26 19:37:14 cellog Exp $
* @version CVS: $Id: Install.php,v 1.141 2008/05/13 18:32:29 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -34,9 +34,9 @@ require_once 'PEAR/Command/Common.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -81,7 +81,12 @@ class PEAR_Command_Install extends PEAR_Command_Common
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'packagingroot' => array(
'shortopt' => 'P',
'arg' => 'DIR',
'doc' => 'root directory used when packaging files, like RPM packaging',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
@@ -196,7 +201,7 @@ More than one package may be specified at once.
'),
'upgrade-all' => array(
'summary' => 'Upgrade All Packages',
'function' => 'doInstall',
'function' => 'doUpgradeAll',
'shortcut' => 'ua',
'options' => array(
'nodeps' => array(
@@ -218,7 +223,7 @@ More than one package may be specified at once.
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
@@ -333,77 +338,302 @@ Run post-installation scripts in package <package>, if any exist.
return $a;
}
function enableExtension($binaries, $type)
{
if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
}
$ini = $this->_parseIni($phpini);
if (PEAR::isError($ini)) {
return $ini;
}
$line = 0;
if ($type == 'extsrc' || $type == 'extbin') {
$search = 'extensions';
$enable = 'extension';
} else {
$search = 'zend_extensions';
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
foreach ($ini[$search] as $line => $extension) {
if (in_array($extension, $binaries, true) || in_array(
$ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
// already enabled - assume if one is, all are
return true;
}
}
if ($line) {
$newini = array_slice($ini['all'], 0, $line);
} else {
$newini = array();
}
foreach ($binaries as $binary) {
if ($ini['extension_dir']) {
$binary = basename($binary);
}
$newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n");
}
$newini = array_merge($newini, array_slice($ini['all'], $line));
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
foreach ($newini as $line) {
fwrite($fp, $line);
}
fclose($fp);
return true;
}
function disableExtension($binaries, $type)
{
if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) {
return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location');
}
$ini = $this->_parseIni($phpini);
if (PEAR::isError($ini)) {
return $ini;
}
$line = 0;
if ($type == 'extsrc' || $type == 'extbin') {
$search = 'extensions';
$enable = 'extension';
} else {
$search = 'zend_extensions';
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
$found = false;
foreach ($ini[$search] as $line => $extension) {
if (in_array($extension, $binaries, true) || in_array(
$ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) {
$found = true;
break;
}
}
if (!$found) {
// not enabled
return true;
}
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
if ($line) {
$newini = array_slice($ini['all'], 0, $line);
// delete the enable line
$newini = array_merge($newini, array_slice($ini['all'], $line + 1));
} else {
$newini = array_slice($ini['all'], 1);
}
foreach ($newini as $line) {
fwrite($fp, $line);
}
fclose($fp);
return true;
}
function _parseIni($filename)
{
if (file_exists($filename)) {
if (filesize($filename) > 300000) {
return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
}
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$zend_extension_line = 'zend_extension' . $debug . $ts;
$all = @file($filename);
if (!$all) {
return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
}
$zend_extensions = $extensions = array();
// assume this is right, but pull from the php.ini if it is found
$extension_dir = ini_get('extension_dir');
foreach ($all as $linenum => $line) {
$line = trim($line);
if (!$line) {
continue;
}
if ($line[0] == ';') {
continue;
}
if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
$line = trim(substr($line, 13));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extension_dir = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, 9)) == 'extension') {
$line = trim(substr($line, 9));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
$zend_extension_line) {
$line = trim(substr($line, strlen($zend_extension_line)));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
}
return array(
'extensions' => $extensions,
'zend_extensions' => $zend_extensions,
'extension_dir' => $extension_dir,
'all' => $all,
);
} else {
return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
}
}
// {{{ doInstall()
function doInstall($command, $options, $params)
{
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
if ($command == 'upgrade') {
if ($command == 'upgrade' || $command == 'upgrade-all') {
$options['upgrade'] = true;
} else {
$packages = $params;
}
if (isset($options['installroot']) && isset($options['packagingroot'])) {
return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
}
$reg = &$this->config->getRegistry();
if ($command == 'upgrade-all') {
$options['upgrade'] = true;
$reg = &$this->config->getRegistry();
$savechannel = $this->config->get('default_channel');
$params = array();
foreach ($reg->listChannels() as $channel) {
if ($channel == '__uri') {
$instreg = &$reg; // instreg used to check if package is installed
if (isset($options['packagingroot']) && !isset($options['upgrade'])) {
$packrootphp_dir = $this->installer->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$options['packagingroot']);
$instreg = new PEAR_Registry($packrootphp_dir); // other instreg!
if ($this->config->get('verbose') > 2) {
$this->ui->outputData('using package root: ' . $options['packagingroot']);
}
}
$abstractpackages = array();
$otherpackages = array();
// parse params
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach($params as $param) {
if (strpos($param, 'http://') === 0) {
$otherpackages[] = $param;
continue;
}
if (strpos($param, 'channel://') === false && @file_exists($param)) {
if (isset($options['force'])) {
$otherpackages[] = $param;
continue;
}
$this->config->set('default_channel', $channel);
$chan = &$reg->getChannel($channel);
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$dorest = true;
unset($remote);
} else {
$dorest = false;
$remote = &$this->config->getRemote($this->config);
}
$state = $this->config->get('preferred_state');
$installed = array_flip($reg->listPackages($channel));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if ($dorest) {
$rest = &$this->config->getREST('1.0', array());
$latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
} else {
if (empty($state) || $state == 'any') {
$latest = $remote->call("package.listLatestReleases");
} else {
$latest = $remote->call("package.listLatestReleases", $state);
}
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest) || !is_array($latest)) {
$pkg = new PEAR_PackageFile($this->config);
$pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING);
if (PEAR::isError($pf)) {
$otherpackages[] = $param;
continue;
}
foreach ($latest as $package => $info) {
$package = strtolower($package);
if (!isset($installed[$package])) {
// skip packages we don't have installed
if ($reg->packageExists($pf->getPackage(), $pf->getChannel()) &&
version_compare($pf->getVersion(),
$reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()),
'<=')) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString(
array('package' => $pf->getPackage(),
'channel' => $pf->getChannel()), true));
}
continue;
}
$otherpackages[] = $param;
continue;
}
$e = $reg->parsePackageName($param, $this->config->get('default_channel'));
if (PEAR::isError($e)) {
$otherpackages[] = $param;
} else {
$abstractpackages[] = $e;
}
}
PEAR::staticPopErrorHandling();
// if there are any local package .tgz or remote static url, we can't
// filter. The filter only works for abstract packages
if (count($abstractpackages) && !isset($options['force'])) {
// when not being forced, only do necessary upgrades/installs
if (isset($options['upgrade'])) {
$abstractpackages = $this->_filterUptodatePackages($abstractpackages,
$command);
} else {
foreach ($abstractpackages as $i => $package) {
if (isset($package['group'])) {
// do not filter out install groups
continue;
}
$inst_version = $reg->packageInfo($package, 'version', $channel);
if (version_compare("$info[version]", "$inst_version", "le")) {
// installed version is up-to-date
continue;
if ($instreg->packageExists($package['package'], $package['channel'])) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString($package, true));
}
unset($abstractpackages[$i]);
}
$params[] = $reg->parsedPackageNameToString(array('package' => $package,
'channel' => $channel));
$this->ui->outputData(array('data' => "Will upgrade $package"), $command);
}
}
$this->config->set('default_channel', $savechannel);
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
} elseif (count($abstractpackages)) {
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
}
$packages = array_merge($abstractpackages, $otherpackages);
if (!count($packages)) {
$this->ui->outputData('Nothing to ' . $command);
return true;
}
$this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
$errors = array();
$binaries = array();
$downloaded = array();
$downloaded = &$this->downloader->download($params);
$downloaded = &$this->downloader->download($packages);
if (PEAR::isError($downloaded)) {
return $this->raiseError($downloaded);
}
$errors = $this->downloader->getErrorMsgs();
if (count($errors)) {
$err = array();
$err['data'] = array();
foreach ($errors as $error) {
$err['data'][] = array($error);
}
@@ -430,6 +660,7 @@ Run post-installation scripts in package <package>, if any exist.
return true;
}
$extrainfo = array();
$binaries = array();
foreach ($downloaded as $param) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->install($param, $options);
@@ -450,13 +681,16 @@ Run post-installation scripts in package <package>, if any exist.
}
if (is_array($info)) {
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin') {
$param->getPackageType() == 'extbin' ||
$param->getPackageType() == 'zendextsrc' ||
$param->getPackageType() == 'zendextbin') {
$pkg = &$param->getPackageFile();
if ($instbin = $pkg->getInstalledBinary()) {
$instpkg = &$reg->getPackage($instbin, $pkg->getChannel());
$instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
} else {
$instpkg = &$reg->getPackage($pkg->getPackage(), $pkg->getChannel());
$instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
}
foreach ($instpkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
@@ -469,11 +703,37 @@ Run post-installation scripts in package <package>, if any exist.
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$extrainfo[] = 'You should add "extension=' . $pinfo['basename']
. '" to php.ini';
$binaries[] = array($atts['installed_as'], $pinfo);
break;
}
}
if (count($binaries)) {
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$extrainfo[] = 'You should add "' . $exttype . '=' .
$pinfo[1]['basename'] . '" to php.ini';
} else {
$extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
' enabled in php.ini';
}
}
}
}
if ($this->config->get('verbose') > 0) {
$channel = $param->getChannel();
@@ -515,28 +775,33 @@ Run post-installation scripts in package <package>, if any exist.
// explicitly chooses to install another group
continue;
}
$this->ui->outputData($param->getPackage() . ': Optional feature ' .
$extrainfo[] = $param->getPackage() . ': Optional feature ' .
$group['attribs']['name'] . ' available (' .
$group['attribs']['hint'] . ')');
$group['attribs']['hint'] . ')';
}
$extrainfo[] = 'To install use "pear install ' .
$param->getPackage() . '#featurename"';
$extrainfo[] = $param->getPackage() .
': To install optional features use "pear install ' .
$reg->parsedPackageNameToString(
array('package' => $param->getPackage(),
'channel' => $param->getChannel()), true) .
'#featurename"';
}
}
if (isset($options['installroot'])) {
$reg = &$this->config->getRegistry();
}
$pkg = &$reg->getPackage($param->getPackage(), $param->getChannel());
$pkg->setConfig($this->config);
if ($list = $pkg->listPostinstallScripts()) {
$pn = $reg->parsedPackageNameToString(array('channel' =>
$param->getChannel(), 'package' => $param->getPackage()), true);
$extrainfo[] = $pn . ' has post-install scripts:';
foreach ($list as $file) {
$extrainfo[] = $file;
$pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
// $pkg may be NULL if install is a 'fake' install via --packagingroot
if (is_object($pkg)) {
$pkg->setConfig($this->config);
if ($list = $pkg->listPostinstallScripts()) {
$pn = $reg->parsedPackageNameToString(array('channel' =>
$param->getChannel(), 'package' => $param->getPackage()), true);
$extrainfo[] = $pn . ' has post-install scripts:';
foreach ($list as $file) {
$extrainfo[] = $file;
}
$extrainfo[] = $param->getPackage() .
': Use "pear run-scripts ' . $pn . '" to finish setup.';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
$extrainfo[] = 'Use "pear run-scripts ' . $pn . '" to run';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
} else {
return $this->raiseError("$command failed");
@@ -550,6 +815,33 @@ Run post-installation scripts in package <package>, if any exist.
return true;
}
// }}}
// {{{ doUpgradeAll()
function doUpgradeAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$toUpgrade = array();
foreach ($reg->listChannels() as $channel) {
if ($channel == '__uri') {
continue;
}
// parse name with channel
foreach ($reg->listPackages($channel) as $name) {
$toUpgrade[] = $reg->parsedPackageNameToString(array(
'channel' => $channel,
'package' => $name
));
}
}
$err = $this->doInstall('upgrade-all', $options, $toUpgrade);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
}
}
// }}}
// {{{ doUninstall()
@@ -569,6 +861,7 @@ Run post-installation scripts in package <package>, if any exist.
}
$reg = &$this->config->getRegistry();
$newparams = array();
$binaries = array();
$badparams = array();
foreach ($params as $pkg) {
$channel = $this->config->get('default_channel');
@@ -607,7 +900,7 @@ Run post-installation scripts in package <package>, if any exist.
if (isset($parsed['group'])) {
$group = $info->getDependencyGroup($parsed['group']);
if ($group) {
$installed = &$reg->getInstalledGroup($group);
$installed = $reg->getInstalledGroup($group);
if ($installed) {
foreach ($installed as $i => $p) {
$newparams[] = &$installed[$i];
@@ -627,6 +920,7 @@ Run post-installation scripts in package <package>, if any exist.
// for circular dependencies like subpackages
$this->installer->setUninstallPackages($newparams);
$params = array_merge($params, $badparams);
$binaries = array();
foreach ($params as $pkg) {
$this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
if ($err = $this->installer->uninstall($pkg, $options)) {
@@ -635,6 +929,58 @@ Run post-installation scripts in package <package>, if any exist.
$this->ui->outputData($err->getMessage(), $command);
continue;
}
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin' ||
$pkg->getPackageType() == 'zendextsrc' ||
$pkg->getPackageType() == 'zendextbin') {
if ($instbin = $pkg->getInstalledBinary()) {
continue; // this will be uninstalled later
}
foreach ($pkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
in_array($pinfo['extension'], array('c', 'h'))) {
continue; // make sure we don't match php_blah.h
}
if ((strpos($pinfo['basename'], 'php_') === 0 &&
$pinfo['extension'] == 'dll') ||
// most unices
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$binaries[] = array($atts['installed_as'], $pinfo);
break;
}
}
if (count($binaries)) {
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$this->ui->outputData('Unable to remove "' . $exttype . '=' .
$pinfo[1]['basename'] . '" from php.ini', $command);
} else {
$this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
' disabled in php.ini', $command);
}
}
}
}
$savepkg = $pkg;
if ($this->config->get('verbose') > 0) {
if (is_object($pkg)) {
@@ -680,7 +1026,7 @@ Run post-installation scripts in package <package>, if any exist.
function doBundle($command, $options, $params)
{
$downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true,
'soft' => true), $this->config);
'soft' => true, 'downloadonly' => true), $this->config);
$reg = &$this->config->getRegistry();
if (sizeof($params) < 1) {
return $this->raiseError("Please supply the package you want to bundle");
@@ -699,11 +1045,20 @@ Run post-installation scripts in package <package>, if any exist.
$dest = $pwd;
}
}
$downloader->setDownloadDir($dest);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $downloader->setDownloadDir($dest);
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return PEAR::raiseError('download directory "' . $dest .
'" is not writeable.');
}
$result = &$downloader->download(array($params[0]));
if (PEAR::isError($result)) {
return $result;
}
if (!isset($result[0])) {
return $this->raiseError('unable to unpack ' . $params[0]);
}
$pkgfile = &$result[0]->getPackageFile();
$pkgname = $pkgfile->getName();
$pkgversion = $pkgfile->getVersion();
@@ -713,7 +1068,7 @@ Run post-installation scripts in package <package>, if any exist.
$orig = $pkgname . '-' . $pkgversion;
$tar = &new Archive_Tar($pkgfile->getArchiveFile());
if (!@$tar->extractModify($dest, $orig)) {
if (!$tar->extractModify($dest, $orig)) {
return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile());
}
$this->ui->outputData("Package ready at '$dest'");
@@ -744,5 +1099,90 @@ Run post-installation scripts in package <package>, if any exist.
$this->ui->outputData('Install scripts complete', $command);
return true;
}
/**
* Given a list of packages, filter out those ones that are already up to date
*
* @param $packages: packages, in parsed array format !
* @return list of packages that can be upgraded
*/
function _filterUptodatePackages($packages, $command)
{
$reg = &$this->config->getRegistry();
$latestReleases = array();
$ret = array();
foreach($packages as $package) {
if (isset($package['group'])) {
$ret[] = $package;
continue;
}
$channel = $package['channel'];
$name = $package['package'];
if (!$reg->packageExists($name, $channel)) {
$ret[] = $package;
continue;
}
if (!isset($latestReleases[$channel])) {
// fill in cache for this channel
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
if ($chan->supportsREST($this->config->get('preferred_mirror',
null, $channel)) &&
$base = $chan->getBaseURL('REST1.0',
$this->config->get('preferred_mirror',
null, $channel)))
{
$dorest = true;
} else {
$dorest = false;
$remote = &$this->config->getRemote($this->config);
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if ($dorest) {
$rest = &$this->config->getREST('1.0', array());
$installed = array_flip($reg->listPackages($channel));
$latest = $rest->listLatestUpgrades($base,
$this->config->get('preferred_state', null, $channel), $installed,
$channel, $reg);
} else {
$latest = $remote->call("package.listLatestReleases",
$this->config->get('preferred_state', null, $channel));
unset($remote);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest)) {
$this->ui->outputData('Error getting channel info from ' . $channel .
': ' . $latest->getMessage());
continue;
}
$latestReleases[$channel] = array_change_key_case($latest);
}
// check package for latest release
if (isset($latestReleases[$channel][strtolower($name)])) {
// if not set, up to date
$inst_version = $reg->packageInfo($name, 'version', $channel);
$channel_version = $latestReleases[$channel][strtolower($name)]['version'];
if (version_compare($channel_version, $inst_version, "le")) {
// installed version is up-to-date
continue;
}
// maintain BC
if ($command == 'upgrade-all') {
$this->ui->outputData(array('data' => 'Will upgrade ' .
$reg->parsedPackageNameToString($package)), $command);
}
$ret[] = $package;
}
}
return $ret;
}
}
?>

View File

@@ -35,8 +35,13 @@
<installroot>
<shortopt>R</shortopt>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT), use packagingroot for RPM</doc>
</installroot>
<packagingroot>
<shortopt>P</shortopt>
<arg>DIR</arg>
<doc>root directory used when packaging files, like RPM packaging</doc>
</packagingroot>
<ignore-errors>
<doc>force install even if there were errors</doc>
</ignore-errors>

View File

@@ -13,9 +13,9 @@
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Mirror.php,v 1.15 2005/05/04 04:39:04 cellog Exp $
* @version CVS: $Id: Mirror.php,v 1.20 2008/04/11 01:16:40 dufuz Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.2.0
*/
@@ -31,9 +31,9 @@ require_once 'PEAR/Command/Common.php';
* @category pear
* @package PEAR
* @author Alexander Merz <alexmerz@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
@@ -98,7 +98,7 @@ packages within preferred_state ({config preferred_state}) will be downloaded'
* @param array $options the command options before the command
* @param array $params the stuff after the command name
* @return bool true if succesful
* @throw PEAR_Error
* @throw PEAR_Error
*/
function doDownloadAll($command, $options, $params)
{
@@ -113,10 +113,13 @@ packages within preferred_state ({config preferred_state}) will be downloaded'
$this->config->set('default_channel', $channel);
$this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$remoteInfo = array_flip($rest->listPackages($base));
$remoteInfo = array_flip($rest->listPackages($base, $channel));
} else {
$remote = &$this->config->getRemote();
$stable = ($this->config->get('preferred_state') == 'stable');
@@ -129,8 +132,11 @@ packages within preferred_state ({config preferred_state}) will be downloaded'
if (PEAR::isError($cmd)) {
return $cmd;
}
$this->ui->outputData('Using Preferred State of ' .
$this->config->get('preferred_state'));
$this->ui->outputData('Gathering release information, please wait...');
/**
* Error handling not necessary, because already done by
* Error handling not necessary, because already done by
* the download command
*/
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);

View File

@@ -16,9 +16,9 @@
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Package.php,v 1.114 2005/10/26 19:14:14 cellog Exp $
* @version CVS: $Id: Package.php,v 1.128 2008/03/29 21:06:58 dufuz Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -36,7 +36,7 @@ require_once 'PEAR/Command/Common.php';
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR
@@ -185,13 +185,18 @@ release), pass them as additional parameters.
'shortcut' => 'pd',
'options' => array(),
'doc' => '
List all depencies the package has.'
List all dependencies the package has.'
),
'sign' => array(
'summary' => 'Sign a package distribution file',
'function' => 'doSign',
'shortcut' => 'si',
'options' => array(),
'options' => array(
'verbose' => array(
'shortopt' => 'v',
'doc' => 'Display GnuPG output',
),
),
'doc' => '<package-file>
Signs a package distribution (.tar or .tgz) file with GnuPG.',
),
@@ -296,7 +301,7 @@ used for automated conversion or learning the format.
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR/PackageFile.php')) {
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
@@ -369,10 +374,9 @@ used for automated conversion or learning the format.
} else {
$valid = $info->validate(PEAR_VALIDATE_PACKAGING);
}
$err = array();
$warn = array();
if (!$valid) {
foreach ($info->getValidationWarnings() as $error) {
$err = $warn = array();
if ($errors = $info->getValidationWarnings()) {
foreach ($errors as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
@@ -511,8 +515,11 @@ used for automated conversion or learning the format.
$cmd .= ' diff';
// the rest of the options are passed right on to "cvs diff"
foreach ($options as $option => $optarg) {
$arg = @$this->commands[$command]['options'][$option]['arg'];
$short = @$this->commands[$command]['options'][$option]['shortopt'];
$arg = $short = false;
if (isset($this->commands[$command]['options'][$option])) {
$arg = $this->commands[$command]['options'][$option]['arg'];
$short = $this->commands[$command]['options'][$option]['shortopt'];
}
$cmd .= $short ? " -$short" : " --$option";
if ($arg && $optarg) {
$cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
@@ -689,10 +696,8 @@ used for automated conversion or learning the format.
}
$tar = new Archive_Tar($params[0]);
$tmpdir = System::mktemp('-d pearsign');
if (!$tar->extractList('package2.xml package.sig', $tmpdir)) {
if (!$tar->extractList('package.xml package.sig', $tmpdir)) {
return $this->raiseError("failed to extract tar file");
}
if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
return $this->raiseError("failed to extract tar file");
}
if (file_exists("$tmpdir/package.sig")) {
return $this->raiseError("package already signed");
@@ -701,11 +706,22 @@ used for automated conversion or learning the format.
if (file_exists("$tmpdir/package2.xml")) {
$packagexml = 'package2.xml';
}
@unlink("$tmpdir/package.sig");
if (file_exists("$tmpdir/package.sig")) {
unlink("$tmpdir/package.sig");
}
if (!file_exists("$tmpdir/$packagexml")) {
return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
}
$input = $this->ui->userDialog($command,
array('GnuPG Passphrase'),
array('password'));
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml 2>/dev/null", "w");
if (!isset($input[0])) {
//use empty passphrase
$input[0] = '';
}
$devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
if (!$gpg) {
return $this->raiseError("gpg command failed");
}
@@ -713,7 +729,11 @@ used for automated conversion or learning the format.
if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
return $this->raiseError("gpg sign failed");
}
$tar->addModify("$tmpdir/package.sig", '', $tmpdir);
if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
return $this->raiseError('failed adding signature to file');
}
$this->ui->outputData("Package signed.", $command);
return true;
}
@@ -731,355 +751,45 @@ used for automated conversion or learning the format.
return $a;
}
/**
* For unit testing purposes
*/
function &getCommandPackaging(&$ui, &$config)
{
if (!class_exists('PEAR_Command_Packaging')) {
if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
fclose($fp);
include_once 'PEAR/Command/Packaging.php';
}
}
if (class_exists('PEAR_Command_Packaging')) {
$a = &new PEAR_Command_Packaging($ui, $config);
} else {
$a = null;
}
return $a;
}
// {{{ doMakeRPM()
/*
(cox)
TODO:
- Fill the rpm dependencies in the template file.
IDEAS:
- Instead of mapping the role to rpm vars, perhaps it's better
to use directly the pear cmd to install the files by itself
in %postrun so:
pear -d php_dir=%{_libdir}/php/pear -d test_dir=.. <package>
*/
function doMakeRPM($command, $options, $params)
{
require_once 'System.php';
require_once 'Archive/Tar.php';
if (sizeof($params) != 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
if (!file_exists($params[0])) {
return $this->raiseError("file does not exist: $params[0]");
}
$reg = &$this->config->getRegistry();
$pkg = &$this->getPackageFile($this->config, $this->_debug);
$pf = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$u = $pf->getUserinfo();
if (is_array($u)) {
foreach ($u as $err) {
if (is_array($err)) {
$err = $err['message'];
}
$this->ui->outputData($err);
}
}
return $this->raiseError("$params[0] is not a valid package");
}
$tmpdir = System::mktemp(array('-d', 'pear2rpm'));
$instroot = System::mktemp(array('-d', 'pear2rpm'));
$tmp = $this->config->get('verbose');
$this->config->set('verbose', 0);
$installer = $this->getInstaller($this->ui);
require_once 'PEAR/Downloader/Package.php';
$pack = new PEAR_Downloader_Package($installer);
$pack->setPackageFile($pf);
$params[0] = &$pack;
$installer->setOptions(array('installroot' => $instroot,
'nodeps' => true, 'soft' => true));
$installer->setDownloadedPackages($params);
$info = $installer->install($params[0],
array('installroot' => $instroot,
'nodeps' => true, 'soft' => true));
$pkgdir = $pf->getPackage() . '-' . $pf->getVersion();
$info['rpm_xml_dir'] = '/var/lib/pear';
$this->config->set('verbose', $tmp);
if (isset($options['spec-template'])) {
$spec_template = $options['spec-template'];
} else {
$spec_template = '@DATA-DIR@/PEAR/template.spec';
}
$info['possible_channel'] = '';
$info['extra_config'] = '';
if (isset($options['rpm-pkgname'])) {
$rpm_pkgname_format = $options['rpm-pkgname'];
} else {
if ($pf->getChannel() == 'pear.php.net' || $pf->getChannel() == 'pecl.php.net') {
$alias = 'PEAR';
} else {
$chan = &$reg->getChannel($pf->getChannel());
$alias = $chan->getAlias();
$alias = strtoupper($alias);
$info['possible_channel'] = $pf->getChannel() . '/';
}
$rpm_pkgname_format = $alias . '::%s';
}
$info['extra_headers'] = '';
$info['doc_files'] = '';
$info['files'] = '';
$info['package2xml'] = '';
$info['rpm_package'] = sprintf($rpm_pkgname_format, $pf->getPackage());
$srcfiles = 0;
foreach ($info['filelist'] as $name => $attr) {
if (!isset($attr['role'])) {
continue;
}
$name = preg_replace('![/:\\\\]!', '/', $name);
if ($attr['role'] == 'doc') {
$info['doc_files'] .= " $name";
// Map role to the rpm vars
} else {
$c_prefix = '%{_libdir}/php/pear';
switch ($attr['role']) {
case 'php':
$prefix = $c_prefix;
break;
case 'ext':
$prefix = '%{_libdir}/php';
break; // XXX good place?
case 'src':
$srcfiles++;
$prefix = '%{_includedir}/php';
break; // XXX good place?
case 'test':
$prefix = "$c_prefix/tests/" . $pf->getPackage();
break;
case 'data':
$prefix = "$c_prefix/data/" . $pf->getPackage();
break;
case 'script':
$prefix = '%{_bindir}';
break;
default: // non-standard roles
$prefix = "$c_prefix/$attr[role]/" . $pf->getPackage();
$info['extra_config'] .=
"\n -d {$attr[role]}_dir=$c_prefix/{$attr[role]} \\";
$this->ui->outputData('WARNING: role "' . $attr['role'] . '" used, ' .
'and will be installed in "' . $c_prefix . '/' . $attr['role'] .
'/' . $pf->getPackage() .
' - hand-edit the final .spec if this is wrong', $command);
break;
}
$name = str_replace('\\', '/', $name);
$info['files'] .= "$prefix/$name\n";
}
}
if ($srcfiles > 0) {
require_once 'OS/Guess.php';
$os = new OS_Guess;
$arch = $os->getCpu();
// Check to see if PEAR_Command_Packaging is installed, and
// transparently switch to use the "make-rpm-spec" command from it
// instead, if it does. Otherwise, continue to use the old version
// of "makerpm" supplied with this package (PEAR).
$packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
if ($packaging_cmd !== null) {
$this->ui->outputData('PEAR_Command_Packaging is installed; using '.
'newer "make-rpm-spec" command instead');
return $packaging_cmd->run('make-rpm-spec', $options, $params);
} else {
$arch = 'noarch';
$this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
'improved version is available via "pear make-rpm-spec", which '.
'is available by installing PEAR_Command_Packaging');
}
$cfg = array('master_server', 'php_dir', 'ext_dir', 'doc_dir',
'bin_dir', 'data_dir', 'test_dir');
foreach ($cfg as $k) {
if ($k == 'master_server') {
$chan = $reg->getChannel($pf->getChannel());
$info[$k] = $chan->getServer();
continue;
}
$info[$k] = $this->config->get($k);
}
$info['arch'] = $arch;
$fp = @fopen($spec_template, "r");
if (!$fp) {
return $this->raiseError("could not open RPM spec file template $spec_template: $php_errormsg");
}
$info['package'] = $pf->getPackage();
$info['version'] = $pf->getVersion();
$info['release_license'] = $pf->getLicense();
if ($pf->getDeps()) {
if ($pf->getPackagexmlVersion() == '1.0') {
$requires = $conflicts = array();
foreach ($pf->getDeps() as $dep) {
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
continue;
}
if ($dep['type'] != 'pkg') {
continue;
}
if (isset($dep['channel']) && $dep['channel'] != 'pear.php.net' &&
$dep['channel'] != 'pecl.php.net') {
$chan = &$reg->getChannel($dep['channel']);
$package = strtoupper($chan->getAlias()) . '::' . $dep['name'];
} else {
$package = 'PEAR::' . $dep['name'];
}
$trans = array(
'>' => '>',
'<' => '<',
'>=' => '>=',
'<=' => '<=',
'=' => '=',
'gt' => '>',
'lt' => '<',
'ge' => '>=',
'le' => '<=',
'eq' => '=',
);
if ($dep['rel'] == 'has') {
$requires[] = $package;
} elseif ($dep['rel'] == 'not') {
$conflicts[] = $package;
} elseif ($dep['rel'] == 'ne') {
$conflicts[] = $package . ' = ' . $dep['version'];
} elseif (isset($trans[$dep['rel']])) {
$requires[] = $package . ' ' . $trans[$dep['rel']] . ' ' . $dep['version'];
}
}
if (count($requires)) {
$info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n";
}
if (count($conflicts)) {
$info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n";
}
} else {
$info['package2xml'] = '2'; // tell the spec to use package2.xml
$requires = $conflicts = array();
$deps = $pf->getDeps(true);
if (isset($deps['required']['package'])) {
if (!isset($deps['required']['package'][0])) {
$deps['required']['package'] = array($deps['required']['package']);
}
foreach ($deps['required']['package'] as $dep) {
if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') {
$chan = &$reg->getChannel($dep['channel']);
$package = strtoupper($chan->getAlias()) . '::' . $dep['name'];
} else {
$package = 'PEAR::' . $dep['name'];
}
if (isset($dep['conflicts']) && (isset($dep['min']) ||
isset($dep['max']))) {
$deprange = array();
if (isset($dep['min'])) {
$deprange[] = array($dep['min'],'>=');
}
if (isset($dep['max'])) {
$deprange[] = array($dep['max'], '<=');
}
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude']) ||
!isset($dep['exclude'][0])) {
$dep['exclude'] = array($dep['exclude']);
}
if (count($deprange)) {
$excl = $dep['exclude'];
// change >= to > if excluding the min version
// change <= to < if excluding the max version
for($i = 0; $i < count($excl); $i++) {
if (isset($deprange[0]) &&
$excl[$i] == $deprange[0][0]) {
$deprange[0][1] = '<';
unset($dep['exclude'][$i]);
}
if (isset($deprange[1]) &&
$excl[$i] == $deprange[1][0]) {
$deprange[1][1] = '>';
unset($dep['exclude'][$i]);
}
}
}
if (count($dep['exclude'])) {
$dep['exclude'] = array_values($dep['exclude']);
$newdeprange = array();
// remove excludes that are outside the existing range
for ($i = 0; $i < count($dep['exclude']); $i++) {
if ($dep['exclude'][$i] < $dep['min'] ||
$dep['exclude'][$i] > $dep['max']) {
unset($dep['exclude'][$i]);
}
}
$dep['exclude'] = array_values($dep['exclude']);
usort($dep['exclude'], 'version_compare');
// take the remaining excludes and
// split the dependency into sub-ranges
$lastmin = $deprange[0];
for ($i = 0; $i < count($dep['exclude']) - 1; $i++) {
$newdeprange[] = '(' .
$package . " {$lastmin[1]} {$lastmin[0]} and " .
$package . ' < ' . $dep['exclude'][$i] . ')';
$lastmin = array($dep['exclude'][$i], '>');
}
if (isset($dep['max'])) {
$newdeprange[] = '(' . $package .
" {$lastmin[1]} {$lastmin[0]} and " .
$package . ' < ' . $dep['max'] . ')';
}
$conflicts[] = implode(' or ', $deprange);
} else {
$conflicts[] = $package .
" {$deprange[0][1]} {$deprange[0][0]}" .
(isset($deprange[1]) ?
" and $package {$deprange[1][1]} {$deprange[1][0]}"
: '');
}
}
continue;
}
if (!isset($dep['min']) && !isset($dep['max']) &&
!isset($dep['exclude'])) {
if (isset($dep['conflicts'])) {
$conflicts[] = $package;
} else {
$requires[] = $package;
}
} else {
if (isset($dep['min'])) {
$requires[] = $package . ' >= ' . $dep['min'];
}
if (isset($dep['max'])) {
$requires[] = $package . ' <= ' . $dep['max'];
}
if (isset($dep['exclude'])) {
$ex = $dep['exclude'];
if (!is_array($ex)) {
$ex = array($ex);
}
foreach ($ex as $ver) {
$conflicts[] = $package . ' = ' . $ver;
}
}
}
}
require_once 'Archive/Tar.php';
$tar = new Archive_Tar($pf->getArchiveFile());
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
$a = $tar->extractInString('package2.xml');
$tar->popErrorHandling();
if ($a === null || PEAR::isError($a)) {
$info['package2xml'] = '';
// this doesn't have a package.xml version 1.0
$requires[] = 'PEAR::PEAR >= ' .
$deps['required']['pearinstaller']['min'];
}
if (count($requires)) {
$info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n";
}
if (count($conflicts)) {
$info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n";
}
}
}
}
// remove the trailing newline
$info['extra_headers'] = trim($info['extra_headers']);
if (function_exists('file_get_contents')) {
fclose($fp);
$spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]',
file_get_contents($spec_template));
} else {
$spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]',
fread($fp, filesize($spec_template)));
fclose($fp);
}
$spec_file = "$info[rpm_package]-$info[version].spec";
$wp = fopen($spec_file, "wb");
if (!$wp) {
return $this->raiseError("could not write RPM spec file $spec_file: $php_errormsg");
}
fwrite($wp, $spec_contents);
fclose($wp);
$this->ui->outputData("Wrote RPM spec file $spec_file", $command);
return true;
}

View File

@@ -133,7 +133,7 @@ use the &quot;slide&quot; option to move the release tag.
<shortcut>pd</shortcut>
<options />
<doc>
List all depencies the package has.</doc>
List all dependencies the package has.</doc>
</package-dependencies>
<sign>
<summary>Sign a package distribution file</summary>
@@ -191,4 +191,4 @@ This is not the most intelligent conversion, and should only be
used for automated conversion or learning the format.
</doc>
</convert>
</commands>
</commands>

View File

@@ -13,9 +13,9 @@
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005 The PHP Group
* @copyright 2005-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Pickle.php,v 1.4 2005/09/27 04:12:52 cellog Exp $
* @version CVS: $Id: Pickle.php,v 1.8 2008/01/29 03:21:01 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.1
*/
@@ -31,9 +31,9 @@ require_once 'PEAR/Command/Common.php';
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 2005 The PHP Group
* @copyright 2005-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.1
*/
@@ -63,8 +63,8 @@ disk in the current directory as "package.xml". Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease
- extbinrelease, phprelease, or bundle release type
- more than one extsrcrelease or zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace
@@ -115,7 +115,7 @@ generate both package.xml.
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR/PackageFile.php')) {
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
@@ -156,7 +156,7 @@ generate both package.xml.
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
$pf->setConfig($this->config);
if (is_array($pf2->getPackageType() != 'extsrc')) {
if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') {
return $this->raiseError('Cannot safely convert "' . $packagexml .
'", is not an extension source package. Using a PEAR_PackageFileManager-based ' .
'script is an option');
@@ -307,7 +307,7 @@ generate both package.xml.
$release = $pf2->getReleases();
if (isset($releases[0])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
. 'multiple extsrcrelease tags. Using a PEAR_PackageFileManager-based script ' .
. 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' .
'or the convert command is an option');
}
if ($configoptions = $pf2->getConfigureOptions()) {

View File

@@ -26,8 +26,8 @@ an automatic conversion will be made to a package.xml 1.0. Note that
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
- dependency types other than required/optional PECL package/ext/php/pearinstaller
- more than one extsrcrelease
- extbinrelease, phprelease, or bundle release type
- more than one extsrcrelease/zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
- tasks other than replace

View File

@@ -14,9 +14,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Registry.php,v 1.68 2005/11/01 22:28:38 cellog Exp $
* @version CVS: $Id: Registry.php,v 1.81 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -33,9 +33,9 @@ require_once 'PEAR/Command/Common.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -58,6 +58,10 @@ class PEAR_Command_Registry extends PEAR_Command_Common
'shortopt' => 'a',
'doc' => 'list installed packages from all channels',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '<package>
If invoked without parameters, this command lists the PEAR packages
@@ -123,10 +127,33 @@ installed package.'
function doList($command, $options, $params)
{
if (isset($options['allchannels'])) {
$reg = &$this->config->getRegistry();
$channelinfo = isset($options['channelinfo']);
if (isset($options['allchannels']) && !$channelinfo) {
return $this->doListAll($command, array(), $params);
}
$reg = &$this->config->getRegistry();
if (isset($options['allchannels']) && $channelinfo) {
// allchannels with $channelinfo
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
$options['channel'] = $channel->getName();
$ret = $this->doList($command, $options, $params);
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
PEAR::staticPopErrorHandling();
if (count($errors)) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
return true;
}
if (count($params) == 1) {
return $this->doFileList($command, $options, $params);
}
@@ -141,21 +168,46 @@ installed package.'
}
$installed = $reg->packageInfo(null, null, $channel);
usort($installed, array(&$this, '_sortinfo'));
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State')
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel,
);
if ($channelinfo) {
$data['headline'] = array('Channel', 'Package', 'Version', 'State');
}
if (count($installed) && !isset($data['data'])) {
$data['data'] = array();
}
foreach ($installed as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
if ($channelinfo) {
$packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
} else {
$packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
$data['data'][] = $packageinfo;
}
if (count($installed)==0) {
$data = '(no packages installed from channel ' . $channel . ')';
if (count($installed) == 0) {
if (!$channelinfo) {
$data = '(no packages installed from channel ' . $channel . ')';
} else {
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'channel' => $channel,
'data' => '(no packages installed)',
);
}
}
$this->ui->outputData($data, $command);
return true;
@@ -163,15 +215,18 @@ installed package.'
function doListAll($command, $options, $params)
{
// This duplicate code is deprecated over
// list --channelinfo, which gives identical
// output for list and list --allchannels.
$reg = &$this->config->getRegistry();
$installed = $reg->packageInfo(null, null, null);
foreach ($installed as $channel => $packages) {
usort($packages, array($this, '_sortinfo'));
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State')
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel
);
foreach ($packages as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
@@ -184,6 +239,7 @@ installed package.'
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'data' => array(array('(no packages installed)')),
'channel' => $channel
);
}
$this->ui->outputData($data, $command);
@@ -197,9 +253,12 @@ installed package.'
return $this->raiseError('list-files expects 1 parameter');
}
$reg = &$this->config->getRegistry();
$fp = false;
if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0],
'r'))) {
@fclose($fp);
if ($fp) {
fclose($fp);
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
@@ -309,7 +368,10 @@ installed package.'
function doShellTest($command, $options, $params)
{
$this->pushErrorHandling(PEAR_ERROR_RETURN);
if (count($params) < 1) {
return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$reg = &$this->config->getRegistry();
$info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
if (PEAR::isError($info)) {
@@ -342,7 +404,7 @@ installed package.'
exit(1);
}
} else {
$this->popErrorHandling();
PEAR::staticPopErrorHandling();
$this->raiseError("$command: expects 1 to 3 parameters");
exit(1);
}
@@ -356,10 +418,12 @@ installed package.'
if (count($params) != 1) {
return $this->raiseError('pear info expects 1 parameter');
}
$info = false;
$info = $fp = false;
$reg = &$this->config->getRegistry();
if ((@is_file($params[0]) && !is_dir($params[0])) || $fp = @fopen($params[0], 'r')) {
@fclose($fp);
if ((file_exists($params[0]) && is_file($params[0]) && !is_dir($params[0])) || $fp = @fopen($params[0], 'r')) {
if ($fp) {
fclose($fp);
}
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
@@ -524,7 +588,7 @@ installed package.'
unset($info[$key]);
$info['Last Modified'] = $hdate;
} elseif ($key == '_lastversion') {
$info['Last Installed Version'] = $info[$key] ? $info[$key] : '- None -';
$info['Previous Installed Version'] = $info[$key] ? $info[$key] : '- None -';
unset($info[$key]);
} else {
$info[$key] = trim($info[$key]);
@@ -566,9 +630,15 @@ installed package.'
case 'extsrc' :
$release = 'PECL-style PHP extension (source code)';
break;
case 'zendextsrc' :
$release = 'PECL-style Zend extension (source code)';
break;
case 'extbin' :
$release = 'PECL-style PHP extension (binary)';
break;
case 'zendextbin' :
$release = 'PECL-style Zend extension (binary)';
break;
case 'bundle' :
$release = 'Package bundle (collection of packages)';
break;
@@ -623,9 +693,12 @@ installed package.'
}
$info['Release Notes'] = $obj->getNotes();
if ($compat = $obj->getCompatible()) {
if (!isset($compat[0])) {
$compat = array($compat);
}
$info['Compatible with'] = '';
foreach ($compat as $package) {
$info['Compatible with'] .= $package['channel'] . '/' . $package['package'] .
$info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
"\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
if (isset($package['exclude'])) {
if (is_array($package['exclude'])) {
@@ -637,7 +710,7 @@ installed package.'
$info['Not Compatible with'] .= "\n";
}
$info['Not Compatible with'] .= $package['channel'] . '/' .
$package['package'] . "\nVersions " . $package['exclude'];
$package['name'] . "\nVersions " . $package['exclude'];
}
}
}
@@ -980,10 +1053,10 @@ installed package.'
$info['package.xml version'] = '2.0';
if ($installed) {
if ($obj->getLastModified()) {
$info['Last Modified'] = date('Y-m-d H:m', $obj->getLastModified());
$info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
}
$v = $obj->getLastInstalledVersion();
$info['Last Installed Version'] = $v ? $v : '- None -';
$info['Previous Installed Version'] = $v ? $v : '- None -';
}
foreach ($info as $key => $value) {
$data['data'][] = array($key, $value);

View File

@@ -13,6 +13,10 @@
<shortopt>a</shortopt>
<doc>list installed packages from all channels</doc>
</allchannels>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>&lt;package&gt;
If invoked without parameters, this command lists the PEAR packages

View File

@@ -15,9 +15,9 @@
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Remote.php,v 1.86 2005/11/14 14:11:05 cellog Exp $
* @version CVS: $Id: Remote.php,v 1.107 2008/04/11 01:16:40 dufuz Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -35,9 +35,9 @@ require_once 'PEAR/REST.php';
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -58,7 +58,12 @@ Get details on a package from the server.',
'summary' => 'List Available Upgrades',
'function' => 'doListUpgrades',
'shortcut' => 'lu',
'options' => array(),
'options' => array(
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '[preferred_state]
List releases on the server of packages you have installed where
a newer version is available with the same release state (stable etc.)
@@ -90,7 +95,15 @@ latest stable release of each package.',
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'allchannels' => array(
'shortopt' => 'a',
'doc' => 'search packages from all known channels',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
@@ -108,7 +121,11 @@ will be used to match any portion of the summary/description',
'shortopt' => 'c',
'doc' => 'specify a channel other than the default channel',
'arg' => 'CHAN',
)
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '
Lists the packages available on the configured server along with the
@@ -158,8 +175,17 @@ parameter.
function _checkChannelForStatus($channel, $chan)
{
if (PEAR::isError($chan)) {
$this->raiseError($chan);
}
if (!is_a($chan, 'PEAR_ChannelFile')) {
return $this->raiseError('Internal corruption error: invalid channel "' .
$channel . '"');
}
$rest = new PEAR_REST($this->config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$mirror = $this->config->get('preferred_mirror', null,
$channel);
$a = $rest->downloadHttp('http://' . $channel .
'/channel.xml', $chan->lastModified());
PEAR::staticPopErrorHandling();
@@ -184,15 +210,17 @@ parameter.
if (PEAR::isError($parsed)) {
return $this->raiseError('Invalid package name "' . $package . '"');
}
$channel = $parsed['channel'];
$this->config->set('default_channel', $channel);
$chan = $reg->getChannel($channel);
$this->_checkChannelForStatus($channel, $chan);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$info = $rest->packageInfo($base, $parsed['package']);
$info = $rest->packageInfo($base, $parsed['package'], $channel);
} else {
$r = &$this->config->getRemote();
$info = $r->call('package.info', $parsed['package']);
@@ -233,7 +261,9 @@ parameter.
}
}
$chan = $reg->getChannel($channel);
$this->_checkChannelForStatus($channel, $chan);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
@@ -242,11 +272,11 @@ parameter.
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options);
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options);
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
@@ -265,6 +295,7 @@ parameter.
'caption' => 'Channel ' . $channel . ' Available packages:',
'border' => true,
'headline' => array('Package', 'Version'),
'channel' => $channel
);
if (count($available)==0) {
$data = '(no packages available yet)';
@@ -299,16 +330,18 @@ parameter.
$list_options = true;
}
$chan = $reg->getChannel($channel);
$this->_checkChannelForStatus($channel, $chan);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
// use faster list-all if available
$rest = &$this->config->getREST('1.1', array());
$available = $rest->listAll($base, $list_options, false);
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, $list_options, false);
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
@@ -323,10 +356,17 @@ parameter.
return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
}
$data = array(
'caption' => 'All packages:',
'caption' => 'All packages [Channel ' . $channel . ']:',
'border' => true,
'headline' => array('Package', 'Latest', 'Local'),
'channel' => $channel,
);
if (isset($options['channelinfo'])) {
// add full channelinfo
$data['caption'] = 'Channel ' . $channel . ' All packages:';
$data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
'Description', 'Dependencies');
}
$local_pkgs = $reg->listPackages($channel);
foreach ($available as $name => $info) {
@@ -360,13 +400,39 @@ parameter.
if (isset($info['stable']) && !$info['stable']) {
$info['stable'] = null;
}
$data['data'][$info['category']][] = array(
$reg->channelAlias($channel) . '/' . $name,
@$info['stable'],
@$installed['version'],
@$desc,
@$info['deps'],
if (isset($options['channelinfo'])) {
// add full channelinfo
if ($info['stable'] === $info['unstable']) {
$state = $info['state'];
} else {
$state = 'stable';
}
$latest = $info['stable'].' ('.$state.')';
$local = '';
if (isset($installed['version'])) {
$inst_state = $reg->packageInfo($name, 'release_state', $channel);
$local = $installed['version'].' ('.$inst_state.')';
}
$packageinfo = array(
$channel,
$name,
$latest,
$local,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
} else {
$packageinfo = array(
$reg->channelAlias($channel) . '/' . $name,
isset($info['stable']) ? $info['stable'] : null,
isset($installed['version']) ? $installed['version'] : null,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
@@ -401,8 +467,33 @@ parameter.
return $this->raiseError('no valid search string supplied');
};
$savechannel = $channel = $this->config->get('default_channel');
$channelinfo = isset($options['channelinfo']);
$reg = &$this->config->getRegistry();
if (isset($options['allchannels'])) {
// search all channels
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
if ($channel->getName() != '__uri') {
$options['channel'] = $channel->getName();
$ret = $this->doSearch($command, $options, $params);
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
}
PEAR::staticPopErrorHandling();
if (count($errors) !== 0) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
return true;
}
$savechannel = $channel = $this->config->get('default_channel');
$package = $params[0];
$summary = isset($params[1]) ? $params[1] : false;
if (isset($options['channel'])) {
@@ -415,50 +506,85 @@ parameter.
}
}
$chan = $reg->getChannel($channel);
$this->_checkChannelForStatus($channel, $chan);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
$available = $rest->listAll($base, false, false, $package, $summary);
$available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
} else {
$r = &$this->config->getRemote();
$available = $r->call('package.search', $package, $summary, true,
$available = $r->call('package.search', $package, $summary, true,
$this->config->get('preferred_state') == 'stable', true);
}
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
if (!$available) {
return $this->raiseError('no packages found that match pattern "' . $package . '"');
if (!$available && !$channelinfo) {
// clean exit when not found, no error !
$data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
$this->ui->outputData($data);
$this->config->set('default_channel', $channel);
return true;
}
if ($channelinfo) {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
} else {
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
'channel' => $channel
);
}
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
);
if (!$available && $channelinfo) {
unset($data['headline']);
$data['data'] = 'No packages found that match pattern "' . $package . '".';
$available = array();
}
foreach ($available as $name => $info) {
$installed = $reg->packageInfo($name, null, $channel);
$desc = $info['summary'];
if (isset($params[$name]))
$desc .= "\n\n".$info['description'];
$unstable = '';
if ($info['unstable']) {
$unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')';
}
if (!isset($info['stable']) || !$info['stable']) {
$info['stable'] = 'none';
$version_remote = 'none';
} else {
if ($info['unstable']) {
$version_remote = $info['unstable'];
} else {
$version_remote = $info['stable'];
}
$version_remote .= ' ('.$info['state'].')';
}
$version = is_array($installed['version']) ? $installed['version']['release'] :
$installed['version'];
$data['data'][$info['category']][] = array(
$name,
$info['stable'] . $unstable,
$version,
$desc,
if ($channelinfo) {
$packageinfo = array(
$channel,
$name,
$version_remote,
$version,
$desc,
);
} else {
$packageinfo = array(
$name,
$version_remote,
$version,
$desc,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $channel);
@@ -480,8 +606,20 @@ parameter.
{
// make certain that dependencies are ignored
$options['downloadonly'] = 1;
// eliminate error messages for preferred_state-related errors
/* TODO: Should be an option, but until now download does respect
prefered state */
/* $options['ignorepreferred_state'] = 1; */
// eliminate error messages for preferred_state-related errors
$downloader = &$this->getDownloader($options);
$downloader->setDownloadDir(getcwd());
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$e = $downloader->setDownloadDir(getcwd());
PEAR::staticPopErrorHandling();
if (PEAR::isError($e)) {
return $this->raiseError('Current directory is not writeable, cannot download');
}
$errors = array();
$downloaded = array();
$err = $downloader->download($params);
@@ -490,10 +628,9 @@ parameter.
}
$errors = $downloader->getErrorMsgs();
if (count($errors)) {
$errinfo = array();
$errinfo['data'] = array($errors);
$errinfo['headline'] = 'Download Errors';
$this->ui->outputData($errinfo);
foreach ($errors as $error) {
$this->ui->outputData($error);
}
return $this->raiseError("$command failed");
}
$downloaded = $downloader->getDownloadedPackages();
@@ -516,6 +653,9 @@ parameter.
function doListUpgrades($command, $options, $params)
{
require_once 'PEAR/Common.php';
if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
}
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
foreach ($reg->listChannels() as $channel) {
@@ -534,7 +674,9 @@ parameter.
}
$caption = $channel . ' Available Upgrades';
$chan = $reg->getChannel($channel);
$this->_checkChannelForStatus($channel, $chan);
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
return $e;
}
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', array());
@@ -570,6 +712,7 @@ parameter.
'caption' => $caption,
'border' => 1,
'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
'channel' => $channel
);
foreach ((array)$latest as $pkg => $info) {
$package = strtolower($pkg);
@@ -595,10 +738,22 @@ parameter.
}
$data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
}
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
if (isset($options['channelinfo'])) {
if (empty($data['data'])) {
unset($data['headline']);
if (count($inst) == 0) {
$data['data'] = '(no packages installed)';
} else {
$data['data'] = '(no upgrades available)';
}
}
$this->ui->outputData($data, $command);
} else {
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
$this->ui->outputData($data, $command);
}
}
}
$this->config->set('default_channel', $savechannel);
@@ -613,6 +768,9 @@ parameter.
$cache_dir = $this->config->get('cache_dir');
$verbose = $this->config->get('verbose');
$output = '';
if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
return $this->raiseError("$cache_dir does not exist or is not a directory");
}
if (!($dp = @opendir($cache_dir))) {
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
}
@@ -621,17 +779,22 @@ parameter.
}
$num = 0;
while ($ent = readdir($dp)) {
if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) ||
preg_match('/rest.cache(file|id)$/', $ent)) {
if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}\\z/', $ent) ||
preg_match('/rest.cache(file|id)\\z/', $ent)) {
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
$ok = @unlink($path);
if (file_exists($path)) {
$ok = @unlink($path);
} else {
$ok = false;
$php_errormsg = '';
}
if ($ok) {
if ($verbose >= 2) {
$output .= "deleted $path\n";
}
$num++;
} elseif ($verbose >= 1) {
$output .= "failed to delete $path\n";
$output .= "failed to delete $path $php_errormsg\n";
}
}
}

View File

@@ -27,6 +27,10 @@ or the state passed as the second parameter.</doc>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>
Lists the packages available on the configured server along with the
@@ -42,6 +46,14 @@ latest stable release of each package.</doc>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
<allchannels>
<shortopt>a</shortopt>
<doc>search packages from all known channels</doc>
</allchannels>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>[packagename] [packageinfo]
Lists all packages which match the search parameters. The first
@@ -59,6 +71,10 @@ will be used to match any portion of the summary/description</doc>
<doc>specify a channel other than the default channel</doc>
<arg>CHAN</arg>
</channel>
<channelinfo>
<shortopt>i</shortopt>
<doc>output fully channel-aware data, even on failure</doc>
</channelinfo>
</options>
<doc>
Lists the packages available on the configured server along with the

View File

@@ -15,9 +15,9 @@
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Test.php,v 1.5 2005/08/31 07:18:46 pajoye Exp $
* @version CVS: $Id: Test.php,v 1.27 2008/01/03 20:26:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
@@ -35,9 +35,9 @@ require_once 'PEAR/Command/Common.php';
* @author Stig Bakken <ssb@php.net>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2005 The PHP Group
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.5
* @version Release: 1.7.2
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
@@ -77,6 +77,24 @@ class PEAR_Command_Test extends PEAR_Command_Common
'shortopt' => 'p',
'doc' => 'Treat parameters as installed packages from which to run tests',
),
'phpunit' => array(
'shortopt' => 'u',
'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
If none is found, all .phpt tests will be tried instead.',
),
'tapoutput' => array(
'shortopt' => 't',
'doc' => 'Output run-tests.log in TAP-compliant format',
),
'cgi' => array(
'shortopt' => 'c',
'doc' => 'CGI php executable (needed for tests with POST/GET section)',
'arg' => 'PHPCGI',
),
'coverage' => array(
'shortopt' => 'x',
'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
),
),
'doc' => '[testfile|dir ...]
Run regression tests with PHP\'s regression testing script (run-tests.php).',
@@ -103,18 +121,16 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).',
function doRunTests($command, $options, $params)
{
if (isset($options['phpunit']) && isset($options['tapoutput'])) {
return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
}
require_once 'PEAR/Common.php';
require_once 'PEAR/RunTest.php';
require_once 'System.php';
$log = new PEAR_Common;
$log->ui = &$this->ui; // slightly hacky, but it will work
$run = new PEAR_RunTest($log, $options);
$tests = array();
if (isset($options['recur'])) {
$depth = 4;
} else {
$depth = 1;
}
$depth = isset($options['recur']) ? 4 : 1;
if (!count($params)) {
$params[] = '.';
}
@@ -127,79 +143,140 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).',
if (PEAR::isError($pname)) {
return $this->raiseError($pname);
}
$package = &$reg->getPackage($pname['package'], $pname['channel']);
if (!$package) {
return PEAR::raiseError('Unknown package "' .
$reg->parsedPackageNameToString($pname) . '"');
}
$filelist = $package->getFilelist();
foreach ($filelist as $name => $atts) {
if (isset($atts['role']) && $atts['role'] != 'test') {
continue;
}
if (!preg_match('/\.phpt$/', $name)) {
if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
$params[] = $atts['installed_as'];
continue;
} elseif (!preg_match('/\.phpt\\z/', $name)) {
continue;
}
$params[] = $atts['installed_as'];
}
}
}
foreach ($params as $p) {
if (is_dir($p)) {
if (isset($options['phpunit'])) {
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', 'AllTests.php'));
if (count($dir)) {
foreach ($dir as $p) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
}
continue;
}
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', '*.phpt'));
$tests = array_merge($tests, $dir);
} else {
if (!@file_exists($p)) {
if (!preg_match('/\.phpt$/', $p)) {
$p .= '.phpt';
if (isset($options['phpunit'])) {
if (preg_match('/AllTests\.php\\z/i', $p)) {
$p = realpath($p);
if (!count($tests) ||
(count($tests) && strlen($p) < strlen($tests[0]))) {
// this is in a higher-level directory, use this one instead.
$tests = array($p);
}
}
$dir = System::find(array(dirname($p), '-type', 'f',
'-maxdepth', $depth,
'-name', $p));
$tests = array_merge($tests, $dir);
} else {
$tests[] = $p;
continue;
}
if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
$tests[] = $p;
continue;
}
if (!preg_match('/\.phpt\\z/', $p)) {
$p .= '.phpt';
}
$dir = System::find(array(dirname($p), '-type', 'f',
'-maxdepth', $depth,
'-name', $p));
$tests = array_merge($tests, $dir);
}
}
$ini_settings = '';
if (isset($options['ini'])) {
$ini_settings .= $options['ini'];
}
if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
$ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
}
if ($ini_settings) {
$this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
}
$skipped = $passed = $failed = array();
$this->ui->outputData('Running ' . count($tests) . ' tests', $command);
$tests_count = count($tests);
$this->ui->outputData('Running ' . $tests_count . ' tests', $command);
$start = time();
if (isset($options['realtimelog'])) {
@unlink('run-tests.log');
if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
unlink('run-tests.log');
}
if (isset($options['tapoutput'])) {
$tap = '1..' . $tests_count . "\n";
}
require_once 'PEAR/RunTest.php';
$run = new PEAR_RunTest($log, $options);
$run->tests_count = $tests_count;
if (isset($options['coverage']) && extension_loaded('xdebug')){
$run->xdebug_loaded = true;
} else {
$run->xdebug_loaded = false;
}
$j = $i = 1;
foreach ($tests as $t) {
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
fwrite($fp, "Running test $t...");
fwrite($fp, "Running test [$i / $tests_count] $t...");
fclose($fp);
}
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$result = $run->run($t, $ini_settings);
if (isset($options['phpunit'])) {
$result = $run->runPHPUnit($t, $ini_settings);
} else {
$result = $run->run($t, $ini_settings, $j);
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($result)) {
$this->ui->log(0, $result->getMessage());
$this->ui->log($result->getMessage());
continue;
}
if (OS_WINDOWS) {
for($i=0;$i<2000;$i++) {
$i = $i; // delay - race conditions on windows
}
if (isset($options['tapoutput'])) {
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
continue;
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
@@ -207,6 +284,7 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).',
fclose($fp);
}
}
if ($result == 'FAILED') {
$failed[] = $t;
}
@@ -216,28 +294,40 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).',
if ($result == 'SKIPPED') {
$skipped[] = $t;
}
$j++;
}
$total = date('i:s', time() - $start);
if (count($failed)) {
$output = "TOTAL TIME: $total\n";
$output .= count($passed) . " PASSED TESTS\n";
$output .= count($skipped) . " SKIPPED TESTS\n";
$output .= count($failed) . " FAILED TESTS:\n";
foreach ($failed as $failure) {
$output .= $failure . "\n";
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
} else {
$fp = @fopen('run-tests.log', 'w');
}
if (isset($options['tapoutput'])) {
$fp = @fopen('run-tests.log', 'w');
if ($fp) {
fwrite($fp, $output, strlen($output));
fwrite($fp, $tap, strlen($tap));
fclose($fp);
$this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
$this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
'"', $command);
}
} else {
if (count($failed)) {
$output = "TOTAL TIME: $total\n";
$output .= count($passed) . " PASSED TESTS\n";
$output .= count($skipped) . " SKIPPED TESTS\n";
$output .= count($failed) . " FAILED TESTS:\n";
foreach ($failed as $failure) {
$output .= $failure . "\n";
}
$mode = isset($options['realtimelog']) ? 'a' : 'w';
$fp = @fopen('run-tests.log', $mode);
if ($fp) {
fwrite($fp, $output, strlen($output));
fclose($fp);
$this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
}
} elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
@unlink('run-tests.log');
}
} elseif (@file_exists('run-tests.log') && !@is_dir('run-tests.log')) {
@unlink('run-tests.log');
}
$this->ui->outputData('TOTAL TIME: ' . $total);
$this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
@@ -252,6 +342,4 @@ Run regression tests with PHP\'s regression testing script (run-tests.php).',
return true;
}
// }}}
}
?>
}

View File

@@ -29,6 +29,24 @@
<shortopt>p</shortopt>
<doc>Treat parameters as installed packages from which to run tests</doc>
</package>
<phpunit>
<shortopt>u</shortopt>
<doc>Search parameters for AllTests.php, and use that to run phpunit-based tests.
If none is found, all .phpt tests will be tried instead.</doc>
</phpunit>
<tapoutput>
<shortopt>t</shortopt>
<doc>Output run-tests.log in TAP-compliant format</doc>
</tapoutput>
<cgi>
<shortopt>c</shortopt>
<doc>CGI php executable (needed for tests with POST/GET section)</doc>
<arg>PHPCGI</arg>
</cgi>
<coverage>
<shortopt>x</shortopt>
<doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc>
</coverage>
</options>
<doc>[testfile|dir ...]
Run regression tests with PHP&apos;s regression testing script (run-tests.php).</doc>