From c6cee196ef75e7e2e0d2fe242cf1835fc6ac7b47 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 12 Mar 2024 11:59:21 -0400 Subject: [PATCH] Stop using drush.services.yml in sql:sanitize plugins (#5902) --- docs/hooks.md | 2 +- .../sql/sanitize}/SanitizeCommands.php | 10 ++++--- .../sanitize}/SanitizeCommentsCommands.php | 13 +++++----- .../sql/sanitize}/SanitizePluginInterface.php | 4 +-- .../sanitize}/SanitizeSessionsCommands.php | 10 ++++--- .../sanitize}/SanitizeUserFieldsCommands.php | 8 ++++-- .../sanitize}/SanitizeUserTableCommands.php | 10 ++++--- src/Drupal/Commands/sql/drush.services.yml | 26 ------------------- src/Runtime/LegacyServiceFinder.php | 9 ++----- src/Runtime/ServiceManager.php | 13 +++++++--- tests/functional/SqlSyncTest.php | 6 ++--- 11 files changed, 50 insertions(+), 61 deletions(-) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizeCommands.php (87%) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizeCommentsCommands.php (86%) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizePluginInterface.php (92%) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizeSessionsCommands.php (85%) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizeUserFieldsCommands.php (96%) rename src/{Drupal/Commands/sql => Commands/sql/sanitize}/SanitizeUserTableCommands.php (96%) delete mode 100644 src/Drupal/Commands/sql/drush.services.yml diff --git a/docs/hooks.md b/docs/hooks.md index c503549b73..a1793979c8 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -7,7 +7,7 @@ All commandfiles may implement methods that are called by Drush at various times ## Custom Hooks -Drush commands can define custom events that other command files can hook. You can find examples in [CacheCommands](https://github.com/drush-ops/drush/blob/12.x/src/Commands/core/CacheCommands.php) and [SanitizeCommands](https://github.com/drush-ops/drush/blob/12.x/src/Drupal/Commands/sql/SanitizeCommands.php) +Drush commands can define custom events that other command files can hook. You can find examples in [CacheCommands](https://github.com/drush-ops/drush/blob/13.x/src/Commands/core/CacheCommands.php) and [SanitizeCommands](https://github.com/drush-ops/drush/blob/13.x/src/Commands/sql/sanitize/SanitizeCommands.php) First, the command must implement CustomEventAwareInterface and use CustomEventAwareTrait, as described in the [dependency injection](dependency-injection.md#inflection) documentation. diff --git a/src/Drupal/Commands/sql/SanitizeCommands.php b/src/Commands/sql/sanitize/SanitizeCommands.php similarity index 87% rename from src/Drupal/Commands/sql/SanitizeCommands.php rename to src/Commands/sql/sanitize/SanitizeCommands.php index 21229304a7..ebe43e5b27 100644 --- a/src/Drupal/Commands/sql/SanitizeCommands.php +++ b/src/Commands/sql/sanitize/SanitizeCommands.php @@ -2,15 +2,17 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface; use Consolidation\AnnotatedCommand\Events\CustomEventAwareTrait; use Drush\Attributes as CLI; +use Drush\Boot\DrupalBootLevels; use Drush\Commands\core\DocsCommands; use Drush\Commands\DrushCommands; use Drush\Exceptions\UserAbortException; +#[CLI\Bootstrap(level: DrupalBootLevels::FULL)] final class SanitizeCommands extends DrushCommands implements CustomEventAwareInterface { use CustomEventAwareTrait; @@ -26,7 +28,7 @@ final class SanitizeCommands extends DrushCommands implements CustomEventAwareIn * - `#[CLI\Hook(type: HookManager::ON_EVENT, target: SanitizeCommands::CONFIRMS)]`. Display summary to user before confirmation. * - `#[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: SanitizeCommands::SANITIZE)]`. Run queries or call APIs to perform sanitizing * - * Several working commandfiles may be found at https://github.com/drush-ops/drush/tree/12.x/src/Drupal/Commands/sql + * Several working commandfiles may be found at https://github.com/drush-ops/drush/tree/13.x/src/Commands/sql/sanitize */ #[CLI\Command(name: self::SANITIZE, aliases: ['sqlsan','sql-sanitize'])] #[CLI\Usage(name: 'drush sql:sanitize --sanitize-password=no', description: 'Sanitize database without modifying any passwords.')] @@ -36,7 +38,7 @@ public function sanitize(): void { /** * In order to present only one prompt, collect all confirmations from - * commandfiles up front. sql-sanitize plugins are commandfiles that implement + * commandfiles up front. sql:sanitize plugins are commandfiles that implement * \Drush\Commands\sql\SanitizePluginInterface */ $messages = []; @@ -54,6 +56,6 @@ public function sanitize(): void } // All sanitize operations defined in post-command hooks, including Drush - // core sanitize routines. See \Drush\Commands\sql\SanitizePluginInterface. + // core sanitize routines. See \Drush\Commands\sql\sanitize\SanitizePluginInterface. } } diff --git a/src/Drupal/Commands/sql/SanitizeCommentsCommands.php b/src/Commands/sql/sanitize/SanitizeCommentsCommands.php similarity index 86% rename from src/Drupal/Commands/sql/SanitizeCommentsCommands.php rename to src/Commands/sql/sanitize/SanitizeCommentsCommands.php index 0960bd4c18..60a45296a8 100644 --- a/src/Drupal/Commands/sql/SanitizeCommentsCommands.php +++ b/src/Commands/sql/sanitize/SanitizeCommentsCommands.php @@ -2,33 +2,35 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\Hooks\HookManager; use Drupal\Core\Database\Connection; use Drupal\Core\Extension\ModuleHandlerInterface; use Drush\Attributes as CLI; -use Drush\Boot\DrupalBootLevels; +use Drush\Commands\AutowireTrait; use Drush\Commands\DrushCommands; -use Drush\Drush; use Symfony\Component\Console\Input\InputInterface; /** - * This class is a good example of a sql-sanitize plugin. + * This class is a good example of a sql:sanitize plugin. */ final class SanitizeCommentsCommands extends DrushCommands implements SanitizePluginInterface { + use AutowireTrait; + public function __construct( protected Connection $database, protected ModuleHandlerInterface $moduleHandler ) { + parent::__construct(); } /** * Sanitize comment names from the DB. */ - #[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: 'sql-sanitize')] + #[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: SanitizeCommands::SANITIZE)] public function sanitize($result, CommandData $commandData): void { if ($this->applies()) { @@ -63,7 +65,6 @@ public function messages(&$messages, InputInterface $input): void protected function applies() { - Drush::bootstrapManager()->doBootstrap(DrupalBootLevels::FULL); return $this->moduleHandler->moduleExists('comment'); } } diff --git a/src/Drupal/Commands/sql/SanitizePluginInterface.php b/src/Commands/sql/sanitize/SanitizePluginInterface.php similarity index 92% rename from src/Drupal/Commands/sql/SanitizePluginInterface.php rename to src/Commands/sql/sanitize/SanitizePluginInterface.php index ec6bda8b8f..5e25967e1c 100644 --- a/src/Drupal/Commands/sql/SanitizePluginInterface.php +++ b/src/Commands/sql/sanitize/SanitizePluginInterface.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\CommandData; -use Consolidation\AnnotatedCommand\Hooks\HookManager; +use Drush\Drupal\Commands\sql\Exit; use Symfony\Component\Console\Input\InputInterface; /** diff --git a/src/Drupal/Commands/sql/SanitizeSessionsCommands.php b/src/Commands/sql/sanitize/SanitizeSessionsCommands.php similarity index 85% rename from src/Drupal/Commands/sql/SanitizeSessionsCommands.php rename to src/Commands/sql/sanitize/SanitizeSessionsCommands.php index b514760131..42a2f3b8d3 100644 --- a/src/Drupal/Commands/sql/SanitizeSessionsCommands.php +++ b/src/Commands/sql/sanitize/SanitizeSessionsCommands.php @@ -2,22 +2,26 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\Hooks\HookManager; +use Drupal\Core\Database\Connection; use Drush\Attributes as CLI; +use Drush\Commands\AutowireTrait; use Drush\Commands\DrushCommands; -use Drupal\Core\Database\Connection; use Symfony\Component\Console\Input\InputInterface; /** - * This class is a good example of how to build a sql-sanitize plugin. + * This class is a good example of how to build a sql:sanitize plugin. */ final class SanitizeSessionsCommands extends DrushCommands implements SanitizePluginInterface { + use AutowireTrait; + public function __construct(protected Connection $database) { + parent::__construct(); } /** diff --git a/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php b/src/Commands/sql/sanitize/SanitizeUserFieldsCommands.php similarity index 96% rename from src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php rename to src/Commands/sql/sanitize/SanitizeUserFieldsCommands.php index f4ca3ffad2..662c87fa7e 100644 --- a/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php +++ b/src/Commands/sql/sanitize/SanitizeUserFieldsCommands.php @@ -2,26 +2,30 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\Hooks\HookManager; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drush\Attributes as CLI; +use Drush\Commands\AutowireTrait; use Drush\Commands\DrushCommands; use Symfony\Component\Console\Input\InputInterface; /** - * This class is a good example of how to build a sql-sanitize plugin. + * This class is a good example of how to build a sql:sanitize plugin. */ final class SanitizeUserFieldsCommands extends DrushCommands implements SanitizePluginInterface { + use AutowireTrait; + public function __construct( protected \Drupal\Core\Database\Connection $database, protected EntityFieldManagerInterface $entityFieldManager, protected EntityTypeManagerInterface $entityTypeManager ) { + parent::__construct(); } /** diff --git a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php b/src/Commands/sql/sanitize/SanitizeUserTableCommands.php similarity index 96% rename from src/Drupal/Commands/sql/SanitizeUserTableCommands.php rename to src/Commands/sql/sanitize/SanitizeUserTableCommands.php index b896047715..87f84ce992 100644 --- a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php +++ b/src/Commands/sql/sanitize/SanitizeUserTableCommands.php @@ -2,33 +2,37 @@ declare(strict_types=1); -namespace Drush\Drupal\Commands\sql; +namespace Drush\Commands\sql\sanitize; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\Hooks\HookManager; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Password\PasswordInterface; use Drush\Attributes as CLI; +use Drush\Commands\AutowireTrait; use Drush\Commands\DrushCommands; use Drush\Sql\SqlBase; use Drush\Utils\StringUtils; use Symfony\Component\Console\Input\InputInterface; /** - * A sql-sanitize plugin. + * A sql:sanitize plugin. */ final class SanitizeUserTableCommands extends DrushCommands implements SanitizePluginInterface { + use AutowireTrait; + public function __construct( protected \Drupal\Core\Database\Connection $database, protected PasswordInterface $passwordHasher, protected EntityTypeManagerInterface $entityTypeManager ) { + parent::__construct(); } /** * Sanitize emails and passwords. This also an example of how to write a - * database sanitizer for sql-sync. + * database sanitizer for sql:sync. */ #[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: SanitizeCommands::SANITIZE)] public function sanitize($result, CommandData $commandData): void diff --git a/src/Drupal/Commands/sql/drush.services.yml b/src/Drupal/Commands/sql/drush.services.yml deleted file mode 100644 index 5f1de8e982..0000000000 --- a/src/Drupal/Commands/sql/drush.services.yml +++ /dev/null @@ -1,26 +0,0 @@ -services: - sanitize.commands: - class: \Drush\Drupal\Commands\sql\SanitizeCommands - arguments: [] - tags: - - { name: drush.command } - sanitize.comments.commands: - class: \Drush\Drupal\Commands\sql\SanitizeCommentsCommands - arguments: ['@database', '@module_handler',] - tags: - - { name: drush.command } - sanitize.sessions.commands: - class: \Drush\Drupal\Commands\sql\SanitizeSessionsCommands - arguments: ['@database'] - tags: - - { name: drush.command } - sanitize.userfields.commands: - class: \Drush\Drupal\Commands\sql\SanitizeUserFieldsCommands - arguments: ['@database', '@entity_field.manager', '@entity_type.manager'] - tags: - - { name: drush.command } - sanitize.usertable.commands: - class: \Drush\Drupal\Commands\sql\SanitizeUserTableCommands - arguments: ['@database', '@password', '@entity_type.manager'] - tags: - - { name: drush.command } diff --git a/src/Runtime/LegacyServiceFinder.php b/src/Runtime/LegacyServiceFinder.php index c69d3c5099..cf4e5a1f66 100644 --- a/src/Runtime/LegacyServiceFinder.php +++ b/src/Runtime/LegacyServiceFinder.php @@ -4,12 +4,9 @@ namespace Drush\Runtime; -use Drush\Log\Logger; -use Drush\Drush; -use Symfony\Component\Console\Application; -use League\Container\Container as DrushContainer; -use Drush\Config\DrushConfig; use Composer\Semver\Semver; +use Drush\Config\DrushConfig; +use Drush\Drush; /** * Find drush.services.yml files. @@ -46,8 +43,6 @@ public function getDrushServiceFiles(): array */ protected function discoverDrushServiceProviders() { - $this->addDrushServiceProvider("_drush__sql", $this->drushConfig->get('drush.base-dir') . '/src/Drupal/Commands/sql/drush.services.yml'); - // Add Drush services from all modules $module_filenames = $this->getModuleFileNames(); // Load each module's serviceProvider class. diff --git a/src/Runtime/ServiceManager.php b/src/Runtime/ServiceManager.php index 09c716c217..a1a3a283de 100644 --- a/src/Runtime/ServiceManager.php +++ b/src/Runtime/ServiceManager.php @@ -368,17 +368,17 @@ protected function hasStaticCreateFactory(string $class): bool /** * Does the provided class have a Bootstrap Attribute, indicating early loading. */ - protected function hasBootStrapAttributeNone(string $class): bool + protected function bootStrapAttributeValue(string $class): ?int { try { $reflection = new \ReflectionClass($class); if ($attributes = $reflection->getAttributes(Bootstrap::class)) { $bootstrap = $attributes[0]->newInstance(); - return $bootstrap->level === DrupalBootLevels::NONE; + return $bootstrap->level; } } catch (\ReflectionException $e) { } - return false; + return null; } /** @@ -386,7 +386,12 @@ protected function hasBootStrapAttributeNone(string $class): bool */ protected function requiresBootstrap(string $class): bool { - return $this->hasStaticCreateFactory($class) && !$this->hasBootStrapAttributeNone($class); + if ($this->bootStrapAttributeValue($class) === DrupalBootLevels::FULL) { + return true; + } elseif ($this->bootStrapAttributeValue($class) === DrupalBootLevels::NONE) { + return false; + } + return $this->hasStaticCreateFactory($class); } /** diff --git a/tests/functional/SqlSyncTest.php b/tests/functional/SqlSyncTest.php index 051865f029..80ba9622e1 100644 --- a/tests/functional/SqlSyncTest.php +++ b/tests/functional/SqlSyncTest.php @@ -5,11 +5,11 @@ namespace Unish; use Drush\Commands\core\PhpCommands; -use Drush\Commands\sql\SqlCommands; -use Drush\Commands\sql\SqlSyncCommands; use Drush\Commands\core\UserCommands; use Drush\Commands\pm\PmCommands; -use Drush\Drupal\Commands\sql\SanitizeCommands; +use Drush\Commands\sql\sanitize\SanitizeCommands; +use Drush\Commands\sql\SqlCommands; +use Drush\Commands\sql\SqlSyncCommands; /** * @group slow