[ Index ] |
|
Code source de GeekLog 1.4.1 |
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-2006 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.119.2.1 2006/06/07 23:39:22 pajoye 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-2006 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 'doc' => '<package-file> 196 Signs a package distribution (.tar or .tgz) file with GnuPG.', 197 ), 198 'makerpm' => array( 199 'summary' => 'Builds an RPM spec file from a PEAR package', 200 'function' => 'doMakeRPM', 201 'shortcut' => 'rpm', 202 'options' => array( 203 'spec-template' => array( 204 'shortopt' => 't', 205 'arg' => 'FILE', 206 'doc' => 'Use FILE as RPM spec file template' 207 ), 208 'rpm-pkgname' => array( 209 'shortopt' => 'p', 210 'arg' => 'FORMAT', 211 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced 212 by the PEAR package name, defaults to "PEAR::%s".', 213 ), 214 ), 215 'doc' => '<package-file> 216 217 Creates an RPM .spec file for wrapping a PEAR package inside an RPM 218 package. Intended to be used from the SPECS directory, with the PEAR 219 package tarball in the SOURCES directory: 220 221 $ pear makerpm ../SOURCES/Net_Socket-1.0.tgz 222 Wrote RPM spec file PEAR::Net_Geo-1.0.spec 223 $ rpm -bb PEAR::Net_Socket-1.0.spec 224 ... 225 Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm 226 ', 227 ), 228 'convert' => array( 229 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', 230 'function' => 'doConvert', 231 'shortcut' => 'c2', 232 'options' => array( 233 'flat' => array( 234 'shortopt' => 'f', 235 'doc' => 'do not beautify the filelist.', 236 ), 237 ), 238 'doc' => '[descfile] [descfile2] 239 Converts a package.xml in 1.0 format into a package.xml 240 in 2.0 format. The new file will be named package2.xml by default, 241 and package.xml will be used as the old file by default. 242 This is not the most intelligent conversion, and should only be 243 used for automated conversion or learning the format. 244 ' 245 ), 246 ); 247 248 var $output; 249 250 // }}} 251 // {{{ constructor 252 253 /** 254 * PEAR_Command_Package constructor. 255 * 256 * @access public 257 */ 258 function PEAR_Command_Package(&$ui, &$config) 259 { 260 parent::PEAR_Command_Common($ui, $config); 261 } 262 263 // }}} 264 265 // {{{ _displayValidationResults() 266 267 function _displayValidationResults($err, $warn, $strict = false) 268 { 269 foreach ($err as $e) { 270 $this->output .= "Error: $e\n"; 271 } 272 foreach ($warn as $w) { 273 $this->output .= "Warning: $w\n"; 274 } 275 $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", 276 sizeof($err), sizeof($warn)); 277 if ($strict && sizeof($err) > 0) { 278 $this->output .= "Fix these errors and try again."; 279 return false; 280 } 281 return true; 282 } 283 284 // }}} 285 function &getPackager() 286 { 287 if (!class_exists('PEAR_Packager')) { 288 require_once 'PEAR/Packager.php'; 289 } 290 $a = &new PEAR_Packager; 291 return $a; 292 } 293 294 function &getPackageFile($config, $debug = false, $tmpdir = null) 295 { 296 if (!class_exists('PEAR_Common')) { 297 require_once 'PEAR/Common.php'; 298 } 299 if (!class_exists('PEAR/PackageFile.php')) { 300 require_once 'PEAR/PackageFile.php'; 301 } 302 $a = &new PEAR_PackageFile($config, $debug, $tmpdir); 303 $common = new PEAR_Common; 304 $common->ui = $this->ui; 305 $a->setLogger($common); 306 return $a; 307 } 308 // {{{ doPackage() 309 310 function doPackage($command, $options, $params) 311 { 312 $this->output = ''; 313 $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; 314 $pkg2 = isset($params[1]) ? $params[1] : null; 315 if (!$pkg2 && !isset($params[0])) { 316 if (file_exists('package2.xml')) { 317 $pkg2 = 'package2.xml'; 318 } 319 } 320 $packager = &$this->getPackager(); 321 $compress = empty($options['nocompress']) ? true : false; 322 $result = $packager->package($pkginfofile, $compress, $pkg2); 323 if (PEAR::isError($result)) { 324 return $this->raiseError($result); 325 } 326 // Don't want output, only the package file name just created 327 if (isset($options['showname'])) { 328 $this->output = $result; 329 } 330 if ($this->output) { 331 $this->ui->outputData($this->output, $command); 332 } 333 return true; 334 } 335 336 // }}} 337 // {{{ doPackageValidate() 338 339 function doPackageValidate($command, $options, $params) 340 { 341 $this->output = ''; 342 if (sizeof($params) < 1) { 343 $params[0] = "package.xml"; 344 } 345 $obj = &$this->getPackageFile($this->config, $this->_debug); 346 $obj->rawReturn(); 347 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 348 $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); 349 if (PEAR::isError($info)) { 350 $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); 351 } else { 352 $archive = $info->getArchiveFile(); 353 $tar = &new Archive_Tar($archive); 354 $tar->extract(dirname($info->getPackageFile())); 355 $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . 356 $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . 357 basename($info->getPackageFile())); 358 } 359 PEAR::staticPopErrorHandling(); 360 if (PEAR::isError($info)) { 361 return $this->raiseError($info); 362 } 363 $valid = false; 364 if ($info->getPackagexmlVersion() == '2.0') { 365 if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { 366 $info->flattenFileList(); 367 $valid = $info->validate(PEAR_VALIDATE_PACKAGING); 368 } 369 } else { 370 $valid = $info->validate(PEAR_VALIDATE_PACKAGING); 371 } 372 $err = array(); 373 $warn = array(); 374 if (!$valid) { 375 foreach ($info->getValidationWarnings() as $error) { 376 if ($error['level'] == 'warning') { 377 $warn[] = $error['message']; 378 } else { 379 $err[] = $error['message']; 380 } 381 } 382 } 383 $this->_displayValidationResults($err, $warn); 384 $this->ui->outputData($this->output, $command); 385 return true; 386 } 387 388 // }}} 389 // {{{ doCvsTag() 390 391 function doCvsTag($command, $options, $params) 392 { 393 $this->output = ''; 394 $_cmd = $command; 395 if (sizeof($params) < 1) { 396 $help = $this->getHelp($command); 397 return $this->raiseError("$command: missing parameter: $help[0]"); 398 } 399 $obj = &$this->getPackageFile($this->config, $this->_debug); 400 $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); 401 if (PEAR::isError($info)) { 402 return $this->raiseError($info); 403 } 404 $err = $warn = array(); 405 if (!$info->validate()) { 406 foreach ($info->getValidationWarnings() as $error) { 407 if ($error['level'] == 'warning') { 408 $warn[] = $error['message']; 409 } else { 410 $err[] = $error['message']; 411 } 412 } 413 } 414 if (!$this->_displayValidationResults($err, $warn, true)) { 415 $this->ui->outputData($this->output, $command); 416 return $this->raiseError('CVS tag failed'); 417 } 418 $version = $info->getVersion(); 419 $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); 420 $cvstag = "RELEASE_$cvsversion"; 421 $files = array_keys($info->getFilelist()); 422 $command = "cvs"; 423 if (isset($options['quiet'])) { 424 $command .= ' -q'; 425 } 426 if (isset($options['reallyquiet'])) { 427 $command .= ' -Q'; 428 } 429 $command .= ' tag'; 430 if (isset($options['slide'])) { 431 $command .= ' -F'; 432 } 433 if (isset($options['delete'])) { 434 $command .= ' -d'; 435 } 436 $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); 437 array_shift($params); 438 if (count($params)) { 439 // add in additional files to be tagged 440 $files = array_merge($files, $params); 441 } 442 foreach ($files as $file) { 443 $command .= ' ' . escapeshellarg($file); 444 } 445 if ($this->config->get('verbose') > 1) { 446 $this->output .= "+ $command\n"; 447 } 448 $this->output .= "+ $command\n"; 449 if (empty($options['dry-run'])) { 450 $fp = popen($command, "r"); 451 while ($line = fgets($fp, 1024)) { 452 $this->output .= rtrim($line)."\n"; 453 } 454 pclose($fp); 455 } 456 $this->ui->outputData($this->output, $_cmd); 457 return true; 458 } 459 460 // }}} 461 // {{{ doCvsDiff() 462 463 function doCvsDiff($command, $options, $params) 464 { 465 $this->output = ''; 466 if (sizeof($params) < 1) { 467 $help = $this->getHelp($command); 468 return $this->raiseError("$command: missing parameter: $help[0]"); 469 } 470 $obj = &$this->getPackageFile($this->config, $this->_debug); 471 $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); 472 if (PEAR::isError($info)) { 473 return $this->raiseError($info); 474 } 475 $err = $warn = array(); 476 if (!$info->validate()) { 477 foreach ($info->getValidationWarnings() as $error) { 478 if ($error['level'] == 'warning') { 479 $warn[] = $error['message']; 480 } else { 481 $err[] = $error['message']; 482 } 483 } 484 } 485 if (!$this->_displayValidationResults($err, $warn, true)) { 486 $this->ui->outputData($this->output, $command); 487 return $this->raiseError('CVS diff failed'); 488 } 489 $info1 = $info->getFilelist(); 490 $files = $info1; 491 $cmd = "cvs"; 492 if (isset($options['quiet'])) { 493 $cmd .= ' -q'; 494 unset($options['quiet']); 495 } 496 if (isset($options['reallyquiet'])) { 497 $cmd .= ' -Q'; 498 unset($options['reallyquiet']); 499 } 500 if (isset($options['release'])) { 501 $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); 502 $cvstag = "RELEASE_$cvsversion"; 503 $options['revision'] = $cvstag; 504 unset($options['release']); 505 } 506 $execute = true; 507 if (isset($options['dry-run'])) { 508 $execute = false; 509 unset($options['dry-run']); 510 } 511 $cmd .= ' diff'; 512 // the rest of the options are passed right on to "cvs diff" 513 foreach ($options as $option => $optarg) { 514 $arg = @$this->commands[$command]['options'][$option]['arg']; 515 $short = @$this->commands[$command]['options'][$option]['shortopt']; 516 $cmd .= $short ? " -$short" : " --$option"; 517 if ($arg && $optarg) { 518 $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); 519 } 520 } 521 foreach ($files as $file) { 522 $cmd .= ' ' . escapeshellarg($file['name']); 523 } 524 if ($this->config->get('verbose') > 1) { 525 $this->output .= "+ $cmd\n"; 526 } 527 if ($execute) { 528 $fp = popen($cmd, "r"); 529 while ($line = fgets($fp, 1024)) { 530 $this->output .= rtrim($line)."\n"; 531 } 532 pclose($fp); 533 } 534 $this->ui->outputData($this->output, $command); 535 return true; 536 } 537 538 // }}} 539 // {{{ doPackageDependencies() 540 541 function doPackageDependencies($command, $options, $params) 542 { 543 // $params[0] -> the PEAR package to list its information 544 if (sizeof($params) != 1) { 545 return $this->raiseError("bad parameter(s), try \"help $command\""); 546 } 547 $obj = &$this->getPackageFile($this->config, $this->_debug); 548 $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); 549 if (PEAR::isError($info)) { 550 return $this->raiseError($info); 551 } 552 $deps = $info->getDeps(); 553 if (is_array($deps)) { 554 if ($info->getPackagexmlVersion() == '1.0') { 555 $data = array( 556 'caption' => 'Dependencies for pear/' . $info->getPackage(), 557 'border' => true, 558 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), 559 ); 560 561 foreach ($deps as $d) { 562 if (isset($d['optional'])) { 563 if ($d['optional'] == 'yes') { 564 $req = 'No'; 565 } else { 566 $req = 'Yes'; 567 } 568 } else { 569 $req = 'Yes'; 570 } 571 if (isset($this->_deps_rel_trans[$d['rel']])) { 572 $rel = $this->_deps_rel_trans[$d['rel']]; 573 } else { 574 $rel = $d['rel']; 575 } 576 577 if (isset($this->_deps_type_trans[$d['type']])) { 578 $type = ucfirst($this->_deps_type_trans[$d['type']]); 579 } else { 580 $type = $d['type']; 581 } 582 583 if (isset($d['name'])) { 584 $name = $d['name']; 585 } else { 586 $name = ''; 587 } 588 589 if (isset($d['version'])) { 590 $version = $d['version']; 591 } else { 592 $version = ''; 593 } 594 595 $data['data'][] = array($req, $type, $name, $rel, $version); 596 } 597 } else { // package.xml 2.0 dependencies display 598 require_once 'PEAR/Dependency2.php'; 599 $deps = $info->getDependencies(); 600 $reg = &$this->config->getRegistry(); 601 if (is_array($deps)) { 602 $d = new PEAR_Dependency2($this->config, array(), ''); 603 $data = array( 604 'caption' => 'Dependencies for ' . $info->getPackage(), 605 'border' => true, 606 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), 607 ); 608 foreach ($deps as $type => $subd) { 609 $req = ($type == 'required') ? 'Yes' : 'No'; 610 if ($type == 'group') { 611 $group = $subd['attribs']['name']; 612 } else { 613 $group = ''; 614 } 615 if (!isset($subd[0])) { 616 $subd = array($subd); 617 } 618 foreach ($subd as $groupa) { 619 foreach ($groupa as $deptype => $depinfo) { 620 if ($deptype == 'attribs') { 621 continue; 622 } 623 if ($deptype == 'pearinstaller') { 624 $deptype = 'pear Installer'; 625 } 626 if (!isset($depinfo[0])) { 627 $depinfo = array($depinfo); 628 } 629 foreach ($depinfo as $inf) { 630 $name = ''; 631 if (isset($inf['channel'])) { 632 $alias = $reg->channelAlias($inf['channel']); 633 if (!$alias) { 634 $alias = '(channel?) ' .$inf['channel']; 635 } 636 $name = $alias . '/'; 637 } 638 if (isset($inf['name'])) { 639 $name .= $inf['name']; 640 } elseif (isset($inf['pattern'])) { 641 $name .= $inf['pattern']; 642 } else { 643 $name .= ''; 644 } 645 if (isset($inf['uri'])) { 646 $name .= ' [' . $inf['uri'] . ']'; 647 } 648 if (isset($inf['conflicts'])) { 649 $ver = 'conflicts'; 650 } else { 651 $ver = $d->_getExtraString($inf); 652 } 653 $data['data'][] = array($req, ucfirst($deptype), $name, 654 $ver, $group); 655 } 656 } 657 } 658 } 659 } 660 } 661 662 $this->ui->outputData($data, $command); 663 return true; 664 } 665 666 // Fallback 667 $this->ui->outputData("This package does not have any dependencies.", $command); 668 } 669 670 // }}} 671 // {{{ doSign() 672 673 function doSign($command, $options, $params) 674 { 675 require_once 'System.php'; 676 require_once 'Archive/Tar.php'; 677 // should move most of this code into PEAR_Packager 678 // so it'll be easy to implement "pear package --sign" 679 if (sizeof($params) != 1) { 680 return $this->raiseError("bad parameter(s), try \"help $command\""); 681 } 682 if (!file_exists($params[0])) { 683 return $this->raiseError("file does not exist: $params[0]"); 684 } 685 $obj = $this->getPackageFile($this->config, $this->_debug); 686 $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); 687 if (PEAR::isError($info)) { 688 return $this->raiseError($info); 689 } 690 $tar = new Archive_Tar($params[0]); 691 $tmpdir = System::mktemp('-d pearsign'); 692 if (!$tar->extractList('package2.xml package.sig', $tmpdir)) { 693 if (!$tar->extractList('package.xml package.sig', $tmpdir)) { 694 return $this->raiseError("failed to extract tar file"); 695 } 696 } 697 if (file_exists("$tmpdir/package.sig")) { 698 return $this->raiseError("package already signed"); 699 } 700 $packagexml = 'package.xml'; 701 if (file_exists("$tmpdir/package2.xml")) { 702 $packagexml = 'package2.xml'; 703 } 704 @unlink("$tmpdir/package.sig"); 705 $input = $this->ui->userDialog($command, 706 array('GnuPG Passphrase'), 707 array('password')); 708 $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml 2>/dev/null", "w"); 709 if (!$gpg) { 710 return $this->raiseError("gpg command failed"); 711 } 712 fwrite($gpg, "$input[0]\n"); 713 if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { 714 return $this->raiseError("gpg sign failed"); 715 } 716 $tar->addModify("$tmpdir/package.sig", '', $tmpdir); 717 return true; 718 } 719 720 // }}} 721 722 /** 723 * For unit testing purposes 724 */ 725 function &getInstaller(&$ui) 726 { 727 if (!class_exists('PEAR_Installer')) { 728 require_once 'PEAR/Installer.php'; 729 } 730 $a = &new PEAR_Installer($ui); 731 return $a; 732 } 733 734 /** 735 * For unit testing purposes 736 */ 737 function &getCommandPackaging(&$ui, &$config) 738 { 739 if (!class_exists('PEAR_Command_Packaging')) { 740 @include_once 'PEAR/Command/Packaging.php'; 741 } 742 743 if (class_exists('PEAR_Command_Packaging')) { 744 $a = &new PEAR_Command_Packaging($ui, $config); 745 } else { 746 $a = null; 747 } 748 return $a; 749 } 750 751 // {{{ doMakeRPM() 752 753 function doMakeRPM($command, $options, $params) 754 { 755 require_once 'System.php'; 756 require_once 'Archive/Tar.php'; 757 758 // Check to see if PEAR_Command_Packaging is installed, and 759 // transparently switch to use the "make-rpm-spec" command from it 760 // instead, if it does. Otherwise, continue to use the old version 761 // of "makerpm" supplied with this package (PEAR). 762 $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); 763 if ($packaging_cmd !== null) { 764 $this->ui->outputData('PEAR_Command_Packaging is installed; using '. 765 'newer "make-rpm-spec" command instead'); 766 return $packaging_cmd->run('make-rpm-spec', $options, $params); 767 } else { 768 $this->ui->outputData('WARNING: "pear makerpm" is now deprecated; an '. 769 'improved version is available via "pear make-rpm-spec", which '. 770 'is available by installing PEAR_Command_Packaging'); 771 } 772 773 if (sizeof($params) != 1) { 774 return $this->raiseError("bad parameter(s), try \"help $command\""); 775 } 776 if (!file_exists($params[0])) { 777 return $this->raiseError("file does not exist: $params[0]"); 778 } 779 $reg = &$this->config->getRegistry(); 780 $pkg = &$this->getPackageFile($this->config, $this->_debug); 781 $pf = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); 782 if (PEAR::isError($pf)) { 783 $u = $pf->getUserinfo(); 784 if (is_array($u)) { 785 foreach ($u as $err) { 786 if (is_array($err)) { 787 $err = $err['message']; 788 } 789 $this->ui->outputData($err); 790 } 791 } 792 return $this->raiseError("$params[0] is not a valid package"); 793 } 794 $tmpdir = System::mktemp(array('-d', 'pear2rpm')); 795 $instroot = System::mktemp(array('-d', 'pear2rpm')); 796 $tmp = $this->config->get('verbose'); 797 $this->config->set('verbose', 0); 798 $installer = $this->getInstaller($this->ui); 799 require_once 'PEAR/Downloader/Package.php'; 800 $pack = new PEAR_Downloader_Package($installer); 801 $pack->setPackageFile($pf); 802 $params[0] = &$pack; 803 $installer->setOptions(array('installroot' => $instroot, 804 'nodeps' => true, 'soft' => true)); 805 $installer->setDownloadedPackages($params); 806 $info = $installer->install($params[0], 807 array('installroot' => $instroot, 808 'nodeps' => true, 'soft' => true)); 809 $pkgdir = $pf->getPackage() . '-' . $pf->getVersion(); 810 $info['rpm_xml_dir'] = '/var/lib/pear'; 811 $this->config->set('verbose', $tmp); 812 if (isset($options['spec-template'])) { 813 $spec_template = $options['spec-template']; 814 } else { 815 $spec_template = '@DATA-DIR@/PEAR/template.spec'; 816 } 817 $info['possible_channel'] = ''; 818 $info['extra_config'] = ''; 819 if (isset($options['rpm-pkgname'])) { 820 $rpm_pkgname_format = $options['rpm-pkgname']; 821 } else { 822 if ($pf->getChannel() == 'pear.php.net' || $pf->getChannel() == 'pecl.php.net') { 823 $alias = 'PEAR'; 824 } else { 825 $chan = &$reg->getChannel($pf->getChannel()); 826 if (PEAR::isError($chan)) { 827 return $this->raiseError($chan); 828 } 829 $alias = $chan->getAlias(); 830 $alias = strtoupper($alias); 831 $info['possible_channel'] = $pf->getChannel() . '/'; 832 } 833 $rpm_pkgname_format = $alias . '::%s'; 834 } 835 836 $info['extra_headers'] = ''; 837 $info['doc_files'] = ''; 838 $info['files'] = ''; 839 $info['package2xml'] = ''; 840 $info['rpm_package'] = sprintf($rpm_pkgname_format, $pf->getPackage()); 841 $srcfiles = 0; 842 foreach ($info['filelist'] as $name => $attr) { 843 if (!isset($attr['role'])) { 844 continue; 845 } 846 $name = preg_replace('![/:\\\\]!', '/', $name); 847 if ($attr['role'] == 'doc') { 848 $info['doc_files'] .= " $name"; 849 // Map role to the rpm vars 850 } else { 851 $c_prefix = '%{_libdir}/php/pear'; 852 switch ($attr['role']) { 853 case 'php': 854 $prefix = $c_prefix; 855 break; 856 case 'ext': 857 $prefix = '%{_libdir}/php'; 858 break; // XXX good place? 859 case 'src': 860 $srcfiles++; 861 $prefix = '%{_includedir}/php'; 862 break; // XXX good place? 863 case 'test': 864 $prefix = "$c_prefix/tests/" . $pf->getPackage(); 865 break; 866 case 'data': 867 $prefix = "$c_prefix/data/" . $pf->getPackage(); 868 break; 869 case 'script': 870 $prefix = '%{_bindir}'; 871 break; 872 default: // non-standard roles 873 $prefix = "$c_prefix/$attr[role]/" . $pf->getPackage(); 874 $info['extra_config'] .= 875 "\n -d {$attr[role]}_dir=$c_prefix/{$attr[role]} \\"; 876 $this->ui->outputData('WARNING: role "' . $attr['role'] . '" used, ' . 877 'and will be installed in "' . $c_prefix . '/' . $attr['role'] . 878 '/' . $pf->getPackage() . 879 ' - hand-edit the final .spec if this is wrong', $command); 880 break; 881 } 882 $name = str_replace('\\', '/', $name); 883 $info['files'] .= "$prefix/$name\n"; 884 } 885 } 886 if ($srcfiles > 0) { 887 require_once 'OS/Guess.php'; 888 $os = new OS_Guess; 889 $arch = $os->getCpu(); 890 } else { 891 $arch = 'noarch'; 892 } 893 $cfg = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', 894 'bin_dir', 'data_dir', 'test_dir'); 895 foreach ($cfg as $k) { 896 if ($k == 'master_server') { 897 $chan = $reg->getChannel($pf->getChannel()); 898 if (PEAR::isError($chan)) { 899 return $this->raiseError($chan); 900 } 901 $info[$k] = $chan->getServer(); 902 continue; 903 } 904 $info[$k] = $this->config->get($k); 905 } 906 $info['arch'] = $arch; 907 $fp = @fopen($spec_template, "r"); 908 if (!$fp) { 909 return $this->raiseError("could not open RPM spec file template $spec_template: $php_errormsg"); 910 } 911 $info['package'] = $pf->getPackage(); 912 $info['version'] = $pf->getVersion(); 913 $info['release_license'] = $pf->getLicense(); 914 if ($pf->getDeps()) { 915 if ($pf->getPackagexmlVersion() == '1.0') { 916 $requires = $conflicts = array(); 917 foreach ($pf->getDeps() as $dep) { 918 if (isset($dep['optional']) && $dep['optional'] == 'yes') { 919 continue; 920 } 921 if ($dep['type'] != 'pkg') { 922 continue; 923 } 924 if (isset($dep['channel']) && $dep['channel'] != 'pear.php.net' && 925 $dep['channel'] != 'pecl.php.net') { 926 $chan = &$reg->getChannel($dep['channel']); 927 if (PEAR::isError($chan)) { 928 return $this->raiseError($chan); 929 } 930 $package = strtoupper($chan->getAlias()) . '::' . $dep['name']; 931 } else { 932 $package = 'PEAR::' . $dep['name']; 933 } 934 $trans = array( 935 '>' => '>', 936 '<' => '<', 937 '>=' => '>=', 938 '<=' => '<=', 939 '=' => '=', 940 'gt' => '>', 941 'lt' => '<', 942 'ge' => '>=', 943 'le' => '<=', 944 'eq' => '=', 945 ); 946 if ($dep['rel'] == 'has') { 947 $requires[] = $package; 948 } elseif ($dep['rel'] == 'not') { 949 $conflicts[] = $package; 950 } elseif ($dep['rel'] == 'ne') { 951 $conflicts[] = $package . ' = ' . $dep['version']; 952 } elseif (isset($trans[$dep['rel']])) { 953 $requires[] = $package . ' ' . $trans[$dep['rel']] . ' ' . $dep['version']; 954 } 955 } 956 if (count($requires)) { 957 $info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n"; 958 } 959 if (count($conflicts)) { 960 $info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n"; 961 } 962 } else { 963 $info['package2xml'] = '2'; // tell the spec to use package2.xml 964 $requires = $conflicts = array(); 965 $deps = $pf->getDeps(true); 966 if (isset($deps['required']['package'])) { 967 if (!isset($deps['required']['package'][0])) { 968 $deps['required']['package'] = array($deps['required']['package']); 969 } 970 foreach ($deps['required']['package'] as $dep) { 971 if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') { 972 $chan = &$reg->getChannel($dep['channel']); 973 if (PEAR::isError($chan)) { 974 return $this->raiseError($chan); 975 } 976 $package = strtoupper($chan->getAlias()) . '::' . $dep['name']; 977 } else { 978 $package = 'PEAR::' . $dep['name']; 979 } 980 if (isset($dep['conflicts']) && (isset($dep['min']) || 981 isset($dep['max']))) { 982 $deprange = array(); 983 if (isset($dep['min'])) { 984 $deprange[] = array($dep['min'],'>='); 985 } 986 if (isset($dep['max'])) { 987 $deprange[] = array($dep['max'], '<='); 988 } 989 if (isset($dep['exclude'])) { 990 if (!is_array($dep['exclude']) || 991 !isset($dep['exclude'][0])) { 992 $dep['exclude'] = array($dep['exclude']); 993 } 994 if (count($deprange)) { 995 $excl = $dep['exclude']; 996 // change >= to > if excluding the min version 997 // change <= to < if excluding the max version 998 for($i = 0; $i < count($excl); $i++) { 999 if (isset($deprange[0]) && 1000 $excl[$i] == $deprange[0][0]) { 1001 $deprange[0][1] = '<'; 1002 unset($dep['exclude'][$i]); 1003 } 1004 if (isset($deprange[1]) && 1005 $excl[$i] == $deprange[1][0]) { 1006 $deprange[1][1] = '>'; 1007 unset($dep['exclude'][$i]); 1008 } 1009 } 1010 } 1011 if (count($dep['exclude'])) { 1012 $dep['exclude'] = array_values($dep['exclude']); 1013 $newdeprange = array(); 1014 // remove excludes that are outside the existing range 1015 for ($i = 0; $i < count($dep['exclude']); $i++) { 1016 if ($dep['exclude'][$i] < $dep['min'] || 1017 $dep['exclude'][$i] > $dep['max']) { 1018 unset($dep['exclude'][$i]); 1019 } 1020 } 1021 $dep['exclude'] = array_values($dep['exclude']); 1022 usort($dep['exclude'], 'version_compare'); 1023 // take the remaining excludes and 1024 // split the dependency into sub-ranges 1025 $lastmin = $deprange[0]; 1026 for ($i = 0; $i < count($dep['exclude']) - 1; $i++) { 1027 $newdeprange[] = '(' . 1028 $package . " {$lastmin[1]} {$lastmin[0]} and " . 1029 $package . ' < ' . $dep['exclude'][$i] . ')'; 1030 $lastmin = array($dep['exclude'][$i], '>'); 1031 } 1032 if (isset($dep['max'])) { 1033 $newdeprange[] = '(' . $package . 1034 " {$lastmin[1]} {$lastmin[0]} and " . 1035 $package . ' < ' . $dep['max'] . ')'; 1036 } 1037 $conflicts[] = implode(' or ', $deprange); 1038 } else { 1039 $conflicts[] = $package . 1040 " {$deprange[0][1]} {$deprange[0][0]}" . 1041 (isset($deprange[1]) ? 1042 " and $package {$deprange[1][1]} {$deprange[1][0]}" 1043 : ''); 1044 } 1045 } 1046 continue; 1047 } 1048 if (!isset($dep['min']) && !isset($dep['max']) && 1049 !isset($dep['exclude'])) { 1050 if (isset($dep['conflicts'])) { 1051 $conflicts[] = $package; 1052 } else { 1053 $requires[] = $package; 1054 } 1055 } else { 1056 if (isset($dep['min'])) { 1057 $requires[] = $package . ' >= ' . $dep['min']; 1058 } 1059 if (isset($dep['max'])) { 1060 $requires[] = $package . ' <= ' . $dep['max']; 1061 } 1062 if (isset($dep['exclude'])) { 1063 $ex = $dep['exclude']; 1064 if (!is_array($ex)) { 1065 $ex = array($ex); 1066 } 1067 foreach ($ex as $ver) { 1068 $conflicts[] = $package . ' = ' . $ver; 1069 } 1070 } 1071 } 1072 } 1073 require_once 'Archive/Tar.php'; 1074 $tar = new Archive_Tar($pf->getArchiveFile()); 1075 $tar->pushErrorHandling(PEAR_ERROR_RETURN); 1076 $a = $tar->extractInString('package2.xml'); 1077 $tar->popErrorHandling(); 1078 if ($a === null || PEAR::isError($a)) { 1079 $info['package2xml'] = ''; 1080 // this doesn't have a package.xml version 1.0 1081 $requires[] = 'PEAR::PEAR >= ' . 1082 $deps['required']['pearinstaller']['min']; 1083 } 1084 if (count($requires)) { 1085 $info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n"; 1086 } 1087 if (count($conflicts)) { 1088 $info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n"; 1089 } 1090 } 1091 } 1092 } 1093 1094 // remove the trailing newline 1095 $info['extra_headers'] = trim($info['extra_headers']); 1096 if (function_exists('file_get_contents')) { 1097 fclose($fp); 1098 $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]', 1099 file_get_contents($spec_template)); 1100 } else { 1101 $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]', 1102 fread($fp, filesize($spec_template))); 1103 fclose($fp); 1104 } 1105 $spec_file = "$info[rpm_package]-$info[version].spec"; 1106 $wp = fopen($spec_file, "wb"); 1107 if (!$wp) { 1108 return $this->raiseError("could not write RPM spec file $spec_file: $php_errormsg"); 1109 } 1110 fwrite($wp, $spec_contents); 1111 fclose($wp); 1112 $this->ui->outputData("Wrote RPM spec file $spec_file", $command); 1113 1114 return true; 1115 } 1116 1117 function doConvert($command, $options, $params) 1118 { 1119 $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; 1120 $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . 1121 DIRECTORY_SEPARATOR . 'package2.xml'; 1122 $pkg = &$this->getPackageFile($this->config, $this->_debug); 1123 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 1124 $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); 1125 PEAR::staticPopErrorHandling(); 1126 if (!PEAR::isError($pf)) { 1127 if (is_a($pf, 'PEAR_PackageFile_v2')) { 1128 $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); 1129 return true; 1130 } 1131 $gen = &$pf->getDefaultGenerator(); 1132 $newpf = &$gen->toV2(); 1133 $newpf->setPackagefile($newpackagexml); 1134 $gen = &$newpf->getDefaultGenerator(); 1135 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 1136 $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); 1137 $saved = $gen->toPackageFile(dirname($newpackagexml), $state, 1138 basename($newpackagexml)); 1139 PEAR::staticPopErrorHandling(); 1140 if (PEAR::isError($saved)) { 1141 if (is_array($saved->getUserInfo())) { 1142 foreach ($saved->getUserInfo() as $warning) { 1143 $this->ui->outputData($warning['message']); 1144 } 1145 } 1146 $this->ui->outputData($saved->getMessage()); 1147 return true; 1148 } 1149 $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); 1150 return true; 1151 } else { 1152 if (is_array($pf->getUserInfo())) { 1153 foreach ($pf->getUserInfo() as $warning) { 1154 $this->ui->outputData($warning['message']); 1155 } 1156 } 1157 return $this->raiseError($pf); 1158 } 1159 } 1160 1161 // }}} 1162 } 1163 1164 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 12:27:40 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |