Bearsampp 2026.9.23
Loading...
Searching...
No Matches
Package.php
Go to the documentation of this file.
1<?php
18
22require_once 'PEAR/Command/Common.php';
23
38
40{
41 var $commands = array(
42 'package' => array(
43 'summary' => 'Build Package',
44 'function' => 'doPackage',
45 'shortcut' => 'p',
46 'options' => array(
47 'nocompress' => array(
48 'shortopt' => 'Z',
49 'doc' => 'Do not gzip the package file'
50 ),
51 'showname' => array(
52 'shortopt' => 'n',
53 'doc' => 'Print the name of the packaged file.',
54 ),
55 ),
56 'doc' => '[descfile] [descfile2]
57Creates a PEAR package from its description file (usually called
58package.xml). If a second packagefile is passed in, then
59the packager will check to make sure that one is a package.xml
60version 1.0, and the other is a package.xml version 2.0. The
61package.xml version 1.0 will be saved as "package.xml" in the archive,
62and the other as "package2.xml" in the archive"
63'
64 ),
65 'package-validate' => array(
66 'summary' => 'Validate Package Consistency',
67 'function' => 'doPackageValidate',
68 'shortcut' => 'pv',
69 'options' => array(),
70 'doc' => '
71',
72 ),
73 'cvsdiff' => array(
74 'summary' => 'Run a "cvs diff" for all files in a package',
75 'function' => 'doCvsDiff',
76 'shortcut' => 'cd',
77 'options' => array(
78 'quiet' => array(
79 'shortopt' => 'q',
80 'doc' => 'Be quiet',
81 ),
82 'reallyquiet' => array(
83 'shortopt' => 'Q',
84 'doc' => 'Be really quiet',
85 ),
86 'date' => array(
87 'shortopt' => 'D',
88 'doc' => 'Diff against revision of DATE',
89 'arg' => 'DATE',
90 ),
91 'release' => array(
92 'shortopt' => 'R',
93 'doc' => 'Diff against tag for package release REL',
94 'arg' => 'REL',
95 ),
96 'revision' => array(
97 'shortopt' => 'r',
98 'doc' => 'Diff against revision REV',
99 'arg' => 'REV',
100 ),
101 'context' => array(
102 'shortopt' => 'c',
103 'doc' => 'Generate context diff',
104 ),
105 'unified' => array(
106 'shortopt' => 'u',
107 'doc' => 'Generate unified diff',
108 ),
109 'ignore-case' => array(
110 'shortopt' => 'i',
111 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent',
112 ),
113 'ignore-whitespace' => array(
114 'shortopt' => 'b',
115 'doc' => 'Ignore changes in amount of white space',
116 ),
117 'ignore-blank-lines' => array(
118 'shortopt' => 'B',
119 'doc' => 'Ignore changes that insert or delete blank lines',
120 ),
121 'brief' => array(
122 'doc' => 'Report only whether the files differ, no details',
123 ),
124 'dry-run' => array(
125 'shortopt' => 'n',
126 'doc' => 'Don\'t do anything, just pretend',
127 ),
128 ),
129 'doc' => '<package.xml>
130Compares all the files in a package. Without any options, this
131command will compare the current code with the last checked-in code.
132Using the -r or -R option you may compare the current code with that
133of a specific release.
134',
135 ),
136 'svntag' => array(
137 'summary' => 'Set SVN Release Tag',
138 'function' => 'doSvnTag',
139 'shortcut' => 'sv',
140 'options' => array(
141 'quiet' => array(
142 'shortopt' => 'q',
143 'doc' => 'Be quiet',
144 ),
145 'slide' => array(
146 'shortopt' => 'F',
147 'doc' => 'Move (slide) tag if it exists',
148 ),
149 'delete' => array(
150 'shortopt' => 'd',
151 'doc' => 'Remove tag',
152 ),
153 'dry-run' => array(
154 'shortopt' => 'n',
155 'doc' => 'Don\'t do anything, just pretend',
156 ),
157 ),
158 'doc' => '<package.xml> [files...]
159 Sets a SVN tag on all files in a package. Use this command after you have
160 packaged a distribution tarball with the "package" command to tag what
161 revisions of what files were in that release. If need to fix something
162 after running svntag once, but before the tarball is released to the public,
163 use the "slide" option to move the release tag.
164
165 to include files (such as a second package.xml, or tests not included in the
166 release), pass them as additional parameters.
167 ',
168 ),
169 'cvstag' => array(
170 'summary' => 'Set CVS Release Tag',
171 'function' => 'doCvsTag',
172 'shortcut' => 'ct',
173 'options' => array(
174 'quiet' => array(
175 'shortopt' => 'q',
176 'doc' => 'Be quiet',
177 ),
178 'reallyquiet' => array(
179 'shortopt' => 'Q',
180 'doc' => 'Be really quiet',
181 ),
182 'slide' => array(
183 'shortopt' => 'F',
184 'doc' => 'Move (slide) tag if it exists',
185 ),
186 'delete' => array(
187 'shortopt' => 'd',
188 'doc' => 'Remove tag',
189 ),
190 'dry-run' => array(
191 'shortopt' => 'n',
192 'doc' => 'Don\'t do anything, just pretend',
193 ),
194 ),
195 'doc' => '<package.xml> [files...]
196Sets a CVS tag on all files in a package. Use this command after you have
197packaged a distribution tarball with the "package" command to tag what
198revisions of what files were in that release. If need to fix something
199after running cvstag once, but before the tarball is released to the public,
200use the "slide" option to move the release tag.
201
202to include files (such as a second package.xml, or tests not included in the
203release), pass them as additional parameters.
204',
205 ),
206 'package-dependencies' => array(
207 'summary' => 'Show package dependencies',
208 'function' => 'doPackageDependencies',
209 'shortcut' => 'pd',
210 'options' => array(),
211 'doc' => '<package-file> or <package.xml> or <install-package-name>
212List all dependencies the package has.
213Can take a tgz / tar file, package.xml or a package name of an installed package.'
214 ),
215 'sign' => array(
216 'summary' => 'Sign a package distribution file',
217 'function' => 'doSign',
218 'shortcut' => 'si',
219 'options' => array(
220 'verbose' => array(
221 'shortopt' => 'v',
222 'doc' => 'Display GnuPG output',
223 ),
224 ),
225 'doc' => '<package-file>
226Signs a package distribution (.tar or .tgz) file with GnuPG.',
227 ),
228 'makerpm' => array(
229 'summary' => 'Builds an RPM spec file from a PEAR package',
230 'function' => 'doMakeRPM',
231 'shortcut' => 'rpm',
232 'options' => array(
233 'spec-template' => array(
234 'shortopt' => 't',
235 'arg' => 'FILE',
236 'doc' => 'Use FILE as RPM spec file template'
237 ),
238 'rpm-pkgname' => array(
239 'shortopt' => 'p',
240 'arg' => 'FORMAT',
241 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced
242by the PEAR package name, defaults to "PEAR::%s".',
243 ),
244 ),
245 'doc' => '<package-file>
246
247Creates an RPM .spec file for wrapping a PEAR package inside an RPM
248package. Intended to be used from the SPECS directory, with the PEAR
249package tarball in the SOURCES directory:
250
251$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
252Wrote RPM spec file PEAR::Net_Geo-1.0.spec
253$ rpm -bb PEAR::Net_Socket-1.0.spec
254...
255Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
256',
257 ),
258 'convert' => array(
259 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format',
260 'function' => 'doConvert',
261 'shortcut' => 'c2',
262 'options' => array(
263 'flat' => array(
264 'shortopt' => 'f',
265 'doc' => 'do not beautify the filelist.',
266 ),
267 ),
268 'doc' => '[descfile] [descfile2]
269Converts a package.xml in 1.0 format into a package.xml
270in 2.0 format. The new file will be named package2.xml by default,
271and package.xml will be used as the old file by default.
272This is not the most intelligent conversion, and should only be
273used for automated conversion or learning the format.
274'
275 ),
276 );
277
279
286 {
287 parent::__construct($ui, $config);
288 }
289
290 function _displayValidationResults($err, $warn, $strict = false)
291 {
292 foreach ($err as $e) {
293 $this->output .= "Error: $e\n";
294 }
295 foreach ($warn as $w) {
296 $this->output .= "Warning: $w\n";
297 }
298 $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
299 sizeof($err), sizeof($warn));
300 if ($strict && count($err) > 0) {
301 $this->output .= "Fix these errors and try again.";
302 return false;
303 }
304 return true;
305 }
306
307 function &getPackager()
308 {
309 if (!class_exists('PEAR_Packager')) {
310 require_once 'PEAR/Packager.php';
311 }
312 $a = new PEAR_Packager;
313 return $a;
314 }
315
316 function &getPackageFile($config, $debug = false)
317 {
318 if (!class_exists('PEAR_Common')) {
319 require_once 'PEAR/Common.php';
320 }
321 if (!class_exists('PEAR_PackageFile')) {
322 require_once 'PEAR/PackageFile.php';
323 }
324 $a = new PEAR_PackageFile($config, $debug);
325 $common = new PEAR_Common;
326 $common->ui = $this->ui;
327 $a->setLogger($common);
328 return $a;
329 }
330
331 function doPackage($command, $options, $params)
332 {
333 $this->output = '';
334 $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
335 $pkg2 = isset($params[1]) ? $params[1] : null;
336 if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) {
337 $pkg2 = 'package2.xml';
338 }
339
340 $packager = &$this->getPackager();
341 $compress = empty($options['nocompress']) ? true : false;
342 $result = $packager->package($pkginfofile, $compress, $pkg2);
343 if (PEAR::isError($result)) {
344 return $this->raiseError($result);
345 }
346
347 // Don't want output, only the package file name just created
348 if (isset($options['showname'])) {
349 $this->output = $result;
350 }
351
352 if ($this->output) {
353 $this->ui->outputData($this->output, $command);
354 }
355
356 return true;
357 }
358
360 {
361 $this->output = '';
362 if (count($params) < 1) {
363 $params[0] = 'package.xml';
364 }
365
366 $obj = &$this->getPackageFile($this->config, $this->_debug);
367 $obj->rawReturn();
369 $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
370 if (PEAR::isError($info)) {
371 $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
372 } else {
373 $archive = $info->getArchiveFile();
374 $tar = new Archive_Tar($archive);
375 $tar->extract(dirname($info->getPackageFile()));
376 $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
377 $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
378 basename($info->getPackageFile()));
379 }
380
382 if (PEAR::isError($info)) {
383 return $this->raiseError($info);
384 }
385
386 $valid = false;
387 if ($info->getPackagexmlVersion() == '2.0') {
388 if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
389 $info->flattenFileList();
390 $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
391 }
392 } else {
393 $valid = $info->validate(PEAR_VALIDATE_PACKAGING);
394 }
395
396 $err = $warn = array();
397 if ($errors = $info->getValidationWarnings()) {
398 foreach ($errors as $error) {
399 if ($error['level'] == 'warning') {
400 $warn[] = $error['message'];
401 } else {
402 $err[] = $error['message'];
403 }
404 }
405 }
406
407 $this->_displayValidationResults($err, $warn);
408 $this->ui->outputData($this->output, $command);
409 return true;
410 }
411
412 function doSvnTag($command, $options, $params)
413 {
414 $this->output = '';
415 $_cmd = $command;
416 if (count($params) < 1) {
417 $help = $this->getHelp($command);
418 return $this->raiseError("$command: missing parameter: $help[0]");
419 }
420
421 $packageFile = realpath($params[0]);
422 $dir = dirname($packageFile);
423 $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
424 $obj = &$this->getPackageFile($this->config, $this->_debug);
425 $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
426 if (PEAR::isError($info)) {
427 return $this->raiseError($info);
428 }
429
430 $err = $warn = array();
431 if (!$info->validate()) {
432 foreach ($info->getValidationWarnings() as $error) {
433 if ($error['level'] == 'warning') {
434 $warn[] = $error['message'];
435 } else {
436 $err[] = $error['message'];
437 }
438 }
439 }
440
441 if (!$this->_displayValidationResults($err, $warn, true)) {
442 $this->ui->outputData($this->output, $command);
443 return $this->raiseError('SVN tag failed');
444 }
445
446 $version = $info->getVersion();
447 $package = $info->getName();
448 $svntag = "$package-$version";
449
450 if (isset($options['delete'])) {
451 return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
452 }
453
454 $path = $this->_svnFindPath($packageFile);
455
456 // Check if there are any modified files
457 $fp = popen('svn st --xml ' . dirname($packageFile), "r");
458 $out = '';
459 while ($line = fgets($fp, 1024)) {
460 $out .= rtrim($line)."\n";
461 }
462 pclose($fp);
463
464 if (!isset($options['quiet']) && strpos($out, 'item="modified"')) {
465 $params = array(array(
466 'name' => 'modified',
467 'type' => 'yesno',
468 'default' => 'no',
469 'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not committed, do you still want to tag ' . $version . '?',
470 ));
471 $answers = $this->ui->confirmDialog($params);
472
473 if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) {
474 return true;
475 }
476 }
477
478 if (isset($options['slide'])) {
479 $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
480 }
481
482 // Check if tag already exists
483 $releaseTag = $path['local']['base'] . 'tags' . DIRECTORY_SEPARATOR . $svntag;
484 $existsCommand = 'svn ls ' . $path['base'] . 'tags/';
485
486 $fp = popen($existsCommand, "r");
487 $out = '';
488 while ($line = fgets($fp, 1024)) {
489 $out .= rtrim($line)."\n";
490 }
491 pclose($fp);
492
493 if (in_array($svntag . DIRECTORY_SEPARATOR, explode("\n", $out))) {
494 $this->ui->outputData($this->output, $command);
495 return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.');
496 } elseif (file_exists($path['local']['base'] . 'tags') === false) {
497 return $this->raiseError('Can not locate the tags directory at ' . $path['local']['base'] . 'tags');
498 } elseif (is_writeable($path['local']['base'] . 'tags') === false) {
499 return $this->raiseError('Can not write to the tag directory at ' . $path['local']['base'] . 'tags');
500 } else {
501 $makeCommand = 'svn mkdir ' . $releaseTag;
502 $this->output .= "+ $makeCommand\n";
503 if (empty($options['dry-run'])) {
504 // We need to create the tag dir.
505 $fp = popen($makeCommand, "r");
506 $out = '';
507 while ($line = fgets($fp, 1024)) {
508 $out .= rtrim($line)."\n";
509 }
510 pclose($fp);
511 $this->output .= "$out\n";
512 }
513 }
514
515 $command = 'svn';
516 if (isset($options['quiet'])) {
517 $command .= ' -q';
518 }
519
520 $command .= ' copy --parents ';
521
522 $dir = dirname($packageFile);
523 $dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
524 $files = array_keys($info->getFilelist());
525 if (!in_array(basename($packageFile), $files)) {
526 $files[] = basename($packageFile);
527 }
528
529 array_shift($params);
530 if (count($params)) {
531 // add in additional files to be tagged (package files and such)
532 $files = array_merge($files, $params);
533 }
534
535 $commands = array();
536 foreach ($files as $file) {
537 if (!file_exists($file)) {
538 $file = $dir . DIRECTORY_SEPARATOR . $file;
539 }
540 $commands[] = $command . ' ' . escapeshellarg($file) . ' ' .
541 escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file);
542 }
543
544 $this->output .= implode("\n", $commands) . "\n";
545 if (empty($options['dry-run'])) {
546 foreach ($commands as $command) {
547 $fp = popen($command, "r");
548 while ($line = fgets($fp, 1024)) {
549 $this->output .= rtrim($line)."\n";
550 }
551 pclose($fp);
552 }
553 }
554
555 $command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n";
556 $this->output .= "+ $command\n";
557 if (empty($options['dry-run'])) {
558 $fp = popen($command, "r");
559 while ($line = fgets($fp, 1024)) {
560 $this->output .= rtrim($line)."\n";
561 }
562 pclose($fp);
563 }
564
565 $this->ui->outputData($this->output, $_cmd);
566 return true;
567 }
568
569 function _svnFindPath($file)
570 {
571 $xml = '';
572 $command = "svn info --xml $file";
573 $fp = popen($command, "r");
574 while ($line = fgets($fp, 1024)) {
575 $xml .= rtrim($line)."\n";
576 }
577 pclose($fp);
578 $url_tag = strpos($xml, '<url>');
579 $url = substr($xml, $url_tag + 5, strpos($xml, '</url>', $url_tag + 5) - ($url_tag + 5));
580
581 $path = array();
582 $path['from'] = substr($url, 0, strrpos($url, '/'));
583 $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1);
584
585 // Figure out the local paths - see http://pear.php.net/bugs/17463
586 $pos = strpos($file, DIRECTORY_SEPARATOR . 'trunk' . DIRECTORY_SEPARATOR);
587 if ($pos === false) {
588 $pos = strpos($file, DIRECTORY_SEPARATOR . 'branches' . DIRECTORY_SEPARATOR);
589 }
590 $path['local']['base'] = substr($file, 0, $pos + 1);
591
592 return $path;
593 }
594
595 function _svnRemoveTag($version, $package, $tag, $packageFile, $options)
596 {
597 $command = 'svn';
598
599 if (isset($options['quiet'])) {
600 $command .= ' -q';
601 }
602
603 $command .= ' remove';
604 $command .= ' -m "Removing tag for the ' . $version . ' release."';
605
606 $path = $this->_svnFindPath($packageFile);
607 $command .= ' ' . $path['base'] . 'tags/' . $tag;
608
609
610 if ($this->config->get('verbose') > 1) {
611 $this->output .= "+ $command\n";
612 }
613
614 $this->output .= "+ $command\n";
615 if (empty($options['dry-run'])) {
616 $fp = popen($command, "r");
617 while ($line = fgets($fp, 1024)) {
618 $this->output .= rtrim($line)."\n";
619 }
620 pclose($fp);
621 }
622
623 $this->ui->outputData($this->output, $command);
624 return true;
625 }
626
627 function doCvsTag($command, $options, $params)
628 {
629 $this->output = '';
630 $_cmd = $command;
631 if (count($params) < 1) {
632 $help = $this->getHelp($command);
633 return $this->raiseError("$command: missing parameter: $help[0]");
634 }
635
636 $packageFile = realpath($params[0]);
637 $obj = &$this->getPackageFile($this->config, $this->_debug);
638 $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
639 if (PEAR::isError($info)) {
640 return $this->raiseError($info);
641 }
642
643 $err = $warn = array();
644 if (!$info->validate()) {
645 foreach ($info->getValidationWarnings() as $error) {
646 if ($error['level'] == 'warning') {
647 $warn[] = $error['message'];
648 } else {
649 $err[] = $error['message'];
650 }
651 }
652 }
653
654 if (!$this->_displayValidationResults($err, $warn, true)) {
655 $this->ui->outputData($this->output, $command);
656 return $this->raiseError('CVS tag failed');
657 }
658
659 $version = $info->getVersion();
660 $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
661 $cvstag = "RELEASE_$cvsversion";
662 $files = array_keys($info->getFilelist());
663 $command = 'cvs';
664 if (isset($options['quiet'])) {
665 $command .= ' -q';
666 }
667
668 if (isset($options['reallyquiet'])) {
669 $command .= ' -Q';
670 }
671
672 $command .= ' tag';
673 if (isset($options['slide'])) {
674 $command .= ' -F';
675 }
676
677 if (isset($options['delete'])) {
678 $command .= ' -d';
679 }
680
681 $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
682 array_shift($params);
683 if (count($params)) {
684 // add in additional files to be tagged
685 $files = array_merge($files, $params);
686 }
687
688 $dir = dirname($packageFile);
689 $dir = substr($dir, strrpos($dir, '/') + 1);
690 foreach ($files as $file) {
691 if (!file_exists($file)) {
692 $file = $dir . DIRECTORY_SEPARATOR . $file;
693 }
694 $command .= ' ' . escapeshellarg($file);
695 }
696
697 if ($this->config->get('verbose') > 1) {
698 $this->output .= "+ $command\n";
699 }
700
701 $this->output .= "+ $command\n";
702 if (empty($options['dry-run'])) {
703 $fp = popen($command, "r");
704 while ($line = fgets($fp, 1024)) {
705 $this->output .= rtrim($line)."\n";
706 }
707 pclose($fp);
708 }
709
710 $this->ui->outputData($this->output, $_cmd);
711 return true;
712 }
713
714 function doCvsDiff($command, $options, $params)
715 {
716 $this->output = '';
717 if (sizeof($params) < 1) {
718 $help = $this->getHelp($command);
719 return $this->raiseError("$command: missing parameter: $help[0]");
720 }
721
722 $file = realpath($params[0]);
723 $obj = &$this->getPackageFile($this->config, $this->_debug);
724 $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL);
725 if (PEAR::isError($info)) {
726 return $this->raiseError($info);
727 }
728
729 $err = $warn = array();
730 if (!$info->validate()) {
731 foreach ($info->getValidationWarnings() as $error) {
732 if ($error['level'] == 'warning') {
733 $warn[] = $error['message'];
734 } else {
735 $err[] = $error['message'];
736 }
737 }
738 }
739
740 if (!$this->_displayValidationResults($err, $warn, true)) {
741 $this->ui->outputData($this->output, $command);
742 return $this->raiseError('CVS diff failed');
743 }
744
745 $info1 = $info->getFilelist();
746 $files = $info1;
747 $cmd = "cvs";
748 if (isset($options['quiet'])) {
749 $cmd .= ' -q';
750 unset($options['quiet']);
751 }
752
753 if (isset($options['reallyquiet'])) {
754 $cmd .= ' -Q';
755 unset($options['reallyquiet']);
756 }
757
758 if (isset($options['release'])) {
759 $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
760 $cvstag = "RELEASE_$cvsversion";
761 $options['revision'] = $cvstag;
762 unset($options['release']);
763 }
764
765 $execute = true;
766 if (isset($options['dry-run'])) {
767 $execute = false;
768 unset($options['dry-run']);
769 }
770
771 $cmd .= ' diff';
772 // the rest of the options are passed right on to "cvs diff"
773 foreach ($options as $option => $optarg) {
774 $arg = $short = false;
775 if (isset($this->commands[$command]['options'][$option])) {
776 $arg = $this->commands[$command]['options'][$option]['arg'];
777 $short = $this->commands[$command]['options'][$option]['shortopt'];
778 }
779 $cmd .= $short ? " -$short" : " --$option";
780 if ($arg && $optarg) {
781 $cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
782 }
783 }
784
785 foreach ($files as $file) {
786 $cmd .= ' ' . escapeshellarg($file['name']);
787 }
788
789 if ($this->config->get('verbose') > 1) {
790 $this->output .= "+ $cmd\n";
791 }
792
793 if ($execute) {
794 $fp = popen($cmd, "r");
795 while ($line = fgets($fp, 1024)) {
796 $this->output .= rtrim($line)."\n";
797 }
798 pclose($fp);
799 }
800
801 $this->ui->outputData($this->output, $command);
802 return true;
803 }
804
806 {
807 // $params[0] -> the PEAR package to list its information
808 if (count($params) !== 1) {
809 return $this->raiseError("bad parameter(s), try \"help $command\"");
810 }
811
812 $obj = &$this->getPackageFile($this->config, $this->_debug);
813 if (is_file($params[0]) || strpos($params[0], '.xml') > 0) {
814 $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
815 } else {
816 $reg = $this->config->getRegistry();
817 $info = $obj->fromArray($reg->packageInfo($params[0]));
818 }
819
820 if (PEAR::isError($info)) {
821 return $this->raiseError($info);
822 }
823
824 $deps = $info->getDeps();
825 if (is_array($deps)) {
826 if ($info->getPackagexmlVersion() == '1.0') {
827 $data = array(
828 'caption' => 'Dependencies for pear/' . $info->getPackage(),
829 'border' => true,
830 'headline' => array("Required?", "Type", "Name", "Relation", "Version"),
831 );
832
833 foreach ($deps as $d) {
834 if (isset($d['optional'])) {
835 if ($d['optional'] == 'yes') {
836 $req = 'No';
837 } else {
838 $req = 'Yes';
839 }
840 } else {
841 $req = 'Yes';
842 }
843
844 if (isset($this->_deps_rel_trans[$d['rel']])) {
845 $rel = $this->_deps_rel_trans[$d['rel']];
846 } else {
847 $rel = $d['rel'];
848 }
849
850 if (isset($this->_deps_type_trans[$d['type']])) {
851 $type = ucfirst($this->_deps_type_trans[$d['type']]);
852 } else {
853 $type = $d['type'];
854 }
855
856 if (isset($d['name'])) {
857 $name = $d['name'];
858 } else {
859 $name = '';
860 }
861
862 if (isset($d['version'])) {
863 $version = $d['version'];
864 } else {
865 $version = '';
866 }
867
868 $data['data'][] = array($req, $type, $name, $rel, $version);
869 }
870 } else { // package.xml 2.0 dependencies display
871 require_once 'PEAR/Dependency2.php';
872 $deps = $info->getDependencies();
873 $reg = &$this->config->getRegistry();
874 if (is_array($deps)) {
875 $data = array(
876 'caption' => 'Dependencies for ' . $info->getPackage(),
877 'border' => true,
878 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'),
879 );
880 foreach ($deps as $type => $subd) {
881 $req = ($type == 'required') ? 'Yes' : 'No';
882 if ($type == 'group' && isset($subd['attribs']['name'])) {
883 $group = $subd['attribs']['name'];
884 } else {
885 $group = '';
886 }
887
888 if (!isset($subd[0])) {
889 $subd = array($subd);
890 }
891
892 foreach ($subd as $groupa) {
893 foreach ($groupa as $deptype => $depinfo) {
894 if ($deptype == 'attribs') {
895 continue;
896 }
897
898 if ($deptype == 'pearinstaller') {
899 $deptype = 'pear Installer';
900 }
901
902 if (!isset($depinfo[0])) {
903 $depinfo = array($depinfo);
904 }
905
906 foreach ($depinfo as $inf) {
907 $name = '';
908 if (isset($inf['channel'])) {
909 $alias = $reg->channelAlias($inf['channel']);
910 if (!$alias) {
911 $alias = '(channel?) ' .$inf['channel'];
912 }
913 $name = $alias . '/';
914
915 }
916 if (isset($inf['name'])) {
917 $name .= $inf['name'];
918 } elseif (isset($inf['pattern'])) {
919 $name .= $inf['pattern'];
920 } else {
921 $name .= '';
922 }
923
924 if (isset($inf['uri'])) {
925 $name .= ' [' . $inf['uri'] . ']';
926 }
927
928 if (isset($inf['conflicts'])) {
929 $ver = 'conflicts';
930 } else {
932 }
933
934 $data['data'][] = array($req, ucfirst($deptype), $name,
935 $ver, $group);
936 }
937 }
938 }
939 }
940 }
941 }
942
943 $this->ui->outputData($data, $command);
944 return true;
945 }
946
947 // Fallback
948 $this->ui->outputData("This package does not have any dependencies.", $command);
949 }
950
951 function doSign($command, $options, $params)
952 {
953 // should move most of this code into PEAR_Packager
954 // so it'll be easy to implement "pear package --sign"
955 if (count($params) !== 1) {
956 return $this->raiseError("bad parameter(s), try \"help $command\"");
957 }
958
959 require_once 'System.php';
960 require_once 'Archive/Tar.php';
961
962 if (!file_exists($params[0])) {
963 return $this->raiseError("file does not exist: $params[0]");
964 }
965
966 $obj = $this->getPackageFile($this->config, $this->_debug);
967 $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
968 if (PEAR::isError($info)) {
969 return $this->raiseError($info);
970 }
971
972 $tar = new Archive_Tar($params[0]);
973
974 $tmpdir = $this->config->get('temp_dir');
975 $tmpdir = System::mktemp(' -t "' . $tmpdir . '" -d pearsign');
976 if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
977 return $this->raiseError("failed to extract tar file");
978 }
979
980 if (file_exists("$tmpdir/package.sig")) {
981 return $this->raiseError("package already signed");
982 }
983
984 $packagexml = 'package.xml';
985 if (file_exists("$tmpdir/package2.xml")) {
986 $packagexml = 'package2.xml';
987 }
988
989 if (file_exists("$tmpdir/package.sig")) {
990 unlink("$tmpdir/package.sig");
991 }
992
993 if (!file_exists("$tmpdir/$packagexml")) {
994 return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
995 }
996
997 $input = $this->ui->userDialog($command,
998 array('GnuPG Passphrase'),
999 array('password'));
1000 if (!isset($input[0])) {
1001 //use empty passphrase
1002 $input[0] = '';
1003 }
1004
1005 $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
1006 $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
1007 if (!$gpg) {
1008 return $this->raiseError("gpg command failed");
1009 }
1010
1011 fwrite($gpg, "$input[0]\n");
1012 if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
1013 return $this->raiseError("gpg sign failed");
1014 }
1015
1016 if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
1017 return $this->raiseError('failed adding signature to file');
1018 }
1019
1020 $this->ui->outputData("Package signed.", $command);
1021 return true;
1022 }
1023
1027 function &getInstaller(&$ui)
1028 {
1029 if (!class_exists('PEAR_Installer')) {
1030 require_once 'PEAR/Installer.php';
1031 }
1032 $a = new PEAR_Installer($ui);
1033 return $a;
1034 }
1035
1040 {
1041 if (!class_exists('PEAR_Command_Packaging')) {
1042 if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) {
1043 fclose($fp);
1044 include_once 'PEAR/Command/Packaging.php';
1045 }
1046 }
1047
1048 if (class_exists('PEAR_Command_Packaging')) {
1049 $a = new PEAR_Command_Packaging($ui, $config);
1050 } else {
1051 $a = null;
1052 }
1053
1054 return $a;
1055 }
1056
1057 function doMakeRPM($command, $options, $params)
1058 {
1059
1060 // Check to see if PEAR_Command_Packaging is installed, and
1061 // transparently switch to use the "make-rpm-spec" command from it
1062 // instead, if it does. Otherwise, continue to use the old version
1063 // of "makerpm" supplied with this package (PEAR).
1064 $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config);
1065 if ($packaging_cmd !== null) {
1066 $this->ui->outputData('PEAR_Command_Packaging is installed; using '.
1067 'newer "make-rpm-spec" command instead');
1068 return $packaging_cmd->run('make-rpm-spec', $options, $params);
1069 }
1070
1071 $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
1072 'improved version is available via "pear make-rpm-spec", which '.
1073 'is available by installing PEAR_Command_Packaging');
1074 return true;
1075 }
1076
1077 function doConvert($command, $options, $params)
1078 {
1079 $packagexml = isset($params[0]) ? $params[0] : 'package.xml';
1080 $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
1081 DIRECTORY_SEPARATOR . 'package2.xml';
1082 $pkg = &$this->getPackageFile($this->config, $this->_debug);
1084 $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
1086 if (PEAR::isError($pf)) {
1087 if (is_array($pf->getUserInfo())) {
1088 foreach ($pf->getUserInfo() as $warning) {
1089 $this->ui->outputData($warning['message']);
1090 }
1091 }
1092 return $this->raiseError($pf);
1093 }
1094
1095 if (is_a($pf, 'PEAR_PackageFile_v2')) {
1096 $this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
1097 return true;
1098 }
1099
1100 $gen = &$pf->getDefaultGenerator();
1101 $newpf = &$gen->toV2();
1102 $newpf->setPackagefile($newpackagexml);
1103 $gen = &$newpf->getDefaultGenerator();
1105 $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
1106 $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml));
1108 if (PEAR::isError($saved)) {
1109 if (is_array($saved->getUserInfo())) {
1110 foreach ($saved->getUserInfo() as $warning) {
1111 $this->ui->outputData($warning['message']);
1112 }
1113 }
1114
1115 $this->ui->outputData($saved->getMessage());
1116 return true;
1117 }
1118
1119 $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
1120 return true;
1121 }
1122}
const PEAR_ERROR_RETURN
Definition PEAR.php:24
const PEAR_VALIDATE_PACKAGING
Definition Validate.php:22
const PEAR_VALIDATE_NORMAL
Definition Validate.php:20
$result
getHelp($command)
Definition Common.php:176
doSign($command, $options, $params)
Definition Package.php:951
__construct(&$ui, &$config)
Definition Package.php:285
doConvert($command, $options, $params)
Definition Package.php:1077
doSvnTag($command, $options, $params)
Definition Package.php:412
doPackage($command, $options, $params)
Definition Package.php:331
& getCommandPackaging(&$ui, &$config)
Definition Package.php:1039
_displayValidationResults($err, $warn, $strict=false)
Definition Package.php:290
doPackageValidate($command, $options, $params)
Definition Package.php:359
_svnRemoveTag($version, $package, $tag, $packageFile, $options)
Definition Package.php:595
doMakeRPM($command, $options, $params)
Definition Package.php:1057
doCvsDiff($command, $options, $params)
Definition Package.php:714
doPackageDependencies($command, $options, $params)
Definition Package.php:805
& getPackageFile($config, $debug=false)
Definition Package.php:316
doCvsTag($command, $options, $params)
Definition Package.php:627
static _getExtraString($dep)
static staticPopErrorHandling()
Definition PEAR.php:654
static staticPushErrorHandling($mode, $options=null)
Definition PEAR.php:619
static isError($data, $code=null)
Definition PEAR.php:306
$options
Definition pearcmd.php:145
if( $raw) foreach($opts as $opt) if( $store_system_config) if($store_user_config) $command
Definition pearcmd.php:322