Upgrade Your Drupal Skills
We trained 1,000+ Drupal Developers over the last decade.
See Advanced Courses NAH, I know EnoughDrupal 8 tip of the day: replace hook_drush_command() by a YAML file
One of the big trends during the Drupal 8 creation has been the replacement of info hooks by two main mechanisms: annotations, and YAML files. In that light, hook_drush_command()
, as the CLI equivalent of the late hook_menu
, replaced by various YAML files, looks just like a perfect candidate for replacement by a commands
section in some mymodule.drush.yml
configuration file. Turns out it is incredibly easy to achieve. Let's see how to kill some hundred lines of code real fast !
The goal
Just like its hook_menu()
web counterpart, hook_drush_command()
defines controllers, the main difference being that it maps them to CLI commands instead of web paths. Its structure is that of a very basic info hook: a nested array of strings and numbers, which maps neatly to a YAML structure. Consider the canonical sandwich example from Drush docs.
hook_drush_command | mymodule.drush.yml |
---|---|
<?php |
commands: # The 'make-me-a-sandwich' command. make-me-a-sandwich: description' => "Makes a delicious sandwich." arguments: filling: 'The type of the sandwich (turkey, cheese, etc.). Defaults to ascii.' options: spreads: description: 'Comma delimited list of spreads.' example-value: 'mayonnaise,mustard' examples: 'drush mmas turkey --spreads=ketchup,mustard': 'Make a terrible-tasting sandwich that is lacking in pickles.' aliases: ['mmas'] # No bootstrap at all. bootstrap: -1 |
The trick
There is no trick ! Well, almost... assuming that simple format for themymodule.drush.yml
file, all it takes is loading it. This can even be entirely generic, like this :
<?php
use Symfony\Component\Yaml\Yaml;/**
* Implements hook_drush_command().
*/
function beanstalkd_drush_command() {
$file = preg_replace('/(inc|php)$/', 'yml', __FILE__);
$config = Yaml::parse(file_get_contents($file));
$items = $config['commands'];
return $items;
}
?>
Since your drush plugin for module mymodule
is named mymodule.drush.inc
(or mymodule.drush.php
if you write them like me), the name of the Yaml file can be deduced from the plugin name. And then, the Symfony Yaml component parses it to a plain array matching the expected hook_drush_command()
structure.
This is the mechanism used by the Drupal 8 version of the Beanstalkd module.
The limitations
You may have noticed a small limitation : hook_drush_command()
implementations may need to use constants like DRUSH_BOOTSTRAP_NONE
. With such a limited implementation, you will need to convert the constants to their values from drush/includes/bootstrap.inc
. Should the mechanism come to be included in Drush at some point, a more evolved mechanism will likely provide translation for these constants, too.
About Drupal Sun
Drupal Sun is an Evolving Web project. It allows you to:
- Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
- Facet based on tags, author, or feed
- Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
- View the entire article text inline, or in the context of the site where it was created
See the blog post at Evolving Web