* support for .tar files in PEAR_Installer

* new command: package-verify
* "package" command now sanity-checks the package information before
  making the tarball
* -Z option to the install/update commands for downloading non-compressed
  packages
This commit is contained in:
Stig Bakken 2002-04-07 10:38:04 +00:00
parent efbb9949a5
commit dc974a0299
5 changed files with 224 additions and 16 deletions

View File

@ -78,7 +78,8 @@ class PEAR_Command_Install extends PEAR_Command_Common
" -f forces the installation of the package\n".
" when it is already installed\n".
" -n do not take care of package dependencies\n".
" -s soft update: install or upgrade only if needed";
" -s soft update: install or upgrade only if needed".
" -Z no compression: download plain .tar files";
return $ret;
}
@ -87,7 +88,7 @@ class PEAR_Command_Install extends PEAR_Command_Common
function getOptions()
{
return array('f', 'n', 's');
return array('f', 'n', 's', 'Z');
}
// }}}
@ -112,6 +113,9 @@ class PEAR_Command_Install extends PEAR_Command_Common
if (isset($options['s'])) {
$opts['soft'] = true;
}
if (isset($options['Z'])) {
$opts['nocompress'] = true;
}
switch ($command) {
case 'upgrade':
$opts['upgrade'] = true;

View File

@ -48,12 +48,15 @@ class PEAR_Command_Package extends PEAR_Command_Common
function getCommands()
{
return array('package',
'package-info',
'package-list',
'package-info');
'package-verify');
}
// }}}
// {{{ getHelp()
function getHelp($command)
{
switch ($command) {
@ -67,9 +70,13 @@ class PEAR_Command_Package extends PEAR_Command_Common
case 'packge-info':
return array('<pear package>',
'Shows information about a PEAR package');
case 'package-verify':
return array('<package.(tgz|tar|xml)>',
'Verifies a package or description file');
}
}
// }}}
// {{{ run()
@ -94,12 +101,26 @@ class PEAR_Command_Package extends PEAR_Command_Common
// {{{ package
case 'package': {
$pkginfofile = isset($params[0]) ? $params[0] : null;
$pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
ob_start();
$packager =& new PEAR_Packager($this->config->get('php_dir'),
$this->config->get('ext_dir'),
$this->config->get('doc_dir'));
$packager->debug = $this->config->get('verbose');
$err = $warn = array();
$packager->validateInfo($pkginfofile, $err, $warn);
foreach ($err as $e) {
$this->ui->displayLine("Error: $e");
}
foreach ($warn as $w) {
$this->ui->displayLine("Warning: $w");
}
$this->ui->displayLine(sprintf('%d error(s), %d warning(s)',
sizeof($err), sizeof($warn)));
if (sizeof($err) > 0) {
$this->ui->displayLine("Fix these errors and try again.");
break;
}
$result = $packager->Package($pkginfofile);
$output = ob_get_contents();
ob_end_clean();
@ -240,6 +261,42 @@ class PEAR_Command_Package extends PEAR_Command_Common
break;
}
// }}}
// {{{ package-verify
case 'package-verify': {
if (sizeof($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
$obj = new PEAR_Common;
$info = null;
$validate_result = $obj->validatePackageInfo($info, $err, $warn);
if (file_exists($params[0])) {
$fp = fopen($params[0], "r");
$test = fread($fp, 5);
fclose($fp);
if ($test == "<?xml") {
$info = $obj->infoFromDescriptionFile($params[0]);
}
}
if (empty($info)) {
$info = $obj->infoFromTgzFile($params[0]);
}
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
foreach ($err as $e) {
$this->ui->displayLine("Error: $e");
}
foreach ($warn as $w) {
$this->ui->displayLine("Warning: $w");
}
$this->ui->displayLine(sprintf('%d error(s), %d warning(s)',
sizeof($err), sizeof($warn)));
break;
}
// }}}
default: {
return false;

View File

@ -57,16 +57,34 @@ class PEAR_Common extends PEAR
var $pkginfo = array();
/**
* Permitted maintainer roles
* Valid maintainer roles
* @var array
*/
var $maintainer_roles = array('lead','developer','contributor','helper');
/**
* Permitted release states
* Valid release states
* @var array
*/
var $releases_states = array('alpha','beta','stable','snapshot','devel');
var $release_states = array('alpha','beta','stable','snapshot','devel');
/**
* Valid dependency types
* @var array
*/
var $dependency_types = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi');
/**
* Valid dependency relations
* @var array
*/
var $dependency_relations = array('has','eq','lt','le','gt','ge');
/**
* Valid file roles
* @var array
*/
var $file_roles = array('php','ext','test','doc','data','extsrc');
/**
* User Interface object (PEAR_Frontend_* class). If null,
@ -417,9 +435,9 @@ class PEAR_Common extends PEAR
}
break;
case 'state':
if (!in_array($data, $this->releases_states)) {
/* if (!in_array($data, $this->release_states)) {
trigger_error("The release state: '$data' is not valid", E_USER_WARNING);
} elseif ($this->in_changelog) {
} else*/if ($this->in_changelog) {
$this->current_release['release_state'] = $data;
} else {
$this->pkginfo['release_state'] = $data;
@ -549,7 +567,12 @@ class PEAR_Common extends PEAR
if (!@is_file($file)) {
return $this->raiseError('tgz :: could not open file');
}
$tar = new Archive_Tar($file, true);
if (substr($file, -4) == '.tar') {
$compress = false;
} else {
$compress = true;
}
$tar = new Archive_Tar($file, $compress);
$content = $tar->listContent();
if (!is_array($content)) {
return $this->raiseError('tgz :: could not get contents of package');
@ -774,6 +797,131 @@ class PEAR_Common extends PEAR
return $ret;
}
// }}}
// {{{ validatePackageInfo()
function validatePackageInfo($info, &$errors, &$warnings)
{
if (is_string($info) && file_exists($info)) {
$tmp = substr($info, -4);
if ($tmp == '.xml') {
$info = $this->infoFromDescriptionFile($info);
} elseif ($tmp == '.tar' || $tmp == '.tgz') {
$info = $this->infoFromTgzFile($info);
} else {
$fp = fopen($params[0], "r");
$test = fread($fp, 5);
fclose($fp);
if ($test == "<?xml") {
$info = $obj->infoFromDescriptionFile($params[0]);
} else {
$info = $obj->infoFromTgzFile($params[0]);
}
}
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
}
if (!is_array($info)) {
return false;
}
$errors = array();
$warnings = array();
if (empty($info['package'])) {
$errors[] = 'missing package name';
}
if (empty($info['summary'])) {
$errors[] = 'missing summary';
} elseif (strpos(trim($info['summary']), "\n") !== false) {
$warnings[] = 'summary should be on a single line';
}
if (empty($info['description'])) {
$errors[] = 'missing description';
}
if (empty($info['release_license'])) {
$errors[] = 'missing license';
}
if (empty($info['version'])) {
$errors[] = 'missing version';
}
if (empty($info['release_state'])) {
$errors[] = 'missing release state';
} elseif (!in_array($info['release_state'], $this->release_states)) {
$errors[] = "invalid release state `$info[release_state]', should be one of: ".implode(' ', $this->release_states);
}
if (empty($info['release_date'])) {
$errors[] = 'missing release date';
} elseif (!preg_match('/^\d{4}-\d\d-\d\d$/', $info['release_date'])) {
$errors[] = "invalid release date `$info[release_date]', format is YYYY-MM-DD";
}
if (empty($info['release_notes'])) {
$errors[] = "missing release notes";
}
if (empty($info['maintainers'])) {
$errors[] = 'no maintainer(s)';
} else {
$i = 1;
foreach ($info['maintainers'] as $m) {
if (empty($m['handle'])) {
$errors[] = "maintainer $i: missing handle";
}
if (empty($m['role'])) {
$errors[] = "maintainer $i: missing role";
} elseif (!in_array($m['role'], $this->maintainer_roles)) {
$errors[] = "maintainer $i: invalid role `$m[role]', should be one of: ".implode(' ', $this->maintainer_roles);
}
if (empty($m['name'])) {
$errors[] = "maintainer $i: missing name";
}
if (empty($m['email'])) {
$errors[] = "maintainer $i: missing email";
}
$i++;
}
}
if (!empty($info['deps'])) {
$i = 1;
foreach ($info['deps'] as $d) {
if (empty($d['type'])) {
$errors[] = "depenency $i: missing type";
} elseif (!in_array($d['type'], $this->dependency_types)) {
$errors[] = "depenency $i: invalid type, should be one of: ".implode(' ', $this->depenency_types);
}
if (empty($d['rel'])) {
$errors[] = "dependency $i: missing relation";
} elseif (!in_array($d['rel'], $this->dependency_relations)) {
$errors[] = "dependency $i: invalid relation, should be one of: ".implode(' ', $this->dependency_relations);
}
if ($d['rel'] != 'has' && empty($d['version'])) {
$warnings[] = "dependency $i: missing version";
} elseif ($d['rel'] == 'has' && !empty($d['version'])) {
$warnings[] = "dependency $i: version ignored for `has' dependencies";
}
if ($d['type'] == 'php' && !empty($d['name'])) {
$warnings[] = "dependency $i: name ignored for php type dependencies";
} elseif ($d['type'] != 'php' && empty($d['name'])) {
$errors[] = "dependency $i: missing name";
}
$i++;
}
}
if (empty($info['filelist'])) {
$errors[] = 'no files';
} else {
foreach ($info['filelist'] as $file => $fa) {
if (empty($fa['role'])) {
$errors[] = "$file: missing role";
} elseif (!in_array($fa['role'], $this->file_roles)) {
$errors[] = "$file: invalid role, should be one of: ".implode(' ', $this->file_roles);
} elseif ($fa['role'] == 'extsrc' && empty($fa['sources'])) {
$errors[] = "$file: no source files";
}
// Any checks we can do for baseinstalldir?
}
}
return true;
}
// }}}
}
?>

View File

@ -88,11 +88,11 @@ class PEAR_Installer extends PEAR_Common
function _deletePackageFiles($package)
{
$info = $this->registry->packageInfo($package);
if ($info == null) {
$filelist = $this->registry->packageInfo($package, 'filelist');
if ($filelist == null) {
return $this->raiseError("$package not installed");
}
foreach ($info['filelist'] as $file => $props) {
foreach ($filelist as $file => $props) {
$path = $props['installed_as'];
// XXX TODO: do a "rmdir -p dirname($path)" to maintain clean the fs
if (!@unlink($path)) {
@ -264,7 +264,7 @@ class PEAR_Installer extends PEAR_Common
// ==> XXX This part should be removed later on
$flag_old_format = false;
if (!is_file($descfile)) {
// ----- Look for old package .tgz archive format
// ----- Look for old package archive format
// In this format the package.xml file was inside the package directory name
$dp = opendir($tmpdir);
do {
@ -320,7 +320,7 @@ class PEAR_Installer extends PEAR_Common
}
if (empty($options['register_only'])) {
// when upgrading, remove old release's files first:
$this->_deletePackageFiles($package);
$this->_deletePackageFiles($pkgname);
}
}

View File

@ -51,7 +51,6 @@ class PEAR_Packager extends PEAR_Common
function _PEAR_Packager()
{
chdir($this->orig_pwd);
$this->_PEAR_Common();
}