Содержимое файла | Последнее изменение | Открыть журнал | RSS
Редакция | Автор | № строки | Строка |
---|---|---|---|
69 | alex-w | 1 | <?php |
2 | /** |
||
3 | * PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands) |
||
4 | * |
||
5 | * PHP versions 4 and 5 |
||
6 | * |
||
7 | * LICENSE: This source file is subject to version 3.0 of the PHP license |
||
8 | * that is available through the world-wide-web at the following URI: |
||
9 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of |
||
10 | * the PHP License and are unable to obtain it through the web, please |
||
11 | * send a note to license@php.net so we can mail you a copy immediately. |
||
12 | * |
||
13 | * @category pear |
||
14 | * @package PEAR |
||
15 | * @author Stig Bakken <ssb@php.net> |
||
16 | * @author Greg Beaver <cellog@php.net> |
||
17 | * @copyright 1997-2008 The PHP Group |
||
18 | * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||
19 | * @version CVS: $Id: Install.php,v 1.141 2008/05/13 18:32:29 cellog Exp $ |
||
20 | * @link http://pear.php.net/package/PEAR |
||
21 | * @since File available since Release 0.1 |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * base class |
||
26 | */ |
||
27 | require_once 'PEAR/Command/Common.php'; |
||
28 | |||
29 | /** |
||
30 | * PEAR commands for installation or deinstallation/upgrading of |
||
31 | * packages. |
||
32 | * |
||
33 | * @category pear |
||
34 | * @package PEAR |
||
35 | * @author Stig Bakken <ssb@php.net> |
||
36 | * @author Greg Beaver <cellog@php.net> |
||
37 | * @copyright 1997-2008 The PHP Group |
||
38 | * @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||
39 | * @version Release: 1.7.2 |
||
40 | * @link http://pear.php.net/package/PEAR |
||
41 | * @since Class available since Release 0.1 |
||
42 | */ |
||
43 | class PEAR_Command_Install extends PEAR_Command_Common |
||
44 | { |
||
45 | // {{{ properties |
||
46 | |||
47 | var $commands = array( |
||
48 | 'install' => array( |
||
49 | 'summary' => 'Install Package', |
||
50 | 'function' => 'doInstall', |
||
51 | 'shortcut' => 'i', |
||
52 | 'options' => array( |
||
53 | 'force' => array( |
||
54 | 'shortopt' => 'f', |
||
55 | 'doc' => 'will overwrite newer installed packages', |
||
56 | ), |
||
57 | 'loose' => array( |
||
58 | 'shortopt' => 'l', |
||
59 | 'doc' => 'do not check for recommended dependency version', |
||
60 | ), |
||
61 | 'nodeps' => array( |
||
62 | 'shortopt' => 'n', |
||
63 | 'doc' => 'ignore dependencies, install anyway', |
||
64 | ), |
||
65 | 'register-only' => array( |
||
66 | 'shortopt' => 'r', |
||
67 | 'doc' => 'do not install files, only register the package as installed', |
||
68 | ), |
||
69 | 'soft' => array( |
||
70 | 'shortopt' => 's', |
||
71 | 'doc' => 'soft install, fail silently, or upgrade if already installed', |
||
72 | ), |
||
73 | 'nobuild' => array( |
||
74 | 'shortopt' => 'B', |
||
75 | 'doc' => 'don\'t build C extensions', |
||
76 | ), |
||
77 | 'nocompress' => array( |
||
78 | 'shortopt' => 'Z', |
||
79 | 'doc' => 'request uncompressed files when downloading', |
||
80 | ), |
||
81 | 'installroot' => array( |
||
82 | 'shortopt' => 'R', |
||
83 | 'arg' => 'DIR', |
||
84 | 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', |
||
85 | ), |
||
86 | 'packagingroot' => array( |
||
87 | 'shortopt' => 'P', |
||
88 | 'arg' => 'DIR', |
||
89 | 'doc' => 'root directory used when packaging files, like RPM packaging', |
||
90 | ), |
||
91 | 'ignore-errors' => array( |
||
92 | 'doc' => 'force install even if there were errors', |
||
93 | ), |
||
94 | 'alldeps' => array( |
||
95 | 'shortopt' => 'a', |
||
96 | 'doc' => 'install all required and optional dependencies', |
||
97 | ), |
||
98 | 'onlyreqdeps' => array( |
||
99 | 'shortopt' => 'o', |
||
100 | 'doc' => 'install all required dependencies', |
||
101 | ), |
||
102 | 'offline' => array( |
||
103 | 'shortopt' => 'O', |
||
104 | 'doc' => 'do not attempt to download any urls or contact channels', |
||
105 | ), |
||
106 | 'pretend' => array( |
||
107 | 'shortopt' => 'p', |
||
108 | 'doc' => 'Only list the packages that would be downloaded', |
||
109 | ), |
||
110 | ), |
||
111 | 'doc' => '[channel/]<package> ... |
||
112 | Installs one or more PEAR packages. You can specify a package to |
||
113 | install in four ways: |
||
114 | |||
115 | "Package-1.0.tgz" : installs from a local file |
||
116 | |||
117 | "http://example.com/Package-1.0.tgz" : installs from |
||
118 | anywhere on the net. |
||
119 | |||
120 | "package.xml" : installs the package described in |
||
121 | package.xml. Useful for testing, or for wrapping a PEAR package in |
||
122 | another package manager such as RPM. |
||
123 | |||
124 | "Package[-version/state][.tar]" : queries your default channel\'s server |
||
125 | ({config master_server}) and downloads the newest package with |
||
126 | the preferred quality/state ({config preferred_state}). |
||
127 | |||
128 | To retrieve Package version 1.1, use "Package-1.1," to retrieve |
||
129 | Package state beta, use "Package-beta." To retrieve an uncompressed |
||
130 | file, append .tar (make sure there is no file by the same name first) |
||
131 | |||
132 | To download a package from another channel, prefix with the channel name like |
||
133 | "channel/Package" |
||
134 | |||
135 | More than one package may be specified at once. It is ok to mix these |
||
136 | four ways of specifying packages. |
||
137 | '), |
||
138 | 'upgrade' => array( |
||
139 | 'summary' => 'Upgrade Package', |
||
140 | 'function' => 'doInstall', |
||
141 | 'shortcut' => 'up', |
||
142 | 'options' => array( |
||
143 | 'force' => array( |
||
144 | 'shortopt' => 'f', |
||
145 | 'doc' => 'overwrite newer installed packages', |
||
146 | ), |
||
147 | 'loose' => array( |
||
148 | 'shortopt' => 'l', |
||
149 | 'doc' => 'do not check for recommended dependency version', |
||
150 | ), |
||
151 | 'nodeps' => array( |
||
152 | 'shortopt' => 'n', |
||
153 | 'doc' => 'ignore dependencies, upgrade anyway', |
||
154 | ), |
||
155 | 'register-only' => array( |
||
156 | 'shortopt' => 'r', |
||
157 | 'doc' => 'do not install files, only register the package as upgraded', |
||
158 | ), |
||
159 | 'nobuild' => array( |
||
160 | 'shortopt' => 'B', |
||
161 | 'doc' => 'don\'t build C extensions', |
||
162 | ), |
||
163 | 'nocompress' => array( |
||
164 | 'shortopt' => 'Z', |
||
165 | 'doc' => 'request uncompressed files when downloading', |
||
166 | ), |
||
167 | 'installroot' => array( |
||
168 | 'shortopt' => 'R', |
||
169 | 'arg' => 'DIR', |
||
170 | 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', |
||
171 | ), |
||
172 | 'ignore-errors' => array( |
||
173 | 'doc' => 'force install even if there were errors', |
||
174 | ), |
||
175 | 'alldeps' => array( |
||
176 | 'shortopt' => 'a', |
||
177 | 'doc' => 'install all required and optional dependencies', |
||
178 | ), |
||
179 | 'onlyreqdeps' => array( |
||
180 | 'shortopt' => 'o', |
||
181 | 'doc' => 'install all required dependencies', |
||
182 | ), |
||
183 | 'offline' => array( |
||
184 | 'shortopt' => 'O', |
||
185 | 'doc' => 'do not attempt to download any urls or contact channels', |
||
186 | ), |
||
187 | 'pretend' => array( |
||
188 | 'shortopt' => 'p', |
||
189 | 'doc' => 'Only list the packages that would be downloaded', |
||
190 | ), |
||
191 | ), |
||
192 | 'doc' => '<package> ... |
||
193 | Upgrades one or more PEAR packages. See documentation for the |
||
194 | "install" command for ways to specify a package. |
||
195 | |||
196 | When upgrading, your package will be updated if the provided new |
||
197 | package has a higher version number (use the -f option if you need to |
||
198 | upgrade anyway). |
||
199 | |||
200 | More than one package may be specified at once. |
||
201 | '), |
||
202 | 'upgrade-all' => array( |
||
203 | 'summary' => 'Upgrade All Packages', |
||
204 | 'function' => 'doUpgradeAll', |
||
205 | 'shortcut' => 'ua', |
||
206 | 'options' => array( |
||
207 | 'nodeps' => array( |
||
208 | 'shortopt' => 'n', |
||
209 | 'doc' => 'ignore dependencies, upgrade anyway', |
||
210 | ), |
||
211 | 'register-only' => array( |
||
212 | 'shortopt' => 'r', |
||
213 | 'doc' => 'do not install files, only register the package as upgraded', |
||
214 | ), |
||
215 | 'nobuild' => array( |
||
216 | 'shortopt' => 'B', |
||
217 | 'doc' => 'don\'t build C extensions', |
||
218 | ), |
||
219 | 'nocompress' => array( |
||
220 | 'shortopt' => 'Z', |
||
221 | 'doc' => 'request uncompressed files when downloading', |
||
222 | ), |
||
223 | 'installroot' => array( |
||
224 | 'shortopt' => 'R', |
||
225 | 'arg' => 'DIR', |
||
226 | 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', |
||
227 | ), |
||
228 | 'ignore-errors' => array( |
||
229 | 'doc' => 'force install even if there were errors', |
||
230 | ), |
||
231 | 'loose' => array( |
||
232 | 'doc' => 'do not check for recommended dependency version', |
||
233 | ), |
||
234 | ), |
||
235 | 'doc' => ' |
||
236 | Upgrades all packages that have a newer release available. Upgrades are |
||
237 | done only if there is a release available of the state specified in |
||
238 | "preferred_state" (currently {config preferred_state}), or a state considered |
||
239 | more stable. |
||
240 | '), |
||
241 | 'uninstall' => array( |
||
242 | 'summary' => 'Un-install Package', |
||
243 | 'function' => 'doUninstall', |
||
244 | 'shortcut' => 'un', |
||
245 | 'options' => array( |
||
246 | 'nodeps' => array( |
||
247 | 'shortopt' => 'n', |
||
248 | 'doc' => 'ignore dependencies, uninstall anyway', |
||
249 | ), |
||
250 | 'register-only' => array( |
||
251 | 'shortopt' => 'r', |
||
252 | 'doc' => 'do not remove files, only register the packages as not installed', |
||
253 | ), |
||
254 | 'installroot' => array( |
||
255 | 'shortopt' => 'R', |
||
256 | 'arg' => 'DIR', |
||
257 | 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', |
||
258 | ), |
||
259 | 'ignore-errors' => array( |
||
260 | 'doc' => 'force install even if there were errors', |
||
261 | ), |
||
262 | 'offline' => array( |
||
263 | 'shortopt' => 'O', |
||
264 | 'doc' => 'do not attempt to uninstall remotely', |
||
265 | ), |
||
266 | ), |
||
267 | 'doc' => '[channel/]<package> ... |
||
268 | Uninstalls one or more PEAR packages. More than one package may be |
||
269 | specified at once. Prefix with channel name to uninstall from a |
||
270 | channel not in your default channel ({config default_channel}) |
||
271 | '), |
||
272 | 'bundle' => array( |
||
273 | 'summary' => 'Unpacks a Pecl Package', |
||
274 | 'function' => 'doBundle', |
||
275 | 'shortcut' => 'bun', |
||
276 | 'options' => array( |
||
277 | 'destination' => array( |
||
278 | 'shortopt' => 'd', |
||
279 | 'arg' => 'DIR', |
||
280 | 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', |
||
281 | ), |
||
282 | 'force' => array( |
||
283 | 'shortopt' => 'f', |
||
284 | 'doc' => 'Force the unpacking even if there were errors in the package', |
||
285 | ), |
||
286 | ), |
||
287 | 'doc' => '<package> |
||
288 | Unpacks a Pecl Package into the selected location. It will download the |
||
289 | package if needed. |
||
290 | '), |
||
291 | 'run-scripts' => array( |
||
292 | 'summary' => 'Run Post-Install Scripts bundled with a package', |
||
293 | 'function' => 'doRunScripts', |
||
294 | 'shortcut' => 'rs', |
||
295 | 'options' => array( |
||
296 | ), |
||
297 | 'doc' => '<package> |
||
298 | Run post-installation scripts in package <package>, if any exist. |
||
299 | '), |
||
300 | ); |
||
301 | |||
302 | // }}} |
||
303 | // {{{ constructor |
||
304 | |||
305 | /** |
||
306 | * PEAR_Command_Install constructor. |
||
307 | * |
||
308 | * @access public |
||
309 | */ |
||
310 | function PEAR_Command_Install(&$ui, &$config) |
||
311 | { |
||
312 | parent::PEAR_Command_Common($ui, $config); |
||
313 | } |
||
314 | |||
315 | // }}} |
||
316 | |||
317 | /** |
||
318 | * For unit testing purposes |
||
319 | */ |
||
320 | function &getDownloader(&$ui, $options, &$config) |
||
321 | { |
||
322 | if (!class_exists('PEAR_Downloader')) { |
||
323 | require_once 'PEAR/Downloader.php'; |
||
324 | } |
||
325 | $a = &new PEAR_Downloader($ui, $options, $config); |
||
326 | return $a; |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * For unit testing purposes |
||
331 | */ |
||
332 | function &getInstaller(&$ui) |
||
333 | { |
||
334 | if (!class_exists('PEAR_Installer')) { |
||
335 | require_once 'PEAR/Installer.php'; |
||
336 | } |
||
337 | $a = &new PEAR_Installer($ui); |
||
338 | return $a; |
||
339 | } |
||
340 | |||
341 | function enableExtension($binaries, $type) |
||
342 | { |
||
343 | if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { |
||
344 | return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); |
||
345 | } |
||
346 | $ini = $this->_parseIni($phpini); |
||
347 | if (PEAR::isError($ini)) { |
||
348 | return $ini; |
||
349 | } |
||
350 | $line = 0; |
||
351 | if ($type == 'extsrc' || $type == 'extbin') { |
||
352 | $search = 'extensions'; |
||
353 | $enable = 'extension'; |
||
354 | } else { |
||
355 | $search = 'zend_extensions'; |
||
356 | ob_start(); |
||
357 | phpinfo(INFO_GENERAL); |
||
358 | $info = ob_get_contents(); |
||
359 | ob_end_clean(); |
||
360 | $debug = function_exists('leak') ? '_debug' : ''; |
||
361 | $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; |
||
362 | $enable = 'zend_extension' . $debug . $ts; |
||
363 | } |
||
364 | foreach ($ini[$search] as $line => $extension) { |
||
365 | if (in_array($extension, $binaries, true) || in_array( |
||
366 | $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { |
||
367 | // already enabled - assume if one is, all are |
||
368 | return true; |
||
369 | } |
||
370 | } |
||
371 | if ($line) { |
||
372 | $newini = array_slice($ini['all'], 0, $line); |
||
373 | } else { |
||
374 | $newini = array(); |
||
375 | } |
||
376 | foreach ($binaries as $binary) { |
||
377 | if ($ini['extension_dir']) { |
||
378 | $binary = basename($binary); |
||
379 | } |
||
380 | $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); |
||
381 | } |
||
382 | $newini = array_merge($newini, array_slice($ini['all'], $line)); |
||
383 | $fp = @fopen($phpini, 'wb'); |
||
384 | if (!$fp) { |
||
385 | return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); |
||
386 | } |
||
387 | foreach ($newini as $line) { |
||
388 | fwrite($fp, $line); |
||
389 | } |
||
390 | fclose($fp); |
||
391 | return true; |
||
392 | } |
||
393 | |||
394 | function disableExtension($binaries, $type) |
||
395 | { |
||
396 | if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { |
||
397 | return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); |
||
398 | } |
||
399 | $ini = $this->_parseIni($phpini); |
||
400 | if (PEAR::isError($ini)) { |
||
401 | return $ini; |
||
402 | } |
||
403 | $line = 0; |
||
404 | if ($type == 'extsrc' || $type == 'extbin') { |
||
405 | $search = 'extensions'; |
||
406 | $enable = 'extension'; |
||
407 | } else { |
||
408 | $search = 'zend_extensions'; |
||
409 | ob_start(); |
||
410 | phpinfo(INFO_GENERAL); |
||
411 | $info = ob_get_contents(); |
||
412 | ob_end_clean(); |
||
413 | $debug = function_exists('leak') ? '_debug' : ''; |
||
414 | $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; |
||
415 | $enable = 'zend_extension' . $debug . $ts; |
||
416 | } |
||
417 | $found = false; |
||
418 | foreach ($ini[$search] as $line => $extension) { |
||
419 | if (in_array($extension, $binaries, true) || in_array( |
||
420 | $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { |
||
421 | $found = true; |
||
422 | break; |
||
423 | } |
||
424 | } |
||
425 | if (!$found) { |
||
426 | // not enabled |
||
427 | return true; |
||
428 | } |
||
429 | $fp = @fopen($phpini, 'wb'); |
||
430 | if (!$fp) { |
||
431 | return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); |
||
432 | } |
||
433 | if ($line) { |
||
434 | $newini = array_slice($ini['all'], 0, $line); |
||
435 | // delete the enable line |
||
436 | $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); |
||
437 | } else { |
||
438 | $newini = array_slice($ini['all'], 1); |
||
439 | } |
||
440 | foreach ($newini as $line) { |
||
441 | fwrite($fp, $line); |
||
442 | } |
||
443 | fclose($fp); |
||
444 | return true; |
||
445 | } |
||
446 | |||
447 | function _parseIni($filename) |
||
448 | { |
||
449 | if (file_exists($filename)) { |
||
450 | if (filesize($filename) > 300000) { |
||
451 | return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); |
||
452 | } |
||
453 | ob_start(); |
||
454 | phpinfo(INFO_GENERAL); |
||
455 | $info = ob_get_contents(); |
||
456 | ob_end_clean(); |
||
457 | $debug = function_exists('leak') ? '_debug' : ''; |
||
458 | $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; |
||
459 | $zend_extension_line = 'zend_extension' . $debug . $ts; |
||
460 | $all = @file($filename); |
||
461 | if (!$all) { |
||
462 | return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); |
||
463 | } |
||
464 | $zend_extensions = $extensions = array(); |
||
465 | // assume this is right, but pull from the php.ini if it is found |
||
466 | $extension_dir = ini_get('extension_dir'); |
||
467 | foreach ($all as $linenum => $line) { |
||
468 | $line = trim($line); |
||
469 | if (!$line) { |
||
470 | continue; |
||
471 | } |
||
472 | if ($line[0] == ';') { |
||
473 | continue; |
||
474 | } |
||
475 | if (strtolower(substr($line, 0, 13)) == 'extension_dir') { |
||
476 | $line = trim(substr($line, 13)); |
||
477 | if ($line[0] == '=') { |
||
478 | $x = trim(substr($line, 1)); |
||
479 | $x = explode(';', $x); |
||
480 | $extension_dir = str_replace('"', '', array_shift($x)); |
||
481 | continue; |
||
482 | } |
||
483 | } |
||
484 | if (strtolower(substr($line, 0, 9)) == 'extension') { |
||
485 | $line = trim(substr($line, 9)); |
||
486 | if ($line[0] == '=') { |
||
487 | $x = trim(substr($line, 1)); |
||
488 | $x = explode(';', $x); |
||
489 | $extensions[$linenum] = str_replace('"', '', array_shift($x)); |
||
490 | continue; |
||
491 | } |
||
492 | } |
||
493 | if (strtolower(substr($line, 0, strlen($zend_extension_line))) == |
||
494 | $zend_extension_line) { |
||
495 | $line = trim(substr($line, strlen($zend_extension_line))); |
||
496 | if ($line[0] == '=') { |
||
497 | $x = trim(substr($line, 1)); |
||
498 | $x = explode(';', $x); |
||
499 | $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); |
||
500 | continue; |
||
501 | } |
||
502 | } |
||
503 | } |
||
504 | return array( |
||
505 | 'extensions' => $extensions, |
||
506 | 'zend_extensions' => $zend_extensions, |
||
507 | 'extension_dir' => $extension_dir, |
||
508 | 'all' => $all, |
||
509 | ); |
||
510 | } else { |
||
511 | return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); |
||
512 | } |
||
513 | } |
||
514 | |||
515 | // {{{ doInstall() |
||
516 | |||
517 | function doInstall($command, $options, $params) |
||
518 | { |
||
519 | if (!class_exists('PEAR_PackageFile')) { |
||
520 | require_once 'PEAR/PackageFile.php'; |
||
521 | } |
||
522 | if (empty($this->installer)) { |
||
523 | $this->installer = &$this->getInstaller($this->ui); |
||
524 | } |
||
525 | if ($command == 'upgrade' || $command == 'upgrade-all') { |
||
526 | $options['upgrade'] = true; |
||
527 | } else { |
||
528 | $packages = $params; |
||
529 | } |
||
530 | if (isset($options['installroot']) && isset($options['packagingroot'])) { |
||
531 | return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); |
||
532 | } |
||
533 | $reg = &$this->config->getRegistry(); |
||
534 | $instreg = &$reg; // instreg used to check if package is installed |
||
535 | if (isset($options['packagingroot']) && !isset($options['upgrade'])) { |
||
536 | $packrootphp_dir = $this->installer->_prependPath( |
||
537 | $this->config->get('php_dir', null, 'pear.php.net'), |
||
538 | $options['packagingroot']); |
||
539 | $instreg = new PEAR_Registry($packrootphp_dir); // other instreg! |
||
540 | |||
541 | if ($this->config->get('verbose') > 2) { |
||
542 | $this->ui->outputData('using package root: ' . $options['packagingroot']); |
||
543 | } |
||
544 | } |
||
545 | $abstractpackages = array(); |
||
546 | $otherpackages = array(); |
||
547 | // parse params |
||
548 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
549 | foreach($params as $param) { |
||
550 | if (strpos($param, 'http://') === 0) { |
||
551 | $otherpackages[] = $param; |
||
552 | continue; |
||
553 | } |
||
554 | if (strpos($param, 'channel://') === false && @file_exists($param)) { |
||
555 | if (isset($options['force'])) { |
||
556 | $otherpackages[] = $param; |
||
557 | continue; |
||
558 | } |
||
559 | $pkg = new PEAR_PackageFile($this->config); |
||
560 | $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING); |
||
561 | if (PEAR::isError($pf)) { |
||
562 | $otherpackages[] = $param; |
||
563 | continue; |
||
564 | } |
||
565 | if ($reg->packageExists($pf->getPackage(), $pf->getChannel()) && |
||
566 | version_compare($pf->getVersion(), |
||
567 | $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()), |
||
568 | '<=')) { |
||
569 | if ($this->config->get('verbose')) { |
||
570 | $this->ui->outputData('Ignoring installed package ' . |
||
571 | $reg->parsedPackageNameToString( |
||
572 | array('package' => $pf->getPackage(), |
||
573 | 'channel' => $pf->getChannel()), true)); |
||
574 | } |
||
575 | continue; |
||
576 | } |
||
577 | $otherpackages[] = $param; |
||
578 | continue; |
||
579 | } |
||
580 | $e = $reg->parsePackageName($param, $this->config->get('default_channel')); |
||
581 | if (PEAR::isError($e)) { |
||
582 | $otherpackages[] = $param; |
||
583 | } else { |
||
584 | $abstractpackages[] = $e; |
||
585 | } |
||
586 | } |
||
587 | PEAR::staticPopErrorHandling(); |
||
588 | |||
589 | // if there are any local package .tgz or remote static url, we can't |
||
590 | // filter. The filter only works for abstract packages |
||
591 | if (count($abstractpackages) && !isset($options['force'])) { |
||
592 | // when not being forced, only do necessary upgrades/installs |
||
593 | if (isset($options['upgrade'])) { |
||
594 | $abstractpackages = $this->_filterUptodatePackages($abstractpackages, |
||
595 | $command); |
||
596 | } else { |
||
597 | foreach ($abstractpackages as $i => $package) { |
||
598 | if (isset($package['group'])) { |
||
599 | // do not filter out install groups |
||
600 | continue; |
||
601 | } |
||
602 | if ($instreg->packageExists($package['package'], $package['channel'])) { |
||
603 | if ($this->config->get('verbose')) { |
||
604 | $this->ui->outputData('Ignoring installed package ' . |
||
605 | $reg->parsedPackageNameToString($package, true)); |
||
606 | } |
||
607 | unset($abstractpackages[$i]); |
||
608 | } |
||
609 | } |
||
610 | } |
||
611 | $abstractpackages = |
||
612 | array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); |
||
613 | } elseif (count($abstractpackages)) { |
||
614 | $abstractpackages = |
||
615 | array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); |
||
616 | } |
||
617 | |||
618 | |||
619 | $packages = array_merge($abstractpackages, $otherpackages); |
||
620 | if (!count($packages)) { |
||
621 | $this->ui->outputData('Nothing to ' . $command); |
||
622 | return true; |
||
623 | } |
||
624 | |||
625 | $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); |
||
626 | $errors = array(); |
||
627 | $binaries = array(); |
||
628 | $downloaded = array(); |
||
629 | $downloaded = &$this->downloader->download($packages); |
||
630 | if (PEAR::isError($downloaded)) { |
||
631 | return $this->raiseError($downloaded); |
||
632 | } |
||
633 | $errors = $this->downloader->getErrorMsgs(); |
||
634 | if (count($errors)) { |
||
635 | $err = array(); |
||
636 | $err['data'] = array(); |
||
637 | foreach ($errors as $error) { |
||
638 | $err['data'][] = array($error); |
||
639 | } |
||
640 | $err['headline'] = 'Install Errors'; |
||
641 | $this->ui->outputData($err); |
||
642 | if (!count($downloaded)) { |
||
643 | return $this->raiseError("$command failed"); |
||
644 | } |
||
645 | } |
||
646 | $data = array( |
||
647 | 'headline' => 'Packages that would be Installed' |
||
648 | ); |
||
649 | if (isset($options['pretend'])) { |
||
650 | foreach ($downloaded as $package) { |
||
651 | $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); |
||
652 | } |
||
653 | $this->ui->outputData($data, 'pretend'); |
||
654 | return true; |
||
655 | } |
||
656 | $this->installer->setOptions($options); |
||
657 | $this->installer->sortPackagesForInstall($downloaded); |
||
658 | if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { |
||
659 | $this->raiseError($err->getMessage()); |
||
660 | return true; |
||
661 | } |
||
662 | $extrainfo = array(); |
||
663 | $binaries = array(); |
||
664 | foreach ($downloaded as $param) { |
||
665 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
666 | $info = $this->installer->install($param, $options); |
||
667 | PEAR::staticPopErrorHandling(); |
||
668 | if (PEAR::isError($info)) { |
||
669 | $oldinfo = $info; |
||
670 | $pkg = &$param->getPackageFile(); |
||
671 | if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { |
||
672 | if (!($info = $pkg->installBinary($this->installer))) { |
||
673 | $this->ui->outputData('ERROR: ' .$oldinfo->getMessage()); |
||
674 | continue; |
||
675 | } |
||
676 | // we just installed a different package than requested, |
||
677 | // let's change the param and info so that the rest of this works |
||
678 | $param = $info[0]; |
||
679 | $info = $info[1]; |
||
680 | } |
||
681 | } |
||
682 | if (is_array($info)) { |
||
683 | if ($param->getPackageType() == 'extsrc' || |
||
684 | $param->getPackageType() == 'extbin' || |
||
685 | $param->getPackageType() == 'zendextsrc' || |
||
686 | $param->getPackageType() == 'zendextbin') { |
||
687 | $pkg = &$param->getPackageFile(); |
||
688 | if ($instbin = $pkg->getInstalledBinary()) { |
||
689 | $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); |
||
690 | } else { |
||
691 | $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); |
||
692 | } |
||
693 | |||
694 | foreach ($instpkg->getFilelist() as $name => $atts) { |
||
695 | $pinfo = pathinfo($atts['installed_as']); |
||
696 | if (!isset($pinfo['extension']) || |
||
697 | in_array($pinfo['extension'], array('c', 'h'))) { |
||
698 | continue; // make sure we don't match php_blah.h |
||
699 | } |
||
700 | if ((strpos($pinfo['basename'], 'php_') === 0 && |
||
701 | $pinfo['extension'] == 'dll') || |
||
702 | // most unices |
||
703 | $pinfo['extension'] == 'so' || |
||
704 | // hp-ux |
||
705 | $pinfo['extension'] == 'sl') { |
||
706 | $binaries[] = array($atts['installed_as'], $pinfo); |
||
707 | break; |
||
708 | } |
||
709 | } |
||
710 | if (count($binaries)) { |
||
711 | foreach ($binaries as $pinfo) { |
||
712 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
713 | $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); |
||
714 | PEAR::staticPopErrorHandling(); |
||
715 | if (PEAR::isError($ret)) { |
||
716 | $extrainfo[] = $ret->getMessage(); |
||
717 | if ($param->getPackageType() == 'extsrc' || |
||
718 | $param->getPackageType() == 'extbin') { |
||
719 | $exttype = 'extension'; |
||
720 | } else { |
||
721 | ob_start(); |
||
722 | phpinfo(INFO_GENERAL); |
||
723 | $info = ob_get_contents(); |
||
724 | ob_end_clean(); |
||
725 | $debug = function_exists('leak') ? '_debug' : ''; |
||
726 | $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; |
||
727 | $exttype = 'zend_extension' . $debug . $ts; |
||
728 | } |
||
729 | $extrainfo[] = 'You should add "' . $exttype . '=' . |
||
730 | $pinfo[1]['basename'] . '" to php.ini'; |
||
731 | } else { |
||
732 | $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . |
||
733 | ' enabled in php.ini'; |
||
734 | } |
||
735 | } |
||
736 | } |
||
737 | } |
||
738 | if ($this->config->get('verbose') > 0) { |
||
739 | $channel = $param->getChannel(); |
||
740 | $label = $reg->parsedPackageNameToString( |
||
741 | array( |
||
742 | 'channel' => $channel, |
||
743 | 'package' => $param->getPackage(), |
||
744 | 'version' => $param->getVersion(), |
||
745 | )); |
||
746 | $out = array('data' => "$command ok: $label"); |
||
747 | if (isset($info['release_warnings'])) { |
||
748 | $out['release_warnings'] = $info['release_warnings']; |
||
749 | } |
||
750 | $this->ui->outputData($out, $command); |
||
751 | if (!isset($options['register-only']) && !isset($options['offline'])) { |
||
752 | if ($this->config->isDefinedLayer('ftp')) { |
||
753 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
754 | $info = $this->installer->ftpInstall($param); |
||
755 | PEAR::staticPopErrorHandling(); |
||
756 | if (PEAR::isError($info)) { |
||
757 | $this->ui->outputData($info->getMessage()); |
||
758 | $this->ui->outputData("remote install failed: $label"); |
||
759 | } else { |
||
760 | $this->ui->outputData("remote install ok: $label"); |
||
761 | } |
||
762 | } |
||
763 | } |
||
764 | } |
||
765 | $deps = $param->getDeps(); |
||
766 | if ($deps) { |
||
767 | if (isset($deps['group'])) { |
||
768 | $groups = $deps['group']; |
||
769 | if (!isset($groups[0])) { |
||
770 | $groups = array($groups); |
||
771 | } |
||
772 | foreach ($groups as $group) { |
||
773 | if ($group['attribs']['name'] == 'default') { |
||
774 | // default group is always installed, unless the user |
||
775 | // explicitly chooses to install another group |
||
776 | continue; |
||
777 | } |
||
778 | $extrainfo[] = $param->getPackage() . ': Optional feature ' . |
||
779 | $group['attribs']['name'] . ' available (' . |
||
780 | $group['attribs']['hint'] . ')'; |
||
781 | } |
||
782 | $extrainfo[] = $param->getPackage() . |
||
783 | ': To install optional features use "pear install ' . |
||
784 | $reg->parsedPackageNameToString( |
||
785 | array('package' => $param->getPackage(), |
||
786 | 'channel' => $param->getChannel()), true) . |
||
787 | '#featurename"'; |
||
788 | } |
||
789 | } |
||
790 | $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); |
||
791 | // $pkg may be NULL if install is a 'fake' install via --packagingroot |
||
792 | if (is_object($pkg)) { |
||
793 | $pkg->setConfig($this->config); |
||
794 | if ($list = $pkg->listPostinstallScripts()) { |
||
795 | $pn = $reg->parsedPackageNameToString(array('channel' => |
||
796 | $param->getChannel(), 'package' => $param->getPackage()), true); |
||
797 | $extrainfo[] = $pn . ' has post-install scripts:'; |
||
798 | foreach ($list as $file) { |
||
799 | $extrainfo[] = $file; |
||
800 | } |
||
801 | $extrainfo[] = $param->getPackage() . |
||
802 | ': Use "pear run-scripts ' . $pn . '" to finish setup.'; |
||
803 | $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; |
||
804 | } |
||
805 | } |
||
806 | } else { |
||
807 | return $this->raiseError("$command failed"); |
||
808 | } |
||
809 | } |
||
810 | if (count($extrainfo)) { |
||
811 | foreach ($extrainfo as $info) { |
||
812 | $this->ui->outputData($info); |
||
813 | } |
||
814 | } |
||
815 | return true; |
||
816 | } |
||
817 | |||
818 | // }}} |
||
819 | // {{{ doUpgradeAll() |
||
820 | |||
821 | function doUpgradeAll($command, $options, $params) |
||
822 | { |
||
823 | $reg = &$this->config->getRegistry(); |
||
824 | $toUpgrade = array(); |
||
825 | foreach ($reg->listChannels() as $channel) { |
||
826 | if ($channel == '__uri') { |
||
827 | continue; |
||
828 | } |
||
829 | |||
830 | // parse name with channel |
||
831 | foreach ($reg->listPackages($channel) as $name) { |
||
832 | $toUpgrade[] = $reg->parsedPackageNameToString(array( |
||
833 | 'channel' => $channel, |
||
834 | 'package' => $name |
||
835 | )); |
||
836 | } |
||
837 | } |
||
838 | |||
839 | $err = $this->doInstall('upgrade-all', $options, $toUpgrade); |
||
840 | if (PEAR::isError($err)) { |
||
841 | $this->ui->outputData($err->getMessage(), $command); |
||
842 | } |
||
843 | } |
||
844 | |||
845 | // }}} |
||
846 | // {{{ doUninstall() |
||
847 | |||
848 | function doUninstall($command, $options, $params) |
||
849 | { |
||
850 | if (empty($this->installer)) { |
||
851 | $this->installer = &$this->getInstaller($this->ui); |
||
852 | } |
||
853 | if (isset($options['remoteconfig'])) { |
||
854 | $e = $this->config->readFTPConfigFile($options['remoteconfig']); |
||
855 | if (!PEAR::isError($e)) { |
||
856 | $this->installer->setConfig($this->config); |
||
857 | } |
||
858 | } |
||
859 | if (sizeof($params) < 1) { |
||
860 | return $this->raiseError("Please supply the package(s) you want to uninstall"); |
||
861 | } |
||
862 | $reg = &$this->config->getRegistry(); |
||
863 | $newparams = array(); |
||
864 | $binaries = array(); |
||
865 | $badparams = array(); |
||
866 | foreach ($params as $pkg) { |
||
867 | $channel = $this->config->get('default_channel'); |
||
868 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
869 | $parsed = $reg->parsePackageName($pkg, $channel); |
||
870 | PEAR::staticPopErrorHandling(); |
||
871 | if (!$parsed || PEAR::isError($parsed)) { |
||
872 | $badparams[] = $pkg; |
||
873 | continue; |
||
874 | } |
||
875 | $package = $parsed['package']; |
||
876 | $channel = $parsed['channel']; |
||
877 | $info = &$reg->getPackage($package, $channel); |
||
878 | if ($info === null && |
||
879 | ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { |
||
880 | // make sure this isn't a package that has flipped from pear to pecl but |
||
881 | // used a package.xml 1.0 |
||
882 | $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; |
||
883 | $info = &$reg->getPackage($package, $testc); |
||
884 | if ($info !== null) { |
||
885 | $channel = $testc; |
||
886 | } |
||
887 | } |
||
888 | if ($info === null) { |
||
889 | $badparams[] = $pkg; |
||
890 | } else { |
||
891 | $newparams[] = &$info; |
||
892 | // check for binary packages (this is an alias for those packages if so) |
||
893 | if ($installedbinary = $info->getInstalledBinary()) { |
||
894 | $this->ui->log('adding binary package ' . |
||
895 | $reg->parsedPackageNameToString(array('channel' => $channel, |
||
896 | 'package' => $installedbinary), true)); |
||
897 | $newparams[] = &$reg->getPackage($installedbinary, $channel); |
||
898 | } |
||
899 | // add the contents of a dependency group to the list of installed packages |
||
900 | if (isset($parsed['group'])) { |
||
901 | $group = $info->getDependencyGroup($parsed['group']); |
||
902 | if ($group) { |
||
903 | $installed = $reg->getInstalledGroup($group); |
||
904 | if ($installed) { |
||
905 | foreach ($installed as $i => $p) { |
||
906 | $newparams[] = &$installed[$i]; |
||
907 | } |
||
908 | } |
||
909 | } |
||
910 | } |
||
911 | } |
||
912 | } |
||
913 | $err = $this->installer->sortPackagesForUninstall($newparams); |
||
914 | if (PEAR::isError($err)) { |
||
915 | $this->ui->outputData($err->getMessage(), $command); |
||
916 | return true; |
||
917 | } |
||
918 | $params = $newparams; |
||
919 | // twist this to use it to check on whether dependent packages are also being uninstalled |
||
920 | // for circular dependencies like subpackages |
||
921 | $this->installer->setUninstallPackages($newparams); |
||
922 | $params = array_merge($params, $badparams); |
||
923 | $binaries = array(); |
||
924 | foreach ($params as $pkg) { |
||
925 | $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); |
||
926 | if ($err = $this->installer->uninstall($pkg, $options)) { |
||
927 | $this->installer->popErrorHandling(); |
||
928 | if (PEAR::isError($err)) { |
||
929 | $this->ui->outputData($err->getMessage(), $command); |
||
930 | continue; |
||
931 | } |
||
932 | if ($pkg->getPackageType() == 'extsrc' || |
||
933 | $pkg->getPackageType() == 'extbin' || |
||
934 | $pkg->getPackageType() == 'zendextsrc' || |
||
935 | $pkg->getPackageType() == 'zendextbin') { |
||
936 | if ($instbin = $pkg->getInstalledBinary()) { |
||
937 | continue; // this will be uninstalled later |
||
938 | } |
||
939 | |||
940 | foreach ($pkg->getFilelist() as $name => $atts) { |
||
941 | $pinfo = pathinfo($atts['installed_as']); |
||
942 | if (!isset($pinfo['extension']) || |
||
943 | in_array($pinfo['extension'], array('c', 'h'))) { |
||
944 | continue; // make sure we don't match php_blah.h |
||
945 | } |
||
946 | if ((strpos($pinfo['basename'], 'php_') === 0 && |
||
947 | $pinfo['extension'] == 'dll') || |
||
948 | // most unices |
||
949 | $pinfo['extension'] == 'so' || |
||
950 | // hp-ux |
||
951 | $pinfo['extension'] == 'sl') { |
||
952 | $binaries[] = array($atts['installed_as'], $pinfo); |
||
953 | break; |
||
954 | } |
||
955 | } |
||
956 | if (count($binaries)) { |
||
957 | foreach ($binaries as $pinfo) { |
||
958 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
959 | $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); |
||
960 | PEAR::staticPopErrorHandling(); |
||
961 | if (PEAR::isError($ret)) { |
||
962 | $extrainfo[] = $ret->getMessage(); |
||
963 | if ($pkg->getPackageType() == 'extsrc' || |
||
964 | $pkg->getPackageType() == 'extbin') { |
||
965 | $exttype = 'extension'; |
||
966 | } else { |
||
967 | ob_start(); |
||
968 | phpinfo(INFO_GENERAL); |
||
969 | $info = ob_get_contents(); |
||
970 | ob_end_clean(); |
||
971 | $debug = function_exists('leak') ? '_debug' : ''; |
||
972 | $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; |
||
973 | $exttype = 'zend_extension' . $debug . $ts; |
||
974 | } |
||
975 | $this->ui->outputData('Unable to remove "' . $exttype . '=' . |
||
976 | $pinfo[1]['basename'] . '" from php.ini', $command); |
||
977 | } else { |
||
978 | $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . |
||
979 | ' disabled in php.ini', $command); |
||
980 | } |
||
981 | } |
||
982 | } |
||
983 | } |
||
984 | $savepkg = $pkg; |
||
985 | if ($this->config->get('verbose') > 0) { |
||
986 | if (is_object($pkg)) { |
||
987 | $pkg = $reg->parsedPackageNameToString($pkg); |
||
988 | } |
||
989 | $this->ui->outputData("uninstall ok: $pkg", $command); |
||
990 | } |
||
991 | if (!isset($options['offline']) && is_object($savepkg) && |
||
992 | defined('PEAR_REMOTEINSTALL_OK')) { |
||
993 | if ($this->config->isDefinedLayer('ftp')) { |
||
994 | $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); |
||
995 | $info = $this->installer->ftpUninstall($savepkg); |
||
996 | $this->installer->popErrorHandling(); |
||
997 | if (PEAR::isError($info)) { |
||
998 | $this->ui->outputData($info->getMessage()); |
||
999 | $this->ui->outputData("remote uninstall failed: $pkg"); |
||
1000 | } else { |
||
1001 | $this->ui->outputData("remote uninstall ok: $pkg"); |
||
1002 | } |
||
1003 | } |
||
1004 | } |
||
1005 | } else { |
||
1006 | $this->installer->popErrorHandling(); |
||
1007 | if (is_object($pkg)) { |
||
1008 | $pkg = $reg->parsedPackageNameToString($pkg); |
||
1009 | } |
||
1010 | return $this->raiseError("uninstall failed: $pkg"); |
||
1011 | } |
||
1012 | } |
||
1013 | return true; |
||
1014 | } |
||
1015 | |||
1016 | // }}} |
||
1017 | |||
1018 | |||
1019 | // }}} |
||
1020 | // {{{ doBundle() |
||
1021 | /* |
||
1022 | (cox) It just downloads and untars the package, does not do |
||
1023 | any check that the PEAR_Installer::_installFile() does. |
||
1024 | */ |
||
1025 | |||
1026 | function doBundle($command, $options, $params) |
||
1027 | { |
||
1028 | $downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true, |
||
1029 | 'soft' => true, 'downloadonly' => true), $this->config); |
||
1030 | $reg = &$this->config->getRegistry(); |
||
1031 | if (sizeof($params) < 1) { |
||
1032 | return $this->raiseError("Please supply the package you want to bundle"); |
||
1033 | } |
||
1034 | |||
1035 | if (isset($options['destination'])) { |
||
1036 | if (!is_dir($options['destination'])) { |
||
1037 | System::mkdir('-p ' . $options['destination']); |
||
1038 | } |
||
1039 | $dest = realpath($options['destination']); |
||
1040 | } else { |
||
1041 | $pwd = getcwd(); |
||
1042 | if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) { |
||
1043 | $dest = $pwd . DIRECTORY_SEPARATOR . 'ext'; |
||
1044 | } else { |
||
1045 | $dest = $pwd; |
||
1046 | } |
||
1047 | } |
||
1048 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
1049 | $err = $downloader->setDownloadDir($dest); |
||
1050 | PEAR::staticPopErrorHandling(); |
||
1051 | if (PEAR::isError($err)) { |
||
1052 | return PEAR::raiseError('download directory "' . $dest . |
||
1053 | '" is not writeable.'); |
||
1054 | } |
||
1055 | $result = &$downloader->download(array($params[0])); |
||
1056 | if (PEAR::isError($result)) { |
||
1057 | return $result; |
||
1058 | } |
||
1059 | if (!isset($result[0])) { |
||
1060 | return $this->raiseError('unable to unpack ' . $params[0]); |
||
1061 | } |
||
1062 | $pkgfile = &$result[0]->getPackageFile(); |
||
1063 | $pkgname = $pkgfile->getName(); |
||
1064 | $pkgversion = $pkgfile->getVersion(); |
||
1065 | |||
1066 | // Unpacking ------------------------------------------------- |
||
1067 | $dest .= DIRECTORY_SEPARATOR . $pkgname; |
||
1068 | $orig = $pkgname . '-' . $pkgversion; |
||
1069 | |||
1070 | $tar = &new Archive_Tar($pkgfile->getArchiveFile()); |
||
1071 | if (!$tar->extractModify($dest, $orig)) { |
||
1072 | return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); |
||
1073 | } |
||
1074 | $this->ui->outputData("Package ready at '$dest'"); |
||
1075 | // }}} |
||
1076 | } |
||
1077 | |||
1078 | // }}} |
||
1079 | |||
1080 | function doRunScripts($command, $options, $params) |
||
1081 | { |
||
1082 | if (!isset($params[0])) { |
||
1083 | return $this->raiseError('run-scripts expects 1 parameter: a package name'); |
||
1084 | } |
||
1085 | $reg = &$this->config->getRegistry(); |
||
1086 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
1087 | $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); |
||
1088 | PEAR::staticPopErrorHandling(); |
||
1089 | if (PEAR::isError($parsed)) { |
||
1090 | return $this->raiseError($parsed); |
||
1091 | } |
||
1092 | $package = &$reg->getPackage($parsed['package'], $parsed['channel']); |
||
1093 | if (is_object($package)) { |
||
1094 | $package->setConfig($this->config); |
||
1095 | $package->runPostinstallScripts(); |
||
1096 | } else { |
||
1097 | return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); |
||
1098 | } |
||
1099 | $this->ui->outputData('Install scripts complete', $command); |
||
1100 | return true; |
||
1101 | } |
||
1102 | |||
1103 | /** |
||
1104 | * Given a list of packages, filter out those ones that are already up to date |
||
1105 | * |
||
1106 | * @param $packages: packages, in parsed array format ! |
||
1107 | * @return list of packages that can be upgraded |
||
1108 | */ |
||
1109 | function _filterUptodatePackages($packages, $command) |
||
1110 | { |
||
1111 | $reg = &$this->config->getRegistry(); |
||
1112 | $latestReleases = array(); |
||
1113 | |||
1114 | $ret = array(); |
||
1115 | foreach($packages as $package) { |
||
1116 | if (isset($package['group'])) { |
||
1117 | $ret[] = $package; |
||
1118 | continue; |
||
1119 | } |
||
1120 | $channel = $package['channel']; |
||
1121 | $name = $package['package']; |
||
1122 | |||
1123 | if (!$reg->packageExists($name, $channel)) { |
||
1124 | $ret[] = $package; |
||
1125 | continue; |
||
1126 | } |
||
1127 | if (!isset($latestReleases[$channel])) { |
||
1128 | // fill in cache for this channel |
||
1129 | $chan = &$reg->getChannel($channel); |
||
1130 | if (PEAR::isError($chan)) { |
||
1131 | return $this->raiseError($chan); |
||
1132 | } |
||
1133 | if ($chan->supportsREST($this->config->get('preferred_mirror', |
||
1134 | null, $channel)) && |
||
1135 | $base = $chan->getBaseURL('REST1.0', |
||
1136 | $this->config->get('preferred_mirror', |
||
1137 | null, $channel))) |
||
1138 | { |
||
1139 | $dorest = true; |
||
1140 | } else { |
||
1141 | $dorest = false; |
||
1142 | $remote = &$this->config->getRemote($this->config); |
||
1143 | } |
||
1144 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
||
1145 | if ($dorest) { |
||
1146 | $rest = &$this->config->getREST('1.0', array()); |
||
1147 | $installed = array_flip($reg->listPackages($channel)); |
||
1148 | $latest = $rest->listLatestUpgrades($base, |
||
1149 | $this->config->get('preferred_state', null, $channel), $installed, |
||
1150 | $channel, $reg); |
||
1151 | } else { |
||
1152 | $latest = $remote->call("package.listLatestReleases", |
||
1153 | $this->config->get('preferred_state', null, $channel)); |
||
1154 | unset($remote); |
||
1155 | } |
||
1156 | PEAR::staticPopErrorHandling(); |
||
1157 | if (PEAR::isError($latest)) { |
||
1158 | $this->ui->outputData('Error getting channel info from ' . $channel . |
||
1159 | ': ' . $latest->getMessage()); |
||
1160 | continue; |
||
1161 | } |
||
1162 | |||
1163 | $latestReleases[$channel] = array_change_key_case($latest); |
||
1164 | } |
||
1165 | |||
1166 | // check package for latest release |
||
1167 | if (isset($latestReleases[$channel][strtolower($name)])) { |
||
1168 | // if not set, up to date |
||
1169 | $inst_version = $reg->packageInfo($name, 'version', $channel); |
||
1170 | $channel_version = $latestReleases[$channel][strtolower($name)]['version']; |
||
1171 | if (version_compare($channel_version, $inst_version, "le")) { |
||
1172 | // installed version is up-to-date |
||
1173 | continue; |
||
1174 | } |
||
1175 | // maintain BC |
||
1176 | if ($command == 'upgrade-all') { |
||
1177 | $this->ui->outputData(array('data' => 'Will upgrade ' . |
||
1178 | $reg->parsedPackageNameToString($package)), $command); |
||
1179 | } |
||
1180 | $ret[] = $package; |
||
1181 | } |
||
1182 | } |
||
1183 | |||
1184 | return $ret; |
||
1185 | } |
||
1186 | |||
1187 | } |
||
1188 | ?> |