Automatically switch Drush versions per project

Now that Drush has become standard equipment in every developer's toolbox, and Drupal 8 is around the corner, you may find yourself asking "Which Drush version should I use?" While Drush 6 has a stable release, only Drush 7 can be used with Drupal 8. Usually, I use Drush 7. It works well with both Drupal 7 and Drupal 8, and even though is doesn't have a stable release yet, it feels pretty stable to me.

Combining Drush versions: the trouble begins

Unfortunately, when you use Drush 7 to run commands on a remote server which runs Drush 6, you will run into errors. For instance when doing a sql-sync:

$ drush sql-sync @mysite-prod @self
  You will destroy data in mysite and replace with data from example.com/mysite.
  Do you really want to continue? (y/n): y
  Starting to dump database on Source.                                                                                 [ok]
  Database dump saved to                                                                                               [success]
  /home/www-data/drush-backups/mysite/20141016113131/mysite_20141016_113132.sql.gz
  The Drush sql-dump command did not report the path to the dump file produced.  Try upgrading the version of Drush you[error]
  are using on the source machine.

Obviously Drush 7 doesn't like to talk to Drush 6. So how do we solve that?

Installing multiple Drush versions side-by-side

It's not too hard to install two Drush versions side-by-side, and use aliases or symlinks to choose a version. On my system I installed Drush 7 using composer and I installed Drush 6 using the manual method.

Next I created two symlinks called "drush6" and "drush7" in a directory in your $PATH variable. I use ~/bin, but it depends on your OS and configuration.

$ cd ~/bin
$ ln -s ~/drush-6.4.0/drush drush6
$ ln -s ~/.composer/vendor/drush/drush/drush drush7

Using those symlinks, I can use both versions anywhere on my system:

$ drush6 --version
 Drush Version   :  6.4.0

$ drush7 --version
 Drush Version   :  7.0-dev

Now I can run drush6 sql-sync @mysite-prod @selfto choose Drush 6 and avoid problems syncing with a remote server.

Automating which version to use

It's nice to be able to choose, but wouldn't it be awesome if you can just run drush ...without having to think which version you need? If you're managing multiple sites on different servers, you don't want to spend your energy remembering which project requires which Drush version.

At Triquanta we use git repositories, one for each project. I want to be able to specify the default Drush version per project, so I will never run the wrong Drush version by mistake. That's where this really simple bash script comes in:

#!/bin/bash
version=$(git config --get drush.version)
if [ "$version" = '6' ];
then
    drush6 "$@"
else
    drush7 "$@"
fi

Save it as "drush" in a directory in your $PATH variable, and make it executable. Now when you execute drush, it will call this script, which by default runs Drush 7.

$ drush --version
 Drush Version   :  7.0-dev

When a project requires Drush 6 instead, I set a variable "drush.version" in the git working copy:

$ git config drush.version 6
$ drush --version
 Drush Version   :  6.4.0

That's all there is to it. Regardless where you are within your git-managed directory structure (the site root, /sites/default/files/, etc.) the script will always know which drush version to use.

Teaser image