? views
? includes/table.inc
Index: commands/pm/pm.drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/pm.drush.inc,v
retrieving revision 1.149
diff -u -p -r1.149 pm.drush.inc
--- commands/pm/pm.drush.inc	3 Dec 2010 16:32:56 -0000	1.149
+++ commands/pm/pm.drush.inc	5 Dec 2010 01:18:52 -0000
@@ -184,6 +184,7 @@ function pm_drush_command() {
       'drush rln pathauto zen' => 'View release notes for the recommended version of Pathauto and Zen projects.',
     ),
     'aliases' => array('rln'),
+    'bootstrap' => DRUSH_BOOTSTRAP_MAX, // No bootstrap required, but we will use a Drupal instance if it is available.
   );
   $items['pm-releases'] = array(
     'description' => 'Print release information for given projects.',
@@ -195,6 +196,7 @@ function pm_drush_command() {
       'drush pm-releases cck zen' => 'View releases for cck and Zen projects.',
     ),
     'deprecated-aliases' => array('info'),
+    'bootstrap' => DRUSH_BOOTSTRAP_MAX, // No bootstrap required, but we will use a Drupal instance if it is available.
   );
   $items['pm-download'] = array(
     'description' => 'Download projects from drupal.org or other sources.',
@@ -205,6 +207,7 @@ function pm_drush_command() {
       'drush dl cck zen es' => 'Download latest versions of CCK, Zen and Spanish translations for your Drupal version.',
       'drush dl og-1.3' => 'Download a specfic version of Organic groups module for my version of Drupal.',
       'drush dl diff-6.x-2.x' => 'Download a specific development branch of diff module for a specific Drupal version.',
+      'drush dl views --dev' => 'Download the most recent development branch of the views module.',
     ),
     'arguments' => array(
       'projects' => 'A list of drpal.org project names, with optional version. Defaults to \'drupal\'',
@@ -215,6 +218,9 @@ function pm_drush_command() {
       '--source' => 'The base URL which provides project release history in XML. Defaults to http://updates.drupal.org/release-history.',
       '--notes' => 'Show release notes after each project is downloaded.',
       '--variant' => "Only useful for install profiles. Possible values: 'core', 'no-core', 'make'.",
+      '--dev' => "Download a development release. Optional.",
+      '--select' => "Select the version to download interactively from a list of available releases.",
+      '--all' => "Useful only with --select; shows all available releases instead of a short list of recent releases.",
       '--drupal-project-rename' => 'Alternate name for "drupal-x.y" directory when downloading Drupal project. If empty, will defaults to "drupal".',
       '--pipe' => 'Returns a list of the names of the extensions (modules and themes) contained in the downloaded projects.',
     ),
@@ -937,6 +943,18 @@ function _pm_find_common_path($project_t
 }
 
 /**
+ * Implementation of drush_COMMAND_init().
+ *
+ * pm-releases doesn't require any bootstrap level to operate but it 
+ * will use a bootstrapped site if available in order to mark the
+ * installed version of projects.
+ */
+function drush_pm_releases_init() {
+  drush_bootstrap_max();
+}
+
+
+/**
  * Command callback. Show available releases for given project(s).
  */
 function drush_pm_releases() {
@@ -956,7 +974,7 @@ function drush_pm_releases() {
     foreach ($project['releases'] as $release) {
       $rows[] = array(
         $release['version'],
-        format_date($release['date'], 'custom', 'Y-M-d'),
+        date('Y-M-d', $release['date']),
         implode(', ', $release['release_status'])
       );
     }
@@ -965,6 +983,114 @@ function drush_pm_releases() {
   }
 }
 
+
+function _drush_pm_get_releases_from_xml($xml, $project) {
+  foreach (array('title', 'short_name', 'dc:creator', 'api_version', 'recommended_major', 'supported_majors', 'default_major', 'project_status', 'link') as $item) {
+    if (array_key_exists($item, $xml)) {
+      $value = $xml->xpath($item);
+      $project_info[$item] = (string)$value[0];
+    }
+  }
+
+  $recommended_major = @$xml->xpath("/project/recommended_major");
+  $recommended_major = (string)$recommended_major[0];
+  $supported_majors = @$xml->xpath("/project/supported_majors");
+  $supported_majors = array_flip(explode(',', (string)$supported_majors[0]));
+  $releases_xml = @$xml->xpath("/project/releases/release[status='published']");
+  $recommended_version = NULL;
+  foreach ($releases_xml as $release) {
+    $release_info = array();
+    foreach (array('name', 'version', 'tag', 'version_major', 'version_extra', 'status', 'release_link', 'download_link', 'date', 'mdhash', 'filesize') as $item) {
+      if (array_key_exists($item, $release)) {
+        $value = $release->xpath($item);
+        $release_info[$item] = (string)$value[0];
+      }
+    }
+    $statuses = array();
+    if (empty($release_info['version_extra'])) {
+      if (array_key_exists($release_info['version_major'], $supported_majors)) {
+        $statuses[] = "Supported";
+        unset($supported_majors[$release_info['version_major']]);
+      }
+      if ($release_info['version_major'] == $recommended_major) {
+        $statuses[] = "Recommended";
+        $recommended_version = $release_info['version'];
+        $recommended_major = NULL;
+      }
+    }
+    elseif ($release_info['version_extra'] == "dev") {
+      $statuses[] = "Development";
+    }
+    foreach ($release->xpath('terms/term/value') as $release_type) {
+      if (("$release_type" != "Bug fixes") && ("$release_type" != "New features")) {
+        $statuses[] = "$release_type";
+      }
+    }
+    $release_info['release_status'] = $statuses;
+    $releases[$release_info['version']] = $release_info;
+  }
+  
+  $project_info['releases'] = $releases;
+  $project_info['recommended'] = $recommended_version;
+  
+  return $project_info;
+}
+
+/**
+ * Return an array of available releases for given project(s).
+ * Generates content equivalent to the 'releases' array returned by _drush_pm_get_releases.
+ */
+function _drush_pm_releases_from_xml($xml, $project) {
+  // If we are bootstrapped, we will get the release info from _drush_pm_get_releases,
+  // so that we can include information about the installed release.
+  $releases = array();
+  if (drush_get_context('DRUSH_BOOTSTRAP_PHASE') >= DRUSH_BOOTSTRAP_DRUPAL_FULL) {
+    $info = _drush_pm_get_releases_from_update_status(array($project));
+    $releases = $info[$project]['releases'];
+  }
+  // If we are not bootstrapped, then we will extract the release info from
+  // the release-history xml.
+  else {
+    $project_info = _drush_pm_get_releases_from_xml($xml, $project);
+    $releases = $project_info['releases'];
+  }
+  return $releases;
+}
+ 
+function _drush_pm_filter_releases($releases, $all = FALSE, $dev = FALSE) {
+  $options = array();
+  $limits_list = array();
+  foreach ($releases as $version => $release_info) {
+    if (!$dev || ((array_key_exists('version_extra', $release_info)) && ($release_info['version_extra'] == 'dev'))) {
+      $release_status = implode(', ', $release_info['release_status']);
+      $limits_key = $release_info['version_major'] . $release_status;
+      // We keep track of how many releases with the given status exists, and show only the first
+      // two that are exactly the same.  This is mostly to filter out the many releases with
+      // empty release status strings, and gives us a reasonable approximation for the other releases.
+      $limits_list[$limits_key] = (array_key_exists($limits_key, $limits_list) ? $limits_list[$limits_key] : 0) + 1;
+      if ($all || ($limits_list[$limits_key] <= 2)) {
+        $options[$release_info['version']] = $release_info;
+      }
+    }
+  }
+  return $options;
+}
+
+/**
+ * Return an array of available releases for given project(s).
+ *
+ * Helper function for pm-download.
+ */
+function _drush_pm_download_releases_choice($xml, $project, $all = FALSE, $dev = FALSE) {
+  $releases = _drush_pm_filter_releases(_drush_pm_releases_from_xml($xml, $project), $all, $dev);
+  
+  $options = array();
+  foreach($releases as $version => $release) {
+    $options[$version] = array($version, '-', date('Y-M-d', $release['date']), '-', implode(', ', $release['release_status']));
+  }
+  return $options;
+}
+
 /**
  * Get releases for given projects and fill in status information.
  *
@@ -975,6 +1101,15 @@ function drush_pm_releases() {
  * @see _drush_pm_releasenotes()
  */
 function _drush_pm_get_releases($projects) {
+  if (drush_get_context('DRUSH_BOOTSTRAP_PHASE') >= DRUSH_BOOTSTRAP_DRUPAL_FULL) {
+    return _drush_pm_get_releases_from_update_status($projects);
+  }
+  else {
+    return _drush_pm_get_releases_from_release_history($projects);    
+  }
+}
+
+function _drush_pm_get_releases_from_update_status($projects) {
   // We don't provide for other options here, so we supply an explicit path.
   drush_include_engine('update_info', 'drupal', NULL, DRUSH_BASE_PATH . '/commands/pm/update_info');
 
@@ -986,8 +1121,8 @@ function _drush_pm_get_releases($project
       continue;
     }
     if ($info[$project]['project_status'] == 'unpublished') {
-      drush_set_error('DRUSH_PM_PROJECT_UNPUBLISHED', dt("Project !project is unpublished ans has no releases available.", array('!project' => $key)), 'warning');
-      unset($info[$key]);
+      drush_set_error('DRUSH_PM_PROJECT_UNPUBLISHED', dt("Project !project is unpublished and has no releases available.", array('!project' => $project)), 'warning');
+      unset($info[$project]);
       continue;
     }
   }
@@ -1065,6 +1200,17 @@ function _drush_pm_get_releases($project
 }
 
 /**
+ * Implementation of drush_COMMAND_init().
+ *
+ * pm-releasenotes doesn't require any bootstrap level to operate but it 
+ * will use a bootstrapped site if available in order to mark the
+ * installed version of projects.
+ */
+function drush_pm_releasenotes_init() {
+  drush_bootstrap_max();
+}
+
+/**
  * Command callback. Show release notes for given project(s).
  */
 function drush_pm_releasenotes() {
@@ -1075,6 +1221,16 @@ function drush_pm_releasenotes() {
   return _drush_pm_releasenotes($requests);
 }
 
+// Poor man's drupal_html_to_text
+function drush_html_to_text($html) {
+  $replacements = array(
+    '<hr>' => '------------------------------------------------------------------------------',
+    '<li>' => ' * ',  
+  );
+  $text = str_replace(array_keys($replacements), array_values($replacements), $html);
+  return preg_replace('/ *<[^>]*> */', ' ', $text);
+}
+
 /**
  * Internal function: prints release notes for given drupal projects.
  *
@@ -1097,7 +1253,7 @@ function _drush_pm_releasenotes($request
   foreach ($info as $key => $project) {
     $selected_versions = array();
     // #TODO# project<->package-name problem. See _drush_pm_get_releases().
-    if (!isset($project['installed'])) {
+    if (!isset($project['installed']) && (drush_get_context('DRUSH_BOOTSTRAP_PHASE') >= DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
       // Installed package's version (e.g. cck) is detected by
       // _drush_pm_get_releases(). Attempted to obtain information
       // about it from update_cache.
@@ -1152,12 +1308,24 @@ function _drush_pm_releasenotes($request
           continue;
         }
       }
-      $data = drupal_http_request($release_page_url);
-      if (isset($data->error)) {
-        drush_log(dt("Error (!error) while requesting the release notes' page for !project project.", array('!error' => $data->error, '!project' => $key)), 'error');
-        continue;
+      // We'll use drupal_http_request if available; it provides better error reporting.
+      if (function_exists('drupal_http_request')) {
+        $data = drupal_http_request($release_page_url);
+        if (isset($data->error)) {
+          drush_log(dt("Error (!error) while requesting the release notes page for !project project.", array('!error' => $data->error, '!project' => $key)), 'error');
+          continue;
+        }
+        @$dom = DOMDocument::loadHTML($data->data);
+      }
+      else {
+        $filename = _drush_pm_download_file($release_page_url);
+        @$dom = DOMDocument::loadHTMLFile($filename);
+        @unlink($filename);
+        if ($dom === FALSE) {
+          drush_log(dt("Error while requesting the release notes page for !project project.", array('!project' => $key)), 'error');
+          continue;
+        }
       }
-      @$dom = DOMDocument::loadHTML($data->data);
       if ($dom) {
         drush_log(dt("Successfully parsed and loaded the HTML contained in the release notes' page for !project (!version) project.", array('!project' => $key, '!version' => $version)), 'notice');
       }
@@ -1204,12 +1372,18 @@ function _drush_pm_releasenotes($request
         $status_msg = '> ' . $status_msg . ' -<hr>';
       }
       $notes_header = dt("<hr>
-        > RELEASE NOTES FOR '!name' PROJECT, VERSION !version:!break
-        > !time.!break
-        !status
-        <hr>", array('!status' => $print_status ? $status_msg : '', '!name' => strtoupper($key), '!break' => $break, '!version' => $version, '!time' => $notes_last_update));
+ > RELEASE NOTES FOR '!name' PROJECT, VERSION !version:!break
+ > !time.!break
+ !status
+<hr>
+", array('!status' => $print_status ? $status_msg : '', '!name' => strtoupper($key), '!break' => $break, '!version' => $version, '!time' => $notes_last_update));
       // Finally we print the release notes for the requested project.
-      $print = drupal_html_to_text($notes_header . $project_notes, array('br', 'p', 'ul', 'ol', 'li', 'hr'));
+      if (function_exists('drupal_html_to_text')) {
+        $print = drupal_html_to_text($notes_header . $project_notes, array('br', 'p', 'ul', 'ol', 'li', 'hr'));
+      }
+      else {
+        $print = drush_html_to_text($notes_header . $project_notes);
+      }
       drush_print($print);
       if (drush_drupal_major_version() < 7) {drush_print();}
     }
@@ -1715,6 +1889,76 @@ function drush_pm_download_validate() {
   }
 }
 
+function _drush_pm_get_releases_from_release_history($requests) {
+  $info = array();
+
+  // Parse out project name and version.
+  $requests = pm_parse_project_version($requests);
+
+  // Get release history for each request and download the project.
+  $project_types = pm_project_types();
+  $project_types_xpath = '(value="' . implode('" or value="', $project_types) . '")';
+  foreach ($requests as $name => $request) {
+    $xml = _drush_pm_get_release_history_xml($request);
+
+    // Unpublished project?
+    $project_status = $xml->xpath('/project/project_status');
+    if ($project_status[0][0] == 'unpublished') {
+      drush_set_error('DRUSH_PM_PROJECT_UNPUBLISHED', dt("Project !project is unpublished and has no releases available.", array('!project' => $name)), 'warning');
+      continue;
+    }
+
+    $project_info = _drush_pm_get_releases_from_xml($xml, $name);
+    $info[$name] = $project_info;
+  }
+  return $info;
+}
+
+/**
+ * Download a file using wget or curl.
+ *
+ * @param string $url
+ *   The path to the file to download
+ *
+ * @return string
+ *   The filename that was downloaded
+ */
+function _drush_pm_download_file($url) {
+  if (!drush_shell_exec("wget $url")) {
+    drush_shell_exec("curl -O $url");
+  }
+  $filename = explode('/', $url);
+  $filename = array_pop($filename);
+  
+  return $filename;
+}
+
+/**
+ * Download the release history xml for the specified release.
+ */
+function _drush_pm_get_release_history_xml($request) {
+  // Don't rely on UPDATE_DEFAULT_URL since perhaps we are not fully
+  // bootstrapped.
+  $url = drush_get_option('source', 'http://updates.drupal.org/release-history') . '/' . $request['name'] . '/' . $request['drupal_version'];
+  drush_log('Downloading release history from ' . $url);
+  // Some hosts have allow_url_fopen disabled.
+  if (!$xml = @simplexml_load_file($url)) {
+    $filename = _drush_pm_download_file($url);
+    $xml = simplexml_load_file($filename);
+    drush_op('unlink', $filename);
+  }
+  if (!$xml) {
+    // We are not getting here since drupal.org always serves an XML response.
+    drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt('Could not download project status information from !url', array('!url' => $url)));
+    continue;
+  }
+  if ($error = $xml->xpath('/error')) {
+    drush_set_error('DRUSH_PM_COULD_NOT_LOAD_UPDATE_FILE', $error[0]);
+    continue;
+  }
+  return $xml;
+}
+
 /**
  * Command callback. Download Drupal core or any project.
  */
@@ -1735,29 +1979,14 @@ function drush_pm_download() {
   foreach ($requests as $name => $request) {
     // Cleanup. We need to unset those variables to avoid using garbage from
     // previous iteration.
-    unset($error, $release, $releases, $types);
+    unset($release, $releases, $types);
 
-    // Don't rely on UPDATE_DEFAULT_URL since perhaps we are not fully
-    // bootstrapped.
-    $url = drush_get_option('source', 'http://updates.drupal.org/release-history') . '/' . $request['name'] . '/' . $request['drupal_version'];
-    drush_log('Downloading release history from ' . $url);
-    // Some hosts have allow_url_fopen disabled.
-    if (!$xml = @simplexml_load_file($url)) {
-      if (!drush_shell_exec("wget $url")) {
-        drush_shell_exec("curl -O $url");
-      }
-      $filename = explode('/', $url);
-      $filename = array_pop($filename);
-      $xml = simplexml_load_file($filename);
-      drush_op('unlink', $filename);
-    }
-    if (!$xml) {
-      // We are not getting here since drupal.org always serves an XML response.
-      drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt('Could not download project status information from !url', array('!url' => $url)));
-      continue;
-    }
-    if ($error = $xml->xpath('/error')) {
-      drush_set_error('DRUSH_PM_COULD_NOT_LOAD_UPDATE_FILE', $error[0]);
+    $xml = _drush_pm_get_release_history_xml($request);
+    
+    // Unpublished project?
+    $project_status = $xml->xpath('/project/project_status');
+    if ($project_status[0][0] == 'unpublished') {
+      drush_set_error('DRUSH_PM_PROJECT_UNPUBLISHED', dt("Project !project is unpublished and has no releases available.", array('!project' => $name)), 'warning');
       continue;
     }
 
@@ -1791,6 +2020,24 @@ function drush_pm_download() {
     if (!empty($recommended_releases)) {
       $releases = $recommended_releases;
     }
+    $release_type = 'recommended';
+    if (drush_get_option('dev', FALSE)) {
+      $releases = @$xml->xpath("/project/releases/release[status='published'][version_extra='dev']");
+      $release_type = 'development';
+    }
+    if (drush_get_option('select', FALSE) || empty($releases)) {
+      $options = _drush_pm_download_releases_choice($xml, $request['name'], drush_get_option('all', FALSE), drush_get_option('dev', FALSE));
+      if (empty($releases)) {
+        drush_print(dt('There is no !type release for project !project.', array('!type' => $release_type, '!project' => $request['name'])));
+      }
+      $choice = drush_choice($options, dt('Choose one of the available releases:'));
+      if ($choice) {
+        $releases = $xml->xpath("/project/releases/release[status='published'][version='" . $choice . "']");
+      }
+      else {
+        continue;
+      }
+    }
     if (empty($releases)) {
       drush_log(dt('There is no *recommended* release for project !project on Drupal !drupal_version. Ask the maintainer to review http://drupal.org/node/197584 and create/recommend a release in order to be compatible with drush and the drupal.org security broadcast system. A recommended development snapshot release is sufficient. Alternatively, run pm-releases command and explicity pm-download any non-recommended release that might be available.', array('!drupal_version' => $request['drupal_version'], '!project' => $request['name'])), 'ok');
       continue;
Index: includes/command.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/command.inc,v
retrieving revision 1.88
diff -u -p -r1.88 command.inc
--- includes/command.inc	10 Nov 2010 02:55:41 -0000	1.88
+++ includes/command.inc	5 Dec 2010 01:18:53 -0000
@@ -942,17 +942,28 @@ function drush_enforce_requirement_boots
  *   TRUE if command is valid.
  */
 function drush_enforce_requirement_drupal_dependencies(&$command) {
-  if (empty($command['drupal dependencies'])) {
-    return TRUE;
+  // If the command bootstrap is DRUSH_BOOTSTRAP_MAX, then we will 
+  // allow the requirements to pass if we have not successfully
+  // bootstrapped Drupal.  The combination of DRUSH_BOOTSTRAP_MAX
+  // and 'drupal dependencies' indicates that the drush command
+  // will use the dependent modules only if they are available.
+  if ($command['bootstrap'] == DRUSH_BOOTSTRAP_MAX) {
+    // If we have not bootstrapped, then let the dependencies pass;
+    // if we have bootstrapped, then enforce them.
+    if (drush_get_context('DRUSH_BOOTSTRAP_PHASE') < DRUSH_BOOTSTRAP_DRUPAL_FULL) {
+      return TRUE;
+    }
   }
-  else {
+  // If there are no drupal dependencies, then do nothing
+  if (!empty($command['drupal dependencies'])) {
     foreach ($command['drupal dependencies'] as $dependency) {
-      if (function_exists('module_exists') && module_exists($dependency)) {
-        return TRUE;
+      if(!function_exists('module_exists') || !module_exists($dependency)) {
+        $command['bootstrap_errors']['DRUSH_COMMAND_DEPENDENCY_ERROR'] = dt('Command !command needs the following modules installed/enabled to run: !dependencies.', array('!command' => $command['command'], '!dependencies' => implode(', ', $command['drupal dependencies'])));
+        return FALSE;
       }
     }
   }
-  $command['bootstrap_errors']['DRUSH_COMMAND_DEPENDENCY_ERROR'] = dt('Command !command needs the following modules installed/enabled to run: !dependencies.', array('!command' => $command['command'], '!dependencies' => implode(', ', $command['drupal dependencies'])));
+  return TRUE;
 }
 
 /**
Index: includes/drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/drush.inc,v
retrieving revision 1.153
diff -u -p -r1.153 drush.inc
--- includes/drush.inc	3 Dec 2010 08:11:07 -0000	1.153
+++ includes/drush.inc	5 Dec 2010 01:18:54 -0000
@@ -1215,19 +1215,27 @@ function drush_confirm($msg, $indent = 0
 function drush_choice($options, $prompt = 'Enter a number.', $label = '!value') {
   print dt($prompt) . "\n";
 
-  drush_print('  [0] : Cancel');
+  $rows[] = array('[0]', ':', 'Cancel');
   $selection_number = 0;
   foreach ($options as $key => $option) {
     if ((substr($key, 0, 3) == '-- ') && (substr($key, -3) == ' --')) {
-      drush_print("  ".$option);
-      continue;
+      $rows[] = array('', '', $option);
+    }
+    else {
+      $selection_number++;
+      $row = array("[$selection_number]", ':');
+      if (is_array($option)) {
+        $row = array_merge($row, $option);
+      }
+      else {
+        $row[] = dt($label, array('!number' => $selection_number, '!key' => $key, '!value' => $option));
+      }
+      $rows[] = $row;
+      $selection_list[$selection_number] = $key;
     }
-    $selection_number++;
-    $message = dt($label, array('!number' => $selection_number, '!key' => $key, '!value' => $option));
-    drush_print(dt("  [!number] : !message", array('!number' => $selection_number, '!message' => $message)));
-    $selection_list[$selection_number] = $key;
   }
-
+  drush_print_table($rows);
+  
   while ($line = trim(fgets(STDIN))) {
     if (array_key_exists($line, $selection_list)) {
       return $selection_list[$line];
Index: includes/environment.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/environment.inc,v
retrieving revision 1.106
diff -u -p -r1.106 environment.inc
--- includes/environment.inc	3 Dec 2010 20:53:02 -0000	1.106
+++ includes/environment.inc	5 Dec 2010 01:18:55 -0000
@@ -27,6 +27,15 @@ define('DRUSH_DRUPAL_BOOTSTRAP', 'includ
 define('DRUSH_BOOTSTRAP_NONE', -1);
 
 /**
+ * Use drush_bootstrap_max instead of drush_bootstrap_to_phase
+ *
+ * This constant is only usable as the value of the 'bootstrap'
+ * item of a command object, or as the parameter to
+ * drush_bootstrap_to_phase.  It is not a real bootstrap state.
+ */
+define('DRUSH_BOOTSTRAP_MAX', -2);
+
+/**
  * Only bootstrap Drush, without any Drupal specific code.
  *
  * Any code that operates on the Drush installation, and not specifically
@@ -277,6 +286,15 @@ function drush_bootstrap_validate($phase
  *   Only attempt bootstrap to the specified level.
  */
 function drush_bootstrap_to_phase($max_phase_index) {
+  // If $max_phase_index is DRUSH_BOOTSTRAP_MAX, then
+  // we will bootstrap as far as we can.  drush_bootstrap_max
+  // is different than drush_bootstrap_to_phase in that
+  // it is not an error if DRUSH_BOOTSTRAP_LOGIN is not reached.
+  if ($max_phase_index == DRUSH_BOOTSTRAP_MAX) {
+    drush_bootstrap_max();
+    return TRUE;
+  }
+  
   drush_log(dt("Bootstrap to phase !phase.", array('!phase' => $max_phase_index)), 'bootstrap');
   $phases = _drush_bootstrap_phases();
   $result = TRUE;
