? .drush-cache.info
? includes/table.inc
Index: commands/core/core.drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/core/core.drush.inc,v
retrieving revision 1.151
diff -u -p -r1.151 core.drush.inc
--- commands/core/core.drush.inc	25 Dec 2010 08:09:41 -0000	1.151
+++ commands/core/core.drush.inc	26 Dec 2010 22:20:36 -0000
@@ -181,6 +181,10 @@ function core_drush_command() {
     'arguments' => array(
       'target' => 'A module/theme name, or special names like root, files, private, or an alias : path alias string such as @alias:%files. Defaults to root.',
     ),
+    'options' => array(
+      'component' => "The portion of the evaluated path to return.  Defaults to 'path'; 'name' returns the site alias of the target.",
+      'local' => "Reject any target that specifies a remote site.",
+    ),
     'examples' => array(
       'cd `drush dd devel`' => 'Navigate into the devel module directory',
       'cd `drush dd` ' => 'Navigate to the root of your Drupal site',
@@ -194,12 +198,17 @@ function core_drush_command() {
 
   $items['core-cli'] = array(
     'description' => dt('Enter a new shell optimized for drush use.'),
+    'options' => array(
+      'cli-override' => 'List of drush commands or aliases that should override built-in shell functions and commands; otherwise, built-ins override drush commands. Default is help,dd',
+      'pipe' => 'Print the generated .bashrc file and exit.',
+    ),
     'examples' => array(
       'help' => 'Print available drush commands',
-      'cdd' => 'Navigate to the root of your Drupal site',
-      'cdd files' => 'Navigate to the files directory.',
+      'cd @alias' => 'Navigate to the root of the site indicated by @alias; subsequent commands will target that site.',
+      'cd %files' => 'Navigate to the files directory.',
       'lsd files' => 'List all files in the Drupal files directory.',
-      'on @alias status' => 'Run the command "status" on the site indicated by @alias',
+      'on @alias core-status' => 'Run the command "core-status" on the site indicated by @alias',
+      'use @alias' => 'Run subsequent commands on the site indicated by @alias',
     ),
     'aliases' => array('cli'),
     'bootstrap' => DRUSH_BOOTSTRAP_MAX,
@@ -667,7 +676,22 @@ function drush_core_updatedb_batch_proce
   _update_batch_command($id);
 }
 
-function _drush_core_directory($target = 'root') {
+/**
+ * Given a target (e.g. @site:%modules), return the evaluated
+ * directory path
+ *
+ * @param $target
+ *   The target to evaluate.  Can be @site or /path or @site:path
+ *   or @site:%pathalais, etc. (just like rsync parameters)
+ * @param $component
+ *   The portion of the evaluated path to return.  Possible values:
+ *   'path' - the full path to the target (default)
+ *   'name' - the name of the site from the path (e.g. @site1)
+ *   'user-path' - the part after the ':' (e.g. %modules)
+ *   'root' & 'uri' - the Drupal root and URI of the site from the path
+ *   'path-component' - The ':' and the path
+ */
+function _drush_core_directory($target = 'root', $component = 'path', $local_only = FALSE) {
   // Normalize to a sitealias in the target.
   $normalized_target = $target;
   if (strpos($target, ':') === FALSE) {
@@ -688,17 +712,16 @@ function _drush_core_directory($target =
   }
 
   $additional_options = array();
-  $values = drush_sitealias_evaluate_path($normalized_target, $additional_options);
-
-  if (isset($values['path'])) {
+  $values = drush_sitealias_evaluate_path($normalized_target, $additional_options, $local_only);
+  if (isset($values[$component])) {
     // Hurray, we found the destination
-    return $values['path'];
+    return $values[$component];
   }
   return NULL;
 }
 
 function drush_core_drupal_directory($target = 'root') {
-  $path = _drush_core_directory($target);
+  $path = _drush_core_directory($target, drush_get_option('component', 'path'), drush_get_option('local', FALSE));
   
   // If _drush_core_directory is working right, it will turn
   // %blah into the path to the item referred to by the key 'blah'.
@@ -744,7 +767,7 @@ function drush_core_cli() {
   if (drush_get_option('in-cli', FALSE)) {
     return drush_set_error('DRUSH_CLI_NOT_REENTRANT', dt('Already in drush core-cli; press control-d to exit.'));
   }
-  if (drush_get_context('DRUSH_BACKEND')) {
+  if (drush_get_context('DRUSH_BACKEND') || drush_get_context('DRUSH_AFFIRMATIVE') || drush_get_context('DRUSH_NEGATIVE')) {
     return drush_set_error('DRUSH_CLI_INTERACTIVE_ERROR', dt('Cannot run drush core-cli from non-interactive mode; aborting.'));
   }
 
@@ -753,16 +776,10 @@ function drush_core_cli() {
 
   $bashrc_data = implode("/n/n", drush_command_invoke_all('cli_bashrc', $drush_command));
 
-  // Before entering the new bash script, cd to the current site root,
-  // if any.  This will make our default site for drush match the
-  // currently bootstrapped site (at least until the user cd's away).
-  if ($site_root = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
-    drush_op('chdir', $site_root);
-  }
-
-  // Print our entire bashrc file in verbose mode
-  if (drush_get_context('DRUSH_VERBOSE')) {
-    drush_print($bashrc_data);
+  // Print our bashrc file and exit in --pipe mode
+  if (drush_get_context('DRUSH_PIPE')) {
+    drush_print_pipe($bashrc_data);
+    return TRUE;
   }
 
   drush_print("Entering the drush cli.  Use CONTROL-D to exit.");
@@ -772,45 +789,115 @@ function drush_core_cli() {
   // control-d to exit.  The temp file will be deleted after
   // we exit.
   $bashrc = drush_save_data_to_temp_file($bashrc_data);
-  drush_op_system('bash --rcfile ' . $bashrc . ' > `tty`');
+  return drush_op_system('bash --rcfile ' . $bashrc . ' > `tty`');
 }
 
 // Implement our own hook_cli_bashrc()
 function core_cli_bashrc($drush_command) {
+  $initial_site = '';
+  $site_list = drush_sitealias_resolve_sitespecs(array('@self'));
+  if (!empty($site_list)) {
+    $site_list = array_keys($site_list);
+    $initial_site = $site_list[0];
+  }
+  
   // Set up our default bashrc file for the drush cli
-  $bashrc_data = <<<EOD
+  $bashrc_data = "# Set our initial site\nDRUPAL_SITE=$initial_site\n" . <<<EOD
+
+# Set the DRUSH_CLI variable; it may also be of use 
+# in the user's .bashrc, or elsewhere.
+DRUSH_CLI=true
 
-# source the user's .bashrc file
+# Source the user's .bashrc file.
 [ -r ~/.bashrc ] && {
   pushd ~ > /dev/null
   . .bashrc
   popd > /dev/null
 }
 
-PS1="drush> "
+# Display our initial site in the bash prompt.
+PS1="\$DRUPAL_SITE> "
 
+# When using the drush shell, all commands will
+# by default target the site specified by the
+# shell variable \$DRUPAL_SITE.  To run a command
+# on some other site, use either:
+#   drush @site command
+# or
+#   on @site command
 alias on="$drush_command"
 alias drush="$drush_command"
-DRUSH_CLI=true
 
-
-function cdd() {
-  TARGET=
-  PARAM=\$1
-  if [ \$# -gt 1 ] ; then
-    TARGET=\$1
-    PARAM=\$2
+# To specify a new DRUPAL_SITE without changing
+# your current directory:
+#   use @site
+function use() {
+  if [ ! -z $1 ] && [ "x$1" != "x@self" ]
+  then
+    SITE=`drush site-alias $1 --short`
+    if [ \$? != 0 ] || [ -z "\$SITE" ]
+    then
+      echo "Alias $1 not found."
+    else
+      DRUPAL_SITE=$1
+      PS1="$1> "
+    fi
   fi
-  DEST=`drush \$TARGET drupal-directory \$PARAM`
-  if [ \$? != 0 ] || [ -z "\$DEST" ]
+}
+
+# We override the cd command to allow convenient
+# shorthand notations, such as:
+#   cd @site1
+#   cd %modules
+#   cd %devel
+#   cd @site2 %files
+# When changing the cwd to a new site, the DRUPAL_SITE
+# variable is also changed, so the new site becomes
+# the default drush target.
+function cd() {
+  # First test and see if this should be an 'ordinary' cd
+  if [ "x\$1" == "x" ] || [ "x\$1" == "x-" ] || [ -d \$1 ]
   then
-    echo "Target \$1 was not found."
+    builtin cd \$1;
   else
-    echo "cd \$DEST"
-    cd \$DEST;
+    # Do a special drush core-cli cd, handling
+    # shorthand notation directory names -- anything
+    # understood by drupal-directory
+    if [ \$# -gt 1 ] ; then
+      DEST=`drush \$1 drupal-directory \$2 --local`
+      if [ \$? == 0 ]
+      then
+        SITE=`drush \$1 drupal-directory \$2 --component=name`
+      fi
+    else
+      DEST=`drupal-directory \$1`
+      if [ \$? == 0 ]
+      then
+        SITE=`drupal-directory \$1 --component=name`
+      fi
+    fi
+    if [ \$? != 0 ] || [ -z "\$DEST" ] || [ ! -d "\$DEST" ]
+    then
+      echo "Could not find \$@."
+    else
+      if [ ! -z "\$SITE" ]
+      then
+        use \$SITE;
+      fi
+      echo "cd \$DEST";
+      builtin cd \$DEST;
+    fi
   fi
 }
 
+# In drush-3, it was necessary to use cdd instead of
+# cd to be able to target special directories.  Continue
+# to accept cdd as an alias for cd.
+alias cdd=cd
+
+# The command lsd will quickly do an 'ls' on the
+# specified special drush directory, e.g.:
+#   lsd %modules
 function lsd() {
   TARGET=
   PARAM=\$1
@@ -821,23 +908,34 @@ function lsd() {
   DEST=`drush \$TARGET drupal-directory \$PARAM`
   if [ \$? != 0 ] || [ -z "\$DEST" ]
   then
-    echo "Target \$1 was not found."
+    echo "Could not find \$TARGET \$PARAM."
   else
-    echo "ls \$DEST"
+    echo "ls \$DEST";
     ls \$DEST;
   fi
 }
 
 EOD;
 
-  // Add aliases for all of our commands
+  // Add aliases for all drush commands
+  $bashrc_data .= "# Add aliases for all drush commands\n";
   $commands = drush_get_commands();
+  $cli_overrides = _convert_csv_to_array(drush_get_option('cli-override', 'help,dd'));
   foreach ($commands as $key => $command) {
-    // Filter out old commands that still have spaces
-    if (strpos($key, ' ') === FALSE) {
-      $bashrc_data .= "function $key() {\n  $drush_command $key \"\$@\"\n}\n";
+    // Filter out old commands that still have spaces;
+    // do not mask any existing bash command (e.g. 'grep')
+    // or builtin (e.g. 'eval') with drush aliases.
+    if ((strpos($key, ' ') === FALSE) && ((in_array($key, $cli_overrides)) || (!drush_shell_exec("which $key")) && (drush_shell_exec("builtin $key") != "1"))) {
+      $bashrc_data .= "function $key() {\n  $drush_command \$DRUPAL_SITE $key \"\$@\"\n}\n";
     }
   }
+  // Before entering the new bash script, cd to the current site root,
+  // if any.  This will make our default site for drush match the
+  // currently bootstrapped site (at least until the user cd's away).
+  if ($site_root = drush_get_context('DRUSH_DRUPAL_SITE_ROOT')) {
+    $site_root = drush_get_context('DRUSH_DRUPAL_ROOT') . '/' . $site_root;
+    $bashrc_data .= "builtin cd $site_root\n";
+  }
 
   return $bashrc_data;
 }
Index: commands/core/sitealias.drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/core/sitealias.drush.inc,v
retrieving revision 1.24
diff -u -p -r1.24 sitealias.drush.inc
--- commands/core/sitealias.drush.inc	25 Dec 2010 08:14:31 -0000	1.24
+++ commands/core/sitealias.drush.inc	26 Dec 2010 22:20:37 -0000
@@ -77,7 +77,6 @@ function _drush_sitealias_site_list() {
  * Return the list of all site aliases and all local sites.
  */
 function _drush_sitealias_all_list() {
-  drush_sitealias_load_all();
   return array_merge(_drush_sitealias_alias_list(), _drush_sitealias_site_list());
 }
 
@@ -87,6 +86,8 @@ function _drush_sitealias_all_list() {
  * then all are returned.
  */
 function _drush_sitealias_user_specified_list() {
+  drush_sitealias_load_all(TRUE);
+
   $command = drush_get_command();
   $specifications = $command['arguments'];
   $site_list = array();
@@ -121,7 +122,10 @@ function _drush_sitealias_user_specified
  * specified.
  */
 function drush_sitealias_print() {
-  drush_bootstrap_max();
+  // Call bootstrap max, unless the caller requested short output
+  if (!drush_get_option('short', FALSE)) {
+    drush_bootstrap_max();
+  }
   
   $site_list = _drush_sitealias_user_specified_list();
   $full_output = drush_get_option('full');
Index: examples/example.drushrc.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/examples/example.drushrc.php,v
retrieving revision 1.18
diff -u -p -r1.18 example.drushrc.php
--- examples/example.drushrc.php	24 Dec 2010 19:04:35 -0000	1.18
+++ examples/example.drushrc.php	26 Dec 2010 22:20:37 -0000
@@ -105,6 +105,19 @@
 // in your php configuration file.  See 'drush status' for the path to your php.ini file.
 # $options['php-notices'] = 'warning';
 
+// List of drush commands or aliases that should override built-in 
+// shell functions and commands; otherwise, built-ins override drush 
+// commands. Default is help,dd.
+// Warning:  bad things can happen if you put the wrong thing here
+// (e.g. eval, grep), so be cautious.
+// If a drush command overrides a built-in command (e.g. bash help),
+// then you can use the `builtin` operator to run the built-in version
+// (e.g. `builtin help` to show bash help instead of drush help.)
+// If a drush command overrides a shell command (e.g. grep), then
+// you can use the regular shell command by typing in the full path
+// to the command (e.g. /bin/grep).
+# $options['cli-override'] = 'help,dd';
+
 // Specify options to pass to ssh in backend invoke. (Default is to prohibit password authentication; uncomment to change)
 # $options['ssh-options'] = '-o PasswordAuthentication=no';
 
Index: includes/sitealias.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/sitealias.inc,v
retrieving revision 1.66
diff -u -p -r1.66 sitealias.inc
--- includes/sitealias.inc	24 Dec 2010 05:10:29 -0000	1.66
+++ includes/sitealias.inc	26 Dec 2010 22:20:38 -0000
@@ -38,8 +38,6 @@ function drush_sitealias_check_arg() {
  * Given a list of alias records, shorten the name used if possible
  */
 function drush_sitealias_simplify_names($site_list) {
-//  foreach ($site_list as $original_name => $alias_record) {
-//  }
   $result = array();
   foreach ($site_list as $original_name => $alias_record) {
     $adjusted_name = $alias_record['name'];
@@ -204,9 +202,14 @@ function _drush_sitealias_get_record($al
         // then use it as a local site specification.
         $alias_record = _drush_sitealias_find_record_for_local_site($alias);
       }
-
     }
   }
+      
+  // If the parameter is a path to a site folder for a loaded
+  // alias, then return that alias record.
+  if (empty($alias_record) && (substr($alias,0,1) == '/')) {
+    $alias_record = drush_find_local_alias($alias);
+  }
 
   if (!empty($alias_record)) {
     // Load the drush config file if there is one associated with this alias
@@ -558,6 +561,9 @@ function _drush_sitealias_add_inherited_
  */
 function _drush_sitealias_cache_alias($alias_name, $alias_record) {
   $cache =& drush_get_context('site-aliases');
+  if (array_key_exists("@$alias_name", $cache)) {
+    $alias_record = array_merge($cache["@$alias_name"], $alias_record);
+  }
   $cache["@$alias_name"] = $alias_record;
 
   // If the alias record points at a local site, make sure
@@ -1077,6 +1083,35 @@ function _drush_find_local_sites_in_site
   return $site_list;
 }
 
+/**
+ * Find an alias for a site given a path to a sites folder.
+ * It is a good idea to call drush_sitealias_load_all() before
+ * this function, as this function will only consider
+ * loaded aliases in its search.
+ *
+ */
+function drush_find_local_alias($at_path) {
+  $result = NULL;
+
+  $all_site_aliases =& drush_get_context('site-aliases');
+  foreach ($all_site_aliases as $alias_name => $alias_record) {
+    if (!array_key_exists('remote-host', $alias_record) && (array_key_exists('root', $alias_record))) {
+      $test_path = drush_sitealias_local_site_path($alias_record);
+      if (!empty($test_path)) {
+        if (substr($at_path,0,strlen($test_path)) == $test_path) {
+          $result = $alias_record;
+          if (!array_key_exists('name', $alias_record)) {
+            $result['name'] = $alias_name;
+          }
+          return $result;
+        }
+      }
+    }
+  }
+  
+  return $result;
+}
+
 function drush_sitealias_create_sites_alias($a_drupal_root = '') {
   $sites_list = _drush_find_local_sites_at_root($a_drupal_root);
   _drush_sitealias_cache_alias('sites', array('site-list' => $sites_list));
@@ -1397,7 +1432,7 @@ function _drush_sitealias_preflight_path
  *   with the path to pass to rsync (including the machine specifier)
  *   in the 'evaluated-path' item.
  */
-function drush_sitealias_evaluate_path($path, &$additional_options) {
+function drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE) {
   $site_alias_settings = array();
   $path_aliases = array();
   $remote_user = '';
@@ -1416,6 +1451,10 @@ function drush_sitealias_evaluate_path($
   }
   
   if (!empty($site_alias_settings)) {
+    if ($local_only && array_key_exists('remote-host', $site_alias_settings)) {
+      return drush_set_error('DRUSH_REMOTE_SITE_IN_LOCAL_CONTEXT', dt("A remote site alias was used in a context where only a local alias is appropriate."));
+    }
+    
     // Apply any options from this alias that might affect our rsync
     drush_sitealias_set_alias_context($site_alias_settings);
 
