drush-ops / drush

Drush is a command-line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those who spend their working hours hacking away at the command prompt.
https://www.drush.org
2.33k stars 1.08k forks source link

Drush finding commands in uninstalled modules #4024

Open jhodgdon-drp opened 5 years ago

jhodgdon-drp commented 5 years ago

Describe the bug

A user of a Drupal module that I mantain: https://www.drupal.org/project/config_update filed a bug today: https://www.drupal.org/project/config_update/issues/3044903

The project in question has two modules: A base module config_update and a Reports sub_module config_update_ui. The Reports submodule has a drush.inc file for Drush 8 and a Drush commands file in src/Commands.

The user who filed the bug was able to try to run one of the Drush commands with only the base module enabled. The user should not have been able to see these Drush commands without the config_update_ui module enabled, and the command did not work.

To Reproduce Install just the config_update module and not config_update_ui. Attempt to use one of the Drush commands from config_update_ui, such as drush config-revert views.view.group_nodes

Expected behavior The command should not be recognized by Drush as a valid command, because the module that contains the command is not installed.

Actual behavior Drush tried to run the command, but it failed because the module was not installed:

Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "config_update_ui.cli". in drupal/html/core/lib/Drupal/Component/DependencyInjection/Container.php:151

Workaround

System Configuration

I will ask the person who reported the bug to supply more information about the system config.

Q A
Drush version? 9.x/8.x (please be specific, and try latest dev build)
Drupal version? 7.x/8.x
PHP version 5.6/7.1
OS? Mac/Linux/Windows

Additional information

weitzman commented 5 years ago

All I can think of is to run drush cr and see if the commands disappear. maybe the submodule was enabled previously and thus the commands are still known to the drupal container.

weitzman commented 5 years ago

Devel and devel generate are in the same boat. I enabled devel and the devel generate commands were still not visible. However, I am using Drush 9 and not Drush 8, as that original bug reporter did.

jhodgdon-drp commented 5 years ago

Oh yeah, you're right, they are using Drush 8. I missed that in their issue post.

Will Drush 8 look in subdirectories for drush.inc files? The file config_update_ui.drush.inc with the Drush 8 commands is in config_update/config_update_ui (along with config_update_ui.module and config_update_ui.info.yml).

weitzman commented 5 years ago

I tried on drush8 and I can confirm this bug there.

greg-1-anderson commented 5 years ago

So, this bug has been around fo-evah. Here's what is going on:

The problem comes in if config_update is enabled, but config_update_ui is not. In this instance, when Drush searches for commandfiles in modules/contrib/config_update, it does a deep search from that location. It does not differentiate the directory config_update_ui (that it should not search) from any other directory that it should test (i.e. the module might decide to put its Drush commands in a drush directory).

The Drush 8 commandfile searching code is a little messy and a little fragile. I think this is bug going to be a "do not fix", since we are mostly pushing toward development on 9.x (the master branch) right now.

There is a workaround, though. In your command definition hook, add a dependency from every command to the module itself.

i.e.:

  $items['config-list-types'] = [
    'description' => 'List config types',
    'aliases' => ['clt'],
    'core' => ['8+'],
    'drupal dependencies' => [ 'config_update_ui', ],
    'outputformat' => [
      'default' => 'list',
    ],
  ];

If you do this, then you will get the following behavior:

$ drush config-revert views.view.group_nodes 
Command config-revert needs the following modules installed/enabled to run:               [error]
config_update_ui.
The drush command 'config-revert views.view.group_nodes' could not be executed.           [error]

This should be sufficient for most cases.