Altering and reacting to existing commands

Drush offers a very broad list of hooks to interact with existing commands. We can modify, react and extend them however we need it. We are going to demonstrate this by first describing each hook and then writing and testing an example that uses some of them. Following is the full list of hooks sorted by the order in which they are called with a short description of each one:

  • hook_drush_init() is executed before any command is run.
  • drush_COMMAND_init() is called before a command is validated.
  • drush_hook_COMMAND_validate() validates a command. We used it in our custom command example in the previous section (drush_userblocker_user_blocker_validate()).
  • drush_hook_pre_COMMAND() operates before a command is going to be executed.
  • drush_hook_COMMAND() is the default callback implementation of a defined command at hook_drush_command().
  • drush_hook_post_COMMAND() runs after a command has been executed.
  • hook_drush_exit() is called after any command is run.

Whenever any of the previous hooks report an error by using drush_set_error() or by returning FALSE, the normal execution stops and the rollback mechanism starts by calling the respective rollback hooks backwards in time. This means, for example, if an error is reported at drush_hook_post_COMMAND(), then the implemented rollback functions will be called in the following order:

  1. drush_hook_COMMAND_rollback()
  2. drush_hook_pre_COMMAND_rollback()
  3. drush_hook_COMMAND_validate_rollback()
  4. drush_hook_post_COMMAND_rollback()

The rollback mechanism helps you to keep your system in a consistent status when an error is reported. If you are doing a long process within a command that needs a rollback mechanism, use the previously given hooks to implement the logic needed. To see which rollback functions are available for a command, execute it with the option --show-invoke.

Note

You can find more hooks and examples by typing drush topic docs-api in the command line.

Altering an existing command

Now we will go through a practical example. We are going to create a new Drush command file located at the .drush folder of our home directory which will enable downloaded projects, when the option --enable is given. Create a file named autoenable.drush.inc and place it in $HOME/.drush/autoenable.drush.inc with the following contents:

<?php
/**
* @file
* Enables modules after they have been downloaded
*/
/**
* Implementation of hook_drush_help_alter()
* Adds an option "enable" to pm-download command.
*/
function autoenable_drush_help_alter(&$command) {

if ($command['command'] == 'pm-download') {
$command['options']['enable'] = "Enable the module automatically.";
}
}
/**
* Implementation of drush_hook_post_COMMAND()
* Hooks into pm-download when it has finished an enables the module automatically.
*/
function autoenable_drush_pm_post_download($request, $release) {

$phase = drush_get_context('DRUSH_BOOTSTRAP_PHASE'),
if (($phase >= DRUSH_BOOTSTRAP_DRUPAL_SITE) &&
drush_get_option('enable')) {
if (file_exists($request['full_project_path'] .
DIRECTORY_SEPARATOR .
$request['name'] . '.info')) {
drush_invoke('pm-enable', $request['name']);
}
}
}

The previous command, being in our .drush directory, is available for all our Drupal sites. Before diving into its logic, let's run a few commands to see what it does. First of all, we have added an option to the pm-download command called --enable. It is now visible in the help information of the command:

$ drush help pm-download
...
Options:
--destination Path to which the project will be copied. If you're providing a relative path, note it is relative to the drupal root (if bootstrapped).
--enable Enable the module automatically.
Aliases: dl

The previous option was added by the first function defined in our file, which is an implementation of hook_drush_help_alter(). This hook allows us to modify the properties of an existing command.

Now we are going to test the second function, an implementation of drush_hook_post_COMMAND(), which performs an operation once a command has completed its execution (in this case, a module has been downloaded within a Drupal site). We will download the Token module and add the option --enable so it gets enabled automatically without having to call pm-enable afterwards. We will also add the option --yes so we do not have to answer to the prompt confirming the act of enabling the module:

$ cd /home/juampy/drupal
$ drush pm-download --enable --yes token
Project token (7.x-1.0-beta7) downloaded to /home/juampy/projects/drupal/sites/all/modules/contrib/token. [success]
The following extensions will be enabled: token
Do you really want to continue? (y/n): y
token was enabled successfully. [ok]

That's it. The pm-download command placed Token module at sites/all/modules/contrib/token. Once it finished, drush_hook_post_pm_download() was invoked so our hook implementation was called, thus enabling the module.

If you see the source code of autoenable_drush_pm_post_download(), you will notice there are two conditions that must be met in order for the module to be enabled: we must be within a Drupal site and the enable option must have been given when pm-download was executed. These two requirements are checked at:

$phase = drush_get_context('DRUSH_BOOTSTRAP_PHASE'),
if (($phase >= DRUSH_BOOTSTRAP_DRUPAL_SITE) && drush_get_option('enable')) {

After that, the function evaluates if the module was downloaded successfully and there is a token.info file within the module (unfortunately not all modules follow this convention). If it does, we make use of the function drush_invoke() to call the pm-enable command with the project name as an argument, which is done at the following line:

drush_invoke('pm-enable', $request['name']);

The previous code was just an example of how you can alter existing commands. Now go on and start thinking about how you can extend commands to make your day to day work easier by implementing a few of these hooks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.5.239