Some months ago, I was developing some Drupal modules for my Company, I noticed the time I loose each time I have to run a Drush command (such as clear cache) in order to do basic Drupal developer stuff.
Some context
The most annoying thing is I always have a lot of opened terminals in order to monitor and do other stuffs, such as:
- tail -f /var/www/myproject/var/log/error.log
- drush -r /var/www/myproject/www/ some command
- grep -iRn "some_function_call(" *
- svn ci -m "foo"
- and many more ...
For every of this commands, I need to chdir to the right path (or include the path in some command line argument, which is not possible for all these stuff).
The fact is I'm not well organized, I do all this stuff in a really intuitive way, like each time I want type in another new command I'll do a CTRL+N to open a new console (which is quite stupid some will think).
And probably the most annoying command of all is Drush. Why? Because each time I want to run a drush command on a Drupal site, I have to tell him where is the Drupal root absolute path? Why? Because each time I need to download a new module, I have to specify the full root path of modules dir I want to use. This is becoming quite confusing.
So, I found a nice solution, to handle those drush root pathes: I called it mdrush.
The solution
mdrush is a python Drush wrapper. It keeps a list of site in a ini style configuration file, or in a MySQL database small schema. For each site, it keeps this data:
- An arbitrary user given canonical name, such as myproject
- Drupal absolute root path on filesystem
- A list of modules path, for each module path its Drupal root relative path
- Drush script path to use with this site
- Optionnaly, a remote hostname in order to use it over SSH
Usage
Its usage is quite simple, all you have to do is replace the drush binary in your command line with mdrush <project-name>.
Sample with a project named foo which absolute file system path is /var/www/foo/www:
pounard@guinevere:~$ # This will be the equivalent of drush -r /var/www/foo/www cache clear
pounard@guinevere:~$ mdrush foo cache clear
Because the drush command line can contain arguments and options, which should not conflict with mdrush one, it will assume that every argument until the first non argument parameter (which should always be the project name) will be its own, and the trailing options and arguments passed to the command line will compose drush command line.
So, let's see a complex example:
pounard@guinevere:~$ # Here, -y will be a drush option
pounard@guinevere:~$ mdrush foo -y cache clear
pounard@guinevere:~$ # Here, -y will be a mdrush option
pounard@guinevere:~$ mdrush -y foo cache clear
The beauty
So, that's it? But where is it really useful then? Well, I'll say that's not it, I also included a small helper which is site tokens. Let's look at the mdrush --help command output:
pounard@guinevere:~$ mdrush -h
mdrush -- Drush wrapper for multiple site handling.
Usage: /usr/local/bin/mdrush [OPTIONS] | [<SITE> <DRUSHOPTIONS>]
Where options can be:
-c <SITE> Register a new drupal site instance into your
configuration
-m <SITE> Modify site instance
-d <SITE> Delete a drupal site instance from your configuration
-l [<SITE>] If <SITE> is specified, list all modules path
else list all known sites
--configure Run configuration wizzard
-h Display this help
And arguments are:
<SITE> Identifier configured in ~/.mdrush/sites.conf
Instead of string identifier, you can use an integer
See list with -l
<DRUSHOPTIONS> Normal drush command line
You can use these tokens within the drush command:
%mX Use the X module path (see list with -l <SITENAME>)
%MX Same as %mX but with absolute path
%r Absolute site root path
Examples
Clear cache of a specific site:
mdrush <sitename> cache clear
Download a module in a specific module dir using token:
mdrush <sitename> dl <module> --destination=%M2
pounard@guinevere:~$
Two things are beautiful here. The first is as I should have said upper, mdrush will always invoke drush using the -r option. The second is whenever you need to write some absolute or relative paths, you won't need to known where is really located the site, because some tokens will help you.
Let's see how it's great. I will demonstrate how I use it with a custom site of mine:
pounard@guinevere:~$ mdrush -l # List all sites
Configured sites:
0 - blog.processus.org (remote) -> /var/www/vhost/blog.processus.org/htdocs
2 - drupal-demo (local) -> /var/www/drupal-demo/www
5 - drupal-6 (local) -> /var/www/drupal-6/www
pounard@guinevere:~$ # Notice that here, I intentionally removed some entries which are some of
pounard@guinevere:~$ # company projects.
Now, I want to known modules folders pathes of
drupal-6 project:
pounard@guinevere:~$ mdrush -l drupal-6
Site 'drupal-6' modules path:
0 - sites/all/modules/contrib
1 - sites/all/modules/custom
2 - sites/all/modules/devel
pounard@guinevere:~$
Nice, now let's download a contribution module to
drupal-6 project. Using classical drush, I would have typed:
pounard@guinevere:~$ drush -r /var/www/drupal-6/www -y dl views --destination=/var/www/drupal-6/www/sites/all/modules/contrib
Whow, what such an horrible command to type in. Let's see what
mdrush could do for me:
pounard@guinevere:~$ mdrush drupal-6 -y dl --destination=%M0 views
Project views (6.x-2.8) downloaded to /var/www/drupal-6/www/sites/all/modules/contrib/.
pounard@guinevere:~$
I won, drush loose, my command line is totally path free! And lot more quickly written.
Remote sites handling
Let's see my module list, did you notice the blog.processus.org (remote) -> /var/www/vhost/blog.processus.org/htdocs entry?
Let's see mdrush in action:
pounard@guinevere:~$ mdrush blog.processus.org cache clear
pounard@hydralisk.processus.org's password:
Cache cleared.
pounard@guinevere:~$
No comments. All you have to do to skip the annoying password phase is to use generate and copy your own ssh key over the server, that's it. It works.
The only limitation here is you have to install the Drush script on your remote site, and precise its full path when you configure your site.
What about interractive mode
If you are this careful, don't worry, the python wrapper uses the stdin/stdout streams to interract with the end user, don't worry about the fact you are using a remote or a local site, their is absolutely no differences.
And for lazy people
You are that lazy, you probably are a good developer! And because I am a lazy developer, I wrote a CLI wizzard to write your sites configuration file (or database entry), let's see it:
pounard@guinevere:~$ mdrush -c drupal-7
Create site 'drupal-7'
Select in:
* 1 - Local site
2 - Remote SSH site
>
Path to Drush command to use, leave empty to use default
>
Type the site root path
> /var/www/drupal-7/www
Type one to n module path (e.g. 'sites/all/modules')
One path per line, finish with an empty line
>
New site 'drupal-7' saved
pounard@guinevere:~$
That's it, mdrush knows your site now. Ready to use:
pounard@guinevere:~$ mdrush drupal-7 status
PHP configuration : /etc/php.ini
Drupal Root : /var/www/drupal-7/www
Drupal version : 7.0-dev
Site Path : sites/default
Site URI : http://default
Database Driver : mysql
Database Hostname : localhost
Database Username : drupal-7
Database Name : drupal-7
Database Password : drupal-7
pounard@guinevere:~$
Quite easy, right?
Conclusion
I really want this python application to be free software, and I definitely want to share it. In the future, I may commit it on drupal.org, but I'd rather prefer to use a real DCVS, like git. Because my choice has not been made, I won't share the code.
Don't worry, it will come soon!
Post new comment