1 | <?php |
---|
2 | /** |
---|
3 | * PEAR_Command_Pickle (pickle command) |
---|
4 | * |
---|
5 | * PHP versions 4 and 5 |
---|
6 | * |
---|
7 | * @category pear |
---|
8 | * @package PEAR |
---|
9 | * @author Greg Beaver <cellog@php.net> |
---|
10 | * @copyright 2005-2009 The Authors |
---|
11 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
12 | * @version CVS: $Id: Pickle.php 313023 2011-07-06 19:17:11Z dufuz $ |
---|
13 | * @link http://pear.php.net/package/PEAR |
---|
14 | * @since File available since Release 1.4.1 |
---|
15 | */ |
---|
16 | |
---|
17 | /** |
---|
18 | * base class |
---|
19 | */ |
---|
20 | require_once 'PEAR/Command/Common.php'; |
---|
21 | |
---|
22 | /** |
---|
23 | * PEAR commands for login/logout |
---|
24 | * |
---|
25 | * @category pear |
---|
26 | * @package PEAR |
---|
27 | * @author Greg Beaver <cellog@php.net> |
---|
28 | * @copyright 2005-2009 The Authors |
---|
29 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
30 | * @version Release: 1.9.4 |
---|
31 | * @link http://pear.php.net/package/PEAR |
---|
32 | * @since Class available since Release 1.4.1 |
---|
33 | */ |
---|
34 | |
---|
35 | class PEAR_Command_Pickle extends PEAR_Command_Common |
---|
36 | { |
---|
37 | var $commands = array( |
---|
38 | 'pickle' => array( |
---|
39 | 'summary' => 'Build PECL Package', |
---|
40 | 'function' => 'doPackage', |
---|
41 | 'shortcut' => 'pi', |
---|
42 | 'options' => array( |
---|
43 | 'nocompress' => array( |
---|
44 | 'shortopt' => 'Z', |
---|
45 | 'doc' => 'Do not gzip the package file' |
---|
46 | ), |
---|
47 | 'showname' => array( |
---|
48 | 'shortopt' => 'n', |
---|
49 | 'doc' => 'Print the name of the packaged file.', |
---|
50 | ), |
---|
51 | ), |
---|
52 | 'doc' => '[descfile] |
---|
53 | Creates a PECL package from its package2.xml file. |
---|
54 | |
---|
55 | An automatic conversion will be made to a package.xml 1.0 and written out to |
---|
56 | disk in the current directory as "package.xml". Note that |
---|
57 | only simple package.xml 2.0 will be converted. package.xml 2.0 with: |
---|
58 | |
---|
59 | - dependency types other than required/optional PECL package/ext/php/pearinstaller |
---|
60 | - more than one extsrcrelease or zendextsrcrelease |
---|
61 | - zendextbinrelease, extbinrelease, phprelease, or bundle release type |
---|
62 | - dependency groups |
---|
63 | - ignore tags in release filelist |
---|
64 | - tasks other than replace |
---|
65 | - custom roles |
---|
66 | |
---|
67 | will cause pickle to fail, and output an error message. If your package2.xml |
---|
68 | uses any of these features, you are best off using PEAR_PackageFileManager to |
---|
69 | generate both package.xml. |
---|
70 | ' |
---|
71 | ), |
---|
72 | ); |
---|
73 | |
---|
74 | /** |
---|
75 | * PEAR_Command_Package constructor. |
---|
76 | * |
---|
77 | * @access public |
---|
78 | */ |
---|
79 | function PEAR_Command_Pickle(&$ui, &$config) |
---|
80 | { |
---|
81 | parent::PEAR_Command_Common($ui, $config); |
---|
82 | } |
---|
83 | |
---|
84 | /** |
---|
85 | * For unit-testing ease |
---|
86 | * |
---|
87 | * @return PEAR_Packager |
---|
88 | */ |
---|
89 | function &getPackager() |
---|
90 | { |
---|
91 | if (!class_exists('PEAR_Packager')) { |
---|
92 | require_once 'PEAR/Packager.php'; |
---|
93 | } |
---|
94 | |
---|
95 | $a = &new PEAR_Packager; |
---|
96 | return $a; |
---|
97 | } |
---|
98 | |
---|
99 | /** |
---|
100 | * For unit-testing ease |
---|
101 | * |
---|
102 | * @param PEAR_Config $config |
---|
103 | * @param bool $debug |
---|
104 | * @param string|null $tmpdir |
---|
105 | * @return PEAR_PackageFile |
---|
106 | */ |
---|
107 | function &getPackageFile($config, $debug = false) |
---|
108 | { |
---|
109 | if (!class_exists('PEAR_Common')) { |
---|
110 | require_once 'PEAR/Common.php'; |
---|
111 | } |
---|
112 | |
---|
113 | if (!class_exists('PEAR_PackageFile')) { |
---|
114 | require_once 'PEAR/PackageFile.php'; |
---|
115 | } |
---|
116 | |
---|
117 | $a = &new PEAR_PackageFile($config, $debug); |
---|
118 | $common = new PEAR_Common; |
---|
119 | $common->ui = $this->ui; |
---|
120 | $a->setLogger($common); |
---|
121 | return $a; |
---|
122 | } |
---|
123 | |
---|
124 | function doPackage($command, $options, $params) |
---|
125 | { |
---|
126 | $this->output = ''; |
---|
127 | $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml'; |
---|
128 | $packager = &$this->getPackager(); |
---|
129 | if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) { |
---|
130 | return $err; |
---|
131 | } |
---|
132 | |
---|
133 | $compress = empty($options['nocompress']) ? true : false; |
---|
134 | $result = $packager->package($pkginfofile, $compress, 'package.xml'); |
---|
135 | if (PEAR::isError($result)) { |
---|
136 | return $this->raiseError($result); |
---|
137 | } |
---|
138 | |
---|
139 | // Don't want output, only the package file name just created |
---|
140 | if (isset($options['showname'])) { |
---|
141 | $this->ui->outputData($result, $command); |
---|
142 | } |
---|
143 | |
---|
144 | return true; |
---|
145 | } |
---|
146 | |
---|
147 | function _convertPackage($packagexml) |
---|
148 | { |
---|
149 | $pkg = &$this->getPackageFile($this->config); |
---|
150 | $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); |
---|
151 | if (!is_a($pf2, 'PEAR_PackageFile_v2')) { |
---|
152 | return $this->raiseError('Cannot process "' . |
---|
153 | $packagexml . '", is not a package.xml 2.0'); |
---|
154 | } |
---|
155 | |
---|
156 | require_once 'PEAR/PackageFile/v1.php'; |
---|
157 | $pf = new PEAR_PackageFile_v1; |
---|
158 | $pf->setConfig($this->config); |
---|
159 | if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') { |
---|
160 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
161 | '", is not an extension source package. Using a PEAR_PackageFileManager-based ' . |
---|
162 | 'script is an option'); |
---|
163 | } |
---|
164 | |
---|
165 | if (is_array($pf2->getUsesRole())) { |
---|
166 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
167 | '", contains custom roles. Using a PEAR_PackageFileManager-based script or ' . |
---|
168 | 'the convert command is an option'); |
---|
169 | } |
---|
170 | |
---|
171 | if (is_array($pf2->getUsesTask())) { |
---|
172 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
173 | '", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' . |
---|
174 | 'the convert command is an option'); |
---|
175 | } |
---|
176 | |
---|
177 | $deps = $pf2->getDependencies(); |
---|
178 | if (isset($deps['group'])) { |
---|
179 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
180 | '", contains dependency groups. Using a PEAR_PackageFileManager-based script ' . |
---|
181 | 'or the convert command is an option'); |
---|
182 | } |
---|
183 | |
---|
184 | if (isset($deps['required']['subpackage']) || |
---|
185 | isset($deps['optional']['subpackage'])) { |
---|
186 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
187 | '", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '. |
---|
188 | 'script is an option'); |
---|
189 | } |
---|
190 | |
---|
191 | if (isset($deps['required']['os'])) { |
---|
192 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
193 | '", contains os dependencies. Using a PEAR_PackageFileManager-based '. |
---|
194 | 'script is an option'); |
---|
195 | } |
---|
196 | |
---|
197 | if (isset($deps['required']['arch'])) { |
---|
198 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
199 | '", contains arch dependencies. Using a PEAR_PackageFileManager-based '. |
---|
200 | 'script is an option'); |
---|
201 | } |
---|
202 | |
---|
203 | $pf->setPackage($pf2->getPackage()); |
---|
204 | $pf->setSummary($pf2->getSummary()); |
---|
205 | $pf->setDescription($pf2->getDescription()); |
---|
206 | foreach ($pf2->getMaintainers() as $maintainer) { |
---|
207 | $pf->addMaintainer($maintainer['role'], $maintainer['handle'], |
---|
208 | $maintainer['name'], $maintainer['email']); |
---|
209 | } |
---|
210 | |
---|
211 | $pf->setVersion($pf2->getVersion()); |
---|
212 | $pf->setDate($pf2->getDate()); |
---|
213 | $pf->setLicense($pf2->getLicense()); |
---|
214 | $pf->setState($pf2->getState()); |
---|
215 | $pf->setNotes($pf2->getNotes()); |
---|
216 | $pf->addPhpDep($deps['required']['php']['min'], 'ge'); |
---|
217 | if (isset($deps['required']['php']['max'])) { |
---|
218 | $pf->addPhpDep($deps['required']['php']['max'], 'le'); |
---|
219 | } |
---|
220 | |
---|
221 | if (isset($deps['required']['package'])) { |
---|
222 | if (!isset($deps['required']['package'][0])) { |
---|
223 | $deps['required']['package'] = array($deps['required']['package']); |
---|
224 | } |
---|
225 | |
---|
226 | foreach ($deps['required']['package'] as $dep) { |
---|
227 | if (!isset($dep['channel'])) { |
---|
228 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
229 | ' contains uri-based dependency on a package. Using a ' . |
---|
230 | 'PEAR_PackageFileManager-based script is an option'); |
---|
231 | } |
---|
232 | |
---|
233 | if ($dep['channel'] != 'pear.php.net' |
---|
234 | && $dep['channel'] != 'pecl.php.net' |
---|
235 | && $dep['channel'] != 'doc.php.net') { |
---|
236 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
237 | ' contains dependency on a non-standard channel package. Using a ' . |
---|
238 | 'PEAR_PackageFileManager-based script is an option'); |
---|
239 | } |
---|
240 | |
---|
241 | if (isset($dep['conflicts'])) { |
---|
242 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
243 | ' contains conflicts dependency. Using a ' . |
---|
244 | 'PEAR_PackageFileManager-based script is an option'); |
---|
245 | } |
---|
246 | |
---|
247 | if (isset($dep['exclude'])) { |
---|
248 | $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); |
---|
249 | } |
---|
250 | |
---|
251 | if (isset($dep['min'])) { |
---|
252 | $pf->addPackageDep($dep['name'], $dep['min'], 'ge'); |
---|
253 | } |
---|
254 | |
---|
255 | if (isset($dep['max'])) { |
---|
256 | $pf->addPackageDep($dep['name'], $dep['max'], 'le'); |
---|
257 | } |
---|
258 | } |
---|
259 | } |
---|
260 | |
---|
261 | if (isset($deps['required']['extension'])) { |
---|
262 | if (!isset($deps['required']['extension'][0])) { |
---|
263 | $deps['required']['extension'] = array($deps['required']['extension']); |
---|
264 | } |
---|
265 | |
---|
266 | foreach ($deps['required']['extension'] as $dep) { |
---|
267 | if (isset($dep['conflicts'])) { |
---|
268 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
269 | ' contains conflicts dependency. Using a ' . |
---|
270 | 'PEAR_PackageFileManager-based script is an option'); |
---|
271 | } |
---|
272 | |
---|
273 | if (isset($dep['exclude'])) { |
---|
274 | $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); |
---|
275 | } |
---|
276 | |
---|
277 | if (isset($dep['min'])) { |
---|
278 | $pf->addExtensionDep($dep['name'], $dep['min'], 'ge'); |
---|
279 | } |
---|
280 | |
---|
281 | if (isset($dep['max'])) { |
---|
282 | $pf->addExtensionDep($dep['name'], $dep['max'], 'le'); |
---|
283 | } |
---|
284 | } |
---|
285 | } |
---|
286 | |
---|
287 | if (isset($deps['optional']['package'])) { |
---|
288 | if (!isset($deps['optional']['package'][0])) { |
---|
289 | $deps['optional']['package'] = array($deps['optional']['package']); |
---|
290 | } |
---|
291 | |
---|
292 | foreach ($deps['optional']['package'] as $dep) { |
---|
293 | if (!isset($dep['channel'])) { |
---|
294 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
295 | ' contains uri-based dependency on a package. Using a ' . |
---|
296 | 'PEAR_PackageFileManager-based script is an option'); |
---|
297 | } |
---|
298 | |
---|
299 | if ($dep['channel'] != 'pear.php.net' |
---|
300 | && $dep['channel'] != 'pecl.php.net' |
---|
301 | && $dep['channel'] != 'doc.php.net') { |
---|
302 | return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . |
---|
303 | ' contains dependency on a non-standard channel package. Using a ' . |
---|
304 | 'PEAR_PackageFileManager-based script is an option'); |
---|
305 | } |
---|
306 | |
---|
307 | if (isset($dep['exclude'])) { |
---|
308 | $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); |
---|
309 | } |
---|
310 | |
---|
311 | if (isset($dep['min'])) { |
---|
312 | $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes'); |
---|
313 | } |
---|
314 | |
---|
315 | if (isset($dep['max'])) { |
---|
316 | $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes'); |
---|
317 | } |
---|
318 | } |
---|
319 | } |
---|
320 | |
---|
321 | if (isset($deps['optional']['extension'])) { |
---|
322 | if (!isset($deps['optional']['extension'][0])) { |
---|
323 | $deps['optional']['extension'] = array($deps['optional']['extension']); |
---|
324 | } |
---|
325 | |
---|
326 | foreach ($deps['optional']['extension'] as $dep) { |
---|
327 | if (isset($dep['exclude'])) { |
---|
328 | $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); |
---|
329 | } |
---|
330 | |
---|
331 | if (isset($dep['min'])) { |
---|
332 | $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes'); |
---|
333 | } |
---|
334 | |
---|
335 | if (isset($dep['max'])) { |
---|
336 | $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes'); |
---|
337 | } |
---|
338 | } |
---|
339 | } |
---|
340 | |
---|
341 | $contents = $pf2->getContents(); |
---|
342 | $release = $pf2->getReleases(); |
---|
343 | if (isset($releases[0])) { |
---|
344 | return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' |
---|
345 | . 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' . |
---|
346 | 'or the convert command is an option'); |
---|
347 | } |
---|
348 | |
---|
349 | if ($configoptions = $pf2->getConfigureOptions()) { |
---|
350 | foreach ($configoptions as $option) { |
---|
351 | $default = isset($option['default']) ? $option['default'] : false; |
---|
352 | $pf->addConfigureOption($option['name'], $option['prompt'], $default); |
---|
353 | } |
---|
354 | } |
---|
355 | |
---|
356 | if (isset($release['filelist']['ignore'])) { |
---|
357 | return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' |
---|
358 | . 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' . |
---|
359 | ' command is an option'); |
---|
360 | } |
---|
361 | |
---|
362 | if (isset($release['filelist']['install']) && |
---|
363 | !isset($release['filelist']['install'][0])) { |
---|
364 | $release['filelist']['install'] = array($release['filelist']['install']); |
---|
365 | } |
---|
366 | |
---|
367 | if (isset($contents['dir']['attribs']['baseinstalldir'])) { |
---|
368 | $baseinstalldir = $contents['dir']['attribs']['baseinstalldir']; |
---|
369 | } else { |
---|
370 | $baseinstalldir = false; |
---|
371 | } |
---|
372 | |
---|
373 | if (!isset($contents['dir']['file'][0])) { |
---|
374 | $contents['dir']['file'] = array($contents['dir']['file']); |
---|
375 | } |
---|
376 | |
---|
377 | foreach ($contents['dir']['file'] as $file) { |
---|
378 | if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) { |
---|
379 | $file['attribs']['baseinstalldir'] = $baseinstalldir; |
---|
380 | } |
---|
381 | |
---|
382 | $processFile = $file; |
---|
383 | unset($processFile['attribs']); |
---|
384 | if (count($processFile)) { |
---|
385 | foreach ($processFile as $name => $task) { |
---|
386 | if ($name != $pf2->getTasksNs() . ':replace') { |
---|
387 | return $this->raiseError('Cannot safely process "' . $packagexml . |
---|
388 | '" contains tasks other than replace. Using a ' . |
---|
389 | 'PEAR_PackageFileManager-based script is an option.'); |
---|
390 | } |
---|
391 | $file['attribs']['replace'][] = $task; |
---|
392 | } |
---|
393 | } |
---|
394 | |
---|
395 | if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) { |
---|
396 | return $this->raiseError('Cannot safely convert "' . $packagexml . |
---|
397 | '", contains custom roles. Using a PEAR_PackageFileManager-based script ' . |
---|
398 | 'or the convert command is an option'); |
---|
399 | } |
---|
400 | |
---|
401 | if (isset($release['filelist']['install'])) { |
---|
402 | foreach ($release['filelist']['install'] as $installas) { |
---|
403 | if ($installas['attribs']['name'] == $file['attribs']['name']) { |
---|
404 | $file['attribs']['install-as'] = $installas['attribs']['as']; |
---|
405 | } |
---|
406 | } |
---|
407 | } |
---|
408 | |
---|
409 | $pf->addFile('/', $file['attribs']['name'], $file['attribs']); |
---|
410 | } |
---|
411 | |
---|
412 | if ($pf2->getChangeLog()) { |
---|
413 | $this->ui->outputData('WARNING: changelog is not translated to package.xml ' . |
---|
414 | '1.0, use PEAR_PackageFileManager-based script if you need changelog-' . |
---|
415 | 'translation for package.xml 1.0'); |
---|
416 | } |
---|
417 | |
---|
418 | $gen = &$pf->getDefaultGenerator(); |
---|
419 | $gen->toPackageFile('.'); |
---|
420 | } |
---|
421 | } |
---|