255 lines
9.1 KiB
HTML
255 lines
9.1 KiB
HTML
<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`.
|