function drush_invoke

8.0.x drush_invoke($command, $arguments = array())
6.x drush_invoke($command, $arguments = array())
7.x drush_invoke($command, $arguments = array())
3.x drush_invoke($command)
4.x drush_invoke($command)
5.x drush_invoke($command, $arguments = array())
master drush_invoke($command, $arguments = array())

Invoke drush api calls.

Call the correct hook for all the modules that implement it. Additionally, the ability to rollback when an error has been encountered is also provided. If at any point during execution, the drush_get_error() function returns anything but 0, drush_invoke() will trigger $hook_rollback for each of the hooks that implement it, in reverse order from how they were executed.

This function will also trigger pre_$hook and post_$hook variants of the hook and its rollbacks automatically.


The name of the hook is composed from the name of the command and the name of the command file that the command definition is declared in. The general form for the hook filename is:


In many cases, drush commands that are functionally part of a common collection of similar commands will all be declared in the same file, and every command defined in that file will start with the same command prefix. For example, the command file "" defines commands such as "pm-enable" and "pm-disable". In the case of "pm-enable", the command file is "pm", and and command name is "pm-enable". When the command name starts with the same sequence of characters as the command file, then the repeated sequence is dropped; thus, the command hook for "pm-enable" is "drush_pm_enable", not "drush_pm_pm_enable".


command: The drush command to execute.

Return value

A boolean specifying whether or not the command was successfully completed.

1 call to drush_invoke()
2 string references to 'drush_invoke'
drush_command in includes/
Entry point for commands into the drush_invoke API
drush_pm_update in commands/pm/
Command callback. Execute updatecode.


includes/, line 277
The drush command engine.


function drush_invoke($command) {
  $args = func_get_args();

  // Generate the base name for the hook by using the
  // php string translation function to convert all
  // dashes and spaces in the command name to underscores.
  // TODO:  put this back to $hook = str_replace("-", "_", $command);
  // for better readability after the allow-spaces-in-commands
  // backwards-compatibility feature is removed.
  $hook = strtr($command, "- ", "__"); // n.b. str tr, not str str.
  $list = drush_commandfile_list();

  $functions = array();
  // First we build a list of functions that are about to be executed
  $variations = array($hook . "_validate", "pre_$hook", $hook, "post_$hook");
  $all_available_hooks = array();
  foreach ($variations as $var_hook) {
    foreach ($list as $commandfile => $filename) {
      $oldfunc = sprintf("drush_%s_%s", $commandfile, $var_hook);
      $func = str_replace('drush_' . $commandfile . '_' . $commandfile, 'drush_' . $commandfile, $oldfunc);
      if (($oldfunc != $func) && (function_exists($oldfunc))) {
        drush_log(dt("The drush command hook naming conventions have changed; the function !oldfunc must be renamed to !func.  The old function will be called, but this will be removed shortly.", array('!oldfunc' => $oldfunc, '!func' => $func)), "error");
        // TEMPORARY:  Allow the function to be called by its old name.
        $functions[] = $oldfunc;
      if (function_exists($func)) {
        $functions[] = $func;
        $all_available_hooks[] = $func . ' [*]';
      else {
        $all_available_hooks[] = $func;
  // If no hook functions were found, print a warning.
  if (empty($functions)) {
    drush_log(dt("No hook functions were found for !command.", array('!command' => $command)), 'warning');
    drush_log(dt("Available drush_invoke() hooks for !command: !available", array('!command' => $command, '!available' => "\n" . implode("\n", $all_available_hooks))), 'warning');
  elseif (drush_get_option('show-invoke')) {
    drush_log(dt("Available drush_invoke() hooks for !command: !available", array('!command' => $command, '!available' => "\n" . implode("\n", $all_available_hooks))), 'internals');
  $rollback = FALSE;
  $completed = array();
  $available_rollbacks = array();
  foreach ($functions as $func) {
    $available_rollbacks[] = $func . '_rollback';
    if ($rollback === FALSE) {
      $completed[] = $func;
      if (function_exists($func)) {
        call_user_func_array($func, $args);
        if (drush_get_error()) {
          drush_log(dt('An error occurred at function : @func', array('@func' => $func)), 'error');
          $rollback = TRUE;
  if (drush_get_option('show-invoke')) {
    drush_log(dt("Available rollback hooks for !command: !rollback", array('!command' => $command, '!rollback' => "\n" . implode("\n", $available_rollbacks))), 'internals');

  // something went wrong, we need to undo
  if ($rollback) {
    foreach (array_reverse($completed) as $func) {
      $rb_func = $func . '_rollback';
      if (function_exists($rb_func)) {
        call_user_func_array($rb_func, $args);
        drush_log("Changes for $func module have been rolled back.", 'rollback');

  return !$rollback;