123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <h1>Creating Custom Drush Commands</h1>
- <p>
- Creating a new drush command is very easy. There are
- four simple steps.
- <ol>
- <li>Create a command file called COMMANDFILE.drush.inc
- <li>Implement the function COMMANDFILE_drush_help(). Optional.
- <li>Implement the function COMMANDFILE_drush_command()
- <li>Implement the functions that your commands will call.
- These will usually be named drush_COMMANDFILE_COMMANDNAME().
- </ol><p>
- For an example drush command, see examples/sandwich.drush.inc.
- The steps for implementing your command are explained in more
- detail below.
- <h2>Create COMMANDFILE.drush.inc</h2>
- <p>
- The name of your drush command is very important. It must end
- in ".drush.inc" to be recognized as a drush command. The part
- of the filename that comes before the ".drush.inc" becomes the
- name of the commandfile. Your commandfile name is used by
- drush to compose the names of the functions it will call, so
- choose wisely.
- <p>
- The example drush command, 'make-me-a-sandwich', is stored
- in the 'sandwich' commandfile, 'sandwich.drush.inc'.
- <p>
- Drush searches for commandfiles in the following locations:
- <ul>
- <li>The "/path/to/drush/commands" folder.
- <li>Folders listed in the 'include' option (see `drush topic docs-configuration`).
- <li>The system-wide drush commands folder, e.g. /usr/share/drush/commands
- <li>The ".drush" folder in the user's HOME folder.
- <li>All modules in the current Drupal installation
- </ul> <p>
- Note that modules in the current Drupal installation will only
- be considered if drush has bootstrapped to at least the DRUSH_BOOSTRAP_SITE
- level. Usually, when working with a Drupal site, drush will
- bootstrap to DRUSH_BOOTSTRAP_FULL; in this case, only the drush
- commandfiles in enabled modules will be considered eligible for
- loading. If a drush only bootstraps to DRUSH_BOOTSTRAP_SITE,
- though, then all drush commandfiles will be considered, whether the
- module is enabled or not. See `drush topic docs-bootstrap` for
- more information on bootstrapping.
- <p>
- Additionally, drush commandfiles may optionally define a function
- COMMANDFILE_drush_load() in the file COMMANDFILE.drush.load.inc.
- If this function returns FALSE, then the commandfile will not be loaded.
- <h2>Implement COMMANDFILE_drush_help()</h2>
- <p>
- The drush_help hook is an optional place to describe a command in long form. If
- the command only requires a brief description, use the description key in
- COMMANDFILE_drush_command(). The drush_help hook for the 'sandwich' commandfile looks
- like this:
- <pre>
- function sandwich_drush_help($section) {
- switch ($section) {
- case 'drush:make-me-a-sandwich':
- return dt("... brief help summary goes here ...");
- }
- }
- </pre><p>
- Note that the command name is prepended with 'drush:' in
- the drush_help hook. Your commandfile may implement
- multiple commands; to do so, just add more 'case' statements
- to the switch, one for each command.
- <h2>Implement COMMANDFILE_drush_command()</h2>
- <p>
- The drush_command hook is the most important part of the
- commandfile. It returns an array of items that define
- how your commands should be called, and how they work.
- Drush commands are very similar to the Drupal menu system.
- The elements that can appear in a drush command definition
- are shown below.
- <ul>
- <li>'aliases':
- Provides a list of shorter names for the command.
- For example, pm-download may also be called via `drush dl`.
- If the alias is used, drush will substitute back in the
- primary command name, so pm-download will still be used
- to generate the command hook, etc.
- <li>'deprecated-aliases':
- Works just like 'aliases', but does not
- appear in help. Used in instances where the drush
- maintainers intend to eventually remove support for a
- command alias. If someone runs a drush command using a
- deprecated alias, drush will print a warning message.
- <li>'command hook':
- Change the name of the function drush will
- call to execute the command from drush_COMMANDFILE_COMMANDNAME()
- to drush_COMMANDFILE_COMMANDHOOK(), where COMMANDNAME is the
- original name of the command, and COMMANDHOOK is the value
- of the 'command hook' item.
- <li>'callback':
- Name of function to invoke for this command. The callback
- function name _must_ begin with "drush_commandfile_", where commandfile
- is from the file "commandfile.drush.inc", which contains the
- commandfile_drush_command() function that returned this command.
- Note that the callback entry is optional; it is preferable to
- omit it, in which case drush_invoke() will generate the hook function name.
- <li>'callback arguments':
- An array of arguments to pass to the callback.
- The command line arguments, if any, will appear after the
- callback arguments in the function parameters.
- <li>'description':
- Description of the command.
- <li>'arguments':
- An array of arguments that are understood by the command.
- Used by `drush help` only.
- <li>'options':
- An array of options that are understood by the command.
- Used by `drush help` only.
- <li>'examples':
- An array of examples that are understood by the command.
- Used by `drush help` only.
- <li>'scope':
- One of 'system', 'project', 'site'. Not currently used.
- <li>'bootstrap':
- Drupal bootstrap level. Valid values are:
- <ul>
- <li>DRUSH_BOOTSTRAP_DRUSH
- <li>DRUSH_BOOTSTRAP_DRUPAL_ROOT
- <li>DRUSH_BOOTSTRAP_DRUPAL_SITE
- <li>DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION
- <li>DRUSH_BOOTSTRAP_DRUPAL_DATABASE
- <li>DRUSH_BOOTSTRAP_DRUPAL_FULL
- <li>DRUSH_BOOTSTRAP_DRUPAL_LOGIN
- <li>DRUSH_BOOTSTRAP_MAX
- </ul>
- See `drush topic docs-bootstrap`.
- <li>'core':
- Drupal major version required. Append a '+' to indicate 'and later versions.'
- <li>'drupal dependencies':
- Drupal modules required for this command.
- <li>'drush dependencies':
- Other drush commandfiles required for this command.
- <li>'topics':
- Provides a list of topic commands that are related in
- some way to this command. Used by `drush help` only.
- <li>'topic':
- Set to TRUE if this command is a topic, callable from the
- `drush docs-topics` command.
- </ul><p>
- The 'sandwich' drush_command hook looks like this:
- <pre>
- function sandwich_drush_command() {
- $items = array();
- $items['make-me-a-sandwich'] = array(
- 'description' => "Makes a delicious sandwich.",
- 'arguments' => array(
- 'filling' => 'The type of the sandwich (turkey, cheese, etc.)',
- ),
- 'options' => array(
- 'spreads' => 'Comma delimited list of spreads (e.g. mayonnaise, mustard)',
- ),
- 'examples' => array(
- 'drush mmas turkey --spreads=ketchup,mustard' => 'Make a terrible-tasting sandwich that is lacking in pickles.',
- ),
- 'aliases' => array('mmas'),
- 'bootstrap' => DRUSH_BOOTSTRAP_DRUSH, // No bootstrap at all.
- );
- return $items;
- }
- </pre><p>
- Most of the items in the 'make-me-a-sandwich' command
- definition have no effect on execution, and are used only
- by `drush help`. The exceptions are 'aliases' (described
- above) and 'bootstrap'. As previously mentioned,
- `drush topic docs-bootstrap` explains the drush bootstrapping
- process in detail.
- <h2>Implement drush_COMMANDFILE_COMMANDNAME()</h2>
- <p>
- The 'make-me-a-sandwich' command in sandwich.drush.inc
- is defined as follows:
- <pre>
- function drush_sandwich_make_me_a_sandwich($filling = 'ascii') {
- ... implementation here ...
- }
- </pre><p>
- If a user runs `drush make-me-a-sandwich` with no command line
- arguments, then drush will call drush_sandwich_make_me_a_sandwich()
- with no function parameters; in this case, $filling will take on
- the provided default value, 'ascii'. (If there is no default
- value provided, then the variable will be NULL, and a warning
- will be printed.) Running `drush make-me-a-sandwich ham` will
- cause drush to call drush_sandwich_make_me_a_sandwich('ham'). In
- the same way, commands that take two command line arguments can
- simply define two functional parameters, and a command that takes
- a variable number of command line arguments can use the standard
- php function func_get_args() to get them all in an array for easy
- processing.
- <p>
- Note that drush will actually call a sequence of functions before
- and after your drush command function. One of these hooks is the
- "validate" hook. The 'sandwich' commandfile provides a validate
- hook for the 'make-me-a-sandwich' command:
- <pre>
- function drush_sandwich_make_me_a_sandwich_validate() {
- $name = posix_getpwuid(posix_geteuid());
- if ($name['name'] !== 'root') {
- return drush_set_error('MAKE_IT_YOUSELF', dt('What? Make your own sandwich.'));
- }
- }
- </pre><p>
- The validate function should call drush_set_error and return
- its result if the command cannot be validated for some reason.
- See `drush topic docs-policy` for more information on defining
- policy functions with validate hooks, and `drush topic docs-api`
- for information on how the command hook process works. Also,
- the list of defined drush error codes can be found in
- `drush topic docs-errorcodes`.
|