Drush Policy is the Best, Honestly!


Drush Example Output

There is no shortage of blog posts about how Drush is the one indispensable tool for working with Drupal. If you are new to Drupal, or just have not yet checked out what all the fuss is about, I highly encourage you to go check out Drush now (recently moved from drupal.org to GitHub).

I want to highlight a feature of Drush that despite being little known is actually very high value:

Drush policies

Drush policies are a way to control how and when Drush commands are used. Because Drush is a powerful tool, the potential for doing harm increases, whether intentional or not. We all make mistakes. It could be a simple typo, or maybe inexperience, but we have all hit that ENTER key one millisecond too soon and regretted it!

Enter Drush Policies to the rescue.

There are many instances in which you would want to set up a policy for Drush usage, including when working alone on a project, or working with a team.

First, let's take a look at how to get started writing a policy file. As with general config (and aliases), the Drush team has provided an excellent example file. You will need to know where Drush is installed on your system. Look in the examples folder for the file policy.drush.php.

The first function is an example implementation of drush_hook_COMMAND_validate().

/** * Implement of drush_hook_COMMAND_validate(). * * Prevent catastrophic braino. Note that this file has to be local to the machine * that intitiates sql-sync command. */ function drush_policy_sql_sync_validate($source = NULL, $destination = NULL) { if ($destination == '@prod') { return drush_set_error(dt('Per examples/policy.drush.inc, you may never overwrite the production database.')); } }

You can set up any validation criteria that makes sense for your workflow. For instance, if you regularly work with multiple sites, you might check for any destination alias that ends with "prod". You might also decide to disallow overwriting any remote database:

/** * Implement of drush_hook_sql_sync_validate(). * * Disallow overwriting remote databases. */ function drush_policy_sql_sync_validate($source = NULL, $destination = NULL) { if (!preg_match('/local$/', $destination) { return drush_set_error(dt('Per /path/to/policy.drush.inc, you may never overwrite any remote database.')); } }

Note, this policy file can be placed in several locations, depending on the use case. The comment at the top of the example file spells out the options:

/** * @file * Example policy commandfile. Modify as desired. * * Validates commands as they are issued and returns an error * or changes options when policy is violated. * * You can copy this file to any of the following * 1. A .drush folder in your HOME folder. * 2. Anywhere in a folder tree below an active module on your site. * 3. /usr/share/drush/commands (configurable) * 4. In an arbitrary folder specified with the --include option. * 5. Drupal's sites/all/drush folder (note: sql-sync validation won't work here). */

So, to prevent myself from overwriting prod, I place a policy file in my ~/.drush folder. To prevent a team of devs from overwriting remote dev databases, I put it in /usr/share/drush/commands on the dev box. Note, this is an either/or choice, so some thought into how you want to split your policy files is required. (ie, you'll get "already defined" errors if Drush finds two versions of drush_hook_sql_sync_validate().) I haven't yet found a good work-around for that. Maybe someone has a suggestion in the comments.

Note, for even more flexibility,read the rest of the example file to see how to add custom command line options using hook_drush_help_alter().

Share This