Index: pm.drush.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/drush_extras/pm.drush.inc,v
retrieving revision 1.2.2.1.2.6
diff -u -r1.2.2.1.2.6 pm.drush.inc
--- pm.drush.inc	8 Mar 2009 04:02:36 -0000	1.2.2.1.2.6
+++ pm.drush.inc	23 Mar 2009 15:48:07 -0000
@@ -63,6 +63,12 @@
       return dt("Usage: drush [options] pm info <package_1> <package_2> ...\n
 View all releases for a given project. Useful for deciding which version to install/update.
     ");
+    
+    case 'drush:list':
+        return dt("Usage: drush [options] list <pattern>\n
+View all contributed modules. A project name including wildcards can be used
+to filter the list. Useful to lookup the name of modules to install.
+    ");
   }
 }
 
@@ -109,6 +115,12 @@
     'drupal dependencies' => array('update'),
     'core' => array('6'),
   );
+    $items['list'] = array(
+    'callback' => 'drush_pm_list',
+    'description' => 'Lists available and installed modules',
+    'core' => array('6'),
+    'drupal dependencies' => array('update'),
+  );
   return $items;
 }
 
@@ -122,7 +134,7 @@
 /**
  * Command callback. Enables one or more modules.
  */
-function drush_pm_enable () {  
+function drush_pm_enable () {
   $modules = func_get_args();
   return drush_pm_module_manage($modules);
 }
@@ -130,7 +142,7 @@
 /**
  * Command callback. Disable one or more modules.
  */
-function drush_pm_disable () {  
+function drush_pm_disable () {
   $modules = func_get_args();
   return drush_pm_module_manage($modules, FALSE);
 }
@@ -177,7 +189,7 @@
     drupal_execute('system_modules', $form_state);
     $form = system_modules();
     foreach (array_unique(array_merge($modules)) as $key => $module) {
-      if ($enable) { 
+      if ($enable) {
         if (array_search($module, $form['status']['#default_value']) !== FALSE) {
           drush_print(dt('!module was enabled successfully.', array('!module' => $form['validation_modules']['#value'][$module]->info['name'])));
         }
@@ -185,7 +197,7 @@
           drush_set_error('DRUSH_PM_ENABLE_MODULE_ISSUE', dt('> There was a problem enabling !module.', array('!module' => $module)));
         }
       }
-      else { 
+      else {
         if (array_search($module, $form['status']['#default_value']) === FALSE) {
           drush_print(dt('!module was disabled successfully.', array('!module' => $form['validation_modules']['#value'][$module]->info['name'])));
         }
@@ -385,6 +397,81 @@
 }
 
 /**
+ * Command callback. Lists available packages that have a compatible API.
+ * Displays short name, title and author.
+ * Accepts a pattern as an argument to filter the project list by short name.
+ */
+function drush_pm_list() {
+  if (func_num_args() > 0) {
+    $pattern = func_get_arg(0);
+    $pattern = '/^' . str_replace('*', '.*', $pattern) . '$/';
+  } else {
+    $pattern = '/.*/';
+  }
+  
+  $reader = new XMLReader;
+  $uri = UPDATE_DEFAULT_URL . '/project-list/all';
+  
+  if (!$reader->open($uri)) {
+    drush_die(dt("Cannot open $uri. Test your network connection"));
+  }
+  
+  drush_print(dt("State=No/Installed"));
+  printf("| %-25s %-40s %-10s\n", dt('Short name'), dt('Title'), dt('Author'));
+  printf("+-%'=-25s-%'=-40s-%'=-10s\n", null, null, null);
+  
+  // need update_get_projetcs function
+  module_load_include('inc', 'update', 'update.compare');
+  
+  while ($reader->read()) {
+    if ($reader->nodeType == XMLReader::ELEMENT) {
+      switch ($reader->localName) {
+        case 'project':
+          $title = '';
+          $short_name = '';
+          $author = '';
+          $api_version = array();
+          break;
+        case 'title':
+          $title = $reader->readString();
+          break;
+        case 'short_name':
+          $short_name = $reader->readString();
+          if (in_array($short_name, array_keys(update_get_projects()))) {
+            $installed = 'i';
+          } else {
+            $installed = 'n';
+          }
+          break;
+        case 'creator':
+          $author = $reader->readString();
+          break;
+        case 'value':
+          // read term value
+          if ($reader->readString() == 'Modules') {
+            $type = 'm';
+          } else if ($reader->readString() == 'Themes') {
+            $type = 't';
+          }
+          break;
+        case 'api_version':
+          $api_version[] = $reader->readString();
+          break;
+      }
+    } else if ($reader->nodeType == XMLReader::END_ELEMENT) {
+      if ($reader->localName == 'project') {
+        if (in_array(DRUPAL_CORE_COMPATIBILITY, $api_version) &&
+            preg_match($pattern, $short_name) && $type == 'm') {
+          printf("%s %-25s %-40s %-10s\n", $installed,
+                substr($short_name, 0, 25), substr($title, 0, 40),
+                substr($author, 0, 10));
+        }
+      }
+    }
+  }
+}
+
+/**
  * Update packages according to an array of releases, following interactive
  * confirmation from the user.
  *
