Implemented the update-command in scripts/plugin. 'install' complains now about an...
[akelos.git] / lib / utils / scripts / plugin.php
bloba248fb31391f5a5e2807049aa8ce8b108694128e
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
11 /**
12 * @package ActiveSupport
13 * @subpackage Scripts
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 error_reporting(defined('AK_ERROR_REPORTING_ON_SCRIPTS') ? AK_ERROR_REPORTING_ON_SCRIPTS : 0);
20 require_once(AK_LIB_DIR.DS.'Ak.php');
21 require_once(AK_LIB_DIR.DS.'AkObject.php');
22 require_once(AK_LIB_DIR.DS.'AkInflector.php');
23 require_once(AK_LIB_DIR.DS.'AkPlugin.php');
24 require_once(AK_LIB_DIR.DS.'AkPlugin/AkPluginManager.php');
25 defined('AK_SKIP_DB_CONNECTION') && AK_SKIP_DB_CONNECTION ? ($dsn='') : Ak::db(&$dsn);
27 $ak_app_dir = AK_APP_DIR;
28 $script_name = array_shift($argv);
29 $command = strtolower(array_shift($argv));
30 array_unshift($argv, $script_name);
31 $_SERVER['argv'] = $argv;
33 $available_commands = array('list', 'sources', 'source', 'unsource', 'discover', 'install', 'update', 'remove', 'info');
35 if(!in_array($command, $available_commands)){
36 echo <<<BANNER
37 Usage: {$script_name} command [OPTIONS]
39 Akelos plugin manager.
41 COMMANDS
43 discover Discover plugin repositories.
44 list List available plugins.
45 install Install plugin(s) from known repositories or URLs.
46 update Update installed plugins.
47 remove Uninstall plugins.
48 source Add a plugin source repository.
49 unsource Remove a plugin repository.
50 sources List currently configured plugin repositories.
53 EXAMPLES
55 Install a plugin:
56 {$script_name} install acts_as_versioned
58 Install a plugin from a subversion URL:
59 {$script_name} install http://svn.akelos.org/plugins/acts_as_versioned
61 Install a plugin and add a svn:externals entry to app/vendor/plugins
62 {$script_name} install -x acts_as_versioned
64 List all available plugins:
65 {$script_name} list
67 List plugins in the specified repository:
68 {$script_name} list --source=http://svn.akelos.org/plugins/
70 Discover and prompt to add new repositories:
71 {$script_name} discover
73 Discover new repositories but just list them, don't add anything:
74 {$script_name} discover -l
76 Add a new repository to the source list:
77 {$script_name} source http://svn.akelos.org/plugins/
79 Remove a repository from the source list:
80 {$script_name} unsource http://svn.akelos.org/plugins/
82 Show currently configured repositories:
83 {$script_name} sources
85 BANNER;
86 exit;
90 set_time_limit(0);
91 error_reporting(E_ALL);
93 require_once (AK_VENDOR_DIR.DS.'pear'.DS.'Console'.DS.'Getargs.php');
94 function get_console_options_for($description, $console_configuration)
96 global $script_name, $argv;
98 $args =& Console_Getargs::factory($console_configuration);
99 if (PEAR::isError($args)) {
101 $replacements = array(
102 '-p --parameters values(1-...)' => 'install plugin_name,URL ...',
103 'Usage: '.basename(__FILE__) =>"Usage: $script_name",
104 '[param1] ' => 'plugin_name PLUGIN_URL'
106 echo "\n$description\n".str_repeat('-', strlen($description)+1)."\n";
107 if ($args->getCode() === CONSOLE_GETARGS_ERROR_USER) {
108 echo str_replace(array_keys($replacements), array_values($replacements),
109 Console_Getargs::getHelp($console_configuration, null, $args->getMessage()))."\n";
110 } else if ($args->getCode() === CONSOLE_GETARGS_HELP) {
111 echo str_replace(array_keys($replacements), array_values($replacements),
112 @Console_Getargs::getHelp($console_configuration))."\n";
114 exit;
116 return $args->getValues();
120 $PluginManager = new AkPluginManager();
125 * List available plugins.
127 if($command == 'list') {
129 $options = get_console_options_for('List available plugins.', array(
130 'source' => array('short' => 's', 'desc' => "Use the specified plugin repositories. --source URL1 URL2", 'max'=> -1, 'min'=> 1),
131 'local' => array('short' => 'l', 'desc' => "List locally installed plugins.", 'max' => 0),
132 'remote' => array('short' => 'r', 'desc' => "List remotely available plugins. This is the default behavior", 'max' => 0)
135 if(isset($options['local']) && isset($options['remote'])){
136 die("Local and remote arguments can not be used simultaneously\n");
138 if(!empty($options['source'])){
139 $PluginManager->tmp_repositories = Ak::toArray($options['source']);
141 $installed_plugins = $PluginManager->getInstalledPlugins();
142 if(isset($options['local'])){
143 $plugins_dir = $ak_app_dir.DS.'vendor'.DS.'plugins';
144 if(empty($installed_plugins)){
145 die("There are not plugins intalled at $plugins_dir\n");
146 }else{
147 echo "Plugins installed at $plugins_dir:\n\n";
148 foreach ($installed_plugins as $plugin){
149 echo " * ".$plugin." (".rtrim($PluginManager->getRepositoryForPlugin($plugin),'/')."/$plugin)\n";
151 die("\n");
153 }else{
154 $plugins = $PluginManager->getPlugins(true);
155 if(empty($plugins)){
156 die("Could not find remote plugins\n");
157 }else{
158 $repsositories = array();
159 foreach ($plugins as $plugin => $repository){
160 if(empty($repsositories[$repository])){
161 $repsositories[$repository] = array();
163 if(in_array($plugin, $installed_plugins)){
164 array_unshift($repsositories[$repository], '[INSTALLED] '.$plugin);
165 }else{
166 $repsositories[$repository][] = $plugin;
169 foreach ($repsositories as $repsository=>$plugins){
170 echo "Plugins available at $repository:\n";
171 echo join(", ",$plugins)."\n\n";
175 die();
181 * List configured plugin repositories.
183 if($command == 'sources') {
184 $options = get_console_options_for('List configured plugin repositories.', array(
185 'check' => array('short' => 'c', 'desc' => "Report status of repository.", 'max' => 0)
187 $repositories = $PluginManager->getAvailableRepositories(true);
189 foreach ($repositories as $repository){
190 $checked = isset($options['check']) && !Ak::url_get_contents($repository, array('timeout'=>5)) ? ' [Connection timeout].' : '';
191 echo " * $repository$checked\n";
193 die();
200 * Adds a repository to the default search list.
202 if($command == 'source') {
203 array_shift($argv);
204 $options = Ak::toArray($argv);
206 if(empty($options)){
207 die("You need to provide at least one repository to add to the default search list.\n");
210 foreach ($options as $repository){
211 if(Ak::url_get_contents($repository, array('timeout'=>10))){
212 $PluginManager->addRepository($repository);
213 echo "Added: $repository\n";
214 }else{
215 echo "Not added: Connection error for repository $repository.\n";
218 die();
225 * Removes a repository to the default search list.
227 if($command == 'unsource') {
228 array_shift($argv);
229 $options = Ak::toArray($argv);
231 if(empty($options)){
232 die("You need to provide at least one repository to remove from the default search list.\n");
235 foreach ($options as $repository){
236 $PluginManager->removeRepository($repository);
237 echo "Removed: $repository\n";
239 die();
246 * Discover repositories referenced on a page.
248 if($command == 'discover') {
250 $options = get_console_options_for('Discover repositories referenced on a page.', array(
251 'source' => array('short' => 's', 'desc' => "Use the specified plugin repositories instead of the default.", 'max' => 1),
252 'list' => array('short' => 'l', 'desc' => "List but don't prompt or add discovered repositories.", 'max' => 0),
253 'no-prompt' => array('short' => 'n', 'desc' => "Add all new repositories without prompting.", 'max' => 0)
256 if(!empty($options['source'])){
257 $PluginManager->respository_discovery_page = $options['source'];
260 $repositories = $PluginManager->getDiscoveredRepositories();
261 $default = 'Y';
263 foreach ($repositories as $repository){
264 echo "* $repository";
265 if(!empty($options['list'])){
266 echo "\n";
267 }else{
268 echo $default == 'Y' ? "[Y/n]:" : "[y/N]:";
270 $key = trim(strtolower(fgetc(STDIN)));
272 if((empty($key) && $default == 'N') || $key == 'n'){
273 echo "Skipped $repository.\n";
274 $default = 'N';
275 }elseif((empty($key) && $default == 'Y') || $key == 'y'){
276 if(Ak::url_get_contents($repository, array('timeout'=>10))){
277 $PluginManager->addRepository($repository);
278 echo "Added $repository.\n";
279 }else{
280 echo "Not added: Connection error for repository $repository.\n";
282 $default = 'Y';
285 if(!empty($key)){
286 fgetc(STDIN);
291 die();
298 * Install plugins.
300 if($command == 'install') {
302 $options = get_console_options_for('Install one or more plugins.', array(
303 CONSOLE_GETARGS_PARAMS => array('short' => 'p', 'desc' => "You can specify plugin names as given in 'plugin list' output or absolute URLs to a plugin repository.", 'max' => -1, 'min' => 1),
304 'externals' => array('short' => 'x', 'desc' => "Use svn:externals to grab the plugin. Enables plugin updates and plugin versioning.", 'max' => 0),
305 'checkout' => array('short' => 'o', 'desc' => "Use svn checkout to grab the plugin. Enables updating but does not add a svn:externals entry.", 'max' => 0),
306 'revision' => array('short' => 'r', 'desc' => "Checks out the given revision from subversion. Ignored if subversion is not used.", 'max' => 1, 'min' => 1),
307 'force' => array('short' => 'f', 'desc' => "Reinstalls a plugin if it's already installed.", 'max' => 0),
310 if(empty($options['parameters'])){
311 die("You must supply at least one plugin name or plugin URL to install.\n");
314 $best = $PluginManager->guessBestInstallMethod($options);
315 if($best == 'http' && (!empty($options['externals']) || !empty($options['checkout']))){
316 die("Cannot install using subversion because `svn' cannot be found in your PATH\n");
317 }elseif ($best == 'export' && !empty($options['externals'])){
318 die("Cannot install using externals because this project is not under subversion.");
319 }elseif ($best == 'export' && !empty($options['checkout'])){
320 die("Cannot install using checkout because this project is not under subversion.");
323 $plugins = Ak::toArray($options['parameters']);
325 foreach ($plugins as $plugin){
326 $repository = null;
327 $plugin_name = basename($plugin);
328 if($plugin_name != $plugin){
329 $repository = preg_replace('/\/?'.$plugin_name.'$/', '', trim($plugin));
331 if (!@$PluginManager->getRepositoryForPlugin($plugin_name, $repository)){
332 is_null($repository) ? $repository = AK_PLUGINS_MAIN_REPOSITORY : null;
333 echo "\nPlugin $plugin_name not found @ ".$repository.".\n";
334 continue;
336 echo "\nInstalling $plugin\n";
337 $PluginManager->installPlugin($plugin_name, $repository, $options);
340 echo "Done.\n";
341 die();
345 * Update plugins.
347 if($command == 'update') {
348 $options = get_console_options_for('Update installed plugins.', array(
349 'externals' => array('short' => 'x', 'desc' => "Use svn:externals to grab the plugin. Enables plugin updates and plugin versioning.", 'max' => 0),
350 'checkout' => array('short' => 'o', 'desc' => "Use svn checkout to grab the plugin. Enables updating but does not add a svn:externals entry.", 'max' => 0),
353 $best = $PluginManager->guessBestInstallMethod($options);
354 if($best == 'http' && (!empty($options['externals']) || !empty($options['checkout']))){
355 die("Cannot install using subversion because `svn' cannot be found in your PATH\n");
356 }elseif ($best == 'export' && !empty($options['externals'])){
357 die("Cannot install using externals because this project is not under subversion.");
358 }elseif ($best == 'export' && !empty($options['checkout'])){
359 die("Cannot install using checkout because this project is not under subversion.");
361 $installed_plugins = $PluginManager->getInstalledPlugins();
362 foreach ($installed_plugins as $plugin){
363 $repository_for_plugin = $PluginManager->getRepositoryForPlugin($plugin);
364 echo "Updating $plugin from $repository_for_plugin.\n";
365 $PluginManager->updatePlugin($plugin,$repository_for_plugin,$options);
367 echo "Done.\n";
368 die();
373 * Remove plugins.
375 if($command == 'remove') {
377 $options = get_console_options_for('Remove plugins.', array(
378 CONSOLE_GETARGS_PARAMS => array('short' => 'p', 'desc' => "You can specify plugin names as given in 'plugin list' output or absolute URLs to a plugin repository.", 'max' => -1, 'min' => 1)));
380 if(empty($options['parameters'])){
381 echo "You must supply at least one plugin name or plugin URL to uninstall.\n";
382 echo "\nInstalled Plugins: ";
383 echo join(', ',$PluginManager->getInstalledPlugins()).'.';
384 die();
387 $plugins = Ak::toArray($options['parameters']);
389 foreach ($plugins as $plugin){
390 $plugin_name = basename($plugin);
391 echo "\nUninstalling $plugin\n";
392 $PluginManager->uninstallPlugin($plugin_name);
395 echo "Done.\n";
396 die();
403 * Shows plugin info at plugin_path/ABOUT.
405 if($command == 'info') {
407 $options = get_console_options_for('Remove plugins.', array(
408 CONSOLE_GETARGS_PARAMS => array('short' => 'p', 'desc' => "Plugin names as given in 'plugin list' output or absolute URL to a plugin repository.", 'max' => 1, 'min' => 1)));
410 if(empty($options['parameters'])){
411 die("You must supply a plugins name or plugin URL.\n");
414 $plugin = $options['parameters'];
415 $plugin_name = basename($plugin);
416 if($plugin_name != $plugin){
417 $repository = preg_replace('/\/?'.$plugin_name.'$/', '', trim($plugin));
418 }else {
419 $repository = $PluginManager->getRepositoryForPlugin($plugin_name);
422 $about = Ak::url_get_contents(rtrim($repository,'/').'/'.$plugin_name.'/ABOUT', array('timeout'=>10));
423 echo empty($about) ? "Could not get plugin information." : $about;
425 die("\n");