Drush Integration for your modules

By shane
Mon, 2011-05-23 14:00
comments

Share with Others

Drush is a very powerful command line utility for creating, managing, and maintaining your Drupal website. There are many things that you can do with Drush, but suffice it to say that if you develop/build Drupal websites and don't currently use Drush, you should most definitely check it out.

Note: If you are looking for help with Drush, check out this link - Drush: Getting started

Sometimes you may be building a module and need to make your Drupal site do things from the command line. In this case, writing custom Drush integration for your module will make your life easier when it comes to maintaining your Drupal site. Lets say you have some periodic (or sporadic) task that needs to be run, there are a few options.

  • Add the ability to perform the task from the Drupal administration back-end of the site
  • If it's a strictly scheduled task, you can use hook_cron() in your module to run code at specified intervals
  • Add Drush integration to your module to allow you to run the task from the command line

Each of the above has its place depending on the circumstances, however in this post we are only going to look at the Drush integration option. Below I will provide a very simple walkthrough for getting started with adding Drush integration to you module.

To add Drush integration to your custom module you need to start by creating a file in your module directory called "MYMODULE.drush.inc" (replacing MYMODULE with your module name). In this file we will need to declare a few hooks to register your command with Drush. The first hook is hook_drush_help():

/**
 * Implements hook_drush_help().
 */
function MYMODULE_drush_help($command) {
  switch ($command) {
    case 'drush:my-command':
      return dt('Run my command');
  }
}

This hook provides help to drush. The second hook we need to implement is hook_drush_command():

/**
 * Implements hook_drush_command().
 */
function MYMODULE_drush_command() {
  $items = array();
  $items['my-command'] = array(
    'description' => dt('Run my command.'),
    'arguments'   => array(
      'arg1'    => dt('An optional example argument'),
    ),
    'examples' => array(
      'Standard example' => 'drush my-command',
      'Argument example' => 'drush my-command 5',
    ),
    'aliases' => array('myc'),
  );
  return $items;
}

This hook defines the command called "my-command" to Drush. There are a few important things to note:

  • The dt() function is used to provide string translations. This is used in replacement of the Drupal t() function for Drush commands.
  • An array of arguments can be used to accept user input from the command line.
  • An array of examples can be added to provide additional help to the user.
  • Aliases are nice ways to shorten the Drush command. In the example created above, the drush my-command command can also be run using drush myc.

Now that we have the code in place, you should be able to view the help by running:


drush help my-command

or


drush help myc

Now it is time to write the callback function to specify exactly what we want this Drush command to do. This is where the bulk of your code will probably go. Often (but not always) this will include inserting, updating, or deleting data from the database. In this example I will just provide the skeleton code and you can fill in the function with the code you actually want to run for this Drush command.

/**
 * Callback function for drush my-command. 
 * Callback is called by using drush_hook_command() where
 * hook is the name of the module (MYMODULE) and command is the name of
 * the Drush command with all "-" characters converted to "_" characters (my_command)
 *
 * @param $arg1
 *   An optional argument
 */
function drush_MYMODULE_my_command($arg1 = NULL) {
  //check if the argument was passed in and just print it out
  if (isset($arg1)) {
   drush_print($arg1);
  }
 
  //log to the command line with an OK status
  drush_log('Running my-command', 'ok');
}

As you can see there are a few more Drush specific functions that you can use. I have provided a list of a few of them below with simple explanations.

drush_log('Log an event using drush', 'warning');
drush_set_error('Set an error with drush.');
dt('Translate strings with drush');
drush_print('Print to command line with drush');
drush_print_table($rows, TRUE); //print a command line table with drush
drush_confirm('Are you sure you want to continue?', $indent = 0); //Add drush confirmation

That should get you started adding Drush integration to your modules. Try it out and let me know if you run into any questions or need more detailed examples. I am beginning to migrate a lot of what I would normally put into hook_cron over to Drush commands so I can schedule it more flexibly using the server's cron. This works especially well for longer tasks as you can provide more memory and a higher time limit to command line PHP if required. This also provides the benefit of not creating additional overhead on the often overcrowded hook_cron().

Useful? Let me know what you think in the comments.