Редакция 69 | Только различия | Учитывать пробелы | Содержимое файла | Авторство | Последнее изменение | Открыть журнал | RSS
Редакция 69 | Редакция 87 | ||
---|---|---|---|
1 | <?php
|
1 | <?php
|
2 | /**
|
2 | /**
|
3 | * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
|
3 | * PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
|
4 | * clear-cache commands)
|
4 | * clear-cache commands)
|
5 | *
|
5 | *
|
6 | * PHP versions 4 and 5
|
6 | * PHP versions 4 and 5
|
7 | *
|
7 | *
|
8 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
8 | * LICENSE: This source file is subject to version 3.0 of the PHP license
|
9 | * that is available through the world-wide-web at the following URI:
|
9 | * that is available through the world-wide-web at the following URI:
|
10 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
10 | * http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
11 | * the PHP License and are unable to obtain it through the web, please
|
11 | * the PHP License and are unable to obtain it through the web, please
|
12 | * send a note to license@php.net so we can mail you a copy immediately.
|
12 | * send a note to license@php.net so we can mail you a copy immediately.
|
13 | *
|
13 | *
|
14 | * @category pear
|
14 | * @category pear
|
15 | * @package PEAR
|
15 | * @package PEAR
|
16 | * @author Stig Bakken <ssb@php.net>
|
16 | * @author Stig Bakken <ssb@php.net>
|
17 | * @author Greg Beaver <cellog@php.net>
|
17 | * @author Greg Beaver <cellog@php.net>
|
18 | * @copyright 1997-2008 The PHP Group
|
18 | * @copyright 1997-2008 The PHP Group
|
19 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
19 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
20 | * @version CVS: $Id: Remote.php,v 1.107 2008/04/11 01:16:40 dufuz Exp $
|
20 | * @version CVS: $Id: Remote.php,v 1.107 2008/04/11 01:16:40 dufuz Exp $
|
21 | * @link http://pear.php.net/package/PEAR
|
21 | * @link http://pear.php.net/package/PEAR
|
22 | * @since File available since Release 0.1
|
22 | * @since File available since Release 0.1
|
23 | */
|
23 | */
|
24 | 24 | ||
25 | /**
|
25 | /**
|
26 | * base class
|
26 | * base class
|
27 | */
|
27 | */
|
28 | require_once 'PEAR/Command/Common.php'; |
28 | require_once 'PEAR/Command/Common.php'; |
29 | require_once 'PEAR/REST.php'; |
29 | require_once 'PEAR/REST.php'; |
30 | 30 | ||
31 | /**
|
31 | /**
|
32 | * PEAR commands for remote server querying
|
32 | * PEAR commands for remote server querying
|
33 | *
|
33 | *
|
34 | * @category pear
|
34 | * @category pear
|
35 | * @package PEAR
|
35 | * @package PEAR
|
36 | * @author Stig Bakken <ssb@php.net>
|
36 | * @author Stig Bakken <ssb@php.net>
|
37 | * @author Greg Beaver <cellog@php.net>
|
37 | * @author Greg Beaver <cellog@php.net>
|
38 | * @copyright 1997-2008 The PHP Group
|
38 | * @copyright 1997-2008 The PHP Group
|
39 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
39 | * @license http://www.php.net/license/3_0.txt PHP License 3.0
|
40 | * @version Release: 1.7.2
|
40 | * @version Release: 1.7.2
|
41 | * @link http://pear.php.net/package/PEAR
|
41 | * @link http://pear.php.net/package/PEAR
|
42 | * @since Class available since Release 0.1
|
42 | * @since Class available since Release 0.1
|
43 | */
|
43 | */
|
44 | class PEAR_Command_Remote extends PEAR_Command_Common |
44 | class PEAR_Command_Remote extends PEAR_Command_Common |
45 | {
|
45 | {
|
46 | // {{{ command definitions
|
46 | // {{{ command definitions
|
47 | 47 | ||
48 | var $commands = array( |
48 | var $commands = array( |
49 | 'remote-info' => array( |
49 | 'remote-info' => array( |
50 | 'summary' => 'Information About Remote Packages', |
50 | 'summary' => 'Information About Remote Packages', |
51 | 'function' => 'doRemoteInfo', |
51 | 'function' => 'doRemoteInfo', |
52 | 'shortcut' => 'ri', |
52 | 'shortcut' => 'ri', |
53 | 'options' => array(), |
53 | 'options' => array(), |
54 | 'doc' => '<package> |
54 | 'doc' => '<package> |
55 | Get details on a package from the server.', |
55 | Get details on a package from the server.', |
56 | ), |
56 | ), |
57 | 'list-upgrades' => array( |
57 | 'list-upgrades' => array( |
58 | 'summary' => 'List Available Upgrades', |
58 | 'summary' => 'List Available Upgrades', |
59 | 'function' => 'doListUpgrades', |
59 | 'function' => 'doListUpgrades', |
60 | 'shortcut' => 'lu', |
60 | 'shortcut' => 'lu', |
61 | 'options' => array( |
61 | 'options' => array( |
62 | 'channelinfo' => array( |
62 | 'channelinfo' => array( |
63 | 'shortopt' => 'i', |
63 | 'shortopt' => 'i', |
64 | 'doc' => 'output fully channel-aware data, even on failure', |
64 | 'doc' => 'output fully channel-aware data, even on failure', |
65 | ), |
65 | ), |
66 | ), |
66 | ), |
67 | 'doc' => '[preferred_state] |
67 | 'doc' => '[preferred_state] |
68 | List releases on the server of packages you have installed where
|
68 | List releases on the server of packages you have installed where
|
69 | a newer version is available with the same release state (stable etc.)
|
69 | a newer version is available with the same release state (stable etc.)
|
70 | or the state passed as the second parameter.'
|
70 | or the state passed as the second parameter.'
|
71 | ), |
71 | ), |
72 | 'remote-list' => array( |
72 | 'remote-list' => array( |
73 | 'summary' => 'List Remote Packages', |
73 | 'summary' => 'List Remote Packages', |
74 | 'function' => 'doRemoteList', |
74 | 'function' => 'doRemoteList', |
75 | 'shortcut' => 'rl', |
75 | 'shortcut' => 'rl', |
76 | 'options' => array( |
76 | 'options' => array( |
77 | 'channel' => |
77 | 'channel' => |
78 | array( |
78 | array( |
79 | 'shortopt' => 'c', |
79 | 'shortopt' => 'c', |
80 | 'doc' => 'specify a channel other than the default channel', |
80 | 'doc' => 'specify a channel other than the default channel', |
81 | 'arg' => 'CHAN', |
81 | 'arg' => 'CHAN', |
82 | )
|
82 | )
|
83 | ), |
83 | ), |
84 | 'doc' => ' |
84 | 'doc' => ' |
85 | Lists the packages available on the configured server along with the
|
85 | Lists the packages available on the configured server along with the
|
86 | latest stable release of each package.', |
86 | latest stable release of each package.', |
87 | ), |
87 | ), |
88 | 'search' => array( |
88 | 'search' => array( |
89 | 'summary' => 'Search remote package database', |
89 | 'summary' => 'Search remote package database', |
90 | 'function' => 'doSearch', |
90 | 'function' => 'doSearch', |
91 | 'shortcut' => 'sp', |
91 | 'shortcut' => 'sp', |
92 | 'options' => array( |
92 | 'options' => array( |
93 | 'channel' => |
93 | 'channel' => |
94 | array( |
94 | array( |
95 | 'shortopt' => 'c', |
95 | 'shortopt' => 'c', |
96 | 'doc' => 'specify a channel other than the default channel', |
96 | 'doc' => 'specify a channel other than the default channel', |
97 | 'arg' => 'CHAN', |
97 | 'arg' => 'CHAN', |
98 | ), |
98 | ), |
99 | 'allchannels' => array( |
99 | 'allchannels' => array( |
100 | 'shortopt' => 'a', |
100 | 'shortopt' => 'a', |
101 | 'doc' => 'search packages from all known channels', |
101 | 'doc' => 'search packages from all known channels', |
102 | ), |
102 | ), |
103 | 'channelinfo' => array( |
103 | 'channelinfo' => array( |
104 | 'shortopt' => 'i', |
104 | 'shortopt' => 'i', |
105 | 'doc' => 'output fully channel-aware data, even on failure', |
105 | 'doc' => 'output fully channel-aware data, even on failure', |
106 | ), |
106 | ), |
107 | ), |
107 | ), |
108 | 'doc' => '[packagename] [packageinfo] |
108 | 'doc' => '[packagename] [packageinfo] |
109 | Lists all packages which match the search parameters. The first
|
109 | Lists all packages which match the search parameters. The first
|
110 | parameter is a fragment of a packagename. The default channel
|
110 | parameter is a fragment of a packagename. The default channel
|
111 | will be used unless explicitly overridden. The second parameter
|
111 | will be used unless explicitly overridden. The second parameter
|
112 | will be used to match any portion of the summary/description', |
112 | will be used to match any portion of the summary/description', |
113 | ), |
113 | ), |
114 | 'list-all' => array( |
114 | 'list-all' => array( |
115 | 'summary' => 'List All Packages', |
115 | 'summary' => 'List All Packages', |
116 | 'function' => 'doListAll', |
116 | 'function' => 'doListAll', |
117 | 'shortcut' => 'la', |
117 | 'shortcut' => 'la', |
118 | 'options' => array( |
118 | 'options' => array( |
119 | 'channel' => |
119 | 'channel' => |
120 | array( |
120 | array( |
121 | 'shortopt' => 'c', |
121 | 'shortopt' => 'c', |
122 | 'doc' => 'specify a channel other than the default channel', |
122 | 'doc' => 'specify a channel other than the default channel', |
123 | 'arg' => 'CHAN', |
123 | 'arg' => 'CHAN', |
124 | ), |
124 | ), |
125 | 'channelinfo' => array( |
125 | 'channelinfo' => array( |
126 | 'shortopt' => 'i', |
126 | 'shortopt' => 'i', |
127 | 'doc' => 'output fully channel-aware data, even on failure', |
127 | 'doc' => 'output fully channel-aware data, even on failure', |
128 | ), |
128 | ), |
129 | ), |
129 | ), |
130 | 'doc' => ' |
130 | 'doc' => ' |
131 | Lists the packages available on the configured server along with the
|
131 | Lists the packages available on the configured server along with the
|
132 | latest stable release of each package.', |
132 | latest stable release of each package.', |
133 | ), |
133 | ), |
134 | 'download' => array( |
134 | 'download' => array( |
135 | 'summary' => 'Download Package', |
135 | 'summary' => 'Download Package', |
136 | 'function' => 'doDownload', |
136 | 'function' => 'doDownload', |
137 | 'shortcut' => 'd', |
137 | 'shortcut' => 'd', |
138 | 'options' => array( |
138 | 'options' => array( |
139 | 'nocompress' => array( |
139 | 'nocompress' => array( |
140 | 'shortopt' => 'Z', |
140 | 'shortopt' => 'Z', |
141 | 'doc' => 'download an uncompressed (.tar) file', |
141 | 'doc' => 'download an uncompressed (.tar) file', |
142 | ), |
142 | ), |
143 | ), |
143 | ), |
144 | 'doc' => '<package>... |
144 | 'doc' => '<package>... |
145 | Download package tarballs. The files will be named as suggested by the
|
145 | Download package tarballs. The files will be named as suggested by the
|
146 | server, for example if you download the DB package and the latest stable
|
146 | server, for example if you download the DB package and the latest stable
|
147 | version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.', |
147 | version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.', |
148 | ), |
148 | ), |
149 | 'clear-cache' => array( |
149 | 'clear-cache' => array( |
150 | 'summary' => 'Clear Web Services Cache', |
150 | 'summary' => 'Clear Web Services Cache', |
151 | 'function' => 'doClearCache', |
151 | 'function' => 'doClearCache', |
152 | 'shortcut' => 'cc', |
152 | 'shortcut' => 'cc', |
153 | 'options' => array(), |
153 | 'options' => array(), |
154 | 'doc' => ' |
154 | 'doc' => ' |
155 | Clear the XML-RPC/REST cache. See also the cache_ttl configuration
|
155 | Clear the XML-RPC/REST cache. See also the cache_ttl configuration
|
156 | parameter.
|
156 | parameter.
|
157 | ', |
157 | ', |
158 | ), |
158 | ), |
159 | ); |
159 | ); |
160 | 160 | ||
161 | // }}}
|
161 | // }}}
|
162 | // {{{ constructor
|
162 | // {{{ constructor
|
163 | 163 | ||
164 | /**
|
164 | /**
|
165 | * PEAR_Command_Remote constructor.
|
165 | * PEAR_Command_Remote constructor.
|
166 | *
|
166 | *
|
167 | * @access public
|
167 | * @access public
|
168 | */
|
168 | */
|
169 | function PEAR_Command_Remote(&$ui, &$config) |
169 | function PEAR_Command_Remote(&$ui, &$config) |
170 | {
|
170 | {
|
171 | parent::PEAR_Command_Common($ui, $config); |
171 | parent::PEAR_Command_Common($ui, $config); |
172 | }
|
172 | }
|
173 | 173 | ||
174 | // }}}
|
174 | // }}}
|
175 | 175 | ||
176 | function _checkChannelForStatus($channel, $chan) |
176 | function _checkChannelForStatus($channel, $chan) |
177 | {
|
177 | {
|
178 | if (PEAR::isError($chan)) { |
178 | if (PEAR::isError($chan)) { |
179 | $this->raiseError($chan); |
179 | $this->raiseError($chan); |
180 | }
|
180 | }
|
181 | if (!is_a($chan, 'PEAR_ChannelFile')) { |
181 | if (!is_a($chan, 'PEAR_ChannelFile')) { |
182 | return $this->raiseError('Internal corruption error: invalid channel "' . |
182 | return $this->raiseError('Internal corruption error: invalid channel "' . |
183 | $channel . '"'); |
183 | $channel . '"'); |
184 | }
|
184 | }
|
185 | $rest = new PEAR_REST($this->config); |
185 | $rest = new PEAR_REST($this->config); |
186 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
186 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
187 | $mirror = $this->config->get('preferred_mirror', null, |
187 | $mirror = $this->config->get('preferred_mirror', null, |
188 | $channel); |
188 | $channel); |
189 | $a = $rest->downloadHttp('http://' . $channel . |
189 | $a = $rest->downloadHttp('http://' . $channel . |
190 | '/channel.xml', $chan->lastModified()); |
190 | '/channel.xml', $chan->lastModified()); |
191 | PEAR::staticPopErrorHandling(); |
191 | PEAR::staticPopErrorHandling(); |
192 | if (!PEAR::isError($a) && $a) { |
192 | if (!PEAR::isError($a) && $a) { |
193 | $this->ui->outputData('WARNING: channel "' . $channel . '" has ' . |
193 | $this->ui->outputData('WARNING: channel "' . $channel . '" has ' . |
194 | 'updated its protocols, use "channel-update ' . $channel . |
194 | 'updated its protocols, use "channel-update ' . $channel . |
195 | '" to update'); |
195 | '" to update'); |
196 | }
|
196 | }
|
197 | }
|
197 | }
|
198 | 198 | ||
199 | // {{{ doRemoteInfo()
|
199 | // {{{ doRemoteInfo()
|
200 | 200 | ||
201 | function doRemoteInfo($command, $options, $params) |
201 | function doRemoteInfo($command, $options, $params) |
202 | {
|
202 | {
|
203 | if (sizeof($params) != 1) { |
203 | if (sizeof($params) != 1) { |
204 | return $this->raiseError("$command expects one param: the remote package name"); |
204 | return $this->raiseError("$command expects one param: the remote package name"); |
205 | }
|
205 | }
|
206 | $savechannel = $channel = $this->config->get('default_channel'); |
206 | $savechannel = $channel = $this->config->get('default_channel'); |
207 | $reg = &$this->config->getRegistry(); |
207 | $reg = &$this->config->getRegistry(); |
208 | $package = $params[0]; |
208 | $package = $params[0]; |
209 | $parsed = $reg->parsePackageName($package, $channel); |
209 | $parsed = $reg->parsePackageName($package, $channel); |
210 | if (PEAR::isError($parsed)) { |
210 | if (PEAR::isError($parsed)) { |
211 | return $this->raiseError('Invalid package name "' . $package . '"'); |
211 | return $this->raiseError('Invalid package name "' . $package . '"'); |
212 | }
|
212 | }
|
213 | 213 | ||
214 | $channel = $parsed['channel']; |
214 | $channel = $parsed['channel']; |
215 | $this->config->set('default_channel', $channel); |
215 | $this->config->set('default_channel', $channel); |
216 | $chan = $reg->getChannel($channel); |
216 | $chan = $reg->getChannel($channel); |
217 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
217 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
218 | return $e; |
218 | return $e; |
219 | }
|
219 | }
|
220 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
220 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
221 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
221 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
222 | $rest = &$this->config->getREST('1.0', array()); |
222 | $rest = &$this->config->getREST('1.0', array()); |
223 | $info = $rest->packageInfo($base, $parsed['package'], $channel); |
223 | $info = $rest->packageInfo($base, $parsed['package'], $channel); |
224 | } else { |
224 | } else { |
225 | $r = &$this->config->getRemote(); |
225 | $r = &$this->config->getRemote(); |
226 | $info = $r->call('package.info', $parsed['package']); |
226 | $info = $r->call('package.info', $parsed['package']); |
227 | }
|
227 | }
|
228 | if (PEAR::isError($info)) { |
228 | if (PEAR::isError($info)) { |
229 | $this->config->set('default_channel', $savechannel); |
229 | $this->config->set('default_channel', $savechannel); |
230 | return $this->raiseError($info); |
230 | return $this->raiseError($info); |
231 | }
|
231 | }
|
232 | if (!isset($info['name'])) { |
232 | if (!isset($info['name'])) { |
233 | return $this->raiseError('No remote package "' . $package . '" was found'); |
233 | return $this->raiseError('No remote package "' . $package . '" was found'); |
234 | }
|
234 | }
|
235 | 235 | ||
236 | $installed = $reg->packageInfo($info['name'], null, $channel); |
236 | $installed = $reg->packageInfo($info['name'], null, $channel); |
237 | $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; |
237 | $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; |
238 | if (is_array($info['installed'])) { |
238 | if (is_array($info['installed'])) { |
239 | $info['installed'] = $info['installed']['release']; |
239 | $info['installed'] = $info['installed']['release']; |
240 | }
|
240 | }
|
241 | 241 | ||
242 | $this->ui->outputData($info, $command); |
242 | $this->ui->outputData($info, $command); |
243 | $this->config->set('default_channel', $savechannel); |
243 | $this->config->set('default_channel', $savechannel); |
244 | 244 | ||
245 | return true; |
245 | return true; |
246 | }
|
246 | }
|
247 | 247 | ||
248 | // }}}
|
248 | // }}}
|
249 | // {{{ doRemoteList()
|
249 | // {{{ doRemoteList()
|
250 | 250 | ||
251 | function doRemoteList($command, $options, $params) |
251 | function doRemoteList($command, $options, $params) |
252 | {
|
252 | {
|
253 | $savechannel = $channel = $this->config->get('default_channel'); |
253 | $savechannel = $channel = $this->config->get('default_channel'); |
254 | $reg = &$this->config->getRegistry(); |
254 | $reg = &$this->config->getRegistry(); |
255 | if (isset($options['channel'])) { |
255 | if (isset($options['channel'])) { |
256 | $channel = $options['channel']; |
256 | $channel = $options['channel']; |
257 | if ($reg->channelExists($channel)) { |
257 | if ($reg->channelExists($channel)) { |
258 | $this->config->set('default_channel', $channel); |
258 | $this->config->set('default_channel', $channel); |
259 | } else { |
259 | } else { |
260 | return $this->raiseError('Channel "' . $channel . '" does not exist'); |
260 | return $this->raiseError('Channel "' . $channel . '" does not exist'); |
261 | }
|
261 | }
|
262 | }
|
262 | }
|
263 | $chan = $reg->getChannel($channel); |
263 | $chan = $reg->getChannel($channel); |
264 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
264 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
265 | return $e; |
265 | return $e; |
266 | }
|
266 | }
|
267 | $list_options = false; |
267 | $list_options = false; |
268 | if ($this->config->get('preferred_state') == 'stable') { |
268 | if ($this->config->get('preferred_state') == 'stable') { |
269 | $list_options = true; |
269 | $list_options = true; |
270 | }
|
270 | }
|
271 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
271 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
272 | $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { |
272 | $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { |
273 | // use faster list-all if available
|
273 | // use faster list-all if available
|
274 | $rest = &$this->config->getREST('1.1', array()); |
274 | $rest = &$this->config->getREST('1.1', array()); |
275 | $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); |
275 | $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); |
276 | } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && |
276 | } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && |
277 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
277 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
278 | $rest = &$this->config->getREST('1.0', array()); |
278 | $rest = &$this->config->getREST('1.0', array()); |
279 | $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); |
279 | $available = $rest->listAll($base, $list_options, true, false, false, $chan->getName()); |
280 | } else { |
280 | } else { |
281 | $r = &$this->config->getRemote(); |
281 | $r = &$this->config->getRemote(); |
282 | if ($channel == 'pear.php.net') { |
282 | if ($channel == 'pear.php.net') { |
283 | // hack because of poor pearweb design
|
283 | // hack because of poor pearweb design
|
284 | $available = $r->call('package.listAll', true, $list_options, false); |
284 | $available = $r->call('package.listAll', true, $list_options, false); |
285 | } else { |
285 | } else { |
286 | $available = $r->call('package.listAll', true, $list_options); |
286 | $available = $r->call('package.listAll', true, $list_options); |
287 | }
|
287 | }
|
288 | }
|
288 | }
|
289 | if (PEAR::isError($available)) { |
289 | if (PEAR::isError($available)) { |
290 | $this->config->set('default_channel', $savechannel); |
290 | $this->config->set('default_channel', $savechannel); |
291 | return $this->raiseError($available); |
291 | return $this->raiseError($available); |
292 | }
|
292 | }
|
293 | $i = $j = 0; |
293 | $i = $j = 0; |
294 | $data = array( |
294 | $data = array( |
295 | 'caption' => 'Channel ' . $channel . ' Available packages:', |
295 | 'caption' => 'Channel ' . $channel . ' Available packages:', |
296 | 'border' => true, |
296 | 'border' => true, |
297 | 'headline' => array('Package', 'Version'), |
297 | 'headline' => array('Package', 'Version'), |
298 | 'channel' => $channel |
298 | 'channel' => $channel |
299 | ); |
299 | ); |
300 | if (count($available)==0) { |
300 | if (count($available)==0) { |
301 | $data = '(no packages available yet)'; |
301 | $data = '(no packages available yet)'; |
302 | } else { |
302 | } else { |
303 | foreach ($available as $name => $info) { |
303 | foreach ($available as $name => $info) { |
304 | $data['data'][] = array($name, (isset($info['stable']) && $info['stable']) |
304 | $data['data'][] = array($name, (isset($info['stable']) && $info['stable']) |
305 | ? $info['stable'] : '-n/a-'); |
305 | ? $info['stable'] : '-n/a-'); |
306 | }
|
306 | }
|
307 | }
|
307 | }
|
308 | $this->ui->outputData($data, $command); |
308 | $this->ui->outputData($data, $command); |
309 | $this->config->set('default_channel', $savechannel); |
309 | $this->config->set('default_channel', $savechannel); |
310 | return true; |
310 | return true; |
311 | }
|
311 | }
|
312 | 312 | ||
313 | // }}}
|
313 | // }}}
|
314 | // {{{ doListAll()
|
314 | // {{{ doListAll()
|
315 | 315 | ||
316 | function doListAll($command, $options, $params) |
316 | function doListAll($command, $options, $params) |
317 | {
|
317 | {
|
318 | $savechannel = $channel = $this->config->get('default_channel'); |
318 | $savechannel = $channel = $this->config->get('default_channel'); |
319 | $reg = &$this->config->getRegistry(); |
319 | $reg = &$this->config->getRegistry(); |
320 | if (isset($options['channel'])) { |
320 | if (isset($options['channel'])) { |
321 | $channel = $options['channel']; |
321 | $channel = $options['channel']; |
322 | if ($reg->channelExists($channel)) { |
322 | if ($reg->channelExists($channel)) { |
323 | $this->config->set('default_channel', $channel); |
323 | $this->config->set('default_channel', $channel); |
324 | } else { |
324 | } else { |
325 | return $this->raiseError("Channel \"$channel\" does not exist"); |
325 | return $this->raiseError("Channel \"$channel\" does not exist"); |
326 | }
|
326 | }
|
327 | }
|
327 | }
|
328 | $list_options = false; |
328 | $list_options = false; |
329 | if ($this->config->get('preferred_state') == 'stable') { |
329 | if ($this->config->get('preferred_state') == 'stable') { |
330 | $list_options = true; |
330 | $list_options = true; |
331 | }
|
331 | }
|
332 | $chan = $reg->getChannel($channel); |
332 | $chan = $reg->getChannel($channel); |
333 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
333 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
334 | return $e; |
334 | return $e; |
335 | }
|
335 | }
|
336 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
336 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
337 | $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { |
337 | $base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) { |
338 | // use faster list-all if available
|
338 | // use faster list-all if available
|
339 | $rest = &$this->config->getREST('1.1', array()); |
339 | $rest = &$this->config->getREST('1.1', array()); |
340 | $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); |
340 | $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); |
341 | } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && |
341 | } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) && |
342 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
342 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
343 | $rest = &$this->config->getREST('1.0', array()); |
343 | $rest = &$this->config->getREST('1.0', array()); |
344 | $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); |
344 | $available = $rest->listAll($base, $list_options, false, false, false, $chan->getName()); |
345 | } else { |
345 | } else { |
346 | $r = &$this->config->getRemote(); |
346 | $r = &$this->config->getRemote(); |
347 | if ($channel == 'pear.php.net') { |
347 | if ($channel == 'pear.php.net') { |
348 | // hack because of poor pearweb design
|
348 | // hack because of poor pearweb design
|
349 | $available = $r->call('package.listAll', true, $list_options, false); |
349 | $available = $r->call('package.listAll', true, $list_options, false); |
350 | } else { |
350 | } else { |
351 | $available = $r->call('package.listAll', true, $list_options); |
351 | $available = $r->call('package.listAll', true, $list_options); |
352 | }
|
352 | }
|
353 | }
|
353 | }
|
354 | if (PEAR::isError($available)) { |
354 | if (PEAR::isError($available)) { |
355 | $this->config->set('default_channel', $savechannel); |
355 | $this->config->set('default_channel', $savechannel); |
356 | return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")'); |
356 | return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")'); |
357 | }
|
357 | }
|
358 | $data = array( |
358 | $data = array( |
359 | 'caption' => 'All packages [Channel ' . $channel . ']:', |
359 | 'caption' => 'All packages [Channel ' . $channel . ']:', |
360 | 'border' => true, |
360 | 'border' => true, |
361 | 'headline' => array('Package', 'Latest', 'Local'), |
361 | 'headline' => array('Package', 'Latest', 'Local'), |
362 | 'channel' => $channel, |
362 | 'channel' => $channel, |
363 | ); |
363 | ); |
364 | if (isset($options['channelinfo'])) { |
364 | if (isset($options['channelinfo'])) { |
365 | // add full channelinfo
|
365 | // add full channelinfo
|
366 | $data['caption'] = 'Channel ' . $channel . ' All packages:'; |
366 | $data['caption'] = 'Channel ' . $channel . ' All packages:'; |
367 | $data['headline'] = array('Channel', 'Package', 'Latest', 'Local', |
367 | $data['headline'] = array('Channel', 'Package', 'Latest', 'Local', |
368 | 'Description', 'Dependencies'); |
368 | 'Description', 'Dependencies'); |
369 | }
|
369 | }
|
370 | $local_pkgs = $reg->listPackages($channel); |
370 | $local_pkgs = $reg->listPackages($channel); |
371 | 371 | ||
372 | foreach ($available as $name => $info) { |
372 | foreach ($available as $name => $info) { |
373 | $installed = $reg->packageInfo($name, null, $channel); |
373 | $installed = $reg->packageInfo($name, null, $channel); |
374 | if (is_array($installed['version'])) { |
374 | if (is_array($installed['version'])) { |
375 | $installed['version'] = $installed['version']['release']; |
375 | $installed['version'] = $installed['version']['release']; |
376 | }
|
376 | }
|
377 | $desc = $info['summary']; |
377 | $desc = $info['summary']; |
378 | if (isset($params[$name])) { |
378 | if (isset($params[$name])) { |
379 | $desc .= "\n\n".$info['description']; |
379 | $desc .= "\n\n".$info['description']; |
380 | }
|
380 | }
|
381 | if (isset($options['mode'])) |
381 | if (isset($options['mode'])) |
382 | {
|
382 | {
|
383 | if ($options['mode'] == 'installed' && !isset($installed['version'])) { |
383 | if ($options['mode'] == 'installed' && !isset($installed['version'])) { |
384 | continue; |
384 | continue; |
385 | }
|
385 | }
|
386 | if ($options['mode'] == 'notinstalled' && isset($installed['version'])) { |
386 | if ($options['mode'] == 'notinstalled' && isset($installed['version'])) { |
387 | continue; |
387 | continue; |
388 | }
|
388 | }
|
389 | if ($options['mode'] == 'upgrades' |
389 | if ($options['mode'] == 'upgrades' |
390 | && (!isset($installed['version']) || version_compare($installed['version'], |
390 | && (!isset($installed['version']) || version_compare($installed['version'], |
391 | $info['stable'], '>='))) { |
391 | $info['stable'], '>='))) { |
392 | continue; |
392 | continue; |
393 | }
|
393 | }
|
394 | }
|
394 | }
|
395 | $pos = array_search(strtolower($name), $local_pkgs); |
395 | $pos = array_search(strtolower($name), $local_pkgs); |
396 | if ($pos !== false) { |
396 | if ($pos !== false) { |
397 | unset($local_pkgs[$pos]); |
397 | unset($local_pkgs[$pos]); |
398 | }
|
398 | }
|
399 | 399 | ||
400 | if (isset($info['stable']) && !$info['stable']) { |
400 | if (isset($info['stable']) && !$info['stable']) { |
401 | $info['stable'] = null; |
401 | $info['stable'] = null; |
402 | }
|
402 | }
|
403 | 403 | ||
404 | if (isset($options['channelinfo'])) { |
404 | if (isset($options['channelinfo'])) { |
405 | // add full channelinfo
|
405 | // add full channelinfo
|
406 | if ($info['stable'] === $info['unstable']) { |
406 | if ($info['stable'] === $info['unstable']) { |
407 | $state = $info['state']; |
407 | $state = $info['state']; |
408 | } else { |
408 | } else { |
409 | $state = 'stable'; |
409 | $state = 'stable'; |
410 | }
|
410 | }
|
411 | $latest = $info['stable'].' ('.$state.')'; |
411 | $latest = $info['stable'].' ('.$state.')'; |
412 | $local = ''; |
412 | $local = ''; |
413 | if (isset($installed['version'])) { |
413 | if (isset($installed['version'])) { |
414 | $inst_state = $reg->packageInfo($name, 'release_state', $channel); |
414 | $inst_state = $reg->packageInfo($name, 'release_state', $channel); |
415 | $local = $installed['version'].' ('.$inst_state.')'; |
415 | $local = $installed['version'].' ('.$inst_state.')'; |
416 | }
|
416 | }
|
417 | 417 | ||
418 | $packageinfo = array( |
418 | $packageinfo = array( |
419 | $channel, |
419 | $channel, |
420 | $name, |
420 | $name, |
421 | $latest, |
421 | $latest, |
422 | $local, |
422 | $local, |
423 | isset($desc) ? $desc : null, |
423 | isset($desc) ? $desc : null, |
424 | isset($info['deps']) ? $info['deps'] : null, |
424 | isset($info['deps']) ? $info['deps'] : null, |
425 | ); |
425 | ); |
426 | } else { |
426 | } else { |
427 | $packageinfo = array( |
427 | $packageinfo = array( |
428 | $reg->channelAlias($channel) . '/' . $name, |
428 | $reg->channelAlias($channel) . '/' . $name, |
429 | isset($info['stable']) ? $info['stable'] : null, |
429 | isset($info['stable']) ? $info['stable'] : null, |
430 | isset($installed['version']) ? $installed['version'] : null, |
430 | isset($installed['version']) ? $installed['version'] : null, |
431 | isset($desc) ? $desc : null, |
431 | isset($desc) ? $desc : null, |
432 | isset($info['deps']) ? $info['deps'] : null, |
432 | isset($info['deps']) ? $info['deps'] : null, |
433 | ); |
433 | ); |
434 | }
|
434 | }
|
435 | $data['data'][$info['category']][] = $packageinfo; |
435 | $data['data'][$info['category']][] = $packageinfo; |
436 | }
|
436 | }
|
437 | 437 | ||
438 | if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) { |
438 | if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) { |
439 | $this->config->set('default_channel', $savechannel); |
439 | $this->config->set('default_channel', $savechannel); |
440 | $this->ui->outputData($data, $command); |
440 | $this->ui->outputData($data, $command); |
441 | return true; |
441 | return true; |
442 | }
|
442 | }
|
443 | foreach ($local_pkgs as $name) { |
443 | foreach ($local_pkgs as $name) { |
444 | $info = &$reg->getPackage($name, $channel); |
444 | $info = &$reg->getPackage($name, $channel); |
445 | $data['data']['Local'][] = array( |
445 | $data['data']['Local'][] = array( |
446 | $reg->channelAlias($channel) . '/' . $info->getPackage(), |
446 | $reg->channelAlias($channel) . '/' . $info->getPackage(), |
447 | '', |
447 | '', |
448 | $info->getVersion(), |
448 | $info->getVersion(), |
449 | $info->getSummary(), |
449 | $info->getSummary(), |
450 | $info->getDeps() |
450 | $info->getDeps() |
451 | ); |
451 | ); |
452 | }
|
452 | }
|
453 | 453 | ||
454 | $this->config->set('default_channel', $savechannel); |
454 | $this->config->set('default_channel', $savechannel); |
455 | $this->ui->outputData($data, $command); |
455 | $this->ui->outputData($data, $command); |
456 | return true; |
456 | return true; |
457 | }
|
457 | }
|
458 | 458 | ||
459 | // }}}
|
459 | // }}}
|
460 | // {{{ doSearch()
|
460 | // {{{ doSearch()
|
461 | 461 | ||
462 | function doSearch($command, $options, $params) |
462 | function doSearch($command, $options, $params) |
463 | {
|
463 | {
|
464 | if ((!isset($params[0]) || empty($params[0])) |
464 | if ((!isset($params[0]) || empty($params[0])) |
465 | && (!isset($params[1]) || empty($params[1]))) |
465 | && (!isset($params[1]) || empty($params[1]))) |
466 | {
|
466 | {
|
467 | return $this->raiseError('no valid search string supplied'); |
467 | return $this->raiseError('no valid search string supplied'); |
468 | }; |
468 | }; |
469 | 469 | ||
470 | $channelinfo = isset($options['channelinfo']); |
470 | $channelinfo = isset($options['channelinfo']); |
471 | $reg = &$this->config->getRegistry(); |
471 | $reg = &$this->config->getRegistry(); |
472 | if (isset($options['allchannels'])) { |
472 | if (isset($options['allchannels'])) { |
473 | // search all channels
|
473 | // search all channels
|
474 | unset($options['allchannels']); |
474 | unset($options['allchannels']); |
475 | $channels = $reg->getChannels(); |
475 | $channels = $reg->getChannels(); |
476 | $errors = array(); |
476 | $errors = array(); |
477 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
477 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
478 | foreach ($channels as $channel) { |
478 | foreach ($channels as $channel) { |
479 | if ($channel->getName() != '__uri') { |
479 | if ($channel->getName() != '__uri') { |
480 | $options['channel'] = $channel->getName(); |
480 | $options['channel'] = $channel->getName(); |
481 | $ret = $this->doSearch($command, $options, $params); |
481 | $ret = $this->doSearch($command, $options, $params); |
482 | if (PEAR::isError($ret)) { |
482 | if (PEAR::isError($ret)) { |
483 | $errors[] = $ret; |
483 | $errors[] = $ret; |
484 | }
|
484 | }
|
485 | }
|
485 | }
|
486 | }
|
486 | }
|
487 | PEAR::staticPopErrorHandling(); |
487 | PEAR::staticPopErrorHandling(); |
488 | if (count($errors) !== 0) { |
488 | if (count($errors) !== 0) { |
489 | // for now, only give first error
|
489 | // for now, only give first error
|
490 | return PEAR::raiseError($errors[0]); |
490 | return PEAR::raiseError($errors[0]); |
491 | }
|
491 | }
|
492 | 492 | ||
493 | return true; |
493 | return true; |
494 | }
|
494 | }
|
495 | 495 | ||
496 | $savechannel = $channel = $this->config->get('default_channel'); |
496 | $savechannel = $channel = $this->config->get('default_channel'); |
497 | $package = $params[0]; |
497 | $package = $params[0]; |
498 | $summary = isset($params[1]) ? $params[1] : false; |
498 | $summary = isset($params[1]) ? $params[1] : false; |
499 | if (isset($options['channel'])) { |
499 | if (isset($options['channel'])) { |
500 | $reg = &$this->config->getRegistry(); |
500 | $reg = &$this->config->getRegistry(); |
501 | $channel = $options['channel']; |
501 | $channel = $options['channel']; |
502 | if ($reg->channelExists($channel)) { |
502 | if ($reg->channelExists($channel)) { |
503 | $this->config->set('default_channel', $channel); |
503 | $this->config->set('default_channel', $channel); |
504 | } else { |
504 | } else { |
505 | return $this->raiseError('Channel "' . $channel . '" does not exist'); |
505 | return $this->raiseError('Channel "' . $channel . '" does not exist'); |
506 | }
|
506 | }
|
507 | }
|
507 | }
|
508 | $chan = $reg->getChannel($channel); |
508 | $chan = $reg->getChannel($channel); |
509 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
509 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
510 | return $e; |
510 | return $e; |
511 | }
|
511 | }
|
512 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
512 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
513 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
513 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
514 | $rest = &$this->config->getREST('1.0', array()); |
514 | $rest = &$this->config->getREST('1.0', array()); |
515 | $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName()); |
515 | $available = $rest->listAll($base, false, false, $package, $summary, $chan->getName()); |
516 | } else { |
516 | } else { |
517 | $r = &$this->config->getRemote(); |
517 | $r = &$this->config->getRemote(); |
518 | $available = $r->call('package.search', $package, $summary, true, |
518 | $available = $r->call('package.search', $package, $summary, true, |
519 | $this->config->get('preferred_state') == 'stable', true); |
519 | $this->config->get('preferred_state') == 'stable', true); |
520 | }
|
520 | }
|
521 | if (PEAR::isError($available)) { |
521 | if (PEAR::isError($available)) { |
522 | $this->config->set('default_channel', $savechannel); |
522 | $this->config->set('default_channel', $savechannel); |
523 | return $this->raiseError($available); |
523 | return $this->raiseError($available); |
524 | }
|
524 | }
|
525 | if (!$available && !$channelinfo) { |
525 | if (!$available && !$channelinfo) { |
526 | // clean exit when not found, no error !
|
526 | // clean exit when not found, no error !
|
527 | $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.'; |
527 | $data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.'; |
528 | $this->ui->outputData($data); |
528 | $this->ui->outputData($data); |
529 | $this->config->set('default_channel', $channel); |
529 | $this->config->set('default_channel', $channel); |
530 | return true; |
530 | return true; |
531 | }
|
531 | }
|
532 | if ($channelinfo) { |
532 | if ($channelinfo) { |
533 | $data = array( |
533 | $data = array( |
534 | 'caption' => 'Matched packages, channel ' . $channel . ':', |
534 | 'caption' => 'Matched packages, channel ' . $channel . ':', |
535 | 'border' => true, |
535 | 'border' => true, |
536 | 'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'), |
536 | 'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'), |
537 | 'channel' => $channel |
537 | 'channel' => $channel |
538 | ); |
538 | ); |
539 | } else { |
539 | } else { |
540 | $data = array( |
540 | $data = array( |
541 | 'caption' => 'Matched packages, channel ' . $channel . ':', |
541 | 'caption' => 'Matched packages, channel ' . $channel . ':', |
542 | 'border' => true, |
542 | 'border' => true, |
543 | 'headline' => array('Package', 'Stable/(Latest)', 'Local'), |
543 | 'headline' => array('Package', 'Stable/(Latest)', 'Local'), |
544 | 'channel' => $channel |
544 | 'channel' => $channel |
545 | ); |
545 | ); |
546 | }
|
546 | }
|
547 | 547 | ||
548 | if (!$available && $channelinfo) { |
548 | if (!$available && $channelinfo) { |
549 | unset($data['headline']); |
549 | unset($data['headline']); |
550 | $data['data'] = 'No packages found that match pattern "' . $package . '".'; |
550 | $data['data'] = 'No packages found that match pattern "' . $package . '".'; |
551 | $available = array(); |
551 | $available = array(); |
552 | }
|
552 | }
|
553 | foreach ($available as $name => $info) { |
553 | foreach ($available as $name => $info) { |
554 | $installed = $reg->packageInfo($name, null, $channel); |
554 | $installed = $reg->packageInfo($name, null, $channel); |
555 | $desc = $info['summary']; |
555 | $desc = $info['summary']; |
556 | if (isset($params[$name])) |
556 | if (isset($params[$name])) |
557 | $desc .= "\n\n".$info['description']; |
557 | $desc .= "\n\n".$info['description']; |
558 | 558 | ||
559 | if (!isset($info['stable']) || !$info['stable']) { |
559 | if (!isset($info['stable']) || !$info['stable']) { |
560 | $version_remote = 'none'; |
560 | $version_remote = 'none'; |
561 | } else { |
561 | } else { |
562 | if ($info['unstable']) { |
562 | if ($info['unstable']) { |
563 | $version_remote = $info['unstable']; |
563 | $version_remote = $info['unstable']; |
564 | } else { |
564 | } else { |
565 | $version_remote = $info['stable']; |
565 | $version_remote = $info['stable']; |
566 | }
|
566 | }
|
567 | $version_remote .= ' ('.$info['state'].')'; |
567 | $version_remote .= ' ('.$info['state'].')'; |
568 | }
|
568 | }
|
569 | $version = is_array($installed['version']) ? $installed['version']['release'] : |
569 | $version = is_array($installed['version']) ? $installed['version']['release'] : |
570 | $installed['version']; |
570 | $installed['version']; |
571 | if ($channelinfo) { |
571 | if ($channelinfo) { |
572 | $packageinfo = array( |
572 | $packageinfo = array( |
573 | $channel, |
573 | $channel, |
574 | $name, |
574 | $name, |
575 | $version_remote, |
575 | $version_remote, |
576 | $version, |
576 | $version, |
577 | $desc, |
577 | $desc, |
578 | ); |
578 | ); |
579 | } else { |
579 | } else { |
580 | $packageinfo = array( |
580 | $packageinfo = array( |
581 | $name, |
581 | $name, |
582 | $version_remote, |
582 | $version_remote, |
583 | $version, |
583 | $version, |
584 | $desc, |
584 | $desc, |
585 | ); |
585 | ); |
586 | }
|
586 | }
|
587 | $data['data'][$info['category']][] = $packageinfo; |
587 | $data['data'][$info['category']][] = $packageinfo; |
588 | }
|
588 | }
|
589 | $this->ui->outputData($data, $command); |
589 | $this->ui->outputData($data, $command); |
590 | $this->config->set('default_channel', $channel); |
590 | $this->config->set('default_channel', $channel); |
591 | return true; |
591 | return true; |
592 | }
|
592 | }
|
593 | 593 | ||
594 | // }}}
|
594 | // }}}
|
595 | function &getDownloader($options) |
595 | function &getDownloader($options) |
596 | {
|
596 | {
|
597 | if (!class_exists('PEAR_Downloader')) { |
597 | if (!class_exists('PEAR_Downloader')) { |
598 | require_once 'PEAR/Downloader.php'; |
598 | require_once 'PEAR/Downloader.php'; |
599 | }
|
599 | }
|
600 | $a = &new PEAR_Downloader($this->ui, $options, $this->config); |
600 | $a = &new PEAR_Downloader($this->ui, $options, $this->config); |
601 | return $a; |
601 | return $a; |
602 | }
|
602 | }
|
603 | // {{{ doDownload()
|
603 | // {{{ doDownload()
|
604 | 604 | ||
605 | function doDownload($command, $options, $params) |
605 | function doDownload($command, $options, $params) |
606 | {
|
606 | {
|
607 | // make certain that dependencies are ignored
|
607 | // make certain that dependencies are ignored
|
608 | $options['downloadonly'] = 1; |
608 | $options['downloadonly'] = 1; |
609 | 609 | ||
610 | // eliminate error messages for preferred_state-related errors
|
610 | // eliminate error messages for preferred_state-related errors
|
611 | /* TODO: Should be an option, but until now download does respect
|
611 | /* TODO: Should be an option, but until now download does respect
|
612 | prefered state */
|
612 | prefered state */
|
613 | /* $options['ignorepreferred_state'] = 1; */
|
613 | /* $options['ignorepreferred_state'] = 1; */
|
614 | // eliminate error messages for preferred_state-related errors
|
614 | // eliminate error messages for preferred_state-related errors
|
615 | 615 | ||
616 | $downloader = &$this->getDownloader($options); |
616 | $downloader = &$this->getDownloader($options); |
617 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
617 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
618 | $e = $downloader->setDownloadDir(getcwd()); |
618 | $e = $downloader->setDownloadDir(getcwd()); |
619 | PEAR::staticPopErrorHandling(); |
619 | PEAR::staticPopErrorHandling(); |
620 | if (PEAR::isError($e)) { |
620 | if (PEAR::isError($e)) { |
621 | return $this->raiseError('Current directory is not writeable, cannot download'); |
621 | return $this->raiseError('Current directory is not writeable, cannot download'); |
622 | }
|
622 | }
|
623 | $errors = array(); |
623 | $errors = array(); |
624 | $downloaded = array(); |
624 | $downloaded = array(); |
625 | $err = $downloader->download($params); |
625 | $err = $downloader->download($params); |
626 | if (PEAR::isError($err)) { |
626 | if (PEAR::isError($err)) { |
627 | return $err; |
627 | return $err; |
628 | }
|
628 | }
|
629 | $errors = $downloader->getErrorMsgs(); |
629 | $errors = $downloader->getErrorMsgs(); |
630 | if (count($errors)) { |
630 | if (count($errors)) { |
631 | foreach ($errors as $error) { |
631 | foreach ($errors as $error) { |
632 | $this->ui->outputData($error); |
632 | $this->ui->outputData($error); |
633 | }
|
633 | }
|
634 | return $this->raiseError("$command failed"); |
634 | return $this->raiseError("$command failed"); |
635 | }
|
635 | }
|
636 | $downloaded = $downloader->getDownloadedPackages(); |
636 | $downloaded = $downloader->getDownloadedPackages(); |
637 | foreach ($downloaded as $pkg) { |
637 | foreach ($downloaded as $pkg) { |
638 | $this->ui->outputData("File $pkg[file] downloaded", $command); |
638 | $this->ui->outputData("File $pkg[file] downloaded", $command); |
639 | }
|
639 | }
|
640 | return true; |
640 | return true; |
641 | }
|
641 | }
|
642 | 642 | ||
643 | function downloadCallback($msg, $params = null) |
643 | function downloadCallback($msg, $params = null) |
644 | {
|
644 | {
|
645 | if ($msg == 'done') { |
645 | if ($msg == 'done') { |
646 | $this->bytes_downloaded = $params; |
646 | $this->bytes_downloaded = $params; |
647 | }
|
647 | }
|
648 | }
|
648 | }
|
649 | 649 | ||
650 | // }}}
|
650 | // }}}
|
651 | // {{{ doListUpgrades()
|
651 | // {{{ doListUpgrades()
|
652 | 652 | ||
653 | function doListUpgrades($command, $options, $params) |
653 | function doListUpgrades($command, $options, $params) |
654 | {
|
654 | {
|
655 | require_once 'PEAR/Common.php'; |
655 | require_once 'PEAR/Common.php'; |
656 | if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) { |
656 | if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) { |
657 | return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"'); |
657 | return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"'); |
658 | }
|
658 | }
|
659 | $savechannel = $channel = $this->config->get('default_channel'); |
659 | $savechannel = $channel = $this->config->get('default_channel'); |
660 | $reg = &$this->config->getRegistry(); |
660 | $reg = &$this->config->getRegistry(); |
661 | foreach ($reg->listChannels() as $channel) { |
661 | foreach ($reg->listChannels() as $channel) { |
662 | $inst = array_flip($reg->listPackages($channel)); |
662 | $inst = array_flip($reg->listPackages($channel)); |
663 | if (!count($inst)) { |
663 | if (!count($inst)) { |
664 | continue; |
664 | continue; |
665 | }
|
665 | }
|
666 | if ($channel == '__uri') { |
666 | if ($channel == '__uri') { |
667 | continue; |
667 | continue; |
668 | }
|
668 | }
|
669 | $this->config->set('default_channel', $channel); |
669 | $this->config->set('default_channel', $channel); |
670 | if (empty($params[0])) { |
670 | if (empty($params[0])) { |
671 | $state = $this->config->get('preferred_state'); |
671 | $state = $this->config->get('preferred_state'); |
672 | } else { |
672 | } else { |
673 | $state = $params[0]; |
673 | $state = $params[0]; |
674 | }
|
674 | }
|
675 | $caption = $channel . ' Available Upgrades'; |
675 | $caption = $channel . ' Available Upgrades'; |
676 | $chan = $reg->getChannel($channel); |
676 | $chan = $reg->getChannel($channel); |
677 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
677 | if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) { |
678 | return $e; |
678 | return $e; |
679 | }
|
679 | }
|
680 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
680 | if ($chan->supportsREST($this->config->get('preferred_mirror')) && |
681 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
681 | $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { |
682 | $rest = &$this->config->getREST('1.0', array()); |
682 | $rest = &$this->config->getREST('1.0', array()); |
683 | if (empty($state) || $state == 'any') { |
683 | if (empty($state) || $state == 'any') { |
684 | $state = false; |
684 | $state = false; |
685 | } else { |
685 | } else { |
686 | $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; |
686 | $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; |
687 | }
|
687 | }
|
688 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
688 | PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); |
689 | $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg); |
689 | $latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg); |
690 | PEAR::staticPopErrorHandling(); |
690 | PEAR::staticPopErrorHandling(); |
691 | } else { |
691 | } else { |
692 | $remote = &$this->config->getRemote(); |
692 | $remote = &$this->config->getRemote(); |
693 | $remote->pushErrorHandling(PEAR_ERROR_RETURN); |
693 | $remote->pushErrorHandling(PEAR_ERROR_RETURN); |
694 | if (empty($state) || $state == 'any') { |
694 | if (empty($state) || $state == 'any') { |
695 | $latest = $remote->call("package.listLatestReleases"); |
695 | $latest = $remote->call("package.listLatestReleases"); |
696 | } else { |
696 | } else { |
697 | $latest = $remote->call("package.listLatestReleases", $state); |
697 | $latest = $remote->call("package.listLatestReleases", $state); |
698 | $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; |
698 | $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; |
699 | }
|
699 | }
|
700 | $remote->popErrorHandling(); |
700 | $remote->popErrorHandling(); |
701 | }
|
701 | }
|
702 | if (PEAR::isError($latest)) { |
702 | if (PEAR::isError($latest)) { |
703 | $this->ui->outputData($latest->getMessage()); |
703 | $this->ui->outputData($latest->getMessage()); |
704 | continue; |
704 | continue; |
705 | }
|
705 | }
|
706 | $caption .= ':'; |
706 | $caption .= ':'; |
707 | if (PEAR::isError($latest)) { |
707 | if (PEAR::isError($latest)) { |
708 | $this->config->set('default_channel', $savechannel); |
708 | $this->config->set('default_channel', $savechannel); |
709 | return $latest; |
709 | return $latest; |
710 | }
|
710 | }
|
711 | $data = array( |
711 | $data = array( |
712 | 'caption' => $caption, |
712 | 'caption' => $caption, |
713 | 'border' => 1, |
713 | 'border' => 1, |
714 | 'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'), |
714 | 'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'), |
715 | 'channel' => $channel |
715 | 'channel' => $channel |
716 | ); |
716 | ); |
717 | foreach ((array)$latest as $pkg => $info) { |
717 | foreach ((array)$latest as $pkg => $info) { |
718 | $package = strtolower($pkg); |
718 | $package = strtolower($pkg); |
719 | if (!isset($inst[$package])) { |
719 | if (!isset($inst[$package])) { |
720 | // skip packages we don't have installed
|
720 | // skip packages we don't have installed
|
721 | continue; |
721 | continue; |
722 | }
|
722 | }
|
723 | extract($info); |
723 | extract($info); |
724 | $inst_version = $reg->packageInfo($package, 'version', $channel); |
724 | $inst_version = $reg->packageInfo($package, 'version', $channel); |
725 | $inst_state = $reg->packageInfo($package, 'release_state', $channel); |
725 | $inst_state = $reg->packageInfo($package, 'release_state', $channel); |
726 | if (version_compare("$version", "$inst_version", "le")) { |
726 | if (version_compare("$version", "$inst_version", "le")) { |
727 | // installed version is up-to-date
|
727 | // installed version is up-to-date
|
728 | continue; |
728 | continue; |
729 | }
|
729 | }
|
730 | if ($filesize >= 20480) { |
730 | if ($filesize >= 20480) { |
731 | $filesize += 1024 - ($filesize % 1024); |
731 | $filesize += 1024 - ($filesize % 1024); |
732 | $fs = sprintf("%dkB", $filesize / 1024); |
732 | $fs = sprintf("%dkB", $filesize / 1024); |
733 | } elseif ($filesize > 0) { |
733 | } elseif ($filesize > 0) { |
734 | $filesize += 103 - ($filesize % 103); |
734 | $filesize += 103 - ($filesize % 103); |
735 | $fs = sprintf("%.1fkB", $filesize / 1024.0); |
735 | $fs = sprintf("%.1fkB", $filesize / 1024.0); |
736 | } else { |
736 | } else { |
737 | $fs = " -"; // XXX center instead |
737 | $fs = " -"; // XXX center instead |
738 | }
|
738 | }
|
739 | $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); |
739 | $data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); |
740 | }
|
740 | }
|
741 | if (isset($options['channelinfo'])) { |
741 | if (isset($options['channelinfo'])) { |
742 | if (empty($data['data'])) { |
742 | if (empty($data['data'])) { |
743 | unset($data['headline']); |
743 | unset($data['headline']); |
744 | if (count($inst) == 0) { |
744 | if (count($inst) == 0) { |
745 | $data['data'] = '(no packages installed)'; |
745 | $data['data'] = '(no packages installed)'; |
746 | } else { |
746 | } else { |
747 | $data['data'] = '(no upgrades available)'; |
747 | $data['data'] = '(no upgrades available)'; |
748 | }
|
748 | }
|
749 | }
|
749 | }
|
750 | $this->ui->outputData($data, $command); |
750 | $this->ui->outputData($data, $command); |
751 | } else { |
751 | } else { |
752 | if (empty($data['data'])) { |
752 | if (empty($data['data'])) { |
753 | $this->ui->outputData('Channel ' . $channel . ': No upgrades available'); |
753 | $this->ui->outputData('Channel ' . $channel . ': No upgrades available'); |
754 | } else { |
754 | } else { |
755 | $this->ui->outputData($data, $command); |
755 | $this->ui->outputData($data, $command); |
756 | }
|
756 | }
|
757 | }
|
757 | }
|
758 | }
|
758 | }
|
759 | $this->config->set('default_channel', $savechannel); |
759 | $this->config->set('default_channel', $savechannel); |
760 | return true; |
760 | return true; |
761 | }
|
761 | }
|
762 | 762 | ||
763 | // }}}
|
763 | // }}}
|
764 | // {{{ doClearCache()
|
764 | // {{{ doClearCache()
|
765 | 765 | ||
766 | function doClearCache($command, $options, $params) |
766 | function doClearCache($command, $options, $params) |
767 | {
|
767 | {
|
768 | $cache_dir = $this->config->get('cache_dir'); |
768 | $cache_dir = $this->config->get('cache_dir'); |
769 | $verbose = $this->config->get('verbose'); |
769 | $verbose = $this->config->get('verbose'); |
770 | $output = ''; |
770 | $output = ''; |
771 | if (!file_exists($cache_dir) || !is_dir($cache_dir)) { |
771 | if (!file_exists($cache_dir) || !is_dir($cache_dir)) { |
772 | return $this->raiseError("$cache_dir does not exist or is not a directory"); |
772 | return $this->raiseError("$cache_dir does not exist or is not a directory"); |
773 | }
|
773 | }
|
774 | if (!($dp = @opendir($cache_dir))) { |
774 | if (!($dp = @opendir($cache_dir))) { |
775 | return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); |
775 | return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); |
776 | }
|
776 | }
|
777 | if ($verbose >= 1) { |
777 | if ($verbose >= 1) { |
778 | $output .= "reading directory $cache_dir\n"; |
778 | $output .= "reading directory $cache_dir\n"; |
779 | }
|
779 | }
|
780 | $num = 0; |
780 | $num = 0; |
781 | while ($ent = readdir($dp)) { |
781 | while ($ent = readdir($dp)) { |
782 | if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}\\z/', $ent) || |
782 | if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}\\z/', $ent) || |
783 | preg_match('/rest.cache(file|id)\\z/', $ent)) { |
783 | preg_match('/rest.cache(file|id)\\z/', $ent)) { |
784 | $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; |
784 | $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; |
785 | if (file_exists($path)) { |
785 | if (file_exists($path)) { |
786 | $ok = @unlink($path); |
786 | $ok = @unlink($path); |
787 | } else { |
787 | } else { |
788 | $ok = false; |
788 | $ok = false; |
789 | $php_errormsg = ''; |
789 | $php_errormsg = ''; |
790 | }
|
790 | }
|
791 | if ($ok) { |
791 | if ($ok) { |
792 | if ($verbose >= 2) { |
792 | if ($verbose >= 2) { |
793 | $output .= "deleted $path\n"; |
793 | $output .= "deleted $path\n"; |
794 | }
|
794 | }
|
795 | $num++; |
795 | $num++; |
796 | } elseif ($verbose >= 1) { |
796 | } elseif ($verbose >= 1) { |
797 | $output .= "failed to delete $path $php_errormsg\n"; |
797 | $output .= "failed to delete $path $php_errormsg\n"; |
798 | }
|
798 | }
|
799 | }
|
799 | }
|
800 | }
|
800 | }
|
801 | closedir($dp); |
801 | closedir($dp); |
802 | if ($verbose >= 1) { |
802 | if ($verbose >= 1) { |
803 | $output .= "$num cache entries cleared\n"; |
803 | $output .= "$num cache entries cleared\n"; |
804 | }
|
804 | }
|
805 | $this->ui->outputData(rtrim($output), $command); |
805 | $this->ui->outputData(rtrim($output), $command); |
806 | return $num; |
806 | return $num; |
807 | }
|
807 | }
|
808 | 808 | ||
809 | // }}}
|
809 | // }}}
|
810 | }
|
810 | }
|
811 | 811 | ||
812 | ?>
|
812 | ?>
|
813 | 813 |