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 |
---|---|
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 :
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.
This is an awesome idea
This is an awesome idea, and one of the Drush maintainers agrees with me. Working on a patch now :)
Issue link ?
Glad to read that ! Do you have the link to the issue ?