Hi all. Our core-cli command already has a hook_cli_bashrc() where commandfiles can supply aliases and other .bashrc info to our custom shell (i.e. core-cli). I just added documentation for this at http://drupalcode.org/viewvc/drupal/contributions/modules/drush/drush.ap...

I was thinking that instead of a commandfile providing this, we could search for .bashrc files in our usual searchpath (i.e. like drushrc.php). If found, the file's contents would be sourced into the custom shell. Any objections to having .bashrc files in our $searchpath directories?

Note that core-cli already looks for ~/.bashrc and sources that so we already do this a little. I guess we would add /etc/.bashrc as well.

Comments

greg.1.anderson’s picture

Those are good suggestions.

moshe weitzman’s picture

Status: Active » Needs work
StatusFileSize
new4.31 KB

Here is as far I can go tonight. I didn't think too deeply about the order of the searchpath. The search is not picking up my ~/.bashrc so there is a bug somewhere. Feedback (and fixes) welcome.

greg.1.anderson’s picture

Assigned: Unassigned » greg.1.anderson
greg.1.anderson’s picture

Status: Needs work » Needs review

I took a slightly different approach, and sourced the different .bashrc files from the shell rather than merging them in to the generated .bashrc file. I liked this better. I left the existing core-cli hook in for the purpose of additional dynamic bashrc content, if desired.

One feature I took out was Drupal site-specific .bashrc files. It did not seem like a good idea to me to have different .bashrc files sourced based on the initial Drupal site unless that feature also worked with the use command. Since I could not think of a good way to 'un-source' a file, I felt it was better to just limit the locations to those that had global scope.

greg.1.anderson’s picture

StatusFileSize
new1.76 KB

Here's the patch.

moshe weitzman’s picture

Status: Needs review » Needs work

$drush_global_command_dir and $drush_global_conf_dir are not used?

Also, "remove the leading ~# on the line below." looks odd as the line below has no hash.

greg.1.anderson’s picture

Those variables are used in the bashrc data -- but I've got a better idea how to make that list. I also have a better idea on how to handle reentrancy, so I'm going to just remove that awkward comment in the next patch.

greg.1.anderson’s picture

Status: Needs work » Needs review
StatusFileSize
new3.76 KB

Improved handling of reentrancy checking and cleaner code to generate the bashrc searchpath. Also included the example.bashrc file that I forgot to put in the patch last time.

greg.1.anderson’s picture

StatusFileSize
new4.34 KB

This is the same as #8, except that the bash prompt is set to "drush>" instead of ">" when there is no alias set. The prompt is still "@alias>" when there is. This change is because ">" is the line-continuation prompt.

e.g.:

bash$ echo "this is a broken line
>

Since bash prints ">" to indicate that your current line is being continued, it would be too confusing to use the same prompt for drush core-cli.

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

This is awesome. I really love the example: 'drush core-cli --pipe > ~/.bash_customizations' => 'Convert your default shell into drush core-cli. Make sure that your .bashrc file sources .bash_customizations.',. I think that technique will become popular. Could we add some more descriptive text here for folks who don't get the verb 'source'.

I will test this tomorrow but feel free to commit before then so we can get more eyes on it.

greg.1.anderson’s picture

Status: Reviewed & tested by the community » Fixed

Committed with suggested documentation change. I agree that recent changes to core-cli are going to make it more practical & useful.

moshe weitzman’s picture

Status: Fixed » Active

Wondering if can cater a bit more to the --pipe crowd:

  1. Should we suggest .bash_drush as a filename instead of .bash_customizations? Seems more descriptive to me.
  2. My .bash_drush defines no DRUPAL_SITE which is fine. Still, when I launch a new shell I'm greeted with 'drush>' as my prompt. Thats quite disconcerting. I prefer to see my usual prompt. Can we be less aggressive about setting PS1 when DRUSH_CLI=false? Maybe only set it after use command?
  3. An alias called 'drush' was defined. Thats probably already defined for most --pipe users. More disconcerting is that the alias has --in-cli option at the end. Thats untrue; I'm not in core-cli.
  4. If we change/remove 'drush' alias, we should alter 'on' accordingly.
moshe weitzman’s picture

Now I see that all new terminal windows start in an unusual directory because of 'builtin cd /Users/mw/htd/fr/sites/default'. That line doesn't belong in --pipe I think.

greg.1.anderson’s picture

Hm, maybe we do the 'cd' prior to launching the bash subshell, and keep it out of the bashrc file.

greg.1.anderson’s picture

Status: Active » Needs review
StatusFileSize
new1.71 KB

There are lots of ways this could have been done, but the easiest was to just move the code 'out of the way' as suggested in #13.

moshe weitzman’s picture

@Greg - Any chance you could comment on my items from #12. It has been 24 hours :)

greg.1.anderson’s picture

I must have been reading that update on my netbook -- I saw #13 and missed #12 entirely. :)

"1. Should we suggest .bash_drush as a filename instead of .bash_customizations?"

The reason I suggested .bash_customizations is that file is already sourced from .bashrc in ubuntu. I don't mind using .bash_drush instead, though (or maybe mention both).

"2. My .bash_drush defines no DRUPAL_SITE which is fine. Still, when I launch a new shell I'm greeted with 'drush>' as my prompt. Thats quite disconcerting. I prefer to see my usual prompt. Can we be less aggressive about setting PS1 when DRUSH_CLI=false? Maybe only set it after use command?"

My cop-out answer is that if you use --pipe, you can always edit the output to suit your purposes. :)

I would like to improve things per your suggestion, though. If we reverted to the user's old prompt when there was no DRUPAL_SITE, we would also want to have a way to run `un-use` to go back to the state where no site was specified.

ex:

my-prompt$ use @alias
@alias> un-use
my-prompt$

I don't think that 'un-use' is a good command name, though. Thoughts?

"3. An alias called 'drush' was defined."

Yes, this code should be moved out of the section that is output via --pipe.

" 4. If we change/remove 'drush' alias, we should alter 'on' accordingly. "

Agreed.

We're getting quite a bit of code in the non-pipe .bashrc that is invisible to --pipe. Should we provide a way for users to see everything? --pipe --verbose?

moshe weitzman’s picture

Didn't know that Ubuntu already sources .bash_customizations. Lets just go with that.

To un-use, what about 'use' without any parameter?

Yes, --pipe --verbose should show everything.

greg.1.anderson’s picture

StatusFileSize
new10.84 KB

New patch, now extra-nifty.

The suggestions from #16, #18 have been implemented. help core-cli now says:

Enter a new shell optimized for drush use. All .bashrc customizations are still
available.

Examples:
 help                                      Print available drush commands       
 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.     
 cd ~                                      Navigate back to your $HOME          
                                           directory.                           
 lsd files                                 List all files in the Drupal files   
                                           directory.                           
 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                  
 use -                                     Switch back to the last alias        
                                           "used".                              
 use ~                                     Use the default alias.               
 use                                       Revert to an ordinary prompt; do not 
                                           use an alias.                        
 drush core-cli --pipe >                   Convert your default shell into      
 ~/.bash_customizations                    drush core-cli.  Make sure that your 
                                           .bashrc file includes                
                                           .bash_customizations (e.g. "source   
                                           ~/.bash_customizations" or ".        
                                           ~/.bash_customizations").            


Options:
 override                                  List of drush commands or aliases    
                                           that should override built-in shell  
                                           functions and commands; otherwise,   
                                           built-ins override drush commands.   
                                           Defaults to help,rsync,dd,sa         
 contextual                                Additional drush overrides that      
                                           function ONLY when the prompt is     
                                           "@alias>".  Defaults to              
                                           cron,updatedb,sync,cc                
 pipe                                      Print the generated .bashrc file and 
                                           exit.                                

The new "contextual" commands are very useful; they allow commands to behave per their default bash behavior when your prompt is 'normal', but when your prompt is a drush alias, then the drush command of the same name takes precedence.

For example:

$ ./drush cli
Entering the drush cli.  Use CONTROL-D to exit.
Type 'help' for help.
$ cc --help
cc: no input files
$ use @gkdev
@gkdev> cc --help
Clear a specific cache, or all drupal caches.

Arguments:
 type                                      The particular cache to clear. Omit 
                                           this argument to choose from        
                                           available caches.                   


Aliases: cc
@gkdev> use -
$ use -
@gkdev> 
moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

Looks good. I will test this over the next day or two. Meanwhile, lets commit.

greg.1.anderson’s picture

Status: Reviewed & tested by the community » Fixed

Committed.

moshe weitzman’s picture

Status: Fixed » Needs work

# Source the user's .bashrc file.. AFAICT, the code here is sourcing drush's .bashrc files, not user.

This works really well - am using the --pipe technique as described in Examples.

msonnabaum’s picture

There appears to be a bug here with the cd alias. If you cd without an argument from anywhere outside a drupal site, you get "A Drupal installation directory could not be found" and a fatal error. This also occurs if you cd to a directory that doesn't exist.

Also, there seems to be quite a few more functions defined here that interfere with other commands. Here's what I found using this:

$ drush core-cli --pipe| grep function | awk '{print $2}'| while read i; do which ${i%(*};done

/usr/sbin/cron
/usr/bin/updatedb
/usr/bin/cc
/usr/bin/rsync
/bin/sync
/bin/dd
/usr/sbin/sa

Not too sure what the best way to handle those are. I use updatedb fairly regularly and wouldn't want drush overriding it, though I'd be happy for it to override cc by default.

msonnabaum’s picture

Its likely that I'm missing something here, but how about simplifying the cd a bit?


function cd() {
  if [[ $1 == @* || $1 == %* ]]
  then
    # Do a special drush core-cli cd, handling
    # shorthand notation directory names -- anything
    # understood by drupal-directory
    DEST=`drupal-directory $1 --local`
    if [ $? == 0 ]
    then
      SITE=`drupal-directory $1 --component=name`
      if [ ! -z "$SITE" ]
      then
        use $SITE;
      fi
      echo "cd $DEST";
      builtin cd $DEST;
    fi
  else
    builtin cd $1;
  fi
}

That does remove the `cd` with no args going to `cd %root`, but I don't really understand how that would work while also retaining cd's natural behavior of doing `cd ~` when you're not in a drupal dir.

greg.1.anderson’s picture

You're on the right track. I wasn't sure whether to do it as you suggested, or key off of if [ -z \$DRUPAL_SITE ], or some combination thereof. Will look at this more later.

greg.1.anderson’s picture

You only need to test $1 == %* if DRUPAL_SITE is not empty. Even if DRUPAL_SITE is empty, you still need to try dd with strings that start with @, or site specs of the form /path/to/drupal/root#uri.

Changes to dd might be necessary to prevent noisy errors. Maybe running with -q would do the trick, though.

msonnabaum’s picture

I had the same thought, although I'm unclear on when $DRUPAL_SITE it supposed to be set. It seems that I have to `use default` in a drupal docroot for it to be defined.

It would be nice if we could detect this automatically. Since it would be pretty slow to figure that out via drush, it seems reasonable to me to drop a .drush or .drushconfig file in the docroot and just look for that. Another idea is to maybe add local site paths to a ~/.drushrc or something similar that's sourced with the cli shell.

Anyhow, this seems to work:

function cd() {
  if [ -n "$DRUPAL_SITE" ]
  then
    if [[ $1 == @* || $1 == %* ]]
    then
      # Do a special drush core-cli cd, handling
      # shorthand notation directory names -- anything
      # understood by drupal-directory
      DEST=`drupal-directory $1 --local`
      if [ $? == 0 ]
      then
        SITE=`drupal-directory $1 --component=name`
        if [ ! -z "$SITE" ]
        then
          use $SITE;
        fi
        echo "cd $DEST";
        builtin cd $DEST;
      fi
    fi
  else
    builtin cd $1;
  fi
}
greg.1.anderson’s picture

Status: Needs work » Needs review
StatusFileSize
new4.97 KB

Here's a new cd that should work a lot better. Also added a --ignore option to core-cli, so you can say --ignore=updatedb (or any other command), and drush will not generate a function wrapper for that command. --ignore defaults to 'core-cli,cli'. Also fixed the comment per #22.

moshe weitzman’s picture

Status: Needs review » Needs work

Found a buglet. @slice is a remote alias. I guess cd should never try to consult a remote site. I retract my earlier feature request to cd into remote sites ... Feel free to commit this after fixing the buglet.

@slice> cd -v
Load alias @slice                                                       [notice]
Begin redispatch via backend invoke                                     [notice]
Initialized Drupal 6.3-dev root directory at                            [notice]
/home/weitzman/public_html/mind.cyrve.com/public
Initialized Drupal site mind.cyrve.com at sites/mind.cyrve.com          [notice]
Command dispatch complete                                               [notice]
Backend invoke is complete                                              [notice]
Load alias @slice                                                       [notice]
Begin redispatch via backend invoke                                     [notice]
Initialized Drupal 6.3-dev root directory at                            [notice]
/home/weitzman/public_html/mind.cyrve.com/public
Initialized Drupal site mind.cyrve.com at sites/mind.cyrve.com          [notice]
Command dispatch complete                                               [notice]
Backend invoke is complete                                              [notice]
Alias /home/weitzman/public_html/mind.cyrve.com/public not found.
cd /home/weitzman/public_html/mind.cyrve.com/public
-bash: cd: /home/weitzman/public_html/mind.cyrve.com/public: No such file or directory
greg.1.anderson’s picture

Status: Needs work » Fixed

Committed with buglet fixed: http://drupal.org/cvs?commit=472550

Now, if you use @splice, your prompt will be:

remotemachine.com:@splice>

This indicator will also be used to insure that 'cd' only happens locally when the site being used is remote.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.