Skip to content

Commit

Permalink
Allow autowire of Drush services (#5923)
Browse files Browse the repository at this point in the history
  • Loading branch information
weitzman committed Mar 20, 2024
1 parent 48dc17e commit 3f2de79
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 12 deletions.
2 changes: 1 addition & 1 deletion docs/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Autowire
------------------
:octicons-tag-24: 12.5+

Command files may inject Drush and Drupal services by adding the [AutowireTrait](https://github.com/drush-ops/drush/blob/12.x/src/Commands/AutowireTrait.php) to the class (example: [PmCommands](https://github.com/drush-ops/drush/blob/12.x/src/Commands/pm/MaintCommands.php)). This enables your [Constructor parameter type hints determine the the injected service](https://www.drupal.org/node/3396179). When a type hint is insufficient, an [#[Autowire] Attribute](https://www.drupal.org/node/3396179) on the constructor property (with _service:_ named argument) directs AutoWireTrait to the right service (example: [LoginCommands](https://github.com/drush-ops/drush/blob/12.x/src/Commands/core/LoginCommands.php)). This Attribute is currently _required_ when injecting Drush services (not required for Drupal services).
Command files may inject Drush and Drupal services by adding the [AutowireTrait](https://github.com/drush-ops/drush/blob/12.x/src/Commands/AutowireTrait.php) to the class (example: [PmCommands](https://github.com/drush-ops/drush/blob/12.x/src/Commands/pm/MaintCommands.php)). This enables your [Constructor parameter type hints determine the the injected service](https://www.drupal.org/node/3396179). When a type hint is insufficient, an [#[Autowire] Attribute](https://www.drupal.org/node/3396179) on the constructor property (with _service:_ named argument) directs AutoWireTrait to the right service (example: [LoginCommands](https://github.com/drush-ops/drush/blob/12.x/src/Commands/core/LoginCommands.php)).

If your command is not found by Drush, add the `-vvv` option for debug info about any service instantiation errors. If Autowire is still insufficient, a commandfile may implement its own `create()` method (see below).

Expand Down
8 changes: 2 additions & 6 deletions docs/site-alias-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ Site Alias Manager

The [Site Alias Manager (SAM)](https://github.com/consolidation/site-alias/blob/4.0.1/src/SiteAliasManager.php) service is used to retrieve information about one or all of the site aliases for the current installation.

- An informative example is the [browse command](https://github.com/drush-ops/drush/blob/12.x/src/Commands/core/BrowseCommands.php)
- A commandfile gets usually access to the SAM via [autowire](dependency-injection.md#autowire) of a dependency:
```php
#[Autowire(service: DependencyInjection::SITE_ALIAS_MANAGER)]
private readonly SiteAliasManagerInterface $siteAliasManager
```
- An informative example is the [browse command](https://github.com/drush-ops/drush/blob/13.x/src/Commands/core/BrowseCommands.php)
- A commandfile gets usually access to the SAM via [autowire](dependency-injection.md#autowire). The type hint to use is SiteAliasManagerInterface
- If an alias was used for the current request, it is available via `$this->siteAliasManager->getself()`.
- The SAM generally deals in [SiteAlias](https://github.com/consolidation/site-alias/blob/main/src/SiteAlias.php) objects. That is how any given site alias is represented. See its methods for determining things like whether the alias points to a local host or remote host.
- [Site alias docs](site-aliases.md).
Expand Down
3 changes: 0 additions & 3 deletions src/Commands/core/LoginCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
use Drush\Commands\DrushCommands;
use Drush\Drush;
use Drush\Exec\ExecTrait;
use Drush\Runtime\DependencyInjection;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

#[CLI\Bootstrap(level: DrupalBootLevels::NONE)]
final class LoginCommands extends DrushCommands implements SiteAliasManagerAwareInterface
Expand All @@ -28,7 +26,6 @@ final class LoginCommands extends DrushCommands implements SiteAliasManagerAware
const LOGIN = 'user:login';

public function __construct(
#[Autowire(service: DependencyInjection::BOOTSTRAP_MANAGER)]
private BootstrapManager $bootstrapManager
) {
parent::__construct();
Expand Down
3 changes: 1 addition & 2 deletions src/Commands/pm/PmCommands.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ public function validateEnableModules(CommandData $commandData): void
// Note: we can't just call the API ($moduleHandler->loadInclude($module, 'install')),
// because the API ignores modules that haven't been installed yet. We have
// to do it the same way the `function drupal_check_module($module)` does.
$module_list = \Drupal::service('extension.list.module');
$file = DRUPAL_ROOT . '/' . $module_list->getPath($module) . "/$module.install";
$file = DRUPAL_ROOT . '/' . $this->extensionListModule->getPath($module) . "/$module.install";
if (is_file($file)) {
require_once $file;
}
Expand Down
5 changes: 5 additions & 0 deletions src/Runtime/DependencyInjection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use Consolidation\Config\Util\ConfigOverlay;
use Consolidation\SiteAlias\SiteAliasManager;
use Consolidation\SiteAlias\SiteAliasManagerAwareInterface;
use Consolidation\SiteAlias\SiteAliasManagerInterface;
use Consolidation\SiteProcess\ProcessManagerAwareInterface;
use Drush\Boot\BootstrapManager;
use Drush\Cache\CommandCache;
use Drush\Command\DrushCommandInfoAlterer;
use Drush\Command\GlobalOptionsEventListener;
Expand Down Expand Up @@ -107,7 +109,9 @@ protected function addDrushServices($container, ClassLoader $loader, DrushDrupal
->addMethodCall('add', ['drush', new Logger($output)]);

Robo::addShared($container, self::LOADER, $loader);
Robo::addShared($container, ClassLoader::class, self::LOADER); // For autowiring
Robo::addShared($container, self::SITE_ALIAS_MANAGER, $aliasManager);
Robo::addShared($container, SiteAliasManagerInterface::class, self::SITE_ALIAS_MANAGER); // For autowiring

// Fetch the runtime config, where -D et. al. are stored, and
// add a reference to it to the container.
Expand All @@ -131,6 +135,7 @@ protected function addDrushServices($container, ClassLoader $loader, DrushDrupal
Robo::addShared($container, self::BOOTSTRAP_MANAGER, 'Drush\Boot\BootstrapManager')
->addMethodCall('setDrupalFinder', [$drupalFinder])
->addMethodCall('add', ['bootstrap.drupal8']);
Robo::addShared($container, BootstrapManager::class, self::BOOTSTRAP_MANAGER); // For autowiring
Robo::addShared($container, 'bootstrap.hook', 'Drush\Boot\BootstrapHook')
->addArgument(self::BOOTSTRAP_MANAGER);
Robo::addShared($container, 'tildeExpansion.hook', 'Drush\Runtime\TildeExpansionHook');
Expand Down

0 comments on commit 3f2de79

Please sign in to comment.