home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / tmp / PEAR-1.7.1 / PEAR / Command / Package.php < prev    next >
Encoding:
PHP Script  |  2008-02-15  |  30.7 KB  |  845 lines

  1. <?php
  2. /**
  3.  * PEAR_Command_Package (package, package-validate, cvsdiff, cvstag, package-dependencies,
  4.  * sign, makerpm, convert commands)
  5.  *
  6.  * PHP versions 4 and 5
  7.  *
  8.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  9.  * that is available through the world-wide-web at the following URI:
  10.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  11.  * the PHP License and are unable to obtain it through the web, please
  12.  * send a note to license@php.net so we can mail you a copy immediately.
  13.  *
  14.  * @category   pear
  15.  * @package    PEAR
  16.  * @author     Stig Bakken <ssb@php.net>
  17.  * @author     Martin Jansen <mj@php.net>
  18.  * @author     Greg Beaver <cellog@php.net>
  19.  * @copyright  1997-2008 The PHP Group
  20.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  21.  * @version    CVS: $Id: Package.php,v 1.126 2008/01/29 03:21:01 cellog Exp $
  22.  * @link       http://pear.php.net/package/PEAR
  23.  * @since      File available since Release 0.1
  24.  */
  25.  
  26. /**
  27.  * base class
  28.  */
  29. require_once 'PEAR/Command/Common.php';
  30.  
  31. /**
  32.  * PEAR commands for login/logout
  33.  *
  34.  * @category   pear
  35.  * @package    PEAR
  36.  * @author     Stig Bakken <ssb@php.net>
  37.  * @author     Martin Jansen <mj@php.net>
  38.  * @author     Greg Beaver <cellog@php.net>
  39.  * @copyright  1997-2008 The PHP Group
  40.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  41.  * @version    Release: @package_version@
  42.  * @link       http://pear.php.net/package/PEAR
  43.  * @since      Class available since Release 0.1
  44.  */
  45.  
  46. class PEAR_Command_Package extends PEAR_Command_Common
  47. {
  48.     // {{{ properties
  49.  
  50.     var $commands = array(
  51.         'package' => array(
  52.             'summary' => 'Build Package',
  53.             'function' => 'doPackage',
  54.             'shortcut' => 'p',
  55.             'options' => array(
  56.                 'nocompress' => array(
  57.                     'shortopt' => 'Z',
  58.                     'doc' => 'Do not gzip the package file'
  59.                     ),
  60.                 'showname' => array(
  61.                     'shortopt' => 'n',
  62.                     'doc' => 'Print the name of the packaged file.',
  63.                     ),
  64.                 ),
  65.             'doc' => '[descfile] [descfile2]
  66. Creates a PEAR package from its description file (usually called
  67. package.xml).  If a second packagefile is passed in, then
  68. the packager will check to make sure that one is a package.xml
  69. version 1.0, and the other is a package.xml version 2.0.  The
  70. package.xml version 1.0 will be saved as "package.xml" in the archive,
  71. and the other as "package2.xml" in the archive"
  72. '
  73.             ),
  74.         'package-validate' => array(
  75.             'summary' => 'Validate Package Consistency',
  76.             'function' => 'doPackageValidate',
  77.             'shortcut' => 'pv',
  78.             'options' => array(),
  79.             'doc' => '
  80. ',
  81.             ),
  82.         'cvsdiff' => array(
  83.             'summary' => 'Run a "cvs diff" for all files in a package',
  84.             'function' => 'doCvsDiff',
  85.             'shortcut' => 'cd',
  86.             'options' => array(
  87.                 'quiet' => array(
  88.                     'shortopt' => 'q',
  89.                     'doc' => 'Be quiet',
  90.                     ),
  91.                 'reallyquiet' => array(
  92.                     'shortopt' => 'Q',
  93.                     'doc' => 'Be really quiet',
  94.                     ),
  95.                 'date' => array(
  96.                     'shortopt' => 'D',
  97.                     'doc' => 'Diff against revision of DATE',
  98.                     'arg' => 'DATE',
  99.                     ),
  100.                 'release' => array(
  101.                     'shortopt' => 'R',
  102.                     'doc' => 'Diff against tag for package release REL',
  103.                     'arg' => 'REL',
  104.                     ),
  105.                 'revision' => array(
  106.                     'shortopt' => 'r',
  107.                     'doc' => 'Diff against revision REV',
  108.                     'arg' => 'REV',
  109.                     ),
  110.                 'context' => array(
  111.                     'shortopt' => 'c',
  112.                     'doc' => 'Generate context diff',
  113.                     ),
  114.                 'unified' => array(
  115.                     'shortopt' => 'u',
  116.                     'doc' => 'Generate unified diff',
  117.                     ),
  118.                 'ignore-case' => array(
  119.                     'shortopt' => 'i',
  120.                     'doc' => 'Ignore case, consider upper- and lower-case letters equivalent',
  121.                     ),
  122.                 'ignore-whitespace' => array(
  123.                     'shortopt' => 'b',
  124.                     'doc' => 'Ignore changes in amount of white space',
  125.                     ),
  126.                 'ignore-blank-lines' => array(
  127.                     'shortopt' => 'B',
  128.                     'doc' => 'Ignore changes that insert or delete blank lines',
  129.                     ),
  130.                 'brief' => array(
  131.                     'doc' => 'Report only whether the files differ, no details',
  132.                     ),
  133.                 'dry-run' => array(
  134.                     'shortopt' => 'n',
  135.                     'doc' => 'Don\'t do anything, just pretend',
  136.                     ),
  137.                 ),
  138.             'doc' => '<package.xml>
  139. Compares all the files in a package.  Without any options, this
  140. command will compare the current code with the last checked-in code.
  141. Using the -r or -R option you may compare the current code with that
  142. of a specific release.
  143. ',
  144.             ),
  145.         'cvstag' => array(
  146.             'summary' => 'Set CVS Release Tag',
  147.             'function' => 'doCvsTag',
  148.             'shortcut' => 'ct',
  149.             'options' => array(
  150.                 'quiet' => array(
  151.                     'shortopt' => 'q',
  152.                     'doc' => 'Be quiet',
  153.                     ),
  154.                 'reallyquiet' => array(
  155.                     'shortopt' => 'Q',
  156.                     'doc' => 'Be really quiet',
  157.                     ),
  158.                 'slide' => array(
  159.                     'shortopt' => 'F',
  160.                     'doc' => 'Move (slide) tag if it exists',
  161.                     ),
  162.                 'delete' => array(
  163.                     'shortopt' => 'd',
  164.                     'doc' => 'Remove tag',
  165.                     ),
  166.                 'dry-run' => array(
  167.                     'shortopt' => 'n',
  168.                     'doc' => 'Don\'t do anything, just pretend',
  169.                     ),
  170.                 ),
  171.             'doc' => '<package.xml> [files...]
  172. Sets a CVS tag on all files in a package.  Use this command after you have
  173. packaged a distribution tarball with the "package" command to tag what
  174. revisions of what files were in that release.  If need to fix something
  175. after running cvstag once, but before the tarball is released to the public,
  176. use the "slide" option to move the release tag.
  177.  
  178. to include files (such as a second package.xml, or tests not included in the
  179. release), pass them as additional parameters.
  180. ',
  181.             ),
  182.         'package-dependencies' => array(
  183.             'summary' => 'Show package dependencies',
  184.             'function' => 'doPackageDependencies',
  185.             'shortcut' => 'pd',
  186.             'options' => array(),
  187.             'doc' => '
  188. List all dependencies the package has.'
  189.             ),
  190.         'sign' => array(
  191.             'summary' => 'Sign a package distribution file',
  192.             'function' => 'doSign',
  193.             'shortcut' => 'si',
  194.             'options' => array(
  195.                 'verbose' => array(
  196.                     'shortopt' => 'v',
  197.                     'doc' => 'Display GnuPG output',
  198.                     ),
  199.             ),
  200.             'doc' => '<package-file>
  201. Signs a package distribution (.tar or .tgz) file with GnuPG.',
  202.             ),
  203.         'makerpm' => array(
  204.             'summary' => 'Builds an RPM spec file from a PEAR package',
  205.             'function' => 'doMakeRPM',
  206.             'shortcut' => 'rpm',
  207.             'options' => array(
  208.                 'spec-template' => array(
  209.                     'shortopt' => 't',
  210.                     'arg' => 'FILE',
  211.                     'doc' => 'Use FILE as RPM spec file template'
  212.                     ),
  213.                 'rpm-pkgname' => array(
  214.                     'shortopt' => 'p',
  215.                     'arg' => 'FORMAT',
  216.                     'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced
  217. by the PEAR package name, defaults to "PEAR::%s".',
  218.                     ),
  219.                 ),
  220.             'doc' => '<package-file>
  221.  
  222. Creates an RPM .spec file for wrapping a PEAR package inside an RPM
  223. package.  Intended to be used from the SPECS directory, with the PEAR
  224. package tarball in the SOURCES directory:
  225.  
  226. $ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
  227. Wrote RPM spec file PEAR::Net_Geo-1.0.spec
  228. $ rpm -bb PEAR::Net_Socket-1.0.spec
  229. ...
  230. Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
  231. ',
  232.             ),
  233.         'convert' => array(
  234.             'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format',
  235.             'function' => 'doConvert',
  236.             'shortcut' => 'c2',
  237.             'options' => array(
  238.                 'flat' => array(
  239.                     'shortopt' => 'f',
  240.                     'doc' => 'do not beautify the filelist.',
  241.                     ),
  242.                 ),
  243.             'doc' => '[descfile] [descfile2]
  244. Converts a package.xml in 1.0 format into a package.xml
  245. in 2.0 format.  The new file will be named package2.xml by default,
  246. and package.xml will be used as the old file by default.
  247. This is not the most intelligent conversion, and should only be
  248. used for automated conversion or learning the format.
  249. '
  250.             ),
  251.         );
  252.  
  253.     var $output;
  254.  
  255.     // }}}
  256.     // {{{ constructor
  257.  
  258.     /**
  259.      * PEAR_Command_Package constructor.
  260.      *
  261.      * @access public
  262.      */
  263.     function PEAR_Command_Package(&$ui, &$config)
  264.     {
  265.         parent::PEAR_Command_Common($ui, $config);
  266.     }
  267.  
  268.     // }}}
  269.  
  270.     // {{{ _displayValidationResults()
  271.  
  272.     function _displayValidationResults($err, $warn, $strict = false)
  273.     {
  274.         foreach ($err as $e) {
  275.             $this->output .= "Error: $e\n";
  276.         }
  277.         foreach ($warn as $w) {
  278.             $this->output .= "Warning: $w\n";
  279.         }
  280.         $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
  281.                                        sizeof($err), sizeof($warn));
  282.         if ($strict && sizeof($err) > 0) {
  283.             $this->output .= "Fix these errors and try again.";
  284.             return false;
  285.         }
  286.         return true;
  287.     }
  288.  
  289.     // }}}
  290.     function &getPackager()
  291.     {
  292.         if (!class_exists('PEAR_Packager')) {
  293.             require_once 'PEAR/Packager.php';
  294.         }
  295.         $a = &new PEAR_Packager;
  296.         return $a;
  297.     }
  298.  
  299.     function &getPackageFile($config, $debug = false, $tmpdir = null)
  300.     {
  301.         if (!class_exists('PEAR_Common')) {
  302.             require_once 'PEAR/Common.php';
  303.         }
  304.         if (!class_exists('PEAR_PackageFile')) {
  305.             require_once 'PEAR/PackageFile.php';
  306.         }
  307.         $a = &new PEAR_PackageFile($config, $debug, $tmpdir);
  308.         $common = new PEAR_Common;
  309.         $common->ui = $this->ui;
  310.         $a->setLogger($common);
  311.         return $a;
  312.     }
  313.     // {{{ doPackage()
  314.  
  315.     function doPackage($command, $options, $params)
  316.     {
  317.         $this->output = '';
  318.         $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
  319.         $pkg2 = isset($params[1]) ? $params[1] : null;
  320.         if (!$pkg2 && !isset($params[0])) {
  321.             if (file_exists('package2.xml')) {
  322.                 $pkg2 = 'package2.xml';
  323.             }
  324.         }
  325.         $packager = &$this->getPackager();
  326.         $compress = empty($options['nocompress']) ? true : false;
  327.         $result = $packager->package($pkginfofile, $compress, $pkg2);
  328.         if (PEAR::isError($result)) {
  329.             return $this->raiseError($result);
  330.         }
  331.         // Don't want output, only the package file name just created
  332.         if (isset($options['showname'])) {
  333.             $this->output = $result;
  334.         }
  335.         if ($this->output) {
  336.             $this->ui->outputData($this->output, $command);
  337.         }
  338.         return true;
  339.     }
  340.  
  341.     // }}}
  342.     // {{{ doPackageValidate()
  343.  
  344.     function doPackageValidate($command, $options, $params)
  345.     {
  346.         $this->output = '';
  347.         if (sizeof($params) < 1) {
  348.             $params[0] = "package.xml";
  349.         }
  350.         $obj = &$this->getPackageFile($this->config, $this->_debug);
  351.         $obj->rawReturn();
  352.         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  353.         $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
  354.         if (PEAR::isError($info)) {
  355.             $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
  356.         } else {
  357.             $archive = $info->getArchiveFile();
  358.             $tar = &new Archive_Tar($archive);
  359.             $tar->extract(dirname($info->getPackageFile()));
  360.             $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
  361.                 $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
  362.                 basename($info->getPackageFile()));
  363.         }
  364.         PEAR::staticPopErrorHandling();
  365.         if (PEAR::isError($info)) {
  366.             return $this->raiseError($info);
  367.         }
  368.         $valid = false;
  369.         if ($info->getPackagexmlVersion() == '2.0') {
  370.             if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
  371.                 $info->flattenFileList();
  372.                 $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
  373.             }
  374.         } else {
  375.             $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
  376.         }
  377.         $err = array();
  378.         $warn = array();
  379.         if (!$valid) {
  380.             foreach ($info->getValidationWarnings() as $error) {
  381.                 if ($error['level'] == 'warning') {
  382.                     $warn[] = $error['message'];
  383.                 } else {
  384.                     $err[] = $error['message'];
  385.                 }
  386.             }
  387.         }
  388.         $this->_displayValidationResults($err, $warn);
  389.         $this->ui->outputData($this->output, $command);
  390.         return true;
  391.     }
  392.  
  393.     // }}}
  394.     // {{{ doCvsTag()
  395.  
  396.     function doCvsTag($command, $options, $params)
  397.     {
  398.         $this->output = '';
  399.         $_cmd = $command;
  400.         if (sizeof($params) < 1) {
  401.             $help = $this->getHelp($command);
  402.             return $this->raiseError("$command: missing parameter: $help[0]");
  403.         }
  404.         $obj = &$this->getPackageFile($this->config, $this->_debug);
  405.         $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
  406.         if (PEAR::isError($info)) {
  407.             return $this->raiseError($info);
  408.         }
  409.         $err = $warn = array();
  410.         if (!$info->validate()) {
  411.             foreach ($info->getValidationWarnings() as $error) {
  412.                 if ($error['level'] == 'warning') {
  413.                     $warn[] = $error['message'];
  414.                 } else {
  415.                     $err[] = $error['message'];
  416.                 }
  417.             }
  418.         }
  419.         if (!$this->_displayValidationResults($err, $warn, true)) {
  420.             $this->ui->outputData($this->output, $command);
  421.             return $this->raiseError('CVS tag failed');
  422.         }
  423.         $version = $info->getVersion();
  424.         $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
  425.         $cvstag = "RELEASE_$cvsversion";
  426.         $files = array_keys($info->getFilelist());
  427.         $command = "cvs";
  428.         if (isset($options['quiet'])) {
  429.             $command .= ' -q';
  430.         }
  431.         if (isset($options['reallyquiet'])) {
  432.             $command .= ' -Q';
  433.         }
  434.         $command .= ' tag';
  435.         if (isset($options['slide'])) {
  436.             $command .= ' -F';
  437.         }
  438.         if (isset($options['delete'])) {
  439.             $command .= ' -d';
  440.         }
  441.         $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
  442.         array_shift($params);
  443.         if (count($params)) {
  444.             // add in additional files to be tagged
  445.             $files = array_merge($files, $params);
  446.         }
  447.         foreach ($files as $file) {
  448.             $command .= ' ' . escapeshellarg($file);
  449.         }
  450.         if ($this->config->get('verbose') > 1) {
  451.             $this->output .= "+ $command\n";
  452.         }
  453.         $this->output .= "+ $command\n";
  454.         if (empty($options['dry-run'])) {
  455.             $fp = popen($command, "r");
  456.             while ($line = fgets($fp, 1024)) {
  457.                 $this->output .= rtrim($line)."\n";
  458.             }
  459.             pclose($fp);
  460.         }
  461.         $this->ui->outputData($this->output, $_cmd);
  462.         return true;
  463.     }
  464.  
  465.     // }}}
  466.     // {{{ doCvsDiff()
  467.  
  468.     function doCvsDiff($command, $options, $params)
  469.     {
  470.         $this->output = '';
  471.         if (sizeof($params) < 1) {
  472.             $help = $this->getHelp($command);
  473.             return $this->raiseError("$command: missing parameter: $help[0]");
  474.         }
  475.         $obj = &$this->getPackageFile($this->config, $this->_debug);
  476.         $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
  477.         if (PEAR::isError($info)) {
  478.             return $this->raiseError($info);
  479.         }
  480.         $err = $warn = array();
  481.         if (!$info->validate()) {
  482.             foreach ($info->getValidationWarnings() as $error) {
  483.                 if ($error['level'] == 'warning') {
  484.                     $warn[] = $error['message'];
  485.                 } else {
  486.                     $err[] = $error['message'];
  487.                 }
  488.             }
  489.         }
  490.         if (!$this->_displayValidationResults($err, $warn, true)) {
  491.             $this->ui->outputData($this->output, $command);
  492.             return $this->raiseError('CVS diff failed');
  493.         }
  494.         $info1 = $info->getFilelist();
  495.         $files = $info1;
  496.         $cmd = "cvs";
  497.         if (isset($options['quiet'])) {
  498.             $cmd .= ' -q';
  499.             unset($options['quiet']);
  500.         }
  501.         if (isset($options['reallyquiet'])) {
  502.             $cmd .= ' -Q';
  503.             unset($options['reallyquiet']);
  504.         }
  505.         if (isset($options['release'])) {
  506.             $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
  507.             $cvstag = "RELEASE_$cvsversion";
  508.             $options['revision'] = $cvstag;
  509.             unset($options['release']);
  510.         }
  511.         $execute = true;
  512.         if (isset($options['dry-run'])) {
  513.             $execute = false;
  514.             unset($options['dry-run']);
  515.         }
  516.         $cmd .= ' diff';
  517.         // the rest of the options are passed right on to "cvs diff"
  518.         foreach ($options as $option => $optarg) {
  519.             $arg = $short = false;
  520.             if (isset($this->commands[$command]['options'][$option])) {
  521.                 $arg = $this->commands[$command]['options'][$option]['arg'];
  522.                 $short = $this->commands[$command]['options'][$option]['shortopt'];
  523.             }
  524.             $cmd .= $short ? " -$short" : " --$option";
  525.             if ($arg && $optarg) {
  526.                 $cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
  527.             }
  528.         }
  529.         foreach ($files as $file) {
  530.             $cmd .= ' ' . escapeshellarg($file['name']);
  531.         }
  532.         if ($this->config->get('verbose') > 1) {
  533.             $this->output .= "+ $cmd\n";
  534.         }
  535.         if ($execute) {
  536.             $fp = popen($cmd, "r");
  537.             while ($line = fgets($fp, 1024)) {
  538.                 $this->output .= rtrim($line)."\n";
  539.             }
  540.             pclose($fp);
  541.         }
  542.         $this->ui->outputData($this->output, $command);
  543.         return true;
  544.     }
  545.  
  546.     // }}}
  547.     // {{{ doPackageDependencies()
  548.  
  549.     function doPackageDependencies($command, $options, $params)
  550.     {
  551.         // $params[0] -> the PEAR package to list its information
  552.         if (sizeof($params) != 1) {
  553.             return $this->raiseError("bad parameter(s), try \"help $command\"");
  554.         }
  555.         $obj = &$this->getPackageFile($this->config, $this->_debug);
  556.         $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
  557.         if (PEAR::isError($info)) {
  558.             return $this->raiseError($info);
  559.         }
  560.         $deps = $info->getDeps();
  561.         if (is_array($deps)) {
  562.             if ($info->getPackagexmlVersion() == '1.0') {
  563.                 $data = array(
  564.                     'caption' => 'Dependencies for pear/' . $info->getPackage(),
  565.                     'border' => true,
  566.                     'headline' => array("Required?", "Type", "Name", "Relation", "Version"),
  567.                     );
  568.  
  569.                 foreach ($deps as $d) {
  570.                     if (isset($d['optional'])) {
  571.                         if ($d['optional'] == 'yes') {
  572.                             $req = 'No';
  573.                         } else {
  574.                             $req = 'Yes';
  575.                         }
  576.                     } else {
  577.                         $req = 'Yes';
  578.                     }
  579.                     if (isset($this->_deps_rel_trans[$d['rel']])) {
  580.                         $rel = $this->_deps_rel_trans[$d['rel']];
  581.                     } else {
  582.                         $rel = $d['rel'];
  583.                     }
  584.  
  585.                     if (isset($this->_deps_type_trans[$d['type']])) {
  586.                         $type = ucfirst($this->_deps_type_trans[$d['type']]);
  587.                     } else {
  588.                         $type = $d['type'];
  589.                     }
  590.  
  591.                     if (isset($d['name'])) {
  592.                         $name = $d['name'];
  593.                     } else {
  594.                         $name = '';
  595.                     }
  596.  
  597.                     if (isset($d['version'])) {
  598.                         $version = $d['version'];
  599.                     } else {
  600.                         $version = '';
  601.                     }
  602.  
  603.                     $data['data'][] = array($req, $type, $name, $rel, $version);
  604.                 }
  605.             } else { // package.xml 2.0 dependencies display
  606.                 require_once 'PEAR/Dependency2.php';
  607.                 $deps = $info->getDependencies();
  608.                 $reg = &$this->config->getRegistry();
  609.                 if (is_array($deps)) {
  610.                     $d = new PEAR_Dependency2($this->config, array(), '');
  611.                     $data = array(
  612.                         'caption' => 'Dependencies for ' . $info->getPackage(),
  613.                         'border' => true,
  614.                         'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'),
  615.                         );
  616.                     foreach ($deps as $type => $subd) {
  617.                         $req = ($type == 'required') ? 'Yes' : 'No';
  618.                         if ($type == 'group') {
  619.                             $group = $subd['attribs']['name'];
  620.                         } else {
  621.                             $group = '';
  622.                         }
  623.                         if (!isset($subd[0])) {
  624.                             $subd = array($subd);
  625.                         }
  626.                         foreach ($subd as $groupa) {
  627.                             foreach ($groupa as $deptype => $depinfo) {
  628.                                 if ($deptype == 'attribs') {
  629.                                     continue;
  630.                                 }
  631.                                 if ($deptype == 'pearinstaller') {
  632.                                     $deptype = 'pear Installer';
  633.                                 }
  634.                                 if (!isset($depinfo[0])) {
  635.                                     $depinfo = array($depinfo);
  636.                                 }
  637.                                 foreach ($depinfo as $inf) {
  638.                                     $name = '';
  639.                                     if (isset($inf['channel'])) {
  640.                                         $alias = $reg->channelAlias($inf['channel']);
  641.                                         if (!$alias) {
  642.                                             $alias = '(channel?) ' .$inf['channel'];
  643.                                         }
  644.                                         $name = $alias . '/';
  645.                                     }
  646.                                     if (isset($inf['name'])) {
  647.                                         $name .= $inf['name'];
  648.                                     } elseif (isset($inf['pattern'])) {
  649.                                         $name .= $inf['pattern'];
  650.                                     } else {
  651.                                         $name .= '';
  652.                                     }
  653.                                     if (isset($inf['uri'])) {
  654.                                         $name .= ' [' . $inf['uri'] .  ']';
  655.                                     }
  656.                                     if (isset($inf['conflicts'])) {
  657.                                         $ver = 'conflicts';
  658.                                     } else {
  659.                                         $ver = $d->_getExtraString($inf);
  660.                                     }
  661.                                     $data['data'][] = array($req, ucfirst($deptype), $name,
  662.                                         $ver, $group);
  663.                                 }
  664.                             }
  665.                         }
  666.                     }
  667.                 }
  668.             }
  669.  
  670.             $this->ui->outputData($data, $command);
  671.             return true;
  672.         }
  673.  
  674.         // Fallback
  675.         $this->ui->outputData("This package does not have any dependencies.", $command);
  676.     }
  677.  
  678.     // }}}
  679.     // {{{ doSign()
  680.  
  681.     function doSign($command, $options, $params)
  682.     {
  683.         require_once 'System.php';
  684.         require_once 'Archive/Tar.php';
  685.         // should move most of this code into PEAR_Packager
  686.         // so it'll be easy to implement "pear package --sign"
  687.         if (sizeof($params) != 1) {
  688.             return $this->raiseError("bad parameter(s), try \"help $command\"");
  689.         }
  690.         if (!file_exists($params[0])) {
  691.             return $this->raiseError("file does not exist: $params[0]");
  692.         }
  693.         $obj = $this->getPackageFile($this->config, $this->_debug);
  694.         $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
  695.         if (PEAR::isError($info)) {
  696.             return $this->raiseError($info);
  697.         }
  698.         $tar = new Archive_Tar($params[0]);
  699.         $tmpdir = System::mktemp('-d pearsign');
  700.         if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
  701.             return $this->raiseError("failed to extract tar file");
  702.         }
  703.         if (file_exists("$tmpdir/package.sig")) {
  704.             return $this->raiseError("package already signed");
  705.         }
  706.         $packagexml = 'package.xml';
  707.         if (file_exists("$tmpdir/package2.xml")) {
  708.             $packagexml = 'package2.xml';
  709.         }
  710.         if (file_exists("$tmpdir/package.sig")) {
  711.             unlink("$tmpdir/package.sig");
  712.         }
  713.         if (!file_exists("$tmpdir/$packagexml")) {
  714.             return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
  715.         }
  716.         $input = $this->ui->userDialog($command,
  717.                                        array('GnuPG Passphrase'),
  718.                                        array('password'));
  719.         if (!isset($input[0])) {
  720.             //use empty passphrase
  721.             $input[0] = '';
  722.         }
  723.  
  724.         $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
  725.         $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
  726.         if (!$gpg) {
  727.             return $this->raiseError("gpg command failed");
  728.         }
  729.         fwrite($gpg, "$input[0]\n");
  730.         if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
  731.             return $this->raiseError("gpg sign failed");
  732.         }
  733.         if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
  734.             return $this->raiseError('failed adding signature to file');
  735.         }
  736.  
  737.         $this->ui->outputData("Package signed.", $command);
  738.         return true;
  739.     }
  740.  
  741.     // }}}
  742.  
  743.     /**
  744.      * For unit testing purposes
  745.      */
  746.     function &getInstaller(&$ui)
  747.     {
  748.         if (!class_exists('PEAR_Installer')) {
  749.             require_once 'PEAR/Installer.php';
  750.         }
  751.         $a = &new PEAR_Installer($ui);
  752.         return $a;
  753.     }
  754.     
  755.     /**
  756.      * For unit testing purposes
  757.      */
  758.     function &getCommandPackaging(&$ui, &$config)
  759.     {
  760.         if (!class_exists('PEAR_Command_Packaging')) {
  761.             if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
  762.                 fclose($fp);
  763.                 include_once 'PEAR/Command/Packaging.php';
  764.             }
  765.         }
  766.         
  767.         if (class_exists('PEAR_Command_Packaging')) {
  768.             $a = &new PEAR_Command_Packaging($ui, $config);
  769.         } else {
  770.             $a = null;
  771.         }
  772.         return $a;
  773.     }
  774.  
  775.     // {{{ doMakeRPM()
  776.  
  777.     function doMakeRPM($command, $options, $params)
  778.     {
  779.  
  780.         // Check to see if PEAR_Command_Packaging is installed, and
  781.         // transparently switch to use the "make-rpm-spec" command from it
  782.         // instead, if it does. Otherwise, continue to use the old version
  783.         // of "makerpm" supplied with this package (PEAR).
  784.         $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
  785.         if ($packaging_cmd !== null) {
  786.             $this->ui->outputData('PEAR_Command_Packaging is installed; using '.
  787.                 'newer "make-rpm-spec" command instead');
  788.             return $packaging_cmd->run('make-rpm-spec', $options, $params);
  789.         } else {
  790.             $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
  791.               'improved version is available via "pear make-rpm-spec", which '.
  792.               'is available by installing PEAR_Command_Packaging');
  793.         }
  794.         return true;
  795.     }
  796.  
  797.     function doConvert($command, $options, $params)
  798.     {
  799.         $packagexml = isset($params[0]) ? $params[0] : 'package.xml';
  800.         $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
  801.             DIRECTORY_SEPARATOR . 'package2.xml';
  802.         $pkg = &$this->getPackageFile($this->config, $this->_debug);
  803.         PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  804.         $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
  805.         PEAR::staticPopErrorHandling();
  806.         if (!PEAR::isError($pf)) {
  807.             if (is_a($pf, 'PEAR_PackageFile_v2')) {
  808.                 $this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
  809.                 return true;
  810.             }
  811.             $gen = &$pf->getDefaultGenerator();
  812.             $newpf = &$gen->toV2();
  813.             $newpf->setPackagefile($newpackagexml);
  814.             $gen = &$newpf->getDefaultGenerator();
  815.             PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
  816.             $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
  817.             $saved = $gen->toPackageFile(dirname($newpackagexml), $state,
  818.                 basename($newpackagexml));
  819.             PEAR::staticPopErrorHandling();
  820.             if (PEAR::isError($saved)) {
  821.                 if (is_array($saved->getUserInfo())) {
  822.                     foreach ($saved->getUserInfo() as $warning) {
  823.                         $this->ui->outputData($warning['message']);
  824.                     }
  825.                 }
  826.                 $this->ui->outputData($saved->getMessage());
  827.                 return true;
  828.             }
  829.             $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
  830.             return true;
  831.         } else {
  832.             if (is_array($pf->getUserInfo())) {
  833.                 foreach ($pf->getUserInfo() as $warning) {
  834.                     $this->ui->outputData($warning['message']);
  835.                 }
  836.             }
  837.             return $this->raiseError($pf);
  838.         }
  839.     }
  840.  
  841.     // }}}
  842. }
  843.  
  844. ?>
  845.