Grey text "drush". In the background: strings of drupal code.

Your own Drush command in Drupal 8

If you are a Drupal developer, it is almost certain you have heard of drush. Drush is a commandline utility which allows you to interact with drupal, well - from command line. Every Drupal agency or any one worth his salt who does drupal development, uses drush because it masively speeds up drupal development, saving time and money. 

Drush comes with many built in commands, but you can also add your own. Let's see how.

In Drupal 8 we can easily add our own command to Drush. The whole code for the new command will be put in a custom module.

We have to create only 2 files.
The structure looks as follows.

The structure of the file visible as tree of catalogs

File d_drush_command_pack.info.yml

A standard file of every module in which there is information about our plugin.

name: Droptica Drush Command Pack
description: Provide useful custom drush commands
package: Drush Commands
type: module
core: 8.x


File d_drush_command_pack.drush.inc

Here, we define our commands and we put our logic that will be executed by a given command.
The following example generates two new commands.

<?php

/**
 * Implements hook_drush_command().
 */
function d_drush_command_pack_drush_command() {   $commands['rebuild-aggregate-file'] = [
    'description' => 'Rebuild aggregate css/js files',
    'aliases' => ['raf'],
    'arguments' => [      
       'js' => 'Rebuild aggregate js files only',
      'css' => 'Rebuild aggregate css files only',
    ],
    'examples' => [       
      'drush raf' => 'Rebuild aggregate css/js files',
      'drush raf js' => 'Rebuild aggregate js files',
      'drush raf css' => 'Rebuild aggregate css files',
    ],
  ];

  $commands['delete-node-alias'] = [
    'description' => 'Delete a node alias',
    'aliases' => ['dna'],
    'arguments' => [       
      'source' => 'Delete by source',
      'alias' => 'Delete by alias',
    ],
    'options' => [      
        'name' => 'Name of source or alias',
    ],
    'examples' => [       
      'drush dna source /node/1' => 'Delete an alias by source path',
      'drush dna alias /path-alias-name' => 'Delete an alias by alias path name',
    ],
  ];

  return $commands;
} /**
 * Drush command logic for rebuilding file cache.
 *
 */
function drush_d_drush_command_pack_rebuild_aggregate_file($arg = NULL) {   $tokens = ['@arg' => $arg];
  switch ($arg) {     case 'js':
      \Drupal::service("asset.js.collection_optimizer")->deleteAll();
      _drupal_flush_css_js();
      drush_print(dt('Rebuild aggregate @arg files.', $tokens));
      break;
    case 'css':
      \Drupal::service("asset.css.collection_optimizer")->deleteAll();
      _drupal_flush_css_js();
      drush_print(dt('Rebuild aggregate @arg files.', $tokens));
      break;
    case '':
      \Drupal::service("asset.css.collection_optimizer")->deleteAll();
      \Drupal::service("asset.js.collection_optimizer")->deleteAll();
      _drupal_flush_css_js();
      drush_print(dt('Rebuild aggregate js/css files.'));
      break;
    default:
      drush_print(dt('Wrong argument. Possible arguments: js, css or use command without argument.'));
  } }

/**
 * Drush command logic for deleting aliases
 *
 */
function drush_d_drush_command_pack_delete_node_alias($arg = NULL, $opt = NULL) {   $tokens = ['@arg' => $arg, '@opt' => $opt];

  switch ($arg) {     case 'alias':
    case 'source':
      $condition = [$arg => $opt];
      \Drupal::service('path.alias_storage')
        ->delete($condition);
      drush_print(dt('Alias @opt deleted', $tokens));
      break;

    default:
      drush_print(dt('Wrong argument and options. Example use: drush dna source /node/1'));
  } }

The above code creates two new drush commands for us
The first one is rebuild-aggregate-file
The second one is delete-node-alias
The commands are defined in the hook:   hook_drush_command(),
here, we set alias, arguments, options and examples for our command
Logic for each of them is created in separate functions.
We create the names of the functions like this: 
drush_[MODULE_NAME]_[COMMAND_NAME]()
All we have to do is turn our new module on, clear cache and test the commands.
Examples of launching the commands from the above code.

drush rebuild-aggregate-file css
drush raf js
drush raf

drush dna source /node/1
drush dna alias /alias-name


You will find the files of the sample module on GitHub.

3. Best practices for software development teams