From ef31e7d66c860de392bac5394fd0a2d70b86b2ff Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 15 Dec 2021 07:56:48 -0500 Subject: [PATCH 001/125] Change min DCG version for entity:bundle-classes to 11.0 in docs. --- src/Commands/core/MkCommands.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/core/MkCommands.php b/src/Commands/core/MkCommands.php index d4746195bb..bfec5ec6c0 100644 --- a/src/Commands/core/MkCommands.php +++ b/src/Commands/core/MkCommands.php @@ -77,8 +77,8 @@ public function createAnnotatedCommands(Application $application_generate, Appli $annotated->setAliases($command->getAliases()); $annotated->setTopics(['docs:generators']); $values = []; - if ($command->getName() == 'entity:bundle-class') { - $values['version'] = '11.x'; + if (in_array($command->getName(), ['entity:bundle-class'])) { + $values['version'] = '11.0'; } $annotated->setAnnotationData(new AnnotationData($values)); // Hack, until we have https://github.com/consolidation/annotated-command/pull/247 From cb2434e319967f65a1f4dee2dcdb68f5c097336b Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 15 Dec 2021 08:52:33 -0500 Subject: [PATCH 002/125] Fix #2927. Don't issue a login link if user is blocked. (#4934) * Fix #2927. Don't issue a login link if user is blocked. * Add name in err msg --- src/Commands/core/LoginCommands.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Commands/core/LoginCommands.php b/src/Commands/core/LoginCommands.php index 887bf87400..3db35557ba 100644 --- a/src/Commands/core/LoginCommands.php +++ b/src/Commands/core/LoginCommands.php @@ -69,6 +69,10 @@ public function login($path = '', $options = ['name' => null, 'uid' => null, 'ma $account = User::load(1); } + if ($account->isBlocked()) { + throw new \InvalidArgumentException(dt('Account !name is blocked and thus cannot login. The user:unblock command may be helpful.', ['!name' => $account->getAccountName()])); + } + $timestamp = \Drupal::time()->getRequestTime(); $link = Url::fromRoute( 'user.reset.login', From 5794cddb9440d169e9e7cd150a8b0bd6c5b82efe Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Wed, 15 Dec 2021 16:18:35 +0100 Subject: [PATCH 003/125] Add field:info command (#4928) * Add field:info command * Move formatting code to trait * Fix dependency injection * Add tests. * change name back. try to avoid conflict * phpcs Co-authored-by: Moshe Weitzman --- src/Drupal/Commands/core/AskBundleTrait.php | 45 ++++++++++ .../core/FieldDefinitionRowsOfFieldsTrait.php | 59 +++++++++++++ .../Commands/core/FieldInfoCommands.php | 87 +++++++++++++++++++ .../Commands/core/ValidateEntityTypeTrait.php | 46 ++++++++++ src/Drupal/Commands/core/drush.services.yml | 7 ++ tests/functional/FieldCreateTest.php | 23 ++++- 6 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 src/Drupal/Commands/core/AskBundleTrait.php create mode 100644 src/Drupal/Commands/core/FieldDefinitionRowsOfFieldsTrait.php create mode 100644 src/Drupal/Commands/core/FieldInfoCommands.php create mode 100644 src/Drupal/Commands/core/ValidateEntityTypeTrait.php diff --git a/src/Drupal/Commands/core/AskBundleTrait.php b/src/Drupal/Commands/core/AskBundleTrait.php new file mode 100644 index 0000000000..1e692474fd --- /dev/null +++ b/src/Drupal/Commands/core/AskBundleTrait.php @@ -0,0 +1,45 @@ +input->getArgument('entityType'); + $entityTypeDefinition = $this->entityTypeManager->getDefinition($entityTypeId); + $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); + $bundleInfo = $this->entityTypeBundleInfo->getBundleInfo($entityTypeId); + $choices = []; + + if (empty($bundleInfo)) { + if ($bundleEntityType) { + throw new \InvalidArgumentException( + t('Entity type with id \':entityType\' does not have any bundles.', [':entityType' => $entityTypeId]) + ); + } + + return null; + } + + foreach ($bundleInfo as $bundle => $data) { + $label = $this->input->getOption('show-machine-names') ? $bundle : $data['label']; + $choices[$bundle] = $label; + } + + if (!$answer = $this->io()->choice('Bundle', $choices)) { + throw new \InvalidArgumentException(t('The bundle argument is required.')); + } + + return $answer; + } +} diff --git a/src/Drupal/Commands/core/FieldDefinitionRowsOfFieldsTrait.php b/src/Drupal/Commands/core/FieldDefinitionRowsOfFieldsTrait.php new file mode 100644 index 0000000000..2e24c31fd7 --- /dev/null +++ b/src/Drupal/Commands/core/FieldDefinitionRowsOfFieldsTrait.php @@ -0,0 +1,59 @@ +getFieldStorageDefinition(); + $handlerSettings = $field->getSetting('handler_settings'); + + $rows[$field->getName()] = [ + 'label' => $field->getLabel(), + 'description' => $field->getDescription(), + 'field_name' => $field->getName(), + 'field_type' => $field->getType(), + 'required' => $field->isRequired(), + 'translatable' => $field->isTranslatable(), + 'cardinality' => $storage->getCardinality(), + 'default_value' => empty($field->getDefaultValueLiteral()) ? null : $field->getDefaultValueLiteral(), + 'default_value_callback' => $field->getDefaultValueCallback(), + 'allowed_values' => $storage->getSetting('allowed_values'), + 'allowed_values_function' => $storage->getSetting('allowed_values_function'), + 'handler' => $field->getSetting('handler'), + 'target_bundles' => $handlerSettings['target_bundles'] ?? null, + ]; + } + + $result = new RowsOfFields($rows); + $result->addRendererFunction([$this, 'renderArray']); + $result->addRendererFunction([$this, 'renderBoolean']); + + return $result; + } +} diff --git a/src/Drupal/Commands/core/FieldInfoCommands.php b/src/Drupal/Commands/core/FieldInfoCommands.php new file mode 100644 index 0000000000..8c962d23e0 --- /dev/null +++ b/src/Drupal/Commands/core/FieldInfoCommands.php @@ -0,0 +1,87 @@ +entityTypeManager = $entityTypeManager; + $this->entityTypeBundleInfo = $entityTypeBundleInfo; + } + + /** + * List all configurable fields of an entity bundle + * + * @command field:info + * @aliases field-info,fi + * + * @param string $entityType + * The machine name of the entity type + * @param string $bundle + * The machine name of the bundle + * + * @option show-machine-names + * Show machine names instead of labels in option lists. + * + * @default-fields field_name,required,field_type,cardinality + * @field-labels + * label: Label + * description: Description + * field_name: Field name + * field_type: Field type + * required: Required + * translatable: Translatable + * cardinality: Cardinality + * default_value: Default value + * default_value_callback: Default value callback + * allowed_values: Allowed values + * allowed_values_function: Allowed values function + * handler: Selection handler + * target_bundles: Target bundles + * @filter-default-field field_name + * @table-style default + * + * @usage drush field-info taxonomy_term tag + * List all fields. + * @usage drush field:info + * List all fields and fill in the remaining information through prompts. + * + * @version 11.0 + */ + public function info(string $entityType, ?string $bundle = null, array $options = [ + 'format' => 'table', + ]): RowsOfFields + { + $this->validateEntityType($entityType); + + $this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); + $this->validateBundle($entityType, $bundle); + + $fieldDefinitions = $this->entityTypeManager + ->getStorage('field_config') + ->loadByProperties([ + 'entity_type' => $entityType, + 'bundle' => $bundle, + ]); + + return $this->getRowsOfFieldsByFieldDefinitions($fieldDefinitions); + } +} diff --git a/src/Drupal/Commands/core/ValidateEntityTypeTrait.php b/src/Drupal/Commands/core/ValidateEntityTypeTrait.php new file mode 100644 index 0000000000..7c968efc30 --- /dev/null +++ b/src/Drupal/Commands/core/ValidateEntityTypeTrait.php @@ -0,0 +1,46 @@ +entityTypeManager->hasDefinition($entityTypeId)) { + throw new \InvalidArgumentException( + t("Entity type with id ':entityType' does not exist.", [':entityType' => $entityTypeId]) + ); + } + } + + protected function validateBundle(string $entityTypeId, string $bundle): void + { + if (!$entityTypeDefinition = $this->entityTypeManager->getDefinition($entityTypeId)) { + return; + } + + $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); + + if ($bundleEntityType === null && $bundle === $entityTypeId) { + return; + } + + $bundleDefinition = $this->entityTypeManager + ->getStorage($bundleEntityType) + ->load($bundle); + + if (!$bundleDefinition) { + throw new \InvalidArgumentException( + t("Bundle ':bundle' does not exist on entity type with id ':entityType'.", [ + ':bundle' => $bundle, + ':entityType' => $entityTypeId, + ]) + ); + } + } +} diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index e70ea33f66..e975013360 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -35,6 +35,13 @@ services: - [ setContentTranslationManager, [ '@?content_translation.manager' ] ] tags: - { name: drush.command } + field.info.commands: + class: \Drush\Drupal\Commands\core\FieldInfoCommands + arguments: + - '@entity_type.manager' + - '@entity_type.bundle.info' + tags: + - { name: drush.command } link.hooks: class: \Drush\Drupal\Commands\core\LinkHooks arguments: diff --git a/tests/functional/FieldCreateTest.php b/tests/functional/FieldCreateTest.php index dc93cc736f..ca676305af 100644 --- a/tests/functional/FieldCreateTest.php +++ b/tests/functional/FieldCreateTest.php @@ -2,6 +2,7 @@ namespace Unish; +use Drupal\Core\Field\FieldStorageDefinitionInterface; use Webmozart\PathUtil\Path; /** @@ -35,12 +36,12 @@ public function testFieldCreate() $this->assertStringNotContainsString('bundle', $this->getErrorOutputRaw()); // New field storage - $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test2', 'field-type' => 'entity_reference', 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => '-1'], null, null, self::EXIT_ERROR); + $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test2', 'field-type' => 'entity_reference', 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED], null, null, self::EXIT_ERROR); $this->assertStringContainsString('The target-type option is required.', $this->getErrorOutputRaw()); /// @todo --target-bundle not yet validated. // $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test3', 'field-type' => 'entity_reference', 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => '-1', 'target-type' => 'unish_article', 'target-bundle' => 'NO-EXIST']); // $this->assertStringContainsString('TODO', $this->getErrorOutputRaw()); - $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test3', 'field-type' => 'entity_reference', 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => '-1', 'target-type' => 'unish_article', 'target-bundle' => 'beta']); + $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test3', 'field-type' => 'entity_reference', 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'target-type' => 'unish_article', 'target-bundle' => 'beta']); $this->assertStringContainsString("Successfully created field 'field_test3' on unish_article type with bundle 'alpha'", $this->getErrorOutputRaw()); $this->assertStringContainsString("http://dev/admin/structure/unish_article_types/manage/alpha/fields/unish_article.alpha.field_test3", $this->getSimplifiedErrorOutput()); $php = "return Drupal::entityTypeManager()->getStorage('field_config')->load('unish_article.alpha.field_test3')->getSettings()"; @@ -57,4 +58,22 @@ public function testFieldCreate() $this->drush('field:create', ['unish_article', 'beta'], ['existing-field-name' => 'field_test3', 'field-label' => 'Body', 'field-widget' => 'text_textarea_with_summary'], null, null, self::EXIT_ERROR); $this->assertStringContainsString('Field with name \'field_test3\' already exists on bundle \'beta\'', $this->getErrorOutputRaw()); } + + public function testFieldInfo() + { + $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test4', 'field-description' => 'baz', 'field-type' => 'entity_reference', 'is-required' => true, 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'target-type' => 'unish_article', 'target-bundle' => 'beta']); + $this->assertStringContainsString("Successfully created field 'field_test4' on unish_article type with bundle 'alpha'", $this->getSimplifiedErrorOutput()); + + $this->drush('field:info', ['unish_article'], [], null, null, self::EXIT_ERROR); + $this->assertStringContainsString('The bundle argument is required.', $this->getSimplifiedErrorOutput()); + $this->drush('field:info', ['unish_article', 'alpha'], ['format' => 'json', 'fields' => '*']); + $json = $this->getOutputFromJSON('field_test4'); + $this->assertSame('field_test4', $json['field_name']); + $this->assertTrue($json['required']); + $this->assertSame('entity_reference', $json['field_type']); + $this->assertSame('baz', $json['description']); + $this->assertSame(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, $json['cardinality']); + $this->assertFalse($json['translatable']); + $this->assertArrayHasKey('beta', $json['target_bundles']); + } } From 2270b5b891f04b6e0bed88fa28af0e56a86da309 Mon Sep 17 00:00:00 2001 From: O'Briat Date: Wed, 15 Dec 2021 18:05:53 +0100 Subject: [PATCH 004/125] Fix #4541: Add again uid and mail options for user commands (#4542) * Fix #4541: Add again uid and mail options for user command. * Code comments. Co-authored-by: O'Briat Co-authored-by: Moshe Weitzman --- src/Drupal/Commands/core/UserCommands.php | 164 +++++++++++++--------- tests/functional/UserTest.php | 63 ++++++++- 2 files changed, 156 insertions(+), 71 deletions(-) diff --git a/src/Drupal/Commands/core/UserCommands.php b/src/Drupal/Commands/core/UserCommands.php index 9a76c02721..ac8fda4b15 100644 --- a/src/Drupal/Commands/core/UserCommands.php +++ b/src/Drupal/Commands/core/UserCommands.php @@ -119,22 +119,19 @@ public function renderRolesCell($key, $cellData, FormatterOptions $options) * @command user:block * * @param string $names A comma delimited list of user names. + * @option $uid A comma delimited list of user ids to lookup (an alternative to names). + * @option $mail A comma delimited list of emails to lookup (an alternative to names). * @aliases ublk,user-block * @usage drush user:block user3 * Block the users whose name is user3 */ - public function block($names) + public function block($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) { - if ($names = StringUtils::csvToArray($names)) { - foreach ($names as $name) { - if ($account = user_load_by_name($name)) { - $account->block(); - $account->save(); - $this->logger->success(dt('Blocked user(s): !user', ['!user' => $name])); - } else { - $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name])); - } - } + $accounts = $this->getAccounts($names, $options); + foreach ($accounts as $id => $account) { + $account->block(); + $account->save(); + $this->logger->success(dt('Blocked user(s): !user', ['!user' => $account->getAccountName()])); } } @@ -144,22 +141,19 @@ public function block($names) * @command user:unblock * * @param string $names A comma delimited list of user names. + * @option $uid A comma delimited list of user ids to lookup (an alternative to names). + * @option $mail A comma delimited list of emails to lookup (an alternative to names). * @aliases uublk,user-unblock * @usage drush user:unblock user3 * Unblock the users with name user3 */ - public function unblock($names) + public function unblock($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) { - if ($names = StringUtils::csvToArray($names)) { - foreach ($names as $name) { - if ($account = user_load_by_name($name)) { - $account->activate(); - $account->save(); - $this->logger->success(dt('Unblocked user(s): !user', ['!user' => $name])); - } else { - $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name])); - } - } + $accounts = $this->getAccounts($names, $options); + foreach ($accounts as $id => $account) { + $account->activate(); + $account->save(); + $this->logger->success(dt('Unblocked user(s): !user', ['!user' => $account->getAccountName()])); } } @@ -171,25 +165,22 @@ public function unblock($names) * @validate-entity-load user_role role * @param string $role The machine name of the role to add. * @param string $names A comma delimited list of user names. + * @option $uid A comma delimited list of user ids to lookup (an alternative to names). + * @option $mail A comma delimited list of emails to lookup (an alternative to names). * @aliases urol,user-add-role * @usage drush user-add-role "editor" user3 * Add the editor role to user3 */ - public function addRole($role, $names) + public function addRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) { - if ($names = StringUtils::csvToArray($names)) { - foreach ($names as $name) { - if ($account = user_load_by_name($name)) { - $account->addRole($role); - $account->save(); - $this->logger->success(dt('Added !role role to !user', [ - '!role' => $role, - '!user' => $name, - ])); - } else { - $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name])); - } - } + $accounts = $this->getAccounts($names, $options); + foreach ($accounts as $id => $account) { + $account->addRole($role); + $account->save(); + $this->logger->success(dt('Added !role role to !user', [ + '!role' => $role, + '!user' => $account->getAccountName(), + ])); } } @@ -201,25 +192,22 @@ public function addRole($role, $names) * @validate-entity-load user_role role * @param string $role The name of the role to add * @param string $names A comma delimited list of user names. + * @option $uid A comma delimited list of user ids to lookup (an alternative to names). + * @option $mail A comma delimited list of emails to lookup (an alternative to names). * @aliases urrol,user-remove-role * @usage drush user:remove-role "power user" user3 * Remove the "power user" role from user3 */ - public function removeRole($role, $names) + public function removeRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) { - if ($names = StringUtils::csvToArray($names)) { - foreach ($names as $name) { - if ($account = user_load_by_name($name)) { - $account->removeRole($role); - $account->save(); - $this->logger->success(dt('Removed !role role from !user', [ - '!role' => $role, - '!user' => $name, - ])); - } else { - $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name])); - } - } + $accounts = $this->getAccounts($names, $options); + foreach ($accounts as $id => $account) { + $account->removeRole($role); + $account->save(); + $this->logger->success(dt('Removed !role role from !user', [ + '!role' => $role, + '!user' => $account->getAccountName(), + ])); } } @@ -279,29 +267,26 @@ public function createValidate(CommandData $commandData) * * @param string $names A comma delimited list of user names. * @option delete-content Delete the user, and all content created by the user + * @option $uid A comma delimited list of user ids to lookup (an alternative to names). + * @option $mail A comma delimited list of emails to lookup (an alternative to names). * @aliases ucan,user-cancel * @usage drush user:cancel username * Cancel the user account with the name username and anonymize all content created by that user. * @usage drush user:cancel --delete-content username * Delete the user account with the name username and delete all content created by that user. */ - public function cancel($names, $options = ['delete-content' => false]) + public function cancel($names, $options = ['delete-content' => false, 'uid' => self::REQ, 'mail' => self::REQ]) { - if ($names = StringUtils::csvToArray($names)) { - foreach ($names as $name) { - if ($account = user_load_by_name($name)) { - if ($options['delete-content']) { - $this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getAccountName()])); - } - if ($this->io()->confirm('Cancel user account?: ')) { - $method = $options['delete-content'] ? 'user_cancel_delete' : 'user_cancel_block'; - user_cancel([], $account->id(), $method); - drush_backend_batch_process(); - // Drupal logs a message for us. - } - } else { - $this->logger()->warning(dt('Unable to load user: !user', ['!user' => $name])); - } + $accounts = $this->getAccounts($names, $options); + foreach ($accounts as $id => $account) { + if ($options['delete-content']) { + $this->logger()->warning(dt('All content created by !name will be deleted.', ['!name' => $account->getAccountName()])); + } + if ($this->io()->confirm('Cancel user account?: ')) { + $method = $options['delete-content'] ? 'user_cancel_delete' : 'user_cancel_block'; + user_cancel([], $account->id(), $method); + drush_backend_batch_process(); + // Drupal logs a message for us. } } } @@ -357,4 +342,51 @@ public function infoArray($account) 'uuid' => $account->uuid->value, ]; } + + /** + * Get accounts from name variables or uid & mail options. + * + * @param string $names + * @param array $options + * + * @return array + * A array of loaded accounts. + * @throws \Exception + */ + protected function getAccounts($names = '', $options = []) + { + $accounts = []; + if ($mails = StringUtils::csvToArray($options['mail'])) { + foreach ($mails as $mail) { + if ($account = user_load_by_mail($mail)) { + $accounts[$account->id()] = $account; + } else { + $this->logger->warning(dt('Unable to load user: !mail', ['!mail' => $mail])); + } + } + } + if ($uids = StringUtils::csvToArray($options['uid'])) { + foreach ($uids as $uid) { + if ($account = User::load($uid)) { + $accounts[$account->id()] = $account; + } else { + $this->logger->warning(dt('Unable to load user: !uid', ['!uid' => $uid])); + } + } + } + if ($names = StringUtils::csvToArray($names)) { + foreach ($names as $name) { + if ($account = user_load_by_name($name)) { + $accounts[$account->id()] = $account; + } else { + $this->logger->warning(dt('Unable to load user: !user', ['!user' => $name])); + } + } + } + if (empty($accounts)) { + throw new \Exception(dt('Unable to find any matching user')); + } + + return $accounts; + } } diff --git a/tests/functional/UserTest.php b/tests/functional/UserTest.php index 988c3b7176..1e992dd37d 100644 --- a/tests/functional/UserTest.php +++ b/tests/functional/UserTest.php @@ -12,6 +12,7 @@ class UserCase extends CommandUnishTestCase { const NAME = 'example'; + const MAIL = 'example@example.com'; public function setup(): void { @@ -23,9 +24,10 @@ public function setup(): void public function testBlockUnblock() { + $uid = 2; + $this->drush('user-block', [self::NAME]); $this->drush('user-information', [self::NAME], ['format' => 'json']); - $uid = 2; $output = $this->getOutputFromJSON($uid); $this->assertEquals(0, $output['user_status'], 'User is blocked.'); @@ -34,15 +36,38 @@ public function testBlockUnblock() $this->drush('user-information', [self::NAME], ['format' => 'json']); $output = $this->getOutputFromJSON($uid); $this->assertEquals(1, $output['user_status'], 'User is unblocked.'); + + // user-block user by uid. + $this->drush('user-block', [], ['uid' => $uid]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $this->assertEquals(0, $output['user_status'], 'User (id) is blocked.'); + + $this->drush('user-unblock', [], ['uid' => $uid]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $this->assertEquals(1, $output['user_status'], 'User (id) is unblocked.'); + + + // user-block user by mail. + $this->drush('user-block', [], ['mail' => self::MAIL]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $this->assertEquals(0, $output['user_status'], 'User (mail) is blocked.'); + + $this->drush('user-unblock', [], ['uid' => $uid]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $this->assertEquals(1, $output['user_status'], 'User (mail) is unblocked.'); } public function testUserRole() { + $uid = 2; // First, create the role since we use testing install profile. $this->drush('role-create', ['test role']); $this->drush('user-add-role', ['test role', self::NAME]); $this->drush('user-information', [self::NAME], ['format' => 'json']); - $uid = 2; $output = $this->getOutputFromJSON($uid); $expected = ['authenticated', 'test role']; $this->assertEquals($expected, array_values($output['roles']), 'User has test role.'); @@ -53,6 +78,34 @@ public function testUserRole() $output = $this->getOutputFromJSON($uid); $expected = ['authenticated']; $this->assertEquals($expected, array_values($output['roles']), 'User removed test role.'); + + // user-add-role by uid. + $this->drush('user-add-role', ['test role'], ['uid' => $uid]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $expected = ['authenticated', 'test role']; + $this->assertEquals($expected, array_values($output['roles']), 'User (id) has test role.'); + + // user-remove-role by uid + $this->drush('user-remove-role', ['test role'], ['uid' => $uid]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $expected = ['authenticated']; + $this->assertEquals($expected, array_values($output['roles']), 'User (id) removed test role.'); + + // user-add-role by mail. + $this->drush('user-add-role', ['test role'], ['mail' => self::MAIL]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $expected = ['authenticated', 'test role']; + $this->assertEquals($expected, array_values($output['roles']), 'User (mail) has test role.'); + + // user-remove-role by mail. + $this->drush('user-remove-role', ['test role'], ['mail' => self::MAIL]); + $this->drush('user-information', [self::NAME], ['format' => 'json']); + $output = $this->getOutputFromJSON($uid); + $expected = ['authenticated']; + $this->assertEquals($expected, array_values($output['roles']), 'User (mail) removed test role.'); } public function testUserPassword() @@ -106,7 +159,7 @@ public function testUserLogin() $this->assertStringContainsString('/user/reset/' . $uid, $url['path'], 'Login with uid option returned a valid reset URL'); // Test specific user by mail. $uid = 2; - $mail = 'example@example.com'; + $mail = self::MAIL; $this->drush('user-login', [], $user_login_options + ['mail' => $mail]); $output = $this->getOutput(); $url = parse_url($output); @@ -138,11 +191,11 @@ public function testUserCancel() public function userCreate() { - $this->drush('user-create', [self::NAME], ['password' => 'password', 'mail' => "example@example.com"]); + $this->drush('user-create', [self::NAME], ['password' => 'password', 'mail' => self::MAIL]); $this->drush('user-information', [self::NAME], ['format' => 'json']); $uid = 2; $output = $this->getOutputFromJSON($uid); - $this->assertEquals('example@example.com', $output['mail']); + $this->assertEquals(self::MAIL, $output['mail']); $this->assertEquals(self::NAME, $output['name']); $this->assertEquals(1, $output['user_status'], 'Newly created user is Active.'); $expected = ['authenticated']; From 66e74947cbb4762500e3ab60e3cc19a39ba42829 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 15 Dec 2021 12:49:48 -0500 Subject: [PATCH 005/125] Fix capitalization --- src/Drupal/Commands/core/UserCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/core/UserCommands.php b/src/Drupal/Commands/core/UserCommands.php index ac8fda4b15..4bcd0c07cc 100644 --- a/src/Drupal/Commands/core/UserCommands.php +++ b/src/Drupal/Commands/core/UserCommands.php @@ -136,7 +136,7 @@ public function block($names = '', $options = ['uid' => self::REQ, 'mail' => sel } /** - * UnBlock the specified user(s). + * Unblock the specified user(s). * * @command user:unblock * From cc23dbe43aab8c034528c84124bd181bc5c3e5de Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Thu, 16 Dec 2021 13:57:21 +0100 Subject: [PATCH 006/125] Add field:delete command (#4926) * Add field:delete command * Add validation for the field-name option * Validate whether field-name option is a valid field * Add tests. * Make entity type argument optional * Update tests and fix PHPCS Co-authored-by: Moshe Weitzman --- ...Trait.php => EntityTypeBundleAskTrait.php} | 20 ++- ...hp => EntityTypeBundleValidationTrait.php} | 2 +- .../Commands/core/FieldCreateCommands.php | 78 +-------- .../Commands/core/FieldDeleteCommands.php | 160 ++++++++++++++++++ .../Commands/core/FieldInfoCommands.php | 7 +- src/Drupal/Commands/core/drush.services.yml | 7 + tests/functional/FieldCreateTest.php | 20 ++- 7 files changed, 213 insertions(+), 81 deletions(-) rename src/Drupal/Commands/core/{AskBundleTrait.php => EntityTypeBundleAskTrait.php} (68%) rename src/Drupal/Commands/core/{ValidateEntityTypeTrait.php => EntityTypeBundleValidationTrait.php} (97%) create mode 100644 src/Drupal/Commands/core/FieldDeleteCommands.php diff --git a/src/Drupal/Commands/core/AskBundleTrait.php b/src/Drupal/Commands/core/EntityTypeBundleAskTrait.php similarity index 68% rename from src/Drupal/Commands/core/AskBundleTrait.php rename to src/Drupal/Commands/core/EntityTypeBundleAskTrait.php index 1e692474fd..3a2700ada6 100644 --- a/src/Drupal/Commands/core/AskBundleTrait.php +++ b/src/Drupal/Commands/core/EntityTypeBundleAskTrait.php @@ -11,8 +11,26 @@ * @property EntityTypeBundleInfoInterface $entityTypeBundleInfo * @property EntityTypeManagerInterface $entityTypeManager */ -trait AskBundleTrait +trait EntityTypeBundleAskTrait { + protected function askEntityType(): ?string + { + $entityTypeDefinitions = $this->entityTypeManager->getDefinitions(); + $choices = []; + + foreach ($entityTypeDefinitions as $entityTypeDefinition) { + $choices[$entityTypeDefinition->id()] = $this->input->getOption('show-machine-names') + ? $entityTypeDefinition->id() + : $entityTypeDefinition->getLabel(); + } + + if (!$answer = $this->io()->choice('Entity type', $choices)) { + throw new \InvalidArgumentException(t('The entityType argument is required.')); + } + + return $answer; + } + protected function askBundle(): ?string { $entityTypeId = $this->input->getArgument('entityType'); diff --git a/src/Drupal/Commands/core/ValidateEntityTypeTrait.php b/src/Drupal/Commands/core/EntityTypeBundleValidationTrait.php similarity index 97% rename from src/Drupal/Commands/core/ValidateEntityTypeTrait.php rename to src/Drupal/Commands/core/EntityTypeBundleValidationTrait.php index 7c968efc30..d50c4b5b18 100644 --- a/src/Drupal/Commands/core/ValidateEntityTypeTrait.php +++ b/src/Drupal/Commands/core/EntityTypeBundleValidationTrait.php @@ -7,7 +7,7 @@ /** * @property EntityTypeManagerInterface $entityTypeManager */ -trait ValidateEntityTypeTrait +trait EntityTypeBundleValidationTrait { protected function validateEntityType(string $entityTypeId): void { diff --git a/src/Drupal/Commands/core/FieldCreateCommands.php b/src/Drupal/Commands/core/FieldCreateCommands.php index b9a441cd1c..38bad23c33 100644 --- a/src/Drupal/Commands/core/FieldCreateCommands.php +++ b/src/Drupal/Commands/core/FieldCreateCommands.php @@ -26,7 +26,9 @@ class FieldCreateCommands extends DrushCommands implements CustomEventAwareInterface { + use EntityTypeBundleAskTrait; use CustomEventAwareTrait; + use EntityTypeBundleValidationTrait; /** @var FieldTypePluginManagerInterface */ protected $fieldTypePluginManager; @@ -118,7 +120,7 @@ public function setContentTranslationManager(ContentTranslationManagerInterface * @see \Drupal\field_ui\Form\FieldConfigEditForm * @see \Drupal\field_ui\Form\FieldStorageConfigEditForm */ - public function create(string $entityType, ?string $bundle = null, array $options = [ + public function create(?string $entityType = null, ?string $bundle = null, array $options = [ 'field-name' => InputOption::VALUE_REQUIRED, 'field-label' => InputOption::VALUE_REQUIRED, 'field-description' => InputOption::VALUE_OPTIONAL, @@ -134,6 +136,7 @@ public function create(string $entityType, ?string $bundle = null, array $option 'existing' => false, ]): void { + $this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); $this->validateEntityType($entityType); $this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); @@ -216,41 +219,6 @@ public function create(string $entityType, ?string $bundle = null, array $option $this->logResult($field); } - protected function validateEntityType(string $entityTypeId): void - { - if (!$this->entityTypeManager->hasDefinition($entityTypeId)) { - throw new \InvalidArgumentException( - t("Entity type with id ':entityType' does not exist.", [':entityType' => $entityTypeId]) - ); - } - } - - protected function validateBundle(string $entityTypeId, string $bundle): void - { - if (!$entityTypeDefinition = $this->entityTypeManager->getDefinition($entityTypeId)) { - return; - } - - $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); - - if ($bundleEntityType === null && $bundle === $entityTypeId) { - return; - } - - $bundleDefinition = $this->entityTypeManager - ->getStorage($bundleEntityType) - ->load($bundle); - - if (!$bundleDefinition) { - throw new \InvalidArgumentException( - t("Bundle ':bundle' does not exist on entity type with id ':entityType'.", [ - ':bundle' => $bundle, - ':entityType' => $entityTypeId, - ]) - ); - } - } - protected function askExistingFieldName(): ?string { $entityType = $this->input->getArgument('entityType'); @@ -361,44 +329,6 @@ protected function askTranslatable(): bool return $this->io()->confirm('Translatable', false); } - protected function askBundle(): ?string - { - $entityTypeId = $this->input->getArgument('entityType'); - $entityTypeDefinition = $this->entityTypeManager->getDefinition($entityTypeId); - $bundleEntityType = $entityTypeDefinition->getBundleEntityType(); - $bundleInfo = $this->entityTypeBundleInfo->getBundleInfo($entityTypeId); - $choices = []; - - // If the entity type has one fixed bundle (eg. user), return it. - if ($bundleEntityType === null && count($bundleInfo) === 1) { - return key($bundleInfo); - } - - // If the entity type doesn't have bundles, return null - // TODO Find an example - if ($bundleEntityType === null && count($bundleInfo) === 0) { - return null; - } - - // If the entity type can have multiple bundles but it doesn't have any, throw an error - if ($bundleEntityType !== null && count($bundleInfo) === 0) { - throw new \InvalidArgumentException( - t("Entity type with id ':entityType' does not have any bundles.", [':entityType' => $entityTypeId]) - ); - } - - foreach ($bundleInfo as $bundle => $data) { - $label = $this->input->getOption('show-machine-names') ? $bundle : $data['label']; - $choices[$bundle] = $label; - } - - if (!$this->input->isInteractive() || !$answer = $this->io()->choice('Bundle', $choices)) { - throw new \InvalidArgumentException(t('The bundle argument is required.')); - } - - return $answer; - } - protected function askCardinality(): int { $fieldType = $this->input->getOption('field-type'); diff --git a/src/Drupal/Commands/core/FieldDeleteCommands.php b/src/Drupal/Commands/core/FieldDeleteCommands.php new file mode 100644 index 0000000000..888f74a82b --- /dev/null +++ b/src/Drupal/Commands/core/FieldDeleteCommands.php @@ -0,0 +1,160 @@ +entityTypeManager = $entityTypeManager; + $this->entityTypeBundleInfo = $entityTypeBundleInfo; + } + + /** + * Delete a field + * + * @command field:delete + * @aliases field-delete,fd + * + * @param string $entityType + * The machine name of the entity type + * @param string $bundle + * The machine name of the bundle + * + * @option field-name + * The machine name of the field + * + * @option show-machine-names + * Show machine names instead of labels in option lists. + * + * @usage drush field:delete + * Delete a field by answering the prompts. + * @usage drush field-delete taxonomy_term tag + * Delete a field and fill in the remaining information through prompts. + * @usage drush field-delete taxonomy_term tag --field-name=field_tag_label + * Delete a field in a non-interactive way. + * + * @version 11.0 + * @see \Drupal\field_ui\Form\FieldConfigDeleteForm + */ + public function delete(?string $entityType = null, ?string $bundle = null, array $options = [ + 'field-name' => InputOption::VALUE_REQUIRED, + 'show-machine-names' => InputOption::VALUE_OPTIONAL, + ]): void + { + $this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); + $this->validateEntityType($entityType); + + $this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); + $this->validateBundle($entityType, $bundle); + + $fieldName = $this->input->getOption('field-name') ?? $this->askExisting($entityType, $bundle); + $this->input->setOption('field-name', $fieldName); + + if ($fieldName === '') { + throw new \InvalidArgumentException(dt('The %optionName option is required.', [ + '%optionName' => 'field-name', + ])); + } + + /** @var FieldConfig[] $results */ + $results = $this->entityTypeManager + ->getStorage('field_config') + ->loadByProperties([ + 'field_name' => $fieldName, + 'entity_type' => $entityType, + 'bundle' => $bundle, + ]); + + if ($results === []) { + throw new \InvalidArgumentException( + t("Field with name ':fieldName' does not exist on bundle ':bundle'.", [ + ':fieldName' => $fieldName, + ':bundle' => $bundle, + ]) + ); + } + + $this->deleteFieldConfig(reset($results)); + + // Fields are purged on cron. However field module prevents disabling modules + // when field types they provided are used in a field until it is fully + // purged. In the case that a field has minimal or no content, a single call + // to field_purge_batch() will remove it from the system. Call this with a + // low batch limit to avoid administrators having to wait for cron runs when + // removing fields that meet this criteria. + field_purge_batch(10); + } + + protected function askExisting(string $entityType, string $bundle): string + { + $choices = []; + /** @var FieldConfigInterface[] $fieldConfigs */ + $fieldConfigs = $this->entityTypeManager + ->getStorage('field_config') + ->loadByProperties([ + 'entity_type' => $entityType, + 'bundle' => $bundle, + ]); + + foreach ($fieldConfigs as $fieldConfig) { + $label = $this->input->getOption('show-machine-names') + ? $fieldConfig->get('field_name') + : $fieldConfig->get('label'); + + $choices[$fieldConfig->get('field_name')] = $label; + } + + if ($choices === []) { + throw new \InvalidArgumentException( + t("Bundle ':bundle' has no fields.", [ + ':bundle' => $bundle, + ]) + ); + } + + return $this->io()->choice('Choose a field to delete', $choices); + } + + protected function deleteFieldConfig(FieldConfigInterface $fieldConfig): void + { + $fieldStorage = $fieldConfig->getFieldStorageDefinition(); + $bundles = $this->entityTypeBundleInfo->getBundleInfo($fieldConfig->getTargetEntityTypeId()); + $bundleLabel = $bundles[$fieldConfig->getTargetBundle()]['label']; + + if ($fieldStorage && !$fieldStorage->isLocked()) { + $fieldConfig->delete(); + + // If there is only one bundle left for this field storage, it will be + // deleted too, notify the user about dependencies. + if (count($fieldStorage->getBundles()) <= 1) { + $fieldStorage->delete(); + } + + $message = 'The field :field has been deleted from the :type bundle.'; + } else { + $message = 'There was a problem removing the :field from the :type content type.'; + } + + $this->logger()->success( + t($message, [':field' => $fieldConfig->label(), ':type' => $bundleLabel]) + ); + } +} diff --git a/src/Drupal/Commands/core/FieldInfoCommands.php b/src/Drupal/Commands/core/FieldInfoCommands.php index 8c962d23e0..5560ffcea7 100644 --- a/src/Drupal/Commands/core/FieldInfoCommands.php +++ b/src/Drupal/Commands/core/FieldInfoCommands.php @@ -10,9 +10,9 @@ class FieldInfoCommands extends DrushCommands { - use AskBundleTrait; + use EntityTypeBundleAskTrait; + use EntityTypeBundleValidationTrait; use FieldDefinitionRowsOfFieldsTrait; - use ValidateEntityTypeTrait; /** @var EntityTypeManagerInterface */ protected $entityTypeManager; @@ -66,10 +66,11 @@ public function __construct( * * @version 11.0 */ - public function info(string $entityType, ?string $bundle = null, array $options = [ + public function info(?string $entityType = null, ?string $bundle = null, array $options = [ 'format' => 'table', ]): RowsOfFields { + $this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); $this->validateEntityType($entityType); $this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index e975013360..2aaac6c711 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -42,6 +42,13 @@ services: - '@entity_type.bundle.info' tags: - { name: drush.command } + field.delete.commands: + class: \Drush\Drupal\Commands\core\FieldDeleteCommands + arguments: + - '@entity_type.manager' + - '@entity_type.bundle.info' + tags: + - { name: drush.command } link.hooks: class: \Drush\Drupal\Commands\core\LinkHooks arguments: diff --git a/tests/functional/FieldCreateTest.php b/tests/functional/FieldCreateTest.php index ca676305af..07e6af8975 100644 --- a/tests/functional/FieldCreateTest.php +++ b/tests/functional/FieldCreateTest.php @@ -27,11 +27,11 @@ public function testFieldCreate() { // Arguments. $this->drush('field:create', [], [], null, null, self::EXIT_ERROR); - $this->assertStringContainsString('Not enough arguments (missing: "entityType")', $this->getErrorOutputRaw()); + $this->assertStringContainsString('The entityType argument is required', $this->getErrorOutputRaw()); $this->drush('field:create', ['foo'], [], null, null, self::EXIT_ERROR); $this->assertStringContainsString('Entity type with id \'foo\' does not exist.', $this->getErrorOutputRaw()); $this->drush('field:create', ['user'], [], null, null, self::EXIT_ERROR); - $this->assertStringNotContainsString('The bundle argument is required.', $this->getErrorOutputRaw()); + $this->assertStringContainsString('The bundle argument is required.', $this->getErrorOutputRaw()); $this->drush('field:create', ['user', 'user'], [], null, null, self::EXIT_ERROR); $this->assertStringNotContainsString('bundle', $this->getErrorOutputRaw()); @@ -76,4 +76,20 @@ public function testFieldInfo() $this->assertFalse($json['translatable']); $this->assertArrayHasKey('beta', $json['target_bundles']); } + + public function testFieldDelete() + { + $this->drush('field:create', ['unish_article', 'alpha'], ['field-label' => 'Test', 'field-name' => 'field_test5', 'field-description' => 'baz', 'field-type' => 'entity_reference', 'is-required' => true, 'field-widget' => 'entity_reference_autocomplete', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'target-type' => 'unish_article', 'target-bundle' => 'beta']); + $this->assertStringContainsString("Successfully created field 'field_test5' on unish_article type with bundle 'alpha'", $this->getSimplifiedErrorOutput()); + + $this->drush('field:delete', ['unish_article'], [], null, null, self::EXIT_ERROR); + $this->assertStringContainsString('The bundle argument is required.', $this->getErrorOutputRaw()); + $this->drush('field:delete', ['unish_article', 'alpha'], [], null, null, self::EXIT_ERROR); + $this->assertStringContainsString('The field-name option is required.', $this->getErrorOutputRaw()); + + $this->drush('field:delete', ['unish_article', 'alpha'], ['field-name' => 'field_testZZZZZ'], null, null, self::EXIT_ERROR); + $this->assertStringContainsString("Field with name 'field_testZZZZZ' does not exist on bundle 'alpha'", $this->getErrorOutputRaw()); + $this->drush('field:delete', ['unish_article', 'alpha'], ['field-name' => 'field_test5']); + $this->assertStringContainsString(" The field Test has been deleted from the Alpha bundle.", $this->getErrorOutputRaw()); + } } From 5f44e6f4be5ccb79f78cfb82d6f3d9bdab39b884 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 16 Dec 2021 07:59:54 -0500 Subject: [PATCH 007/125] Rename test class. --- tests/functional/{FieldCreateTest.php => FieldTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/functional/{FieldCreateTest.php => FieldTest.php} (99%) diff --git a/tests/functional/FieldCreateTest.php b/tests/functional/FieldTest.php similarity index 99% rename from tests/functional/FieldCreateTest.php rename to tests/functional/FieldTest.php index 07e6af8975..3524ac3d35 100644 --- a/tests/functional/FieldCreateTest.php +++ b/tests/functional/FieldTest.php @@ -8,7 +8,7 @@ /** * @group commands */ -class FieldCreateTest extends CommandUnishTestCase +class FieldTest extends CommandUnishTestCase { public function setup(): void From 8730cdbad3e5be94dab99125976ed19db4245878 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Fri, 17 Dec 2021 21:10:34 +0100 Subject: [PATCH 008/125] Add field:base-info command (#4930) * Add base-field:info command * WIP tests. * Rename command to field:base-info + change class type hints to interfaces + fix renamed traits + make entityType argument optional * Add tests Co-authored-by: Moshe Weitzman --- .../Commands/core/FieldBaseInfoCommands.php | 82 +++++++++++++++++++ .../Commands/core/FieldInfoCommands.php | 7 +- src/Drupal/Commands/core/drush.services.yml | 8 ++ tests/functional/FieldTest.php | 8 ++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/Drupal/Commands/core/FieldBaseInfoCommands.php diff --git a/src/Drupal/Commands/core/FieldBaseInfoCommands.php b/src/Drupal/Commands/core/FieldBaseInfoCommands.php new file mode 100644 index 0000000000..19017008da --- /dev/null +++ b/src/Drupal/Commands/core/FieldBaseInfoCommands.php @@ -0,0 +1,82 @@ +entityTypeManager = $entityTypeManager; + $this->entityTypeBundleInfo = $entityTypeBundleInfo; + $this->entityFieldManager = $entityFieldManager; + } + + /** + * List all base fields of an entity type + * + * @command field:base-info + * @aliases field-base-info,fbi + * + * @param string $entityType + * The machine name of the entity type + * + * @option show-machine-names + * Show machine names instead of labels in option lists. + * + * @default-fields field_name,required,field_type,cardinality + * @field-labels + * label: Label + * description: Description + * field_name: Field name + * field_type: Field type + * required: Required + * translatable: Translatable + * cardinality: Cardinality + * default_value: Default value + * default_value_callback: Default value callback + * allowed_values: Allowed values + * allowed_values_function: Allowed values function + * handler: Selection handler + * target_bundles: Target bundles + * @filter-default-field field_name + * @table-style default + * + * @usage drush field:base-info taxonomy_term + * List all base fields. + * @usage drush field:base-info + * List all base fields and fill in the remaining information through prompts. + * + * @version 11.0 + */ + public function info(?string $entityType = null, array $options = [ + 'format' => 'table', + ]): RowsOfFields + { + $this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); + $this->validateEntityType($entityType); + + $fieldDefinitions = $this->entityFieldManager->getBaseFieldDefinitions($entityType); + + return $this->getRowsOfFieldsByFieldDefinitions($fieldDefinitions); + } +} diff --git a/src/Drupal/Commands/core/FieldInfoCommands.php b/src/Drupal/Commands/core/FieldInfoCommands.php index 5560ffcea7..68c6770b71 100644 --- a/src/Drupal/Commands/core/FieldInfoCommands.php +++ b/src/Drupal/Commands/core/FieldInfoCommands.php @@ -2,9 +2,8 @@ namespace Drush\Drupal\Commands\core; -use Consolidation\OutputFormatters\Options\FormatterOptions; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; -use Drupal\Core\Entity\EntityTypeBundleInfo; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drush\Commands\DrushCommands; @@ -16,12 +15,12 @@ class FieldInfoCommands extends DrushCommands /** @var EntityTypeManagerInterface */ protected $entityTypeManager; - /** @var EntityTypeBundleInfo */ + /** @var EntityTypeBundleInfoInterface */ protected $entityTypeBundleInfo; public function __construct( EntityTypeManagerInterface $entityTypeManager, - EntityTypeBundleInfo $entityTypeBundleInfo + EntityTypeBundleInfoInterface $entityTypeBundleInfo ) { $this->entityTypeManager = $entityTypeManager; $this->entityTypeBundleInfo = $entityTypeBundleInfo; diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index 2aaac6c711..a5d6faf5e9 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -49,6 +49,14 @@ services: - '@entity_type.bundle.info' tags: - { name: drush.command } + field.base-info.commands: + class: \Drush\Drupal\Commands\core\FieldBaseInfoCommands + arguments: + - '@entity_type.manager' + - '@entity_type.bundle.info' + - '@entity_field.manager' + tags: + - { name: drush.command } link.hooks: class: \Drush\Drupal\Commands\core\LinkHooks arguments: diff --git a/tests/functional/FieldTest.php b/tests/functional/FieldTest.php index 3524ac3d35..0a4d4488ea 100644 --- a/tests/functional/FieldTest.php +++ b/tests/functional/FieldTest.php @@ -92,4 +92,12 @@ public function testFieldDelete() $this->drush('field:delete', ['unish_article', 'alpha'], ['field-name' => 'field_test5']); $this->assertStringContainsString(" The field Test has been deleted from the Alpha bundle.", $this->getErrorOutputRaw()); } + + public function testFieldBaseInfo() + { + $this->drush('field:base-info', ['user'], ['format' => 'json', 'fields' => '*']); + $json = $this->getOutputFromJSON(); + $this->assertArrayHasKey('name', $json); + $this->assertSame('Name', $json['name']['label']); + } } From 39b5de32a5b549f616ecb80ff4ccda6edf05fe27 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sat, 18 Dec 2021 00:24:26 +0100 Subject: [PATCH 009/125] Add field:base-override-create command (#4929) * Add base-field-override:create command * Fix logging * Change command name * Change command name * Change class type hints to interfaces * Rename command class + fix renamed traits + make entityType argument optional * Fix "Call to a member function render() on string" * Add tests. * Use separate test methods. Co-authored-by: Moshe Weitzman --- .../core/FieldBaseOverrideCreateCommands.php | 193 ++++++++++++++++++ src/Drupal/Commands/core/drush.services.yml | 8 + tests/functional/FieldTest.php | 15 ++ 3 files changed, 216 insertions(+) create mode 100644 src/Drupal/Commands/core/FieldBaseOverrideCreateCommands.php diff --git a/src/Drupal/Commands/core/FieldBaseOverrideCreateCommands.php b/src/Drupal/Commands/core/FieldBaseOverrideCreateCommands.php new file mode 100644 index 0000000000..94630a03e5 --- /dev/null +++ b/src/Drupal/Commands/core/FieldBaseOverrideCreateCommands.php @@ -0,0 +1,193 @@ +entityTypeManager = $entityTypeManager; + $this->entityTypeBundleInfo = $entityTypeBundleInfo; + $this->entityFieldManager = $entityFieldManager; + } + + /** + * Create a new base field override + * + * @command field:base-override-create + * @aliases field-base-override-create,base-field-override-create,bfoc + * + * @param string $entityType + * The machine name of the entity type + * @param string $bundle + * The machine name of the bundle + * + * @option field-name + * A unique machine-readable name containing letters, numbers, and underscores. + * @option field-label + * The field label + * @option field-description + * The field description + * @option is-required + * Whether the field is required + * + * @option show-machine-names + * Show machine names instead of labels in option lists. + * + * @usage drush field:base-field-override-create + * Create a base field override by answering the prompts. + * @usage drush field:base-field-override-create taxonomy_term tag + * Create a base field override and fill in the remaining information through prompts. + * @usage drush field:base-field-override-create taxonomy_term tag --field-name=name --field-label=Label --is-required=1 + * Create a base field override in a completely non-interactive way. + * + * @see \Drupal\field_ui\Form\FieldConfigEditForm + * @see \Drupal\field_ui\Form\FieldStorageConfigEditForm + * + * @version 11.0 + */ + public function create(?string $entityType = null, ?string $bundle = null, array $options = [ + 'field-name' => InputOption::VALUE_REQUIRED, + 'field-label' => InputOption::VALUE_REQUIRED, + 'field-description' => InputOption::VALUE_REQUIRED, + 'is-required' => InputOption::VALUE_REQUIRED, + 'show-machine-names' => InputOption::VALUE_OPTIONAL, + ]): void + { + $this->input->setArgument('entityType', $entityType = $entityType ?? $this->askEntityType()); + $this->validateEntityType($entityType); + + $this->input->setArgument('bundle', $bundle = $bundle ?? $this->askBundle()); + $this->validateBundle($entityType, $bundle); + + $fieldName = $this->input->getOption('field-name') ?? $this->askFieldName($entityType); + $this->input->setOption('field-name', $fieldName); + + if ($fieldName === '') { + throw new \InvalidArgumentException(dt('The %optionName option is required.', [ + '%optionName' => 'field-name', + ])); + } + + /** @var BaseFieldOverride|BaseFieldDefinition $definition */ + $definition = BaseFieldOverride::loadByName($entityType, $bundle, $fieldName) + ?? $this->getBaseFieldDefinition($entityType, $fieldName); + + if ($definition === null) { + throw new \InvalidArgumentException( + t("Base field with name ':fieldName' does not exist on bundle ':bundle'.", [ + ':fieldName' => $fieldName, + ':bundle' => $bundle, + ]) + ); + } + + $this->input->setOption( + 'field-label', + $this->input->getOption('field-label') ?? $this->askFieldLabel((string) $definition->getLabel()) + ); + $this->input->setOption( + 'field-description', + $this->input->getOption('field-description') ?? $this->askFieldDescription($definition->getDescription()) + ); + $this->input->setOption( + 'is-required', + (bool) ($this->input->getOption('is-required') ?? $this->askRequired($definition->isRequired())) + ); + + $fieldName = $this->input->getOption('field-name'); + $fieldLabel = $this->input->getOption('field-label'); + $fieldDescription = $this->input->getOption('field-description'); + $isRequired = $this->input->getOption('is-required'); + + $baseFieldOverride = $this->createBaseFieldOverride($entityType, $bundle, $fieldName, $fieldLabel, $fieldDescription, $isRequired); + + $this->logResult($baseFieldOverride); + } + + protected function askFieldName(string $entityType): ?string + { + /** @var BaseFieldDefinition[] $definitions */ + $definitions = $this->entityFieldManager->getBaseFieldDefinitions($entityType); + $choices = []; + + foreach ($definitions as $definition) { + $label = $this->input->getOption('show-machine-names') ? $definition->getName() : (string) $definition->getLabel(); + $choices[$definition->getName()] = $label; + } + + return $this->io()->choice('Field name', $choices); + } + + protected function askFieldLabel(string $default): string + { + return $this->io()->ask('Field label', $default); + } + + protected function askFieldDescription(?string $default): ?string + { + return $this->io()->ask('Field description', $default); + } + + protected function askRequired(bool $default): bool + { + return $this->io()->askQuestion(new ConfirmationQuestion('Required', $default)); + } + + protected function createBaseFieldOverride(string $entityType, string $bundle, string $fieldName, $fieldLabel, $fieldDescription, bool $isRequired): BaseFieldOverride + { + $definition = $this->getBaseFieldDefinition($entityType, $fieldName); + $override = BaseFieldOverride::loadByName($entityType, $bundle, $fieldName) + ?? BaseFieldOverride::createFromBaseFieldDefinition($definition, $bundle); + + $override + ->setLabel($fieldLabel) + ->setDescription($fieldDescription) + ->setRequired($isRequired) + ->save(); + + return $override; + } + + protected function logResult(BaseFieldOverride $baseFieldOverride): void + { + $this->logger()->success( + sprintf( + 'Successfully created base field override \'%s\' on %s with bundle \'%s\'', + $baseFieldOverride->getName(), + $baseFieldOverride->getTargetEntityTypeId(), + $baseFieldOverride->getTargetBundle() + ) + ); + } + + protected function getBaseFieldDefinition(string $entityType, string $fieldName): ?BaseFieldDefinition + { + /** @var BaseFieldDefinition[] $definitions */ + $definitions = $this->entityFieldManager->getBaseFieldDefinitions($entityType); + + return $definitions[$fieldName] ?? null; + } +} diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index a5d6faf5e9..c51ef06999 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -49,6 +49,14 @@ services: - '@entity_type.bundle.info' tags: - { name: drush.command } + field.base-override-create.commands: + class: \Drush\Drupal\Commands\core\FieldBaseOverrideCreateCommands + arguments: + - '@entity_type.manager' + - '@entity_type.bundle.info' + - '@entity_field.manager' + tags: + - { name: drush.command } field.base-info.commands: class: \Drush\Drupal\Commands\core\FieldBaseInfoCommands arguments: diff --git a/tests/functional/FieldTest.php b/tests/functional/FieldTest.php index 0a4d4488ea..2c96b619df 100644 --- a/tests/functional/FieldTest.php +++ b/tests/functional/FieldTest.php @@ -100,4 +100,19 @@ public function testFieldBaseInfo() $this->assertArrayHasKey('name', $json); $this->assertSame('Name', $json['name']['label']); } + + public function testFieldBaseCreateOverride() + { + $options = [ + 'field-name' => 'name', + 'field-label' => 'Handle', + 'field-description' => 'The way this person wishes to called', + 'is-required' => true, + ]; + $this->drush('field:base-override-create', ['user', 'user'], $options); + $this->drush('config:get', ['core.base_field_override.user.user.name'], ['format' => 'json']); + $json = $this->getOutputFromJSON(); + $this->assertSame('Handle', $json['label']); + $this->assertSame(true, $json['required']); + } } From e484ee61a95e9fa085a785ab19ada9183cf26a45 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 18 Dec 2021 10:59:27 -0500 Subject: [PATCH 010/125] Fix #4933 and test failures on 'Highest'. Suppress --quiet during redispatches. (#4938) * Fix #4933 and test failures on 'Highest'. Suppress --quiet during redispatches. * Fix assertions * No longer need --quiet handling in updatedb * Fix test --- src/Commands/core/UpdateDBCommands.php | 3 --- src/Drush.php | 3 +++ tests/functional/SqlSyncTest.php | 23 ++++++----------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/Commands/core/UpdateDBCommands.php b/src/Commands/core/UpdateDBCommands.php index 1ab13535c6..0621570eff 100644 --- a/src/Commands/core/UpdateDBCommands.php +++ b/src/Commands/core/UpdateDBCommands.php @@ -66,9 +66,6 @@ public function updatedb($options = ['cache-clear' => true, 'entity-updates' => ]; $status_options = array_merge(Drush::redispatchOptions(), $status_options); - // Since output needs to be checked, this option must be removed - unset($status_options['quiet']); - $process = $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'updatedb:status', [], $status_options); $process->mustRun(); if ($output = $process->getOutput()) { diff --git a/src/Drush.php b/src/Drush.php index 1111169525..e3577ab6ba 100644 --- a/src/Drush.php +++ b/src/Drush.php @@ -454,6 +454,9 @@ public static function redispatchOptions($input = null) // Remove anything in $options that was not on the cli $options = array_intersect_key($options, array_flip($optionNamesFromCommandline)); + // Don't suppress output as it is usually needed in redispatches. See https://github.com/drush-ops/drush/issues/4805 and https://github.com/drush-ops/drush/issues/4933 + unset($options['quiet']); + // Add in the 'runtime.context' items, which includes --include, --alias-path et. al. return $options + array_filter(self::config()->get(PreflightArgs::DRUSH_RUNTIME_CONTEXT_NAMESPACE)); } diff --git a/tests/functional/SqlSyncTest.php b/tests/functional/SqlSyncTest.php index 3077d7fedf..c33c4afcdb 100644 --- a/tests/functional/SqlSyncTest.php +++ b/tests/functional/SqlSyncTest.php @@ -1,13 +1,4 @@ 'OMIT', 'simulate' => null, 'alias-path' => __DIR__ . '/resources/alias-fixtures', - // Ensure that shortcuts are normalized to long option names https://github.com/drush-ops/drush/pull/4515. - 'q' => null, - // This option is needed in order to "override" -q and get error output from Drush. + // @todo Ensure that shortcuts are normalized to long option names https://github.com/drush-ops/drush/pull/4515. 'verbose' => null, ]; @@ -54,21 +43,21 @@ public function testSimulatedSqlSync() // Test simulated simple rsync remote-to-local $this->drush('sql:sync', ['@synctest.remote', '@synctest.local'], $options, '@synctest.local'); $output = $this->getSimplifiedErrorOutput(); - $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-dump --quiet --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=remote --root=__DIR__/sut", $output); + $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-dump --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=remote --root=__DIR__/sut", $output); $this->assertStringContainsString("[notice] Simulating: __DIR__/drush core-rsync @synctest.remote:/simulated/path/to/dump.tgz @synctest.local:__SANDBOX__/tmp/dump.tgz --yes --uri=local --root=__DIR__/sut -- --remove-source-files", $output); - $this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-query --quiet --no-interaction --strict=0 --file=__SANDBOX__/tmp/dump.tgz --file-delete --uri=local --root=__DIR__/sut", $output); + $this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-query --no-interaction --strict=0 --file=__SANDBOX__/tmp/dump.tgz --file-delete --uri=local --root=__DIR__/sut", $output); // Test simulated simple sql:sync local-to-remote $this->drush('sql:sync', ['@synctest.local', '@synctest.remote'], $options, '@synctest.local'); $output = $this->getSimplifiedErrorOutput(); - $this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-dump --quiet --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=local --root=__DIR__/sut", $output); + $this->assertStringContainsString("[notice] Simulating: __DIR__/drush sql-dump --no-interaction --strict=0 --gzip --result-file=auto --format=json --uri=local --root=__DIR__/sut", $output); $this->assertStringContainsString("[notice] Simulating: __DIR__/drush core-rsync @synctest.local:/simulated/path/to/dump.tgz @synctest.remote:/tmp/dump.tgz --yes --uri=local --root=__DIR__/sut -- --remove-source-files", $output); - $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-query --quiet --no-interaction --strict=0 --file=/tmp/dump.tgz --file-delete --uri=remote --root=__DIR__/sut'", $output); + $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=whatever www-admin@server.isp.simulated '/path/to/drush sql-query --no-interaction --strict=0 --file=/tmp/dump.tgz --file-delete --uri=remote --root=__DIR__/sut'", $output); // Test simulated remote invoke with a remote runner. $this->drush('sql:sync', ['@synctest.remote', '@synctest.local'], $options, 'user@server/path/to/drupal#sitename'); $output = $this->getSimplifiedErrorOutput(); - $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=no user@server 'drush --no-interaction sql:sync @synctest.remote @synctest.local -q --uri=sitename --root=/path/to/drupal'", $output); + $this->assertStringContainsString("[notice] Simulating: ssh -o PasswordAuthentication=no user@server 'drush --no-interaction sql:sync @synctest.remote @synctest.local --uri=sitename --root=/path/to/drupal'", $output); } /** From 1db72f4b2b8e1ee75d72830960b11c5991a97a1d Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 18 Dec 2021 20:01:07 -0500 Subject: [PATCH 011/125] Remove fork of symfony/yaml (#4941) --- composer.json | 3 +- phpcs.xml | 1 - src/Config/Loader/YamlConfigLoader.php | 2 +- .../Util/InternalYamlDataFileLoader.php | 2 +- src/internal-forks/Config/Yaml/Escaper.php | 101 -- .../Yaml/Exception/ExceptionInterface.php | 21 - .../Config/Yaml/Exception/ParseException.php | 139 --- .../Yaml/Exception/RuntimeException.php | 21 - src/internal-forks/Config/Yaml/Inline.php | 831 ------------- src/internal-forks/Config/Yaml/LICENSE | 19 - src/internal-forks/Config/Yaml/Parser.php | 1089 ----------------- src/internal-forks/Config/Yaml/README.md | 20 - .../Config/Yaml/Tag/TaggedValue.php | 48 - src/internal-forks/Config/Yaml/Unescaper.php | 142 --- src/internal-forks/Config/Yaml/Yaml.php | 84 -- 15 files changed, 3 insertions(+), 2520 deletions(-) delete mode 100644 src/internal-forks/Config/Yaml/Escaper.php delete mode 100644 src/internal-forks/Config/Yaml/Exception/ExceptionInterface.php delete mode 100644 src/internal-forks/Config/Yaml/Exception/ParseException.php delete mode 100644 src/internal-forks/Config/Yaml/Exception/RuntimeException.php delete mode 100644 src/internal-forks/Config/Yaml/Inline.php delete mode 100644 src/internal-forks/Config/Yaml/LICENSE delete mode 100644 src/internal-forks/Config/Yaml/Parser.php delete mode 100644 src/internal-forks/Config/Yaml/README.md delete mode 100644 src/internal-forks/Config/Yaml/Tag/TaggedValue.php delete mode 100644 src/internal-forks/Config/Yaml/Unescaper.php delete mode 100644 src/internal-forks/Config/Yaml/Yaml.php diff --git a/composer.json b/composer.json index b3116b8fc8..b7dd8326c1 100644 --- a/composer.json +++ b/composer.json @@ -73,8 +73,7 @@ }, "autoload": { "psr-4": { - "Drush\\": "src/", - "Drush\\Internal\\": "src/internal-forks" + "Drush\\": "src/" } }, "autoload-dev": { diff --git a/phpcs.xml b/phpcs.xml index 88a82d9a6a..717fdb3136 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -4,7 +4,6 @@ src examples tests - src/internal-forks diff --git a/src/Config/Loader/YamlConfigLoader.php b/src/Config/Loader/YamlConfigLoader.php index 4a5d7bb2bb..f7b5c11cc9 100644 --- a/src/Config/Loader/YamlConfigLoader.php +++ b/src/Config/Loader/YamlConfigLoader.php @@ -2,7 +2,7 @@ namespace Drush\Config\Loader; -use Drush\Internal\Config\Yaml\Yaml; +use Symfony\Component\Yaml\Yaml; use Consolidation\Config\Loader\ConfigLoader; /** diff --git a/src/SiteAlias/Util/InternalYamlDataFileLoader.php b/src/SiteAlias/Util/InternalYamlDataFileLoader.php index be139be226..1b516825b7 100644 --- a/src/SiteAlias/Util/InternalYamlDataFileLoader.php +++ b/src/SiteAlias/Util/InternalYamlDataFileLoader.php @@ -1,7 +1,7 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml; - -/** - * Escaper encapsulates escaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - * - * @internal - */ -class Escaper -{ - // Characters that would cause a dumped string to require double quoting. - const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; - - // Mapping arrays for escaping a double quoted string. The backslash is - // first to ensure proper escaping because str_replace operates iteratively - // on the input arrays. This ordering of the characters avoids the use of strtr, - // which performs more slowly. - private static $escapees = array('\\', '\\\\', '\\"', '"', - "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", - "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", - "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", - "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", - "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", - ); - private static $escaped = array('\\\\', '\\"', '\\\\', '\\"', - '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', - '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', - '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', - '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', - '\\N', '\\_', '\\L', '\\P', - ); - - /** - * Determines if a PHP value would require double quoting in YAML. - * - * @param string $value A PHP value - * - * @return bool True if the value would require double quotes - */ - public static function requiresDoubleQuoting($value) - { - return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); - } - - /** - * Escapes and surrounds a PHP value with double quotes. - * - * @param string $value A PHP value - * - * @return string The quoted, escaped string - */ - public static function escapeWithDoubleQuotes($value) - { - return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value)); - } - - /** - * Determines if a PHP value would require single quoting in YAML. - * - * @param string $value A PHP value - * - * @return bool True if the value would require single quotes - */ - public static function requiresSingleQuoting($value) - { - // Determines if a PHP value is entirely composed of a value that would - // require single quoting in YAML. - if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) { - return true; - } - - // Determines if the PHP value contains any single characters that would - // cause it to require single quoting in YAML. - return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); - } - - /** - * Escapes and surrounds a PHP value with single quotes. - * - * @param string $value A PHP value - * - * @return string The quoted, escaped string - */ - public static function escapeWithSingleQuotes($value) - { - return sprintf("'%s'", str_replace('\'', '\'\'', $value)); - } -} diff --git a/src/internal-forks/Config/Yaml/Exception/ExceptionInterface.php b/src/internal-forks/Config/Yaml/Exception/ExceptionInterface.php deleted file mode 100644 index 266a2f6f1d..0000000000 --- a/src/internal-forks/Config/Yaml/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml\Exception; - -/** - * Exception interface for all exceptions thrown by the component. - * - * @author Fabien Potencier - */ -interface ExceptionInterface -{ -} diff --git a/src/internal-forks/Config/Yaml/Exception/ParseException.php b/src/internal-forks/Config/Yaml/Exception/ParseException.php deleted file mode 100644 index eca5a3265c..0000000000 --- a/src/internal-forks/Config/Yaml/Exception/ParseException.php +++ /dev/null @@ -1,139 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Fabien Potencier - */ -class ParseException extends RuntimeException -{ - private $parsedFile; - private $parsedLine; - private $snippet; - private $rawMessage; - - /** - * @param string $message The error message - * @param int $parsedLine The line where the error occurred - * @param string|null $snippet The snippet of code near the problem - * @param string|null $parsedFile The file name where the error occurred - * @param \Exception|null $previous The previous exception - */ - public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) - { - $this->parsedFile = $parsedFile; - $this->parsedLine = $parsedLine; - $this->snippet = $snippet; - $this->rawMessage = $message; - - $this->updateRepr(); - - parent::__construct($this->message, 0, $previous); - } - - /** - * Gets the snippet of code near the error. - * - * @return string The snippet of code - */ - public function getSnippet() - { - return $this->snippet; - } - - /** - * Sets the snippet of code near the error. - * - * @param string $snippet The code snippet - */ - public function setSnippet($snippet) - { - $this->snippet = $snippet; - - $this->updateRepr(); - } - - /** - * Gets the filename where the error occurred. - * - * This method returns null if a string is parsed. - * - * @return string The filename - */ - public function getParsedFile() - { - return $this->parsedFile; - } - - /** - * Sets the filename where the error occurred. - * - * @param string $parsedFile The filename - */ - public function setParsedFile($parsedFile) - { - $this->parsedFile = $parsedFile; - - $this->updateRepr(); - } - - /** - * Gets the line where the error occurred. - * - * @return int The file line - */ - public function getParsedLine() - { - return $this->parsedLine; - } - - /** - * Sets the line where the error occurred. - * - * @param int $parsedLine The file line - */ - public function setParsedLine($parsedLine) - { - $this->parsedLine = $parsedLine; - - $this->updateRepr(); - } - - private function updateRepr() - { - $this->message = $this->rawMessage; - - $dot = false; - if ('.' === substr($this->message, -1)) { - $this->message = substr($this->message, 0, -1); - $dot = true; - } - - if (null !== $this->parsedFile) { - $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); - } - - if ($this->parsedLine >= 0) { - $this->message .= sprintf(' at line %d', $this->parsedLine); - } - - if ($this->snippet) { - $this->message .= sprintf(' (near "%s")', $this->snippet); - } - - if ($dot) { - $this->message .= '.'; - } - } -} diff --git a/src/internal-forks/Config/Yaml/Exception/RuntimeException.php b/src/internal-forks/Config/Yaml/Exception/RuntimeException.php deleted file mode 100644 index 37f65205e5..0000000000 --- a/src/internal-forks/Config/Yaml/Exception/RuntimeException.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml\Exception; - -/** - * Exception class thrown when an error occurs during parsing. - * - * @author Romain Neutron - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/src/internal-forks/Config/Yaml/Inline.php b/src/internal-forks/Config/Yaml/Inline.php deleted file mode 100644 index 4e537d9eb9..0000000000 --- a/src/internal-forks/Config/Yaml/Inline.php +++ /dev/null @@ -1,831 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml; - -use Drush\Internal\Config\Yaml\Exception\ParseException; -use Drush\Internal\Config\Yaml\Exception\DumpException; -use Drush\Internal\Config\Yaml\Tag\TaggedValue; - -/** - * Inline implements a YAML parser/dumper for the YAML inline syntax. - * - * @author Fabien Potencier - * - * @internal - */ -class Inline -{ - const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; - - public static $parsedLineNumber; - - private static $exceptionOnInvalidType = false; - private static $objectSupport = false; - private static $objectForMap = false; - private static $constantSupport = false; - - /** - * Converts a YAML string to a PHP value. - * - * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * @param array $references Mapping of variable names to values - * - * @return mixed A PHP value - * - * @throws ParseException - */ - public static function parse($value, $flags = 0, $references = array()) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3 && !is_array($references)) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if ($references) { - $flags |= Yaml::PARSE_OBJECT; - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= Yaml::PARSE_OBJECT_FOR_MAP; - } - } - - if (func_num_args() >= 5) { - $references = func_get_arg(4); - } else { - $references = array(); - } - } - - self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); - self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); - self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); - self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); - - if (is_null($value) || '' === trim($value)) { - return ''; - } - - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('ASCII'); - } - - $i = 0; - $tag = self::parseTag($value, $i, $flags); - switch ($value[$i]) { - case '[': - $result = self::parseSequence($value, $flags, $i, $references); - ++$i; - break; - case '{': - $result = self::parseMapping($value, $flags, $i, $references); - ++$i; - break; - default: - $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); - } - - if (null !== $tag) { - return new TaggedValue($tag, $result); - } - - // some comments are allowed at the end - if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - return $result; - } - - /** - * Dumps a given PHP variable to a YAML string. - * - * @param mixed $value The PHP variable to convert - * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string - * - * @return string The YAML string representing the PHP value - * - * @throws DumpException When trying to dump PHP resource - */ - public static function dump($value, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= Yaml::DUMP_OBJECT; - } - } - - switch (true) { - case is_resource($value): - if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { - throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); - } - - return 'null'; - case $value instanceof \DateTimeInterface: - return $value->format('c'); - case is_object($value): - if ($value instanceof TaggedValue) { - return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags); - } - - if (Yaml::DUMP_OBJECT & $flags) { - return '!php/object:'.serialize($value); - } - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { - return self::dumpArray($value, $flags & ~Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE); - } - - if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { - throw new DumpException('Object support when dumping a YAML file has been disabled.'); - } - - return 'null'; - case is_array($value): - return self::dumpArray($value, $flags); - case null === $value: - return 'null'; - case true === $value: - return 'true'; - case false === $value: - return 'false'; - case ctype_digit($value): - return is_string($value) ? "'$value'" : (int) $value; - case is_numeric($value): - $locale = setlocale(LC_NUMERIC, 0); - if (false !== $locale) { - setlocale(LC_NUMERIC, 'C'); - } - if (is_float($value)) { - $repr = (string) $value; - if (is_infinite($value)) { - $repr = str_ireplace('INF', '.Inf', $repr); - } elseif (floor($value) == $value && $repr == $value) { - // Preserve float data type since storing a whole number will result in integer value. - $repr = '!!float '.$repr; - } - } else { - $repr = is_string($value) ? "'$value'" : (string) $value; - } - if (false !== $locale) { - setlocale(LC_NUMERIC, $locale); - } - - return $repr; - case '' == $value: - return "''"; - case self::isBinaryString($value): - return '!!binary '.base64_encode($value); - case Escaper::requiresDoubleQuoting($value): - return Escaper::escapeWithDoubleQuotes($value); - case Escaper::requiresSingleQuoting($value): - case Parser::pregMatch('{^[0-9]+[_0-9]*$}', $value): - case Parser::pregMatch(self::getHexRegex(), $value): - case Parser::pregMatch(self::getTimestampRegex(), $value): - return Escaper::escapeWithSingleQuotes($value); - default: - return $value; - } - } - - /** - * Check if given array is hash or just normal indexed array. - * - * @internal - * - * @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check - * - * @return bool true if value is hash array, false otherwise - */ - public static function isHash($value) - { - if ($value instanceof \stdClass || $value instanceof \ArrayObject) { - return true; - } - - $expectedKey = 0; - - foreach ($value as $key => $val) { - if ($key !== $expectedKey++) { - return true; - } - } - - return false; - } - - /** - * Dumps a PHP array to a YAML string. - * - * @param array $value The PHP array to dump - * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string - * - * @return string The YAML string representing the PHP array - */ - private static function dumpArray($value, $flags) - { - // array - if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) { - $output = array(); - foreach ($value as $val) { - $output[] = self::dump($val, $flags); - } - - return sprintf('[%s]', implode(', ', $output)); - } - - // hash - $output = array(); - foreach ($value as $key => $val) { - $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags)); - } - - return sprintf('{ %s }', implode(', ', $output)); - } - - /** - * Parses a YAML scalar. - * - * @param string $scalar - * @param int $flags - * @param string[] $delimiters - * @param int &$i - * @param bool $evaluate - * @param array $references - * - * @return string - * - * @throws ParseException When malformed inline YAML string is parsed - * - * @internal - */ - public static function parseScalar($scalar, $flags = 0, $delimiters = null, &$i = 0, $evaluate = true, $references = array(), $legacyOmittedKeySupport = false) - { - if (in_array($scalar[$i], array('"', "'"))) { - // quoted scalar - $output = self::parseQuotedScalar($scalar, $i); - - if (null !== $delimiters) { - $tmp = ltrim(substr($scalar, $i), ' '); - if (!in_array($tmp[0], $delimiters)) { - throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); - } - } - } else { - // "normal" string - if (!$delimiters) { - $output = substr($scalar, $i); - $i += strlen($output); - - // remove comments - if (Parser::pregMatch('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) { - $output = substr($output, 0, $match[0][1]); - } - } elseif (Parser::pregMatch('/^(.'.($legacyOmittedKeySupport ? '+' : '*').'?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { - $output = $match[1]; - $i += strlen($output); - } else { - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar)); - } - - // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >) - if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) { - throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); - } - - if ($output && '%' === $output[0]) { - @trigger_error(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0 on line %d.', $output, self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - - if ($evaluate) { - $output = self::evaluateScalar($output, $flags, $references); - } - } - - return $output; - } - - /** - * Parses a YAML quoted scalar. - * - * @param string $scalar - * @param int &$i - * - * @return string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseQuotedScalar($scalar, &$i) - { - if (!Parser::pregMatch('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { - throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i))); - } - - $output = substr($match[0], 1, strlen($match[0]) - 2); - - $unescaper = new Unescaper(); - if ('"' == $scalar[$i]) { - $output = $unescaper->unescapeDoubleQuotedString($output); - } else { - $output = $unescaper->unescapeSingleQuotedString($output); - } - - $i += strlen($match[0]); - - return $output; - } - - /** - * Parses a YAML sequence. - * - * @param string $sequence - * @param int $flags - * @param int &$i - * @param array $references - * - * @return array - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseSequence($sequence, $flags, &$i = 0, $references = array()) - { - $output = array(); - $len = strlen($sequence); - ++$i; - - // [foo, bar, ...] - while ($i < $len) { - if (']' === $sequence[$i]) { - return $output; - } - if (',' === $sequence[$i] || ' ' === $sequence[$i]) { - ++$i; - - continue; - } - - $tag = self::parseTag($sequence, $i, $flags); - switch ($sequence[$i]) { - case '[': - // nested sequence - $value = self::parseSequence($sequence, $flags, $i, $references); - break; - case '{': - // nested mapping - $value = self::parseMapping($sequence, $flags, $i, $references); - break; - default: - $isQuoted = in_array($sequence[$i], array('"', "'")); - $value = self::parseScalar($sequence, $flags, array(',', ']'), $i, null === $tag, $references); - - // the value can be an array if a reference has been resolved to an array var - if (is_string($value) && !$isQuoted && false !== strpos($value, ': ')) { - // embedded mapping? - try { - $pos = 0; - $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references); - } catch (\InvalidArgumentException $e) { - // no, it's not - } - } - - --$i; - } - - if (null !== $tag) { - $value = new TaggedValue($tag, $value); - } - - $output[] = $value; - - ++$i; - } - - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence)); - } - - /** - * Parses a YAML mapping. - * - * @param string $mapping - * @param int $flags - * @param int &$i - * @param array $references - * - * @return array|\stdClass - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseMapping($mapping, $flags, &$i = 0, $references = array()) - { - $output = array(); - $len = strlen($mapping); - ++$i; - $allowOverwrite = false; - - // {foo: bar, bar:foo, ...} - while ($i < $len) { - switch ($mapping[$i]) { - case ' ': - case ',': - ++$i; - continue 2; - case '}': - if (self::$objectForMap) { - return (object) $output; - } - - return $output; - } - - // key - $isKeyQuoted = in_array($mapping[$i], array('"', "'"), true); - $key = self::parseScalar($mapping, $flags, array(':', ' '), $i, false, array(), true); - - if (':' !== $key && false === $i = strpos($mapping, ':', $i)) { - break; - } - - if (':' === $key) { - @trigger_error(sprintf('Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0 on line %d.', self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - - if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags)) { - $evaluatedKey = self::evaluateScalar($key, $flags, $references); - - if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey) && !is_int($evaluatedKey)) { - @trigger_error(sprintf('Implicit casting of incompatible mapping keys to strings is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line %d.', self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - } - - if (':' !== $key && !$isKeyQuoted && (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) { - @trigger_error(sprintf('Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since version 3.2 and will throw a ParseException in 4.0 on line %d.', self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - - if ('<<' === $key) { - $allowOverwrite = true; - } - - while ($i < $len) { - if (':' === $mapping[$i] || ' ' === $mapping[$i]) { - ++$i; - - continue; - } - - $tag = self::parseTag($mapping, $i, $flags); - switch ($mapping[$i]) { - case '[': - // nested sequence - $value = self::parseSequence($mapping, $flags, $i, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - foreach ($value as $parsedValue) { - $output += $parsedValue; - } - } elseif ($allowOverwrite || !isset($output[$key])) { - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - break; - case '{': - // nested mapping - $value = self::parseMapping($mapping, $flags, $i, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - $output += $value; - } elseif ($allowOverwrite || !isset($output[$key])) { - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - break; - default: - $value = self::parseScalar($mapping, $flags, array(',', '}'), $i, null === $tag, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - // But overwriting is allowed when a merge node is used in current block. - if ('<<' === $key) { - $output += $value; - } elseif ($allowOverwrite || !isset($output[$key])) { - if (null !== $tag) { - $output[$key] = new TaggedValue($tag, $value); - } else { - $output[$key] = $value; - } - } elseif (isset($output[$key])) { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - --$i; - } - ++$i; - - continue 2; - } - } - - throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping)); - } - - /** - * Evaluates scalars and replaces magic values. - * - * @param string $scalar - * @param int $flags - * @param array $references - * - * @return mixed The evaluated YAML string - * - * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved - */ - private static function evaluateScalar($scalar, $flags, $references = array()) - { - $scalar = trim($scalar); - $scalarLower = strtolower($scalar); - - if (0 === strpos($scalar, '*')) { - if (false !== $pos = strpos($scalar, '#')) { - $value = substr($scalar, 1, $pos - 2); - } else { - $value = substr($scalar, 1); - } - - // an unquoted * - if (false === $value || '' === $value) { - throw new ParseException('A reference must contain at least one character.'); - } - - if (!array_key_exists($value, $references)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value)); - } - - return $references[$value]; - } - - switch (true) { - case 'null' === $scalarLower: - case '' === $scalar: - case '~' === $scalar: - return; - case 'true' === $scalarLower: - return true; - case 'false' === $scalarLower: - return false; - case '!' === $scalar[0]: - switch (true) { - case 0 === strpos($scalar, '!str'): - return (string) substr($scalar, 5); - case 0 === strpos($scalar, '! '): - return (int) self::parseScalar(substr($scalar, 2), $flags); - case 0 === strpos($scalar, '!php/object:'): - if (self::$objectSupport) { - return unserialize(substr($scalar, 12)); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); - } - - return; - case 0 === strpos($scalar, '!!php/object:'): - if (self::$objectSupport) { - @trigger_error(sprintf('The !!php/object tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object tag instead on line %d.', self::$parsedLineNumber + 1), E_USER_DEPRECATED); - - return unserialize(substr($scalar, 13)); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); - } - - return; - case 0 === strpos($scalar, '!php/const:'): - if (self::$constantSupport) { - if (defined($const = substr($scalar, 11))) { - return constant($const); - } - - throw new ParseException(sprintf('The constant "%s" is not defined.', $const)); - } - if (self::$exceptionOnInvalidType) { - throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar)); - } - - return; - case 0 === strpos($scalar, '!!float '): - return (float) substr($scalar, 8); - case 0 === strpos($scalar, '!!binary '): - return self::evaluateBinaryScalar(substr($scalar, 9)); - default: - @trigger_error(sprintf('Using the unquoted scalar value "%s" is deprecated since version 3.3 and will be considered as a tagged value in 4.0. You must quote it on line %d.', $scalar, self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - - // Optimize for returning strings. - // no break - case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]): - switch (true) { - case Parser::pregMatch('{^[+-]?[0-9][0-9_]*$}', $scalar): - $scalar = str_replace('_', '', (string) $scalar); - // omitting the break / return as integers are handled in the next case - // no break - case ctype_digit($scalar): - $raw = $scalar; - $cast = (int) $scalar; - - return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw); - case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): - $raw = $scalar; - $cast = (int) $scalar; - - return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw); - case is_numeric($scalar): - case Parser::pregMatch(self::getHexRegex(), $scalar): - $scalar = str_replace('_', '', $scalar); - - return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; - case '.inf' === $scalarLower: - case '.nan' === $scalarLower: - return -log(0); - case '-.inf' === $scalarLower: - return log(0); - case Parser::pregMatch('/^(-|\+)?[0-9][0-9,]*(\.[0-9_]+)?$/', $scalar): - case Parser::pregMatch('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): - if (false !== strpos($scalar, ',')) { - @trigger_error(sprintf('Using the comma as a group separator for floats is deprecated since version 3.2 and will be removed in 4.0 on line %d.', self::$parsedLineNumber + 1), E_USER_DEPRECATED); - } - - return (float) str_replace(array(',', '_'), '', $scalar); - case Parser::pregMatch(self::getTimestampRegex(), $scalar): - if (Yaml::PARSE_DATETIME & $flags) { - // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. - return new \DateTime($scalar, new \DateTimeZone('UTC')); - } - - $timeZone = date_default_timezone_get(); - date_default_timezone_set('UTC'); - $time = strtotime($scalar); - date_default_timezone_set($timeZone); - - return $time; - } - } - - return (string) $scalar; - } - - /** - * @param string $value - * @param int &$i - * @param int $flags - * - * @return null|string - */ - private static function parseTag($value, &$i, $flags) - { - if ('!' !== $value[$i]) { - return; - } - - $tagLength = strcspn($value, " \t\n", $i + 1); - $tag = substr($value, $i + 1, $tagLength); - - $nextOffset = $i + $tagLength + 1; - $nextOffset += strspn($value, ' ', $nextOffset); - - // Is followed by a scalar - if (!isset($value[$nextOffset]) || !in_array($value[$nextOffset], array('[', '{'), true)) { - // Manage scalars in {@link self::evaluateScalar()} - return; - } - - // Built-in tags - if ($tag && '!' === $tag[0]) { - throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag)); - } - - if (Yaml::PARSE_CUSTOM_TAGS & $flags) { - $i = $nextOffset; - - return $tag; - } - - throw new ParseException(sprintf('Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!%s".', $tag)); - } - - /** - * @param string $scalar - * - * @return string - * - * @internal - */ - public static function evaluateBinaryScalar($scalar) - { - $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar)); - - if (0 !== (strlen($parsedBinaryData) % 4)) { - throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', strlen($parsedBinaryData))); - } - - if (!Parser::pregMatch('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { - throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData)); - } - - return base64_decode($parsedBinaryData, true); - } - - private static function isBinaryString($value) - { - return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value); - } - - /** - * Gets a regex that matches a YAML date. - * - * @return string The regular expression - * - * @see http://www.yaml.org/spec/1.2/spec.html#id2761573 - */ - private static function getTimestampRegex() - { - return <<[0-9][0-9][0-9][0-9]) - -(?P[0-9][0-9]?) - -(?P[0-9][0-9]?) - (?:(?:[Tt]|[ \t]+) - (?P[0-9][0-9]?) - :(?P[0-9][0-9]) - :(?P[0-9][0-9]) - (?:\.(?P[0-9]*))? - (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) - (?::(?P[0-9][0-9]))?))?)? - $~x -EOF; - } - - /** - * Gets a regex that matches a YAML number in hexadecimal notation. - * - * @return string - */ - private static function getHexRegex() - { - return '~^0x[0-9a-f_]++$~i'; - } -} diff --git a/src/internal-forks/Config/Yaml/LICENSE b/src/internal-forks/Config/Yaml/LICENSE deleted file mode 100644 index 17d16a1336..0000000000 --- a/src/internal-forks/Config/Yaml/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-2017 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/internal-forks/Config/Yaml/Parser.php b/src/internal-forks/Config/Yaml/Parser.php deleted file mode 100644 index a3376decee..0000000000 --- a/src/internal-forks/Config/Yaml/Parser.php +++ /dev/null @@ -1,1089 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml; - -use Drush\Internal\Config\Yaml\Exception\ParseException; -use Drush\Internal\Config\Yaml\Tag\TaggedValue; - -/** - * Parser parses YAML strings to convert them to PHP arrays. - * - * @author Fabien Potencier - */ -class Parser -{ - const TAG_PATTERN = '(?P![\w!.\/:-]+)'; - const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; - - private $offset = 0; - private $totalNumberOfLines; - private $lines = array(); - private $currentLineNb = -1; - private $currentLine = ''; - private $refs = array(); - private $skippedLineNumbers = array(); - private $locallySkippedLineNumbers = array(); - - public function __construct() - { - if (func_num_args() > 0) { - @trigger_error(sprintf('The constructor arguments $offset, $totalNumberOfLines, $skippedLineNumbers of %s are deprecated and will be removed in 4.0', self::class), E_USER_DEPRECATED); - - $this->offset = func_get_arg(0); - if (func_num_args() > 1) { - $this->totalNumberOfLines = func_get_arg(1); - } - if (func_num_args() > 2) { - $this->skippedLineNumbers = func_get_arg(2); - } - } - } - - /** - * Parses a YAML string to a PHP value. - * - * @param string $value A YAML string - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed A PHP value - * - * @throws ParseException If the YAML is not valid - */ - public function parse($value, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= Yaml::PARSE_OBJECT; - } - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= Yaml::PARSE_OBJECT_FOR_MAP; - } - } - - if (false === preg_match('//u', $value)) { - throw new ParseException('The YAML value does not appear to be valid UTF-8.'); - } - - $this->refs = array(); - - $mbEncoding = null; - $e = null; - $data = null; - - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - - try { - $data = $this->doParse($value, $flags); - } catch (\Exception $e) { - } catch (\Throwable $e) { - } - - if (null !== $mbEncoding) { - mb_internal_encoding($mbEncoding); - } - - $this->lines = array(); - $this->currentLine = ''; - $this->refs = array(); - $this->skippedLineNumbers = array(); - $this->locallySkippedLineNumbers = array(); - - if (null !== $e) { - throw $e; - } - - return $data; - } - - private function doParse($value, $flags) - { - $this->currentLineNb = -1; - $this->currentLine = ''; - $value = $this->cleanup($value); - $this->lines = explode("\n", $value); - $this->locallySkippedLineNumbers = array(); - - if (null === $this->totalNumberOfLines) { - $this->totalNumberOfLines = count($this->lines); - } - - if (!$this->moveToNextLine()) { - return null; - } - - $data = array(); - $context = null; - $allowOverwrite = false; - - while ($this->isCurrentLineEmpty()) { - if (!$this->moveToNextLine()) { - return null; - } - } - - // Resolves the tag and returns if end of the document - if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) { - return new TaggedValue($tag, ''); - } - - do { - if ($this->isCurrentLineEmpty()) { - continue; - } - - // tab? - if ("\t" === $this->currentLine[0]) { - throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - $isRef = $mergeNode = false; - if (self::pregMatch('#^\-((?P\s+)(?P.+))?$#u', rtrim($this->currentLine), $values)) { - if ($context && 'mapping' == $context) { - throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - $context = 'sequence'; - - if (isset($values['value']) && self::pregMatch('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) { - @trigger_error(sprintf('Starting an unquoted string with a question mark followed by a space is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - - // array - if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags); - } elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) { - $data[] = new TaggedValue( - $subTag, - $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags) - ); - } else { - if (isset($values['leadspaces']) - && self::pregMatch('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $this->trimTag($values['value']), $matches) - ) { - // this is a compact notation element, add to next block and parse - $block = $values['value']; - if ($this->isNextLineIndented()) { - $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1); - } - - $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags); - } else { - $data[] = $this->parseValue($values['value'], $flags, $context); - } - } - if ($isRef) { - $this->refs[$isRef] = end($data); - } - } elseif (self::pregMatch('#^(?P'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P.+))?$#u', rtrim($this->currentLine), $values) - && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'"))) - ) { - if ($context && 'sequence' == $context) { - throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine); - } - $context = 'mapping'; - - // force correct settings - Inline::parse(null, $flags, $this->refs); - try { - Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); - $i = 0; - $evaluateKey = !(Yaml::PARSE_KEYS_AS_STRINGS & $flags); - - // constants in key will be evaluated anyway - if (isset($values['key'][0]) && '!' === $values['key'][0] && Yaml::PARSE_CONSTANT & $flags) { - $evaluateKey = true; - } - - $key = Inline::parseScalar($values['key'], 0, null, $i, $evaluateKey); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags) && !is_string($key) && !is_int($key)) { - $keyType = is_numeric($key) ? 'numeric key' : 'non-string key'; - @trigger_error(sprintf('Implicit casting of %s to string is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line %d.', $keyType, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - - // Convert float keys to strings, to avoid being converted to integers by PHP - if (is_float($key)) { - $key = (string) $key; - } - - if ('<<' === $key && (!isset($values['value']) || !self::pregMatch('#^&(?P[^ ]+)#u', $values['value'], $refMatches))) { - $mergeNode = true; - $allowOverwrite = true; - if (isset($values['value'][0]) && '*' === $values['value'][0]) { - $refName = substr(rtrim($values['value']), 1); - if (!array_key_exists($refName, $this->refs)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - $refValue = $this->refs[$refName]; - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) { - $refValue = (array) $refValue; - } - - if (!is_array($refValue)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - $data += $refValue; // array union - } else { - if (isset($values['value']) && '' !== $values['value']) { - $value = $values['value']; - } else { - $value = $this->getNextEmbedBlock(); - } - $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags); - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) { - $parsed = (array) $parsed; - } - - if (!is_array($parsed)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - if (isset($parsed[0])) { - // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes - // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier - // in the sequence override keys specified in later mapping nodes. - foreach ($parsed as $parsedItem) { - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) { - $parsedItem = (array) $parsedItem; - } - - if (!is_array($parsedItem)) { - throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem); - } - - $data += $parsedItem; // array union - } - } else { - // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the - // current mapping, unless the key already exists in it. - $data += $parsed; // array union - } - } - } elseif ('<<' !== $key && isset($values['value']) && self::pregMatch('#^&(?P[^ ]++) *+(?P.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - $subTag = null; - if ($mergeNode) { - // Merge keys - } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) { - // hash - // if next line is less indented or equal, then it means that the current value is null - if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !isset($data[$key])) { - if (null !== $subTag) { - $data[$key] = new TaggedValue($subTag, ''); - } else { - $data[$key] = null; - } - } else { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - } else { - // remember the parsed line number here in case we need it to provide some contexts in error messages below - $realCurrentLineNbKey = $this->getRealCurrentLineNb(); - $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); - if ('<<' === $key) { - $this->refs[$refMatches['ref']] = $value; - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) { - $value = (array) $value; - } - - $data += $value; - } elseif ($allowOverwrite || !isset($data[$key])) { - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if (null !== $subTag) { - $data[$key] = new TaggedValue($subTag, $value); - } else { - $data[$key] = $value; - } - } else { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, $realCurrentLineNbKey + 1), E_USER_DEPRECATED); - } - } - } else { - $value = $this->parseValue(rtrim($values['value']), $flags, $context); - // Spec: Keys MUST be unique; first one wins. - // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !isset($data[$key])) { - $data[$key] = $value; - } else { - @trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $key, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - } - if ($isRef) { - $this->refs[$isRef] = $data[$key]; - } - } else { - // multiple documents are not supported - if ('---' === $this->currentLine) { - throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine); - } - - if (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1]) { - @trigger_error(sprintf('Starting an unquoted string with a question mark followed by a space is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d.', $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - - // 1-liner optionally followed by newline(s) - if (is_string($value) && $this->lines[0] === trim($value)) { - try { - Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); - $value = Inline::parse($this->lines[0], $flags, $this->refs); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - return $value; - } - - // try to parse the value as a multi-line string as a last resort - if (0 === $this->currentLineNb) { - $parseError = false; - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - $value = ''; - - foreach ($this->lines as $line) { - try { - if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { - $parsedLine = $line; - } else { - $parsedLine = Inline::parse($line, $flags, $this->refs); - } - - if (!is_string($parsedLine)) { - $parseError = true; - break; - } - - if ('' === trim($parsedLine)) { - $value .= "\n"; - } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { - $value .= ' '; - } - - if ('' !== trim($parsedLine) && '\\' === substr($parsedLine, -1)) { - $value .= ltrim(substr($parsedLine, 0, -1)); - } elseif ('' !== trim($parsedLine)) { - $value .= trim($parsedLine); - } - - if ('' === trim($parsedLine)) { - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($parsedLine, -1)) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = true; - } else { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - } - } catch (ParseException $e) { - $parseError = true; - break; - } - } - - if (!$parseError) { - return Inline::parse(trim($value)); - } - } - - throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } while ($this->moveToNextLine()); - - if (null !== $tag) { - $data = new TaggedValue($tag, $data); - } - - if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !is_object($data) && 'mapping' === $context) { - $object = new \stdClass(); - - foreach ($data as $key => $value) { - $object->$key = $value; - } - - $data = $object; - } - - return empty($data) ? null : $data; - } - - private function parseBlock($offset, $yaml, $flags) - { - $skippedLineNumbers = $this->skippedLineNumbers; - - foreach ($this->locallySkippedLineNumbers as $lineNumber) { - if ($lineNumber < $offset) { - continue; - } - - $skippedLineNumbers[] = $lineNumber; - } - - $parser = new self(); - $parser->offset = $offset; - $parser->totalNumberOfLines = $this->totalNumberOfLines; - $parser->skippedLineNumbers = $skippedLineNumbers; - $parser->refs = &$this->refs; - - return $parser->doParse($yaml, $flags); - } - - /** - * Returns the current line number (takes the offset into account). - * - * @return int The current line number - */ - private function getRealCurrentLineNb() - { - $realCurrentLineNumber = $this->currentLineNb + $this->offset; - - foreach ($this->skippedLineNumbers as $skippedLineNumber) { - if ($skippedLineNumber > $realCurrentLineNumber) { - break; - } - - ++$realCurrentLineNumber; - } - - return $realCurrentLineNumber; - } - - /** - * Returns the current line indentation. - * - * @return int The current line indentation - */ - private function getCurrentLineIndentation() - { - return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' ')); - } - - /** - * Returns the next embed block of YAML. - * - * @param int $indentation The indent level at which the block is to be read, or null for default - * @param bool $inSequence True if the enclosing data structure is a sequence - * - * @return string A YAML string - * - * @throws ParseException When indentation problem are detected - */ - private function getNextEmbedBlock($indentation = null, $inSequence = false) - { - $oldLineIndentation = $this->getCurrentLineIndentation(); - $blockScalarIndentations = array(); - - if ($this->isBlockScalarHeader()) { - $blockScalarIndentations[] = $oldLineIndentation; - } - - if (!$this->moveToNextLine()) { - return; - } - - if (null === $indentation) { - $newIndent = $this->getCurrentLineIndentation(); - - $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); - - if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } else { - $newIndent = $indentation; - } - - $data = array(); - if ($this->getCurrentLineIndentation() >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } else { - $this->moveToPreviousLine(); - - return; - } - - if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) { - // the previous line contained a dash but no item content, this line is a sequence item with the same indentation - // and therefore no nested list or mapping - $this->moveToPreviousLine(); - - return; - } - - $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); - - if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) { - $blockScalarIndentations[] = $this->getCurrentLineIndentation(); - } - - $previousLineIndentation = $this->getCurrentLineIndentation(); - - while ($this->moveToNextLine()) { - $indent = $this->getCurrentLineIndentation(); - - // terminate all block scalars that are more indented than the current line - if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) { - foreach ($blockScalarIndentations as $key => $blockScalarIndentation) { - if ($blockScalarIndentation >= $indent) { - unset($blockScalarIndentations[$key]); - } - } - } - - if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) { - $blockScalarIndentations[] = $indent; - } - - $previousLineIndentation = $indent; - - if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { - $this->moveToPreviousLine(); - break; - } - - if ($this->isCurrentLineBlank()) { - $data[] = substr($this->currentLine, $newIndent); - continue; - } - - if ($indent >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } elseif ($this->isCurrentLineComment()) { - $data[] = $this->currentLine; - } elseif (0 == $indent) { - $this->moveToPreviousLine(); - - break; - } else { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } - - return implode("\n", $data); - } - - /** - * Moves the parser to the next line. - * - * @return bool - */ - private function moveToNextLine() - { - if ($this->currentLineNb >= count($this->lines) - 1) { - return false; - } - - $this->currentLine = $this->lines[++$this->currentLineNb]; - - return true; - } - - /** - * Moves the parser to the previous line. - * - * @return bool - */ - private function moveToPreviousLine() - { - if ($this->currentLineNb < 1) { - return false; - } - - $this->currentLine = $this->lines[--$this->currentLineNb]; - - return true; - } - - /** - * Parses a YAML value. - * - * @param string $value A YAML value - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * @param string $context The parser context (either sequence or mapping) - * - * @return mixed A PHP value - * - * @throws ParseException When reference does not exist - */ - private function parseValue($value, $flags, $context) - { - if (0 === strpos($value, '*')) { - if (false !== $pos = strpos($value, '#')) { - $value = substr($value, 1, $pos - 2); - } else { - $value = substr($value, 1); - } - - if (!array_key_exists($value, $this->refs)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine); - } - - return $this->refs[$value]; - } - - if (self::pregMatch('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { - $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - - $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers)); - - if ('' !== $matches['tag']) { - if ('!!binary' === $matches['tag']) { - return Inline::evaluateBinaryScalar($data); - } elseif ('!' !== $matches['tag']) { - @trigger_error(sprintf('Using the custom tag "%s" for the value "%s" is deprecated since version 3.3. It will be replaced by an instance of %s in 4.0 on line %d.', $matches['tag'], $data, TaggedValue::class, $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED); - } - } - - return $data; - } - - try { - $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null; - - // do not take following lines into account when the current line is a quoted single line value - if (null !== $quotation && self::pregMatch('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) { - return Inline::parse($value, $flags, $this->refs); - } - - $lines = array(); - - while ($this->moveToNextLine()) { - // unquoted strings end before the first unindented line - if (null === $quotation && 0 === $this->getCurrentLineIndentation()) { - $this->moveToPreviousLine(); - - break; - } - - $lines[] = trim($this->currentLine); - - // quoted string values end with a line that is terminated with the quotation character - if ('' !== $this->currentLine && substr($this->currentLine, -1) === $quotation) { - break; - } - } - - for ($i = 0, $linesCount = count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) { - if ('' === $lines[$i]) { - $value .= "\n"; - $previousLineBlank = true; - } elseif ($previousLineBlank) { - $value .= $lines[$i]; - $previousLineBlank = false; - } else { - $value .= ' '.$lines[$i]; - $previousLineBlank = false; - } - } - - Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); - $parsedValue = Inline::parse($value, $flags, $this->refs); - - if ('mapping' === $context && is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { - throw new ParseException('A colon cannot be used in an unquoted mapping value.'); - } - - return $parsedValue; - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - } - - /** - * Parses a block scalar. - * - * @param string $style The style indicator that was used to begin this block scalar (| or >) - * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -) - * @param int $indentation The indentation indicator that was used to begin this block scalar - * - * @return string The text value - */ - private function parseBlockScalar($style, $chomping = '', $indentation = 0) - { - $notEOF = $this->moveToNextLine(); - if (!$notEOF) { - return ''; - } - - $isCurrentLineBlank = $this->isCurrentLineBlank(); - $blockLines = array(); - - // leading blank lines are consumed before determining indentation - while ($notEOF && $isCurrentLineBlank) { - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $blockLines[] = ''; - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - - // determine indentation if not specified - if (0 === $indentation) { - if (self::pregMatch('/^ +/', $this->currentLine, $matches)) { - $indentation = strlen($matches[0]); - } - } - - if ($indentation > 0) { - $pattern = sprintf('/^ {%d}(.*)$/', $indentation); - - while ($notEOF && ( - $isCurrentLineBlank || - self::pregMatch($pattern, $this->currentLine, $matches) - ) - ) { - if ($isCurrentLineBlank && strlen($this->currentLine) > $indentation) { - $blockLines[] = substr($this->currentLine, $indentation); - } elseif ($isCurrentLineBlank) { - $blockLines[] = ''; - } else { - $blockLines[] = $matches[1]; - } - - // newline only if not EOF - if ($notEOF = $this->moveToNextLine()) { - $isCurrentLineBlank = $this->isCurrentLineBlank(); - } - } - } elseif ($notEOF) { - $blockLines[] = ''; - } - - if ($notEOF) { - $blockLines[] = ''; - $this->moveToPreviousLine(); - } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { - $blockLines[] = ''; - } - - // folded style - if ('>' === $style) { - $text = ''; - $previousLineIndented = false; - $previousLineBlank = false; - - for ($i = 0, $blockLinesCount = count($blockLines); $i < $blockLinesCount; ++$i) { - if ('' === $blockLines[$i]) { - $text .= "\n"; - $previousLineIndented = false; - $previousLineBlank = true; - } elseif (' ' === $blockLines[$i][0]) { - $text .= "\n".$blockLines[$i]; - $previousLineIndented = true; - $previousLineBlank = false; - } elseif ($previousLineIndented) { - $text .= "\n".$blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } elseif ($previousLineBlank || 0 === $i) { - $text .= $blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } else { - $text .= ' '.$blockLines[$i]; - $previousLineIndented = false; - $previousLineBlank = false; - } - } - } else { - $text = implode("\n", $blockLines); - } - - // deal with trailing newlines - if ('' === $chomping) { - $text = preg_replace('/\n+$/', "\n", $text); - } elseif ('-' === $chomping) { - $text = preg_replace('/\n+$/', '', $text); - } - - return $text; - } - - /** - * Returns true if the next line is indented. - * - * @return bool Returns true if the next line is indented, false otherwise - */ - private function isNextLineIndented() - { - $currentIndentation = $this->getCurrentLineIndentation(); - $EOF = !$this->moveToNextLine(); - - while (!$EOF && $this->isCurrentLineEmpty()) { - $EOF = !$this->moveToNextLine(); - } - - if ($EOF) { - return false; - } - - $ret = $this->getCurrentLineIndentation() > $currentIndentation; - - $this->moveToPreviousLine(); - - return $ret; - } - - /** - * Returns true if the current line is blank or if it is a comment line. - * - * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise - */ - private function isCurrentLineEmpty() - { - return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); - } - - /** - * Returns true if the current line is blank. - * - * @return bool Returns true if the current line is blank, false otherwise - */ - private function isCurrentLineBlank() - { - return '' == trim($this->currentLine, ' '); - } - - /** - * Returns true if the current line is a comment line. - * - * @return bool Returns true if the current line is a comment line, false otherwise - */ - private function isCurrentLineComment() - { - //checking explicitly the first char of the trim is faster than loops or strpos - $ltrimmedLine = ltrim($this->currentLine, ' '); - - return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; - } - - private function isCurrentLineLastLineInDocument() - { - return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); - } - - /** - * Cleanups a YAML string to be parsed. - * - * @param string $value The input YAML string - * - * @return string A cleaned up YAML string - */ - private function cleanup($value) - { - $value = str_replace(array("\r\n", "\r"), "\n", $value); - - // strip YAML header - $count = 0; - $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count); - $this->offset += $count; - - // remove leading comments - $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); - if (1 === $count) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - } - - // remove start of the document marker (---) - $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); - if (1 === $count) { - // items have been removed, update the offset - $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); - $value = $trimmedValue; - - // remove end of the document marker (...) - $value = preg_replace('#\.\.\.\s*$#', '', $value); - } - - return $value; - } - - /** - * Returns true if the next line starts unindented collection. - * - * @return bool Returns true if the next line starts unindented collection, false otherwise - */ - private function isNextLineUnIndentedCollection() - { - $currentIndentation = $this->getCurrentLineIndentation(); - $notEOF = $this->moveToNextLine(); - - while ($notEOF && $this->isCurrentLineEmpty()) { - $notEOF = $this->moveToNextLine(); - } - - if (false === $notEOF) { - return false; - } - - $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); - - $this->moveToPreviousLine(); - - return $ret; - } - - /** - * Returns true if the string is un-indented collection item. - * - * @return bool Returns true if the string is un-indented collection item, false otherwise - */ - private function isStringUnIndentedCollectionItem() - { - return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- '); - } - - /** - * Tests whether or not the current line is the header of a block scalar. - * - * @return bool - */ - private function isBlockScalarHeader() - { - return (bool) self::pregMatch('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine); - } - - /** - * A local wrapper for `preg_match` which will throw a ParseException if there - * is an internal error in the PCRE engine. - * - * This avoids us needing to check for "false" every time PCRE is used - * in the YAML engine - * - * DRUSH FORK: Renamed from preg_match to pregMatch. Not what I would have - * preferred, but easier / cleaner than customizing phpcs to not flag this - * one warning. - * - * @throws ParseException on a PCRE internal error - * - * @see preg_last_error() - * - * @internal - */ - public static function pregMatch($pattern, $subject, &$matches = null, $flags = 0, $offset = 0) - { - if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) { - switch (preg_last_error()) { - case PREG_INTERNAL_ERROR: - $error = 'Internal PCRE error.'; - break; - case PREG_BACKTRACK_LIMIT_ERROR: - $error = 'pcre.backtrack_limit reached.'; - break; - case PREG_RECURSION_LIMIT_ERROR: - $error = 'pcre.recursion_limit reached.'; - break; - case PREG_BAD_UTF8_ERROR: - $error = 'Malformed UTF-8 data.'; - break; - case PREG_BAD_UTF8_OFFSET_ERROR: - $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; - break; - default: - $error = 'Error.'; - } - - throw new ParseException($error); - } - - return $ret; - } - - /** - * Trim the tag on top of the value. - * - * Prevent values such as `!foo {quz: bar}` to be considered as - * a mapping block. - */ - private function trimTag($value) - { - if ('!' === $value[0]) { - return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' '); - } - - return $value; - } - - private function getLineTag($value, $flags, $nextLineCheck = true) - { - if ('' === $value || '!' !== $value[0] || 1 !== self::pregMatch('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) { - return; - } - - if ($nextLineCheck && !$this->isNextLineIndented()) { - return; - } - - $tag = substr($matches['tag'], 1); - - // Built-in tags - if ($tag && '!' === $tag[0]) { - throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag)); - } - - if (Yaml::PARSE_CUSTOM_TAGS & $flags) { - return $tag; - } - - throw new ParseException(sprintf('Tags support is not enabled. You must use the flag `Yaml::PARSE_CUSTOM_TAGS` to use "%s".', $matches['tag'])); - } -} diff --git a/src/internal-forks/Config/Yaml/README.md b/src/internal-forks/Config/Yaml/README.md deleted file mode 100644 index 730ce8aca4..0000000000 --- a/src/internal-forks/Config/Yaml/README.md +++ /dev/null @@ -1,20 +0,0 @@ -Yaml Component -============== - -The Yaml component loads and dumps YAML files. - -This is a COPY of symfony/yaml re-namespaced to Drush\Config\Yaml. This is -here so that Drush can parse its yaml config and aliasfiles prior to autoloading -any Symfony packages. This helps avoid dependency conflicts when the global -Drush includes the autoload file from Drupal. - -DO NOT USE THESE CLASSES OUTSIDE OF PREFLIGHT. Instead, use symfony/yaml. - -Resources ---------- - - * [Documentation](https://symfony.com/doc/current/components/yaml/index.html) - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/internal-forks/Config/Yaml/Tag/TaggedValue.php b/src/internal-forks/Config/Yaml/Tag/TaggedValue.php deleted file mode 100644 index 5935bfa67d..0000000000 --- a/src/internal-forks/Config/Yaml/Tag/TaggedValue.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml\Tag; - -/** - * @author Nicolas Grekas - * @author Guilhem N. - */ -final class TaggedValue -{ - private $tag; - private $value; - - /** - * @param string $tag - * @param mixed $value - */ - public function __construct($tag, $value) - { - $this->tag = $tag; - $this->value = $value; - } - - /** - * @return string - */ - public function getTag() - { - return $this->tag; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } -} diff --git a/src/internal-forks/Config/Yaml/Unescaper.php b/src/internal-forks/Config/Yaml/Unescaper.php deleted file mode 100644 index 02e6edefac..0000000000 --- a/src/internal-forks/Config/Yaml/Unescaper.php +++ /dev/null @@ -1,142 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml; - -use Drush\Internal\Config\Yaml\Exception\ParseException; - -/** - * Unescaper encapsulates unescaping rules for single and double-quoted - * YAML strings. - * - * @author Matthew Lewinski - * - * @internal - */ -class Unescaper -{ - /** - * Regex fragment that matches an escaped character in a double quoted string. - */ - const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)'; - - /** - * Unescapes a single quoted string. - * - * @param string $value A single quoted string - * - * @return string The unescaped string - */ - public function unescapeSingleQuotedString($value) - { - return str_replace('\'\'', '\'', $value); - } - - /** - * Unescapes a double quoted string. - * - * @param string $value A double quoted string - * - * @return string The unescaped string - */ - public function unescapeDoubleQuotedString($value) - { - $callback = function ($match) { - return $this->unescapeCharacter($match[0]); - }; - - // evaluate the string - return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); - } - - /** - * Unescapes a character that was found in a double-quoted string. - * - * @param string $value An escaped character - * - * @return string The unescaped character - */ - private function unescapeCharacter($value) - { - switch ($value[1]) { - case '0': - return "\x0"; - case 'a': - return "\x7"; - case 'b': - return "\x8"; - case 't': - return "\t"; - case "\t": - return "\t"; - case 'n': - return "\n"; - case 'v': - return "\xB"; - case 'f': - return "\xC"; - case 'r': - return "\r"; - case 'e': - return "\x1B"; - case ' ': - return ' '; - case '"': - return '"'; - case '/': - return '/'; - case '\\': - return '\\'; - case 'N': - // U+0085 NEXT LINE - return "\xC2\x85"; - case '_': - // U+00A0 NO-BREAK SPACE - return "\xC2\xA0"; - case 'L': - // U+2028 LINE SEPARATOR - return "\xE2\x80\xA8"; - case 'P': - // U+2029 PARAGRAPH SEPARATOR - return "\xE2\x80\xA9"; - case 'x': - return self::utf8chr(hexdec(substr($value, 2, 2))); - case 'u': - return self::utf8chr(hexdec(substr($value, 2, 4))); - case 'U': - return self::utf8chr(hexdec(substr($value, 2, 8))); - default: - throw new ParseException(sprintf('Found unknown escape character "%s".', $value)); - } - } - - /** - * Get the UTF-8 character for the given code point. - * - * @param int $c The unicode code point - * - * @return string The corresponding UTF-8 character - */ - private static function utf8chr($c) - { - if (0x80 > $c %= 0x200000) { - return chr($c); - } - if (0x800 > $c) { - return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F); - } - if (0x10000 > $c) { - return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F); - } - - return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F); - } -} diff --git a/src/internal-forks/Config/Yaml/Yaml.php b/src/internal-forks/Config/Yaml/Yaml.php deleted file mode 100644 index 693aa0f67a..0000000000 --- a/src/internal-forks/Config/Yaml/Yaml.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Drush\Internal\Config\Yaml; - -use Drush\Internal\Config\Yaml\Exception\ParseException; - -/** - * Yaml offers convenience methods to load and dump YAML. - * - * @author Fabien Potencier - */ -class Yaml -{ - const DUMP_OBJECT = 1; - const PARSE_EXCEPTION_ON_INVALID_TYPE = 2; - const PARSE_OBJECT = 4; - const PARSE_OBJECT_FOR_MAP = 8; - const DUMP_EXCEPTION_ON_INVALID_TYPE = 16; - const PARSE_DATETIME = 32; - const DUMP_OBJECT_AS_MAP = 64; - const DUMP_MULTI_LINE_LITERAL_BLOCK = 128; - const PARSE_CONSTANT = 256; - const PARSE_CUSTOM_TAGS = 512; - const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024; - const PARSE_KEYS_AS_STRINGS = 2048; - - /** - * Parses YAML into a PHP value. - * - * Usage: - * - * $array = Yaml::parse(file_get_contents('config.yml')); - * print_r($array); - * - * - * @param string $input A string containing YAML - * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior - * - * @return mixed The YAML converted to a PHP value - * - * @throws ParseException If the YAML is not valid - */ - public static function parse($input, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = self::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= self::PARSE_OBJECT; - } - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= self::PARSE_OBJECT_FOR_MAP; - } - } - - $yaml = new Parser(); - - return $yaml->parse($input, $flags); - } -} From 502b45db4dfdd846e155704b84eb26a5dd802730 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 19 Dec 2021 08:31:58 -0500 Subject: [PATCH 012/125] Move field commands into own namespace. (#4940) * Move field commands into own namespace. * Fix field command discovery and remove an alias to make help list briefer. --- src/Drupal/Commands/core/drush.services.yml | 44 ------------------ .../EntityTypeBundleAskTrait.php | 4 +- .../EntityTypeBundleValidationTrait.php | 4 +- .../{core => field}/FieldBaseInfoCommands.php | 2 +- .../FieldBaseOverrideCreateCommands.php | 7 ++- .../{core => field}/FieldCreateCommands.php | 5 ++- .../FieldDefinitionRowsOfFieldsTrait.php | 2 +- .../{core => field}/FieldDeleteCommands.php | 7 ++- .../{core => field}/FieldInfoCommands.php | 2 +- src/Drupal/Commands/field/drush.services.yml | 45 +++++++++++++++++++ src/Drupal/DrupalKernelTrait.php | 1 + 11 files changed, 70 insertions(+), 53 deletions(-) rename src/Drupal/Commands/{core => field}/EntityTypeBundleAskTrait.php (97%) rename src/Drupal/Commands/{core => field}/EntityTypeBundleValidationTrait.php (95%) rename src/Drupal/Commands/{core => field}/FieldBaseInfoCommands.php (98%) rename src/Drupal/Commands/{core => field}/FieldBaseOverrideCreateCommands.php (98%) rename src/Drupal/Commands/{core => field}/FieldCreateCommands.php (99%) rename src/Drupal/Commands/{core => field}/FieldDefinitionRowsOfFieldsTrait.php (98%) rename src/Drupal/Commands/{core => field}/FieldDeleteCommands.php (97%) rename src/Drupal/Commands/{core => field}/FieldInfoCommands.php (98%) create mode 100644 src/Drupal/Commands/field/drush.services.yml diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index c51ef06999..915e5e1232 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -21,50 +21,6 @@ services: arguments: ['@entity_type.manager'] tags: - { name: drush.command } - field.create.commands: - class: \Drush\Drupal\Commands\core\FieldCreateCommands - arguments: - - '@plugin.manager.field.field_type' - - '@plugin.manager.field.widget' - - '@plugin.manager.entity_reference_selection' - - '@entity_type.manager' - - '@entity_type.bundle.info' - - '@module_handler' - - '@entity_field.manager' - calls: - - [ setContentTranslationManager, [ '@?content_translation.manager' ] ] - tags: - - { name: drush.command } - field.info.commands: - class: \Drush\Drupal\Commands\core\FieldInfoCommands - arguments: - - '@entity_type.manager' - - '@entity_type.bundle.info' - tags: - - { name: drush.command } - field.delete.commands: - class: \Drush\Drupal\Commands\core\FieldDeleteCommands - arguments: - - '@entity_type.manager' - - '@entity_type.bundle.info' - tags: - - { name: drush.command } - field.base-override-create.commands: - class: \Drush\Drupal\Commands\core\FieldBaseOverrideCreateCommands - arguments: - - '@entity_type.manager' - - '@entity_type.bundle.info' - - '@entity_field.manager' - tags: - - { name: drush.command } - field.base-info.commands: - class: \Drush\Drupal\Commands\core\FieldBaseInfoCommands - arguments: - - '@entity_type.manager' - - '@entity_type.bundle.info' - - '@entity_field.manager' - tags: - - { name: drush.command } link.hooks: class: \Drush\Drupal\Commands\core\LinkHooks arguments: diff --git a/src/Drupal/Commands/core/EntityTypeBundleAskTrait.php b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php similarity index 97% rename from src/Drupal/Commands/core/EntityTypeBundleAskTrait.php rename to src/Drupal/Commands/field/EntityTypeBundleAskTrait.php index 3a2700ada6..649fc68a25 100644 --- a/src/Drupal/Commands/core/EntityTypeBundleAskTrait.php +++ b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php @@ -1,11 +1,13 @@ addDrushServiceProvider("_drush__config", DRUSH_BASE_PATH . '/src/Drupal/Commands/config/drush.services.yml'); $this->addDrushServiceProvider("_drush__core", DRUSH_BASE_PATH . '/src/Drupal/Commands/core/drush.services.yml'); + $this->addDrushServiceProvider("_drush__field", DRUSH_BASE_PATH . '/src/Drupal/Commands/field/drush.services.yml'); $this->addDrushServiceProvider("_drush__pm", DRUSH_BASE_PATH . '/src/Drupal/Commands/pm/drush.services.yml'); $this->addDrushServiceProvider("_drush__sql", DRUSH_BASE_PATH . '/src/Drupal/Commands/sql/drush.services.yml'); From 2088bcf684075f09678de41d26f63fba6b20f191 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 19 Dec 2021 11:11:22 -0500 Subject: [PATCH 013/125] Fix #4801. Rename several test classes (fix deprecation) (#4942) * Fix #4801. Rename several test classes (fix deprecation) * Fix typo AttributesTest. * Fix ci file --- .circleci/config.yml | 4 ++++ tests/functional/BatchTest.php | 2 +- tests/functional/ConfigPullTest.php | 2 +- tests/functional/ConfigTest.php | 2 +- tests/functional/CoreTest.php | 2 +- tests/functional/LanguageAddTest.php | 2 +- tests/functional/PmEnDisUnListInfoTest.php | 2 +- tests/functional/PmEnLocaleImportTest.php | 2 +- tests/functional/QueueTest.php | 2 +- tests/functional/RoleTest.php | 2 +- tests/functional/SiteInstallTest.php | 2 +- tests/functional/SiteSetTest.php | 2 +- tests/functional/SiteSshTest.php | 2 +- .../{SqlConnectCreateTest.php => SqlConnectTest.php} | 2 +- tests/functional/UserTest.php | 2 +- tests/integration/{AttibutesTest.php => AttributesTest.php} | 0 tests/integration/CacheCommandTest.php | 2 +- 17 files changed, 19 insertions(+), 15 deletions(-) rename tests/functional/{SqlConnectCreateTest.php => SqlConnectTest.php} (98%) rename tests/integration/{AttibutesTest.php => AttributesTest.php} (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6fa41ab98b..d5c99a0fae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -130,6 +130,10 @@ jobs: - run: composer unit -- --log-junit /tmp/results/unit.junit.xml - run: composer functional -- --log-junit /tmp/results/functional.junit.xml - run: composer integration -- --log-junit /tmp/results/integration.junit.xml + - store_test_results: + path: /tmp/results + - store_artifacts: + path: /tmp/results workflows: version: 2 diff --git a/tests/functional/BatchTest.php b/tests/functional/BatchTest.php index 60d2b3ae35..f122411585 100644 --- a/tests/functional/BatchTest.php +++ b/tests/functional/BatchTest.php @@ -7,7 +7,7 @@ * * @group base */ -class BatchCase extends CommandUnishTestCase +class BatchTest extends CommandUnishTestCase { public function testBatch() diff --git a/tests/functional/ConfigPullTest.php b/tests/functional/ConfigPullTest.php index 381ef15580..efe76609bd 100644 --- a/tests/functional/ConfigPullTest.php +++ b/tests/functional/ConfigPullTest.php @@ -9,7 +9,7 @@ * @group slow * @group config */ -class ConfigPullCase extends CommandUnishTestCase +class ConfigPullTest extends CommandUnishTestCase { public function setup(): void diff --git a/tests/functional/ConfigTest.php b/tests/functional/ConfigTest.php index e0381418ac..8be7c82def 100644 --- a/tests/functional/ConfigTest.php +++ b/tests/functional/ConfigTest.php @@ -11,7 +11,7 @@ * @group commands * @group config */ -class ConfigCase extends CommandUnishTestCase +class ConfigTest extends CommandUnishTestCase { use TestModuleHelperTrait; diff --git a/tests/functional/CoreTest.php b/tests/functional/CoreTest.php index 5c3275748b..991949414d 100644 --- a/tests/functional/CoreTest.php +++ b/tests/functional/CoreTest.php @@ -10,7 +10,7 @@ * * @group commands */ -class CoreCase extends CommandUnishTestCase +class CoreTest extends CommandUnishTestCase { public function setup(): void { diff --git a/tests/functional/LanguageAddTest.php b/tests/functional/LanguageAddTest.php index f886a97793..447ea670ba 100644 --- a/tests/functional/LanguageAddTest.php +++ b/tests/functional/LanguageAddTest.php @@ -10,7 +10,7 @@ * @group slow * @group pm */ -class LanguageAddCase extends CommandUnishTestCase +class LanguageAddTest extends CommandUnishTestCase { protected function setup(): void { diff --git a/tests/functional/PmEnDisUnListInfoTest.php b/tests/functional/PmEnDisUnListInfoTest.php index 4eff2dad93..59094c37b9 100644 --- a/tests/functional/PmEnDisUnListInfoTest.php +++ b/tests/functional/PmEnDisUnListInfoTest.php @@ -13,7 +13,7 @@ * @group slow * @group pm */ -class EnDisUnListInfoCase extends CommandUnishTestCase +class EnDisUnListInfoTest extends CommandUnishTestCase { public function testEnDisUnList() diff --git a/tests/functional/PmEnLocaleImportTest.php b/tests/functional/PmEnLocaleImportTest.php index 547c74d0ef..4d17fa15fb 100644 --- a/tests/functional/PmEnLocaleImportTest.php +++ b/tests/functional/PmEnLocaleImportTest.php @@ -11,7 +11,7 @@ * @group slow * @group pm */ -class PmEnLocaleImportCase extends CommandUnishTestCase +class PmEnLocaleImportTest extends CommandUnishTestCase { public function testBatchImportTranslations() diff --git a/tests/functional/QueueTest.php b/tests/functional/QueueTest.php index 682e73dc5a..67900cbde1 100644 --- a/tests/functional/QueueTest.php +++ b/tests/functional/QueueTest.php @@ -7,7 +7,7 @@ /** * @group commands */ -class QueueCase extends CommandUnishTestCase +class QueueTest extends CommandUnishTestCase { use TestModuleHelperTrait; diff --git a/tests/functional/RoleTest.php b/tests/functional/RoleTest.php index 50c98fb308..8103c573c0 100644 --- a/tests/functional/RoleTest.php +++ b/tests/functional/RoleTest.php @@ -8,7 +8,7 @@ * @group slow * @group commands */ -class RoleCase extends CommandUnishTestCase +class RoleTest extends CommandUnishTestCase { use TestModuleHelperTrait; diff --git a/tests/functional/SiteInstallTest.php b/tests/functional/SiteInstallTest.php index 31e4838af8..c7b6ed8847 100644 --- a/tests/functional/SiteInstallTest.php +++ b/tests/functional/SiteInstallTest.php @@ -6,7 +6,7 @@ * @group base * @group slow */ -class SiteInstallCommandCase extends CommandUnishTestCase +class SiteInstallTest extends CommandUnishTestCase { /** diff --git a/tests/functional/SiteSetTest.php b/tests/functional/SiteSetTest.php index 89e8e4ac6e..0e31941557 100644 --- a/tests/functional/SiteSetTest.php +++ b/tests/functional/SiteSetTest.php @@ -6,7 +6,7 @@ * @group base * @group slow */ -class SiteSetCommandCase extends CommandUnishTestCase +class SiteSetTest extends CommandUnishTestCase { /** diff --git a/tests/functional/SiteSshTest.php b/tests/functional/SiteSshTest.php index 85762b4855..8e16106bc3 100644 --- a/tests/functional/SiteSshTest.php +++ b/tests/functional/SiteSshTest.php @@ -8,7 +8,7 @@ * * @group commands */ -class SiteSshCase extends CommandUnishTestCase +class SiteSshTest extends CommandUnishTestCase { /** diff --git a/tests/functional/SqlConnectCreateTest.php b/tests/functional/SqlConnectTest.php similarity index 98% rename from tests/functional/SqlConnectCreateTest.php rename to tests/functional/SqlConnectTest.php index 6857b9e9df..e58fe58d59 100644 --- a/tests/functional/SqlConnectCreateTest.php +++ b/tests/functional/SqlConnectTest.php @@ -10,7 +10,7 @@ * @group commands * @group sql */ -class SqlConnectCase extends CommandUnishTestCase +class SqlConnectTest extends CommandUnishTestCase { public function testSqlConnect() diff --git a/tests/functional/UserTest.php b/tests/functional/UserTest.php index 1e992dd37d..3871965fe2 100644 --- a/tests/functional/UserTest.php +++ b/tests/functional/UserTest.php @@ -8,7 +8,7 @@ * @group slow * @group commands */ -class UserCase extends CommandUnishTestCase +class UserTest extends CommandUnishTestCase { const NAME = 'example'; diff --git a/tests/integration/AttibutesTest.php b/tests/integration/AttributesTest.php similarity index 100% rename from tests/integration/AttibutesTest.php rename to tests/integration/AttributesTest.php diff --git a/tests/integration/CacheCommandTest.php b/tests/integration/CacheCommandTest.php index bc2ad9ae1a..7bebfd2573 100644 --- a/tests/integration/CacheCommandTest.php +++ b/tests/integration/CacheCommandTest.php @@ -7,7 +7,7 @@ * * @group commands */ -class CacheCommandCase extends UnishIntegrationTestCase +class CacheCommandTest extends UnishIntegrationTestCase { public function testCacheGet() { From 30872fce76e15681c8436c7d8591b0a9b039c3de Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 19 Dec 2021 12:01:48 -0500 Subject: [PATCH 014/125] Formalize maintainers list with CODEOWNERS file. (#4943) --- CODEOWNERS | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..d47c6a0fce --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,36 @@ +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +# +# We are always looking for more maintainers! Please submit a couple PRs in an +# area and then submit a PR to add yourself to this file :). +# + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +* @weitzman @greg-1-anderson + +/src/Commands/Config/ @bircher +/src/Drupal/Commands/config/ @bircher + +/src/Drupal/Commands/core/MigrateRunnerCommands.php @claudiu-cristea +/src/Drupal/Migrate/ @claudiu-cristea + +/src/Drupal/Commands/field/ @DieterHolvoet + +/src/Commands/core/RunServerCommands.php @grugnog + +/includes/batch.inc @jonhattan +/src/Drupal/Commands/core/BatchCommands.php @jonhattan + +/src/Drupal/Commands/core/CLICommands.php @damiankloip +/src/Psysh @damiankloip + +/src/Commands/core/UpdateDBCommands.php @pfrenssen + +/src/Drupal/Commands/core/LocaleCommands.php @Sutharsan + +/src/Drupal/Commands/core/QueueCommands.php @davereid + + From b74f9e580f5522d1da402df417987c4698b40035 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 20 Dec 2021 06:43:25 -0500 Subject: [PATCH 015/125] Preo for RC3 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..9bf30c7cd6 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0-rc3 From 60e49d8897ec7f7f733974610093bbd546ed8c3f Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 20 Dec 2021 07:06:46 -0500 Subject: [PATCH 016/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9bf30c7cd6..9ad93d53df 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-rc3 +drush_version=11.0.0-dev From 6d93c9a90021b67315cbefb8473bd3987862fef1 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 20 Dec 2021 08:31:32 -0500 Subject: [PATCH 017/125] Bump to Drupal 9.4 in highest test. (#4944) --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d5c99a0fae..8c96c40125 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,7 +109,7 @@ jobs: # PHP 8 test with Drupal tip # Determines whether a newer version of a dependency has broken Drush. - test_81_drupal93_highest: + test_81_drupal94_highest: <<: *defaults docker: # @todo After release change to wodby/php:latest @@ -123,7 +123,7 @@ jobs: - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - run: php --version - run: composer config platform.php --unset - - run: composer require --dev drupal/core-recommended:9.3.x-dev --no-update + - run: composer require --dev drupal/core-recommended:9.4.x-dev --no-update - run: composer update - run: mkdir -p /tmp/results - run: composer lint @@ -145,7 +145,7 @@ workflows: <<: *requires - test_74_drupal9_mysql: <<: *requires - - test_81_drupal93_highest: + - test_81_drupal94_highest: <<: *requires - test_74_drupal9_sqlite: <<: *requires From 5bc1ca3ff6142cd847b968cbfc51d47b1fdbf815 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 22 Dec 2021 17:57:29 -0500 Subject: [PATCH 018/125] Use latest php in hightest tests. (#4945) --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8c96c40125..7263ba9f0d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -112,8 +112,7 @@ jobs: test_81_drupal94_highest: <<: *defaults docker: -# @todo After release change to wodby/php:latest - - image: wodby/php:8.1-rc-dev + - image: wodby/php:latest environment: - MYSQL_HOST=127.0.0.1 - UNISH_DB_URL=mysql://root:@127.0.0.1 From db078ba1b068fe621ced477cb926b1634d89d935 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 24 Dec 2021 08:05:13 -0500 Subject: [PATCH 019/125] Add Attribute for Version. (#4946) * Add Attribute for Version. * On Windows no curl and non-specific php * bump * Fix test --- appveyor.yml | 6 ++--- src/Attributes/Bootstrap.php | 1 - src/Attributes/Version.php | 25 +++++++++++++++++++ .../Commands/ExampleAttributesCommands.php | 1 + 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/Attributes/Version.php diff --git a/appveyor.yml b/appveyor.yml index a7833b904f..06c9d6cf30 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,8 +20,8 @@ init: # Inspired by https://github.com/Codeception/base/blob/master/appveyor.yml and https://github.com/phpmd/phpmd/blob/master/appveyor.yml install: - ps: Set-Service wuauserv -StartupType Manual - - ps: appveyor-retry cinst -y curl - - SET PATH=C:\Program Files\curl;%PATH% +# - ps: appveyor-retry cinst -y curl +# - SET PATH=C:\Program Files\curl;%PATH% #which is only needed by the test suite. - cinst --limit-output -y which - SET PATH=C:\Program Files\which;%PATH% @@ -30,7 +30,7 @@ install: - SET PATH=C:\Program Files\MySql\MySQL Server 5.7\bin\;%PATH% - choco search php --exact --all-versions -r #Install PHP per https://blog.wyrihaximus.net/2016/11/running-php-unit-tests-on-windows-using-appveyor-and-chocolatey/ - - ps: appveyor-retry cinst --limit-output --ignore-checksums -y php --version 7.4.26 + - ps: appveyor-retry cinst --limit-output --ignore-checksums -y php --version 7.4.27 - cd c:\tools\php74 - copy php.ini-production php.ini diff --git a/src/Attributes/Bootstrap.php b/src/Attributes/Bootstrap.php index 38545a3bad..725151c8f6 100644 --- a/src/Attributes/Bootstrap.php +++ b/src/Attributes/Bootstrap.php @@ -4,7 +4,6 @@ use Attribute; use Consolidation\AnnotatedCommand\Parser\CommandInfo; -use Drush\Boot\DrupalBoot; use Drush\Boot\DrupalBootLevels; use JetBrains\PhpStorm\ExpectedValues; diff --git a/src/Attributes/Version.php b/src/Attributes/Version.php new file mode 100644 index 0000000000..a7d9e6989c --- /dev/null +++ b/src/Attributes/Version.php @@ -0,0 +1,25 @@ +getArguments(); + $commandInfo->addAnnotation('version', $args['version']); + } +} diff --git a/tests/integration/resources/Commands/ExampleAttributesCommands.php b/tests/integration/resources/Commands/ExampleAttributesCommands.php index 08823e7037..90631b2561 100644 --- a/tests/integration/resources/Commands/ExampleAttributesCommands.php +++ b/tests/integration/resources/Commands/ExampleAttributesCommands.php @@ -16,6 +16,7 @@ class ExampleAttributesCommands extends DrushCommands #[CLI\Argument(name: 'two', description: 'The other parameter')] #[CLI\Option(name: 'flip', description: 'Whether or not the second parameter should come first in the result.')] #[CLI\Usage(name: 'bet alpha --flip', description: 'Concatenate "alpha" and "bet".')] + #[CLI\Version(version: '11.0')] public function myEcho($one, $two = '', array $options = ['flip' => false]) { if ($options['flip']) { From 9071e2704b1a0c1d7a931d205bb5fb3269414b71 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 25 Dec 2021 18:02:12 -0500 Subject: [PATCH 020/125] Fix #4933. Dont let Console propogate --quiet to subprocesses by default. (#4947) --- src/SiteAlias/ProcessManager.php | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/SiteAlias/ProcessManager.php b/src/SiteAlias/ProcessManager.php index 8af0a2512a..4a272c7fe4 100644 --- a/src/SiteAlias/ProcessManager.php +++ b/src/SiteAlias/ProcessManager.php @@ -1,17 +1,14 @@ setSimulated(Drush::simulate()); $process->setVerbose(Drush::verbose()); - // Handle BC method of making env variables inherited. The default in - // later versions is always inherit and this method disappears. - // @todo Remove this if() block once Symfony 3 support is dropped. - if (method_exists($process, 'inheritEnvironmentVariables')) { - set_error_handler(null); - $process->inheritEnvironmentVariables(); - restore_error_handler(); - } + // Don't let sub-process inherit the verbosity of its parent. + putenv('SHELL_VERBOSITY=' . OutputInterface::VERBOSITY_NORMAL); + $_ENV['SHELL_VERBOSITY'] = OutputInterface::VERBOSITY_NORMAL; $process->setLogger(Drush::logger()); $process->setRealtimeOutput(new DrushStyle(Drush::input(), Drush::output())); $process->setTimeout(Drush::getTimeout()); From 6b42e4c7f3a72a35d8d708e686d515d334164376 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 25 Dec 2021 20:02:21 -0500 Subject: [PATCH 021/125] Fix #4543. Support DelayedRequeueException (added in Drupal 9.1.x) (#4948) --- src/Drupal/Commands/core/QueueCommands.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Drupal/Commands/core/QueueCommands.php b/src/Drupal/Commands/core/QueueCommands.php index db2fae835e..d7e9b0cd7f 100644 --- a/src/Drupal/Commands/core/QueueCommands.php +++ b/src/Drupal/Commands/core/QueueCommands.php @@ -4,6 +4,8 @@ use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\CommandError; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; +use Drupal\Core\Queue\DelayableQueueInterface; +use Drupal\Core\Queue\DelayedRequeueException; use Drupal\Core\Queue\QueueFactory; use Drupal\Core\Queue\QueueWorkerManagerInterface; use Drupal\Core\Queue\RequeueException; @@ -87,6 +89,17 @@ public function run($name, $options = ['time-limit' => self::REQ, 'items-limit' // release the item. $queue->releaseItem($item); throw new \Exception($e->getMessage()); + } catch (DelayedRequeueException $e) { + // The worker requested the task not be immediately re-queued. + // - If the queue doesn't support ::delayItem(), we should leave the + // item's current expiry time alone. + // - If the queue does support ::delayItem(), we should allow the + // queue to update the item's expiry using the requested delay. + if ($queue instanceof DelayableQueueInterface) { + // This queue can handle a custom delay; use the duration provided + // by the exception. + $queue->delayItem($item, $e->getDelay()); + } } catch (\Exception $e) { // In case of any other kind of exception, log it and leave the // item in the queue to be processed again later. From eb41746ad0f5956beb115bfd24c2a9adc07f6415 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sun, 26 Dec 2021 02:54:37 +0100 Subject: [PATCH 022/125] Stop prepending the Cancel option to choice lists (#4908) Co-authored-by: Moshe Weitzman --- src/Style/DrushStyle.php | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/Style/DrushStyle.php b/src/Style/DrushStyle.php index 89920a8f69..d980798713 100644 --- a/src/Style/DrushStyle.php +++ b/src/Style/DrushStyle.php @@ -24,23 +24,13 @@ public function confirm($question, $default = true) return $return; } - /** - * @param string $question - * @param array $choices - * If an associative array is passed, the chosen *key* is returned. - * @param null $default - * @return mixed - */ public function choice($question, array $choices, $default = null) { - $choices = array_merge(['cancel' => 'Cancel'], $choices) ; + // Display the choices without their keys. $choices_values = array_values($choices); $return = parent::choice($question, $choices_values, $default); - if ($return == 'Cancel') { - throw new UserAbortException(); - } else { - return array_search($return, $choices); - } + + return array_search($return, $choices); } public function warning($message) From fbe4980f084d95b76d72453cc3ad42d568e2f663 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Mon, 27 Dec 2021 13:09:31 +0100 Subject: [PATCH 023/125] Fix default value of the field:create cardinality option (#4951) Since the Cancel option is removed from choice lists (#4907), the numerical indexes changed. Commands that use an indexed array for options and that have a default value will have to update that default value. I haven't found another occurrence of this issue in Drush core. --- src/Drupal/Commands/field/FieldCreateCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/field/FieldCreateCommands.php b/src/Drupal/Commands/field/FieldCreateCommands.php index a5ed09d2a1..d45d28e0b5 100644 --- a/src/Drupal/Commands/field/FieldCreateCommands.php +++ b/src/Drupal/Commands/field/FieldCreateCommands.php @@ -346,7 +346,7 @@ protected function askCardinality(): int $cardinality = $this->io()->choice( 'Allowed number of values', array_combine($choices, $choices), - 1 + 0 ); $limit = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED; From 0c58c41cabd0197384373b3e82d65ed33577e25b Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Mon, 27 Dec 2021 13:39:00 +0100 Subject: [PATCH 024/125] Add askRequired helper to DrushStyle (#4950) --- .../Commands/field/FieldCreateCommands.php | 15 ++------------ src/Style/DrushStyle.php | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Drupal/Commands/field/FieldCreateCommands.php b/src/Drupal/Commands/field/FieldCreateCommands.php index d45d28e0b5..326eedd56d 100644 --- a/src/Drupal/Commands/field/FieldCreateCommands.php +++ b/src/Drupal/Commands/field/FieldCreateCommands.php @@ -248,7 +248,7 @@ protected function askFieldName(): string } while (!$fieldName) { - $answer = $this->io()->ask('Field name', $machineName, [static::class, 'validateRequired']); + $answer = $this->io()->ask('Field name', $machineName); if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $answer)) { $this->logger()->error('Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character.'); @@ -273,7 +273,7 @@ protected function askFieldName(): string protected function askFieldLabel(): string { - return $this->io()->ask('Field label', null, [static::class, 'validateRequired']); + return $this->io()->askRequired('Field label'); } protected function askFieldDescription(): ?string @@ -646,15 +646,4 @@ protected function ensureOption(string $name, callable $asker, bool $required): $this->input->setOption($name, $value); } - - public static function validateRequired(?string $value): string - { - // FALSE is not considered as empty value because question helper use - // it as negative answer on confirmation questions. - if ($value === null || $value === '') { - throw new \UnexpectedValueException('This value is required.'); - } - - return $value; - } } diff --git a/src/Style/DrushStyle.php b/src/Style/DrushStyle.php index d980798713..cbf564a032 100644 --- a/src/Style/DrushStyle.php +++ b/src/Style/DrushStyle.php @@ -4,6 +4,7 @@ use Drush\Drush; use Drush\Exceptions\UserAbortException; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; class DrushStyle extends SymfonyStyle @@ -47,4 +48,23 @@ public function caution($message) { $this->block($message, 'CAUTION', 'fg=black;bg=yellow', ' ! ', true); } + + /** + * @return mixed + */ + public function askRequired($question) + { + $question = new Question($question); + $question->setValidator(function (?string $value) { + // FALSE is not considered as empty value because question helper use + // it as negative answer on confirmation questions. + if ($value === null || $value === '') { + throw new \UnexpectedValueException('This value is required.'); + } + + return $value; + }); + + return $this->askQuestion($question); + } } From 128665408656e75846169cbf3c668d004fbbe09e Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 27 Dec 2021 08:19:26 -0500 Subject: [PATCH 025/125] Fix #4373. The command output does not check verbosity correctly. (#4949) --- src/Preflight/PreflightArgs.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Preflight/PreflightArgs.php b/src/Preflight/PreflightArgs.php index 52aeeeec1d..7f0d997f19 100644 --- a/src/Preflight/PreflightArgs.php +++ b/src/Preflight/PreflightArgs.php @@ -82,7 +82,6 @@ public function optionsWithValues() '--root=' => 'setSelectedSite', '--debug' => 'setDebug', '-d' => 'setDebug', - '-vv' => 'setDebug', '-vvv' => 'setDebug', '-l=' => 'setUri', '--uri=' => 'setUri', From 2126b4a42cb2a463ed093294b628c1aa31b0bbaf Mon Sep 17 00:00:00 2001 From: "Richard B. Porter" Date: Mon, 27 Dec 2021 10:11:31 -0600 Subject: [PATCH 026/125] Implement site-specific config file loading. (#4345) --- src/Boot/DrupalBoot8.php | 11 +++++++++- src/Config/ConfigLocator.php | 32 ++++++++++++++++++++++++++++- tests/functional/CoreTest.php | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Boot/DrupalBoot8.php b/src/Boot/DrupalBoot8.php index 2e2d9cfda0..6f2e550aa2 100644 --- a/src/Boot/DrupalBoot8.php +++ b/src/Boot/DrupalBoot8.php @@ -5,6 +5,7 @@ use Consolidation\AnnotatedCommand\AnnotationData; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; +use Drush\Config\ConfigLocator; use Drush\Drupal\DrushLoggerServiceProvider; use Drush\Drupal\DrushServiceModifier; use Drush\Drush; @@ -158,7 +159,15 @@ public function bootstrapDrupalSiteValidate(BootstrapManager $manager) */ public function bootstrapDoDrupalSite(BootstrapManager $manager) { - // Note: this reports the'default' during site:install even if we eventually install to a different multisite. + $siteConfig = $this->confPath() . '/drush.yml'; + + if (ConfigLocator::addSiteSpecificConfig(Drush::config(), $siteConfig)) { + $this->logger->debug(dt("Loaded Drush config file at !file.", ['!file' => $siteConfig])); + } else { + $this->logger->debug(dt("Could not find a Drush config file at !file.", ['!file' => $siteConfig])); + } + + // Note: this reports the 'default' site during site:install even if we eventually install to a different multisite. $this->logger->info(dt("Initialized Drupal site !site at !site_root", ['!site' => $this->getRequest()->getHttpHost(), '!site_root' => $this->confPath()])); } diff --git a/src/Config/ConfigLocator.php b/src/Config/ConfigLocator.php index a872a7a0cf..35f609f475 100644 --- a/src/Config/ConfigLocator.php +++ b/src/Config/ConfigLocator.php @@ -106,7 +106,7 @@ public function __construct($envPrefix = '', $configFileVariant = '') } $this->config->addPlaceholder(self::USER_CONTEXT); $this->config->addPlaceholder(self::DRUPAL_CONTEXT); - $this->config->addPlaceholder(self::SITE_CONTEXT); // not implemented yet (multisite) + $this->config->addPlaceholder(self::SITE_CONTEXT); $this->config->addPlaceholder(self::ALIAS_CONTEXT); $this->config->addPlaceholder(self::PREFLIGHT_CONTEXT); $this->config->addPlaceholder(self::ENVIRONMENT_CONTEXT); @@ -554,4 +554,34 @@ protected function findConfigFiles($paths, $candidates) return $config_files; } + + /** + * Attempt to load site specific configuration. + * + * @param DrushConfig $config + * The config object. + * @param $siteConfig + * The site-specific config file. + * + * @return bool + * Whether the config exists and was processed. + */ + public static function addSiteSpecificConfig(DrushConfig $config, $siteConfig): bool + { + if (file_exists($siteConfig)) { + $loader = new YamlConfigLoader(); + $processor = new ConfigProcessor(); + $reference = $config->export(); + $context = $config->getContext(ConfigLocator::SITE_CONTEXT); + $processor->add($context->export()); + $processor->extend($loader->load($siteConfig)); + $context->import($processor->export($reference)); + $config->addContext(ConfigLocator::SITE_CONTEXT, $context); + $presetConfig = $config->get('runtime.config.paths'); + $config->set('runtime.config.paths', array_merge($presetConfig, [$siteConfig])); + return true; + } else { + return false; + } + } } diff --git a/tests/functional/CoreTest.php b/tests/functional/CoreTest.php index 991949414d..cd5ab915bd 100644 --- a/tests/functional/CoreTest.php +++ b/tests/functional/CoreTest.php @@ -171,4 +171,42 @@ public function testRecursiveConfigLoading() $this->assertContains($b_drush_config_file, $output['drush-conf'], "Loaded drush config files are: " . $drush_conf_as_string); $this->assertEquals($test_uri, $output['uri']); } + + public function testSiteSpecificConfigLoading() + { + $sandbox = $this->getSandbox(); + + foreach (['default', 'dev', 'stage'] as $site) { + $site_cache_dir = "{$sandbox}/tmp/{$site}"; + $drush_config_file = Path::join($this->webroot(), "/sites/{$site}/drush.yml"); + + $drush_config_yml = [ + 'drush' => [ + 'paths' => [ + 'cache-directory' => $site_cache_dir, + ] + ] + ]; + + file_put_contents($drush_config_file, Yaml::dump($drush_config_yml, PHP_INT_MAX, 2)); + + // Don't use the uri option for the default site. + $options = [ + 'uri' => ($site == 'default') ? 'OMIT' : $site, + 'format' => 'json', + ]; + + // Test that the config file is loaded. + $this->drush('core-status', [], $options); + $output = $this->getOutputFromJSON(); + $loaded = array_flip($output['drush-conf']); + $this->assertArrayHasKey("sites/{$site}/drush.yml", $loaded); + + // Test that the cache directory config is set. The field option + // forces format to string. + $this->drush('core-status', [], $options + ['field' => 'drush-cache-directory']); + $output = $this->getOutput(); + $this->assertEquals($site_cache_dir, $output); + } + } } From 57bbe7ee335c905951b54c4de04f7a47c3e65ba3 Mon Sep 17 00:00:00 2001 From: Florent Torregrosa Date: Mon, 27 Dec 2021 23:23:59 +0100 Subject: [PATCH 027/125] Add the option to skip language autocreation on the command locale:import. (#4586) * Add the option to skip language autocreation on the command locale:import. * Use boolean option that defaults to false Co-authored-by: Moshe Weitzman --- src/Drupal/Commands/core/LocaleCommands.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Drupal/Commands/core/LocaleCommands.php b/src/Drupal/Commands/core/LocaleCommands.php index da7eb04b44..e3c32ac84e 100644 --- a/src/Drupal/Commands/core/LocaleCommands.php +++ b/src/Drupal/Commands/core/LocaleCommands.php @@ -220,6 +220,7 @@ public function exportValidate(CommandData $commandData) * @param $file Path and file name of the gettext file. * @option type The type of translations to be imported. Recognized values: customized, not-customized * @option override Whether and how imported strings will override existing translations. Defaults to the Import behavior configured in the admin interface. Recognized values: none, customized, not-customized, all, + * @option autocreate-language Create the language in addition to import. * @usage drush locale-import nl drupal-8.4.2.nl.po * Import the Dutch drupal core translation. * @usage drush locale-import --type=customized nl drupal-8.4.2.nl.po @@ -233,13 +234,13 @@ public function exportValidate(CommandData $commandData) * @aliases locale-import * @throws \Exception */ - public function import($langcode, $file, $options = ['type' => 'not-customized', 'override' => self::REQ]) + public function import($langcode, $file, $options = ['type' => 'not-customized', 'override' => self::REQ, 'autocreate-language' => false]) { if (!drush_file_not_empty($file)) { throw new \Exception(dt('File @file not found or empty.', ['@file' => $file])); } - $language = $this->getTranslatableLanguage($langcode, true); + $language = $this->getTranslatableLanguage($langcode, $options['autocreate-language']); $this->getModuleHandler()->loadInclude('locale', 'translation.inc'); $this->getModuleHandler()->loadInclude('locale', 'bulk.inc'); From b6bce9f25a188eedb2511e9151a8866b676563af Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 27 Dec 2021 17:32:26 -0500 Subject: [PATCH 028/125] Update all packages and up the composer conflict so we require at least Drupal 9.2 --- composer.json | 2 +- composer.lock | 935 +++++++++++++++++++++++++++----------------------- 2 files changed, 508 insertions(+), 429 deletions(-) diff --git a/composer.json b/composer.json index b7dd8326c1..38c1cfae3f 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,7 @@ "yoast/phpunit-polyfills": "^0.2.0" }, "conflict": { - "drupal/core": "<= 8", + "drupal/core": "<= 9.1", "drupal/migrate_run": "*", "drupal/migrate_tools": "<= 5" }, diff --git a/composer.lock b/composer.lock index 28f3781f0c..13b19363d4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "87e752a74905a62d75a08cf4bf0a8954", + "content-hash": "a5462ee13843158cf999d6ec578fe401", "packages": [ { "name": "chi-teck/drupal-code-generator", - "version": "2.3.0", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/Chi-teck/drupal-code-generator.git", - "reference": "3508f0bb67ba905d6c0c59d1b51e7bc78876ad71" + "reference": "69f7a9cdbf0ef7021f1f960d237d3b224f6864d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/3508f0bb67ba905d6c0c59d1b51e7bc78876ad71", - "reference": "3508f0bb67ba905d6c0c59d1b51e7bc78876ad71", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/69f7a9cdbf0ef7021f1f960d237d3b224f6864d3", + "reference": "69f7a9cdbf0ef7021f1f960d237d3b224f6864d3", "shasum": "" }, "require": { @@ -64,22 +64,22 @@ "description": "Drupal code generator", "support": { "issues": "https://github.com/Chi-teck/drupal-code-generator/issues", - "source": "https://github.com/Chi-teck/drupal-code-generator/tree/2.3.0" + "source": "https://github.com/Chi-teck/drupal-code-generator/tree/2.3.1" }, - "time": "2021-11-24T08:04:06+00:00" + "time": "2021-12-09T10:20:43+00:00" }, { "name": "composer/semver", - "version": "3.2.5", + "version": "3.2.6", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "31f3ea725711245195f62e54ffa402d8ef2fdba9" + "reference": "83e511e247de329283478496f7a1e114c9517506" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/31f3ea725711245195f62e54ffa402d8ef2fdba9", - "reference": "31f3ea725711245195f62e54ffa402d8ef2fdba9", + "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", + "reference": "83e511e247de329283478496f7a1e114c9517506", "shasum": "" }, "require": { @@ -131,7 +131,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.5" + "source": "https://github.com/composer/semver/tree/3.2.6" }, "funding": [ { @@ -147,31 +147,32 @@ "type": "tidelift" } ], - "time": "2021-05-24T12:41:47+00:00" + "time": "2021-10-25T11:34:17+00:00" }, { "name": "consolidation/annotated-command", - "version": "4.4.0", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707" + "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/308f6ac178566a1ce9aa90ed908dac90a2c1e707", - "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", + "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", "shasum": "" }, "require": { "consolidation/output-formatters": "^4.1.1", "php": ">=7.1.3", "psr/log": "^1|^2", - "symfony/console": "^4.4.8|~5.1.0", - "symfony/event-dispatcher": "^4.4.8|^5", - "symfony/finder": "^4.4.8|^5" + "symfony/console": "^4.4.8|^5|^6", + "symfony/event-dispatcher": "^4.4.8|^5|^6", + "symfony/finder": "^4.4.8|^5|^6" }, "require-dev": { + "composer-runtime-api": "^2.0", "phpunit/phpunit": "^7.5.20 || ^8 || ^9", "squizlabs/php_codesniffer": "^3", "yoast/phpunit-polyfills": "^0.2.0" @@ -200,9 +201,9 @@ "description": "Initialize Symfony Console commands from annotated command class methods.", "support": { "issues": "https://github.com/consolidation/annotated-command/issues", - "source": "https://github.com/consolidation/annotated-command/tree/4.4.0" + "source": "https://github.com/consolidation/annotated-command/tree/4.5.0" }, - "time": "2021-09-30T01:08:15+00:00" + "time": "2021-12-27T19:34:17+00:00" }, { "name": "consolidation/config", @@ -413,30 +414,30 @@ }, { "name": "consolidation/output-formatters", - "version": "4.1.2", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9" + "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/5821e6ae076bf690058a4de6c94dce97398a69c9", - "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/27cf221f6e59b1debed0c6c94015e78cd5f10e24", + "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24", "shasum": "" }, "require": { "dflydev/dot-access-data": "^1.1.0", "php": ">=7.1.3", - "symfony/console": "^4|^5", - "symfony/finder": "^4|^5" + "symfony/console": "^4|^5|^6", + "symfony/finder": "^4|^5|^6" }, "require-dev": { "php-coveralls/php-coveralls": "^2.4.2", "phpunit/phpunit": ">=7", "squizlabs/php_codesniffer": "^3", - "symfony/var-dumper": "^4", - "symfony/yaml": "^4", + "symfony/var-dumper": "^4|^5|^6", + "symfony/yaml": "^4|^5|^6", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { @@ -466,30 +467,30 @@ "description": "Format text by applying transformations provided by plug-in formatters.", "support": { "issues": "https://github.com/consolidation/output-formatters/issues", - "source": "https://github.com/consolidation/output-formatters/tree/4.1.2" + "source": "https://github.com/consolidation/output-formatters/tree/4.2.0" }, - "time": "2020-12-12T19:04:59+00:00" + "time": "2021-12-27T14:30:41+00:00" }, { "name": "consolidation/robo", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/consolidation/Robo.git", - "reference": "a9ce34c3d0fb3e8619fc4a6f72c51678caf1b99b" + "reference": "36dce2965a67abe5cf91f2bc36d2582a64a11258" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/Robo/zipball/a9ce34c3d0fb3e8619fc4a6f72c51678caf1b99b", - "reference": "a9ce34c3d0fb3e8619fc4a6f72c51678caf1b99b", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/36dce2965a67abe5cf91f2bc36d2582a64a11258", + "reference": "36dce2965a67abe5cf91f2bc36d2582a64a11258", "shasum": "" }, "require": { - "consolidation/annotated-command": "^4.2.4", + "consolidation/annotated-command": "^4.3", "consolidation/config": "^1.2.1|^2.0.1", "consolidation/log": "^1.1.1|^2.0.2", "consolidation/output-formatters": "^4.1.2", - "consolidation/self-update": "^1.2", + "consolidation/self-update": "^2.0", "league/container": "^3.3.1", "php": ">=7.1.3", "symfony/console": "^4.4.19 || ^5", @@ -507,7 +508,7 @@ "patchwork/jsqueeze": "^2", "pear/archive_tar": "^1.4.4", "phpunit/phpunit": "^7.5.20 | ^8", - "squizlabs/php_codesniffer": "^3", + "squizlabs/php_codesniffer": "^3.6", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { @@ -565,25 +566,26 @@ "description": "Modern task runner", "support": { "issues": "https://github.com/consolidation/Robo/issues", - "source": "https://github.com/consolidation/Robo/tree/3.0.5" + "source": "https://github.com/consolidation/Robo/tree/3.0.6" }, - "time": "2021-08-29T21:11:31+00:00" + "time": "2021-10-05T23:56:45+00:00" }, { "name": "consolidation/self-update", - "version": "1.2.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/consolidation/self-update.git", - "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4" + "reference": "74289cf9b37d5cf84321ebea47deeea21678b940" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/self-update/zipball/dba6b2c0708f20fa3ba8008a2353b637578849b4", - "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/74289cf9b37d5cf84321ebea47deeea21678b940", + "reference": "74289cf9b37d5cf84321ebea47deeea21678b940", "shasum": "" }, "require": { + "composer/semver": "^3.2", "php": ">=5.5.0", "symfony/console": "^2.8|^3|^4|^5", "symfony/filesystem": "^2.5|^3|^4|^5" @@ -594,7 +596,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -619,22 +621,22 @@ "description": "Provides a self:update command for Symfony Console applications.", "support": { "issues": "https://github.com/consolidation/self-update/issues", - "source": "https://github.com/consolidation/self-update/tree/1.2.0" + "source": "https://github.com/consolidation/self-update/tree/2.0.2" }, - "time": "2020-04-13T02:49:20+00:00" + "time": "2021-12-17T16:45:58+00:00" }, { "name": "consolidation/site-alias", - "version": "3.1.1", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/consolidation/site-alias.git", - "reference": "e824b57253d9174f4a500f87e6d0e1e497c2a50a" + "reference": "2d514a1b278a1c5f28df20df317631f9829a88f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/site-alias/zipball/e824b57253d9174f4a500f87e6d0e1e497c2a50a", - "reference": "e824b57253d9174f4a500f87e6d0e1e497c2a50a", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/2d514a1b278a1c5f28df20df317631f9829a88f2", + "reference": "2d514a1b278a1c5f28df20df317631f9829a88f2", "shasum": "" }, "require": { @@ -677,9 +679,9 @@ "description": "Manage alias records for local and remote sites.", "support": { "issues": "https://github.com/consolidation/site-alias/issues", - "source": "https://github.com/consolidation/site-alias/tree/3.1.1" + "source": "https://github.com/consolidation/site-alias/tree/3.1.2" }, - "time": "2021-09-21T00:30:48+00:00" + "time": "2021-10-29T17:58:54+00:00" }, { "name": "consolidation/site-process", @@ -1044,16 +1046,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.4.1", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", "shasum": "" }, "require": { @@ -1065,7 +1067,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -1081,10 +1083,25 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], "description": "Guzzle promises library", @@ -1093,22 +1110,36 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" + "source": "https://github.com/guzzle/promises/tree/1.5.1" }, - "time": "2021-03-07T09:25:29+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:56:57+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.8.2", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" + "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", + "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85", "shasum": "" }, "require": { @@ -1145,13 +1176,34 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, { "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], @@ -1168,9 +1220,23 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.2" + "source": "https://github.com/guzzle/psr7/tree/1.8.3" }, - "time": "2021-04-26T09:17:50+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2021-10-05T13:56:00+00:00" }, { "name": "league/container", @@ -1253,16 +1319,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.0", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", - "reference": "50953a2691a922aa1769461637869a0a2faa3f53", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -1303,9 +1369,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "time": "2021-09-20T12:20:58+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "psr/container", @@ -1579,16 +1645,16 @@ }, { "name": "symfony/console", - "version": "v4.4.30", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a3f7189a0665ee33b50e9e228c46f50f5acbed22" + "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a3f7189a0665ee33b50e9e228c46f50f5acbed22", - "reference": "a3f7189a0665ee33b50e9e228c46f50f5acbed22", + "url": "https://api.github.com/repos/symfony/console/zipball/329b3a75cc6b16d435ba1b1a41df54a53382a3f0", + "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0", "shasum": "" }, "require": { @@ -1649,7 +1715,7 @@ "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.30" + "source": "https://github.com/symfony/console/tree/v4.4.34" }, "funding": [ { @@ -1665,20 +1731,87 @@ "type": "tidelift" } ], - "time": "2021-08-25T19:27:26+00:00" + "time": "2021-11-04T12:23:33+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.30", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "2fe81680070043c4c80e7cedceb797e34f377bac" + "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2fe81680070043c4c80e7cedceb797e34f377bac", - "reference": "2fe81680070043c4c80e7cedceb797e34f377bac", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8", + "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8", "shasum": "" }, "require": { @@ -1733,7 +1866,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.30" + "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.34" }, "funding": [ { @@ -1749,20 +1882,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T20:31:23+00:00" + "time": "2021-11-15T14:42:25+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.9", + "version": "v1.1.11", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7" + "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/84e23fdcd2517bf37aecbd16967e83f0caee25a7", - "reference": "84e23fdcd2517bf37aecbd16967e83f0caee25a7", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/01e9a4efac0ee33a05dfdf93b346f62e7d0e998c", + "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c", "shasum": "" }, "require": { @@ -1775,7 +1908,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "1.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -1812,7 +1945,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.9" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.11" }, "funding": [ { @@ -1828,25 +1961,26 @@ "type": "tidelift" } ], - "time": "2020-07-06T13:19:58+00:00" + "time": "2021-03-23T15:25:38+00:00" }, { "name": "symfony/filesystem", - "version": "v4.4.27", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "517fb795794faf29086a77d99eb8f35e457837a7" + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/517fb795794faf29086a77d99eb8f35e457837a7", - "reference": "517fb795794faf29086a77d99eb8f35e457837a7", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", "symfony/polyfill-php80": "^1.16" }, "type": "library", @@ -1875,7 +2009,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v4.4.27" + "source": "https://github.com/symfony/filesystem/tree/v5.4.0" }, "funding": [ { @@ -1891,24 +2025,25 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:19:41+00:00" + "time": "2021-10-28T13:39:27+00:00" }, { "name": "symfony/finder", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590", + "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16" }, "type": "library", @@ -1937,7 +2072,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.7" + "source": "https://github.com/symfony/finder/tree/v5.4.0" }, "funding": [ { @@ -1953,7 +2088,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-28T15:25:38+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2606,16 +2741,16 @@ }, { "name": "symfony/process", - "version": "v4.4.30", + "version": "v4.4.35", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d" + "reference": "c2098705326addae6e6742151dfade47ac71da1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d", - "reference": "13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d", + "url": "https://api.github.com/repos/symfony/process/zipball/c2098705326addae6e6742151dfade47ac71da1b", + "reference": "c2098705326addae6e6742151dfade47ac71da1b", "shasum": "" }, "require": { @@ -2648,7 +2783,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v4.4.30" + "source": "https://github.com/symfony/process/tree/v4.4.35" }, "funding": [ { @@ -2664,25 +2799,29 @@ "type": "tidelift" } ], - "time": "2021-08-04T20:31:23+00:00" + "time": "2021-11-22T22:36:24+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1" + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -2690,7 +2829,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2727,7 +2866,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, "funding": [ { @@ -2743,20 +2882,20 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:43:52+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { "name": "symfony/string", - "version": "v5.3.7", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" + "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", - "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", + "url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", + "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", "shasum": "" }, "require": { @@ -2767,11 +2906,14 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "~1.15" }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -2810,7 +2952,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.7" + "source": "https://github.com/symfony/string/tree/v5.4.0" }, "funding": [ { @@ -2826,20 +2968,20 @@ "type": "tidelift" } ], - "time": "2021-08-26T08:00:08+00:00" + "time": "2021-11-24T10:02:00+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.3.8", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "eaaea4098be1c90c8285543e1356a09c8aa5c8da" + "reference": "89ab66eaef230c9cd1992de2e9a1b26652b127b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eaaea4098be1c90c8285543e1356a09c8aa5c8da", - "reference": "eaaea4098be1c90c8285543e1356a09c8aa5c8da", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/89ab66eaef230c9cd1992de2e9a1b26652b127b9", + "reference": "89ab66eaef230c9cd1992de2e9a1b26652b127b9", "shasum": "" }, "require": { @@ -2853,8 +2995,9 @@ }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/uid": "^5.1|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -2898,7 +3041,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.8" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.0" }, "funding": [ { @@ -2914,20 +3057,20 @@ "type": "tidelift" } ], - "time": "2021-09-24T15:59:58+00:00" + "time": "2021-11-29T15:30:56+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.29", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "3abcc4db06d4e776825eaa3ed8ad924d5bc7432a" + "reference": "2c309e258adeb9970229042be39b360d34986fad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/3abcc4db06d4e776825eaa3ed8ad924d5bc7432a", - "reference": "3abcc4db06d4e776825eaa3ed8ad924d5bc7432a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2c309e258adeb9970229042be39b360d34986fad", + "reference": "2c309e258adeb9970229042be39b360d34986fad", "shasum": "" }, "require": { @@ -2969,7 +3112,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v4.4.29" + "source": "https://github.com/symfony/yaml/tree/v4.4.34" }, "funding": [ { @@ -2985,7 +3128,7 @@ "type": "tidelift" } ], - "time": "2021-07-27T16:19:30+00:00" + "time": "2021-11-18T18:49:23+00:00" }, { "name": "twig/twig", @@ -3216,6 +3359,7 @@ "issues": "https://github.com/webmozart/path-util/issues", "source": "https://github.com/webmozart/path-util/tree/2.3.0" }, + "abandoned": "symfony/filesystem", "time": "2015-12-17T08:42:14+00:00" } ], @@ -3849,16 +3993,16 @@ }, { "name": "drupal/core", - "version": "9.3.x-dev", + "version": "9.3.0", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "4d5164bf86cfcde10135505c5966397d000f7e32" + "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/4d5164bf86cfcde10135505c5966397d000f7e32", - "reference": "4d5164bf86cfcde10135505c5966397d000f7e32", + "url": "https://api.github.com/repos/drupal/core/zipball/1e1bf0e841e11029b21775dd125332d7ffd6fb47", + "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47", "shasum": "" }, "require": { @@ -3866,7 +4010,7 @@ "composer/semver": "^3.0", "doctrine/annotations": "^1.12", "doctrine/reflection": "^1.1", - "egulias/email-validator": "^2.0", + "egulias/email-validator": "^2.1.22|^3.0", "ext-date": "*", "ext-dom": "*", "ext-filter": "*", @@ -3894,7 +4038,7 @@ "symfony/event-dispatcher": "^4.4", "symfony/http-foundation": "^4.4.7", "symfony/http-kernel": "^4.4", - "symfony/mime": "^5.3.0", + "symfony/mime": "^5.4", "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-php80": "^1.16", "symfony/process": "^4.4", @@ -3923,6 +4067,7 @@ "drupal/book": "self.version", "drupal/breakpoint": "self.version", "drupal/ckeditor": "self.version", + "drupal/ckeditor5": "self.version", "drupal/claro": "self.version", "drupal/classy": "self.version", "drupal/color": "self.version", @@ -4099,39 +4244,39 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/9.3.x" + "source": "https://github.com/drupal/core/tree/9.3.0" }, - "time": "2021-10-01T12:45:01+00:00" + "time": "2021-12-08T22:09:38+00:00" }, { "name": "drupal/core-recommended", - "version": "9.3.x-dev", + "version": "9.3.0", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "0763c9db8e41012509356c5eb59485a0215808ce" + "reference": "d65aaa36a8cab54332787a20676f81928f675bb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/0763c9db8e41012509356c5eb59485a0215808ce", - "reference": "0763c9db8e41012509356c5eb59485a0215808ce", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/d65aaa36a8cab54332787a20676f81928f675bb3", + "reference": "d65aaa36a8cab54332787a20676f81928f675bb3", "shasum": "" }, "require": { "asm89/stack-cors": "1.3.0", - "composer/semver": "3.2.5", + "composer/semver": "3.2.6", "doctrine/annotations": "1.13.2", "doctrine/lexer": "1.2.1", "doctrine/reflection": "1.2.2", - "drupal/core": "9.3.x-dev", - "egulias/email-validator": "2.1.25", + "drupal/core": "9.3.0", + "egulias/email-validator": "3.1.2", "guzzlehttp/guzzle": "6.5.5", - "guzzlehttp/promises": "1.4.1", - "guzzlehttp/psr7": "1.8.2", + "guzzlehttp/promises": "1.5.1", + "guzzlehttp/psr7": "1.8.3", "laminas/laminas-diactoros": "2.8.0", "laminas/laminas-escaper": "2.9.0", "laminas/laminas-feed": "2.15.0", - "laminas/laminas-stdlib": "3.6.0", + "laminas/laminas-stdlib": "3.6.1", "masterminds/html5": "2.7.5", "pear/archive_tar": "1.4.14", "pear/console_getopt": "v1.4.3", @@ -4144,34 +4289,34 @@ "psr/log": "1.1.4", "ralouphie/getallheaders": "3.0.3", "stack/builder": "v1.0.6", - "symfony-cmf/routing": "2.3.3", - "symfony/console": "v4.4.30", + "symfony-cmf/routing": "2.3.4", + "symfony/console": "v4.4.34", "symfony/debug": "v4.4.31", - "symfony/dependency-injection": "v4.4.31", - "symfony/deprecation-contracts": "v2.4.0", - "symfony/error-handler": "v4.4.30", - "symfony/event-dispatcher": "v4.4.30", - "symfony/event-dispatcher-contracts": "v1.1.9", - "symfony/http-client-contracts": "v2.4.0", - "symfony/http-foundation": "v4.4.30", - "symfony/http-kernel": "v4.4.32", - "symfony/mime": "v5.3.8", + "symfony/dependency-injection": "v4.4.34", + "symfony/deprecation-contracts": "v2.5.0", + "symfony/error-handler": "v4.4.34", + "symfony/event-dispatcher": "v4.4.34", + "symfony/event-dispatcher-contracts": "v1.1.11", + "symfony/http-client-contracts": "v2.5.0", + "symfony/http-foundation": "v4.4.34", + "symfony/http-kernel": "v4.4.35", + "symfony/mime": "v5.4.0", "symfony/polyfill-ctype": "v1.23.0", "symfony/polyfill-iconv": "v1.23.0", "symfony/polyfill-intl-idn": "v1.23.0", "symfony/polyfill-intl-normalizer": "v1.23.0", "symfony/polyfill-mbstring": "v1.23.1", "symfony/polyfill-php80": "v1.23.1", - "symfony/process": "v4.4.30", - "symfony/psr-http-message-bridge": "v2.1.1", - "symfony/routing": "v4.4.30", - "symfony/serializer": "v4.4.31", - "symfony/service-contracts": "v2.4.0", - "symfony/translation": "v4.4.32", - "symfony/translation-contracts": "v2.4.0", - "symfony/validator": "v4.4.31", - "symfony/var-dumper": "v5.3.8", - "symfony/yaml": "v4.4.29", + "symfony/process": "v4.4.35", + "symfony/psr-http-message-bridge": "v2.1.2", + "symfony/routing": "v4.4.34", + "symfony/serializer": "v4.4.35", + "symfony/service-contracts": "v2.5.0", + "symfony/translation": "v4.4.34", + "symfony/translation-contracts": "v2.5.0", + "symfony/validator": "v4.4.35", + "symfony/var-dumper": "v5.4.0", + "symfony/yaml": "v4.4.34", "twig/twig": "v2.14.7", "typo3/phar-stream-wrapper": "v3.1.7" }, @@ -4185,9 +4330,9 @@ ], "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/9.3.x" + "source": "https://github.com/drupal/core-recommended/tree/9.3.0" }, - "time": "2021-09-29T09:09:29+00:00" + "time": "2021-12-08T22:09:38+00:00" }, { "name": "drupal/semver_example", @@ -4243,27 +4388,27 @@ }, { "name": "egulias/email-validator", - "version": "2.1.25", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4" + "reference": "ee0db30118f661fb166bcffbf5d82032df484697" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4", - "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ee0db30118f661fb166bcffbf5d82032df484697", + "reference": "ee0db30118f661fb166bcffbf5d82032df484697", "shasum": "" }, "require": { - "doctrine/lexer": "^1.0.1", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.10" + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" }, "require-dev": { - "dominicsayers/isemail": "^3.0.7", - "phpunit/phpunit": "^4.8.36|^7.5.15", - "satooshi/php-coveralls": "^1.0.1" + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" }, "suggest": { "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" @@ -4271,7 +4416,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -4299,7 +4444,7 @@ ], "support": { "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/2.1.25" + "source": "https://github.com/egulias/EmailValidator/tree/3.1.2" }, "funding": [ { @@ -4307,7 +4452,7 @@ "type": "github" } ], - "time": "2020-12-29T14:50:06+00:00" + "time": "2021-10-11T09:18:27+00:00" }, { "name": "jakeasmith/http_build_url", @@ -4586,16 +4731,16 @@ }, { "name": "laminas/laminas-stdlib", - "version": "3.6.0", + "version": "3.6.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "c53d8537f108fac3fae652677a19735db730ba46" + "reference": "db581851a092246ad99e12d4fddf105184924c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/c53d8537f108fac3fae652677a19735db730ba46", - "reference": "c53d8537f108fac3fae652677a19735db730ba46", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/db581851a092246ad99e12d4fddf105184924c71", + "reference": "db581851a092246ad99e12d4fddf105184924c71", "shasum": "" }, "require": { @@ -4641,7 +4786,7 @@ "type": "community_bridge" } ], - "time": "2021-09-02T16:11:32+00:00" + "time": "2021-11-10T11:33:52+00:00" }, { "name": "masterminds/html5", @@ -5231,16 +5376,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { @@ -5251,7 +5396,8 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -5281,22 +5427,22 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" }, - "time": "2020-09-03T19:13:55+00:00" + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -5331,22 +5477,22 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" }, - "time": "2021-09-17T15:28:14+00:00" + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -5398,9 +5544,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpstan/phpstan", @@ -5468,23 +5614,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.7", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d4c798ed8d51506800b441f7a13ecb0f76f12218", - "reference": "d4c798ed8d51506800b441f7a13ecb0f76f12218", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.12.0", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -5533,7 +5679,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.7" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { @@ -5541,20 +5687,20 @@ "type": "github" } ], - "time": "2021-09-17T05:39:03+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -5593,7 +5739,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -5601,7 +5747,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -5786,16 +5932,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.10", + "version": "9.5.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "reference": "2406855036db1102126125537adb1406f7242fdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd", + "reference": "2406855036db1102126125537adb1406f7242fdd", "shasum": "" }, "require": { @@ -5873,11 +6019,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -5885,7 +6031,7 @@ "type": "github" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2021-12-25T07:07:57+00:00" }, { "name": "psr/cache", @@ -5993,16 +6139,16 @@ }, { "name": "rector/rector", - "version": "0.11.58", + "version": "0.11.60", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "15a8647cf05641db35f091edf0a558ffa9619fee" + "reference": "428f593818f8c50fe12c543e8c0a107f9bd899ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/15a8647cf05641db35f091edf0a558ffa9619fee", - "reference": "15a8647cf05641db35f091edf0a558ffa9619fee", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/428f593818f8c50fe12c543e8c0a107f9bd899ae", + "reference": "428f593818f8c50fe12c543e8c0a107f9bd899ae", "shasum": "" }, "require": { @@ -6042,7 +6188,7 @@ "description": "Prefixed and PHP 7.1 downgraded version of rector/rector", "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.11.58" + "source": "https://github.com/rectorphp/rector/tree/0.11.60" }, "funding": [ { @@ -6050,7 +6196,7 @@ "type": "github" } ], - "time": "2021-10-12T20:26:47+00:00" + "time": "2021-10-20T13:08:22+00:00" }, { "name": "sebastian/cli-parser", @@ -6481,16 +6627,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -6539,14 +6685,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" }, "funding": [ { @@ -6554,7 +6700,7 @@ "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", @@ -7018,16 +7164,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.0", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", "shasum": "" }, "require": { @@ -7070,7 +7216,7 @@ "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2021-04-09T00:54:41+00:00" + "time": "2021-12-12T21:44:58+00:00" }, { "name": "stack/builder", @@ -7128,21 +7274,21 @@ }, { "name": "symfony-cmf/routing", - "version": "2.3.3", + "version": "2.3.4", "source": { "type": "git", "url": "https://github.com/symfony-cmf/Routing.git", - "reference": "3c97e7b7709b313cecfb76d691ad4cc22acbf3f5" + "reference": "bbcdf2f6301d740454ba9ebb8adaefd436c36a6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/3c97e7b7709b313cecfb76d691ad4cc22acbf3f5", - "reference": "3c97e7b7709b313cecfb76d691ad4cc22acbf3f5", + "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/bbcdf2f6301d740454ba9ebb8adaefd436c36a6b", + "reference": "bbcdf2f6301d740454ba9ebb8adaefd436c36a6b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "psr/log": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "symfony/http-kernel": "^4.4 || ^5.0", "symfony/routing": "^4.4 || ^5.0" }, @@ -7185,9 +7331,9 @@ ], "support": { "issues": "https://github.com/symfony-cmf/Routing/issues", - "source": "https://github.com/symfony-cmf/Routing/tree/2.3.3" + "source": "https://github.com/symfony-cmf/Routing/tree/2.3.4" }, - "time": "2020-10-06T10:15:37+00:00" + "time": "2021-11-08T16:33:10+00:00" }, { "name": "symfony/debug", @@ -7259,16 +7405,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.4.31", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "75dd7094870feaa5be9ed2b6b1efcfc2b7d3b9b4" + "reference": "117d7f132ed7efbd535ec947709d49bec1b9d24b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/75dd7094870feaa5be9ed2b6b1efcfc2b7d3b9b4", - "reference": "75dd7094870feaa5be9ed2b6b1efcfc2b7d3b9b4", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/117d7f132ed7efbd535ec947709d49bec1b9d24b", + "reference": "117d7f132ed7efbd535ec947709d49bec1b9d24b", "shasum": "" }, "require": { @@ -7325,7 +7471,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v4.4.31" + "source": "https://github.com/symfony/dependency-injection/tree/v4.4.34" }, "funding": [ { @@ -7341,87 +7487,20 @@ "type": "tidelift" } ], - "time": "2021-09-21T06:20:06+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-11-15T14:42:25+00:00" }, { "name": "symfony/error-handler", - "version": "v4.4.30", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "51f98f7aa99f00f3b1da6bafe934e67ae6ba6dc5" + "reference": "17785c374645def1e884d8ec49976c156c61db4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/51f98f7aa99f00f3b1da6bafe934e67ae6ba6dc5", - "reference": "51f98f7aa99f00f3b1da6bafe934e67ae6ba6dc5", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/17785c374645def1e884d8ec49976c156c61db4d", + "reference": "17785c374645def1e884d8ec49976c156c61db4d", "shasum": "" }, "require": { @@ -7460,7 +7539,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v4.4.30" + "source": "https://github.com/symfony/error-handler/tree/v4.4.34" }, "funding": [ { @@ -7476,20 +7555,20 @@ "type": "tidelift" } ], - "time": "2021-08-27T17:42:48+00:00" + "time": "2021-11-12T14:57:39+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ec82e57b5b714dbb69300d348bd840b345e24166", + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166", "shasum": "" }, "require": { @@ -7501,7 +7580,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -7538,7 +7617,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.0" }, "funding": [ { @@ -7554,20 +7633,20 @@ "type": "tidelift" } ], - "time": "2021-04-11T23:07:08+00:00" + "time": "2021-11-03T09:24:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.30", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "09b3202651ab23ac8dcf455284a48a3500e56731" + "reference": "f4cbbb6fc428588ce8373802461e7fe84e6809ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/09b3202651ab23ac8dcf455284a48a3500e56731", - "reference": "09b3202651ab23ac8dcf455284a48a3500e56731", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4cbbb6fc428588ce8373802461e7fe84e6809ab", + "reference": "f4cbbb6fc428588ce8373802461e7fe84e6809ab", "shasum": "" }, "require": { @@ -7606,7 +7685,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v4.4.30" + "source": "https://github.com/symfony/http-foundation/tree/v4.4.34" }, "funding": [ { @@ -7622,20 +7701,20 @@ "type": "tidelift" } ], - "time": "2021-08-26T15:51:23+00:00" + "time": "2021-11-04T12:23:33+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.32", + "version": "v4.4.35", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f7bda3ea8f05ae90627400e58af5179b25ce0f38" + "reference": "fb793f1381c34b79a43596a532a6a49bd729c9db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f7bda3ea8f05ae90627400e58af5179b25ce0f38", - "reference": "f7bda3ea8f05ae90627400e58af5179b25ce0f38", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/fb793f1381c34b79a43596a532a6a49bd729c9db", + "reference": "fb793f1381c34b79a43596a532a6a49bd729c9db", "shasum": "" }, "require": { @@ -7710,7 +7789,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v4.4.32" + "source": "https://github.com/symfony/http-kernel/tree/v4.4.35" }, "funding": [ { @@ -7726,25 +7805,25 @@ "type": "tidelift" } ], - "time": "2021-09-28T10:20:04+00:00" + "time": "2021-11-24T08:40:10+00:00" }, { "name": "symfony/mime", - "version": "v5.3.8", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "a756033d0a7e53db389618653ae991eba5a19a11" + "reference": "d4365000217b67c01acff407573906ff91bcfb34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a756033d0a7e53db389618653ae991eba5a19a11", - "reference": "a756033d0a7e53db389618653ae991eba5a19a11", + "url": "https://api.github.com/repos/symfony/mime/zipball/d4365000217b67c01acff407573906ff91bcfb34", + "reference": "d4365000217b67c01acff407573906ff91bcfb34", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.16" @@ -7758,10 +7837,10 @@ "require-dev": { "egulias/email-validator": "^2.1.10|^3.1", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/property-access": "^4.4|^5.1", - "symfony/property-info": "^4.4|^5.1", - "symfony/serializer": "^5.2" + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/property-access": "^4.4|^5.1|^6.0", + "symfony/property-info": "^4.4|^5.1|^6.0", + "symfony/serializer": "^5.2|^6.0" }, "type": "library", "autoload": { @@ -7793,7 +7872,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.3.8" + "source": "https://github.com/symfony/mime/tree/v5.4.0" }, "funding": [ { @@ -7809,7 +7888,7 @@ "type": "tidelift" } ], - "time": "2021-09-10T12:30:38+00:00" + "time": "2021-11-23T10:19:22+00:00" }, { "name": "symfony/polyfill-iconv", @@ -7893,32 +7972,32 @@ }, { "name": "symfony/psr-http-message-bridge", - "version": "v2.1.1", + "version": "v2.1.2", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba" + "reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/c9012994c4b4fb23e7c57dd86b763a417a04feba", - "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34", + "reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34", "shasum": "" }, "require": { "php": ">=7.1", "psr/http-message": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.0" + "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0" }, "require-dev": { "nyholm/psr7": "^1.1", "psr/log": "^1.1 || ^2 || ^3", - "symfony/browser-kit": "^4.4 || ^5.0", - "symfony/config": "^4.4 || ^5.0", - "symfony/event-dispatcher": "^4.4 || ^5.0", - "symfony/framework-bundle": "^4.4 || ^5.0", - "symfony/http-kernel": "^4.4 || ^5.0", - "symfony/phpunit-bridge": "^4.4.19 || ^5.2" + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/config": "^4.4 || ^5.0 || ^6.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4@dev || ^6.0" }, "suggest": { "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" @@ -7961,7 +8040,7 @@ ], "support": { "issues": "https://github.com/symfony/psr-http-message-bridge/issues", - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.1" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.2" }, "funding": [ { @@ -7977,20 +8056,20 @@ "type": "tidelift" } ], - "time": "2021-07-27T17:25:39+00:00" + "time": "2021-11-05T13:13:39+00:00" }, { "name": "symfony/routing", - "version": "v4.4.30", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9ddf033927ad9f30ba2bfd167a7b342cafa13e8e" + "reference": "fc9dda0c8496f8ef0a89805c2eabfc43b8cef366" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9ddf033927ad9f30ba2bfd167a7b342cafa13e8e", - "reference": "9ddf033927ad9f30ba2bfd167a7b342cafa13e8e", + "url": "https://api.github.com/repos/symfony/routing/zipball/fc9dda0c8496f8ef0a89805c2eabfc43b8cef366", + "reference": "fc9dda0c8496f8ef0a89805c2eabfc43b8cef366", "shasum": "" }, "require": { @@ -8050,7 +8129,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v4.4.30" + "source": "https://github.com/symfony/routing/tree/v4.4.34" }, "funding": [ { @@ -8066,20 +8145,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:41:01+00:00" + "time": "2021-11-04T12:23:33+00:00" }, { "name": "symfony/serializer", - "version": "v4.4.31", + "version": "v4.4.35", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "a10b610f75349dbee1d3ad05c7a2cbf4f1872e34" + "reference": "1b2ae02cb1b923987947e013688c51954a80b751" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/a10b610f75349dbee1d3ad05c7a2cbf4f1872e34", - "reference": "a10b610f75349dbee1d3ad05c7a2cbf4f1872e34", + "url": "https://api.github.com/repos/symfony/serializer/zipball/1b2ae02cb1b923987947e013688c51954a80b751", + "reference": "1b2ae02cb1b923987947e013688c51954a80b751", "shasum": "" }, "require": { @@ -8144,7 +8223,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v4.4.31" + "source": "https://github.com/symfony/serializer/tree/v4.4.35" }, "funding": [ { @@ -8160,20 +8239,20 @@ "type": "tidelift" } ], - "time": "2021-09-17T08:50:49+00:00" + "time": "2021-11-24T08:12:42+00:00" }, { "name": "symfony/translation", - "version": "v4.4.32", + "version": "v4.4.34", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "db0ba1e85280d8ff11e38d53c70f8814d4d740f5" + "reference": "26d330720627b234803595ecfc0191eeabc65190" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/db0ba1e85280d8ff11e38d53c70f8814d4d740f5", - "reference": "db0ba1e85280d8ff11e38d53c70f8814d4d740f5", + "url": "https://api.github.com/repos/symfony/translation/zipball/26d330720627b234803595ecfc0191eeabc65190", + "reference": "26d330720627b234803595ecfc0191eeabc65190", "shasum": "" }, "require": { @@ -8233,7 +8312,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v4.4.32" + "source": "https://github.com/symfony/translation/tree/v4.4.34" }, "funding": [ { @@ -8249,20 +8328,20 @@ "type": "tidelift" } ], - "time": "2021-08-26T05:57:13+00:00" + "time": "2021-11-04T12:23:33+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95" + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", "shasum": "" }, "require": { @@ -8274,7 +8353,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -8311,7 +8390,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.0" }, "funding": [ { @@ -8327,20 +8406,20 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-08-17T14:20:01+00:00" }, { "name": "symfony/validator", - "version": "v4.4.31", + "version": "v4.4.35", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "9420a2e8874263a684588283e40252209d80e1a5" + "reference": "629f420d8350634fd8ed686d4472c1f10044b265" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/9420a2e8874263a684588283e40252209d80e1a5", - "reference": "9420a2e8874263a684588283e40252209d80e1a5", + "url": "https://api.github.com/repos/symfony/validator/zipball/629f420d8350634fd8ed686d4472c1f10044b265", + "reference": "629f420d8350634fd8ed686d4472c1f10044b265", "shasum": "" }, "require": { @@ -8417,7 +8496,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v4.4.31" + "source": "https://github.com/symfony/validator/tree/v4.4.35" }, "funding": [ { @@ -8433,7 +8512,7 @@ "type": "tidelift" } ], - "time": "2021-09-20T16:52:24+00:00" + "time": "2021-11-22T21:43:32+00:00" }, { "name": "theseer/tokenizer", @@ -8542,16 +8621,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v2.6.7", + "version": "v2.6.9", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "b786088918a884258c9e3e27405c6a4cf2ee246e" + "reference": "2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b786088918a884258c9e3e27405c6a4cf2ee246e", - "reference": "b786088918a884258c9e3e27405c6a4cf2ee246e", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141", + "reference": "2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141", "shasum": "" }, "require": { @@ -8561,7 +8640,7 @@ "require-dev": { "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.21" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -8585,13 +8664,13 @@ "authors": [ { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "homepage": "https://gjcampbell.co.uk/" + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { "name": "Vance Lucas", "email": "vance@vancelucas.com", - "homepage": "https://vancelucas.com/" + "homepage": "https://github.com/vlucas" } ], "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", @@ -8602,7 +8681,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v2.6.7" + "source": "https://github.com/vlucas/phpdotenv/tree/v2.6.9" }, "funding": [ { @@ -8614,7 +8693,7 @@ "type": "tidelift" } ], - "time": "2021-01-20T14:39:13+00:00" + "time": "2021-12-12T22:59:22+00:00" }, { "name": "yoast/phpunit-polyfills", From 12e54a45004b973999368f72c81e04a5d8235958 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 27 Dec 2021 21:12:00 -0500 Subject: [PATCH 029/125] Bump security test from drupal/core 9.1 to 9.2.8 (#4952) * Bump security test from drupal/core 9.1 to 9.2.8 * fix job name --- .circleci/config.yml | 8 ++++---- tests/integration/SecurityUpdatesTest.php | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7263ba9f0d..8ec7c1167b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -89,8 +89,8 @@ jobs: POSTGRES_USER: unish <<: *test74steps - # Drupal 9.1.0 for Security test coverage for drupal/core - test_74_drupal91_security: + # Drupal 9.2.8 for Security test coverage for drupal/core + test_74_drupal92_security: <<: *defaults docker: - image: wodby/php:7.4 @@ -101,7 +101,7 @@ jobs: steps: - checkout - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - - run: composer require --dev drupal/core-recommended:9.1.0 --no-update + - run: composer require --dev drupal/core-recommended:9.2.8 --no-update - run: composer require symfony/polyfill-php80:"1.23 as 1.20" --no-update - run: php --version - run: composer update @@ -140,7 +140,7 @@ workflows: jobs: - code_style - check_mergable - - test_74_drupal91_security: + - test_74_drupal92_security: <<: *requires - test_74_drupal9_mysql: <<: *requires diff --git a/tests/integration/SecurityUpdatesTest.php b/tests/integration/SecurityUpdatesTest.php index 3cc1df6435..0897fa69dd 100644 --- a/tests/integration/SecurityUpdatesTest.php +++ b/tests/integration/SecurityUpdatesTest.php @@ -24,14 +24,14 @@ public function testInsecureDrupalPackage() $this->assertEquals($expected_package, $security_advisories[$expected_package]['name']); $this->assertEquals($expected_version, $security_advisories[$expected_package]['version']); - // If our SUT is 9.0.0, then we should find a security update for Drupal core too. - if (\Drupal::VERSION != '9.0.0') { - $this->markTestSkipped("We only test for drupal/core security updates if the SUT is on Drupal 9.0.0"); + // If our SUT is 9.2.8, then we should find a security update for Drupal core too. + if (\Drupal::VERSION != '9.2.8') { + $this->markTestSkipped("We only test for drupal/core security updates if the SUT is on Drupal 9.2.8"); } $this->assertStringContainsString("Try running: composer require drupal/core", $this->getErrorOutput()); $this->arrayHasKey('drupal/core', $security_advisories); $this->assertEquals('drupal/core', $security_advisories['drupal/core']['name']); - $this->assertEquals('9.0.0', $security_advisories['drupal/core']['version']); + $this->assertEquals('9.2.8', $security_advisories['drupal/core']['version']); } /** From 2d50f2b8b2d29e4b0dbf28c32de6df7045459cab Mon Sep 17 00:00:00 2001 From: Claudiu Cristea Date: Tue, 28 Dec 2021 04:25:06 +0200 Subject: [PATCH 030/125] Debug info preserved in stderr (#4835) * Debug info preserved in stderr * Use raw err output * Finally! Dont persist --verbose across drush() calls in Unish. Co-authored-by: Moshe Weitzman --- src/SiteAlias/ProcessManager.php | 5 ++--- tests/integration/IntegrationTestsTest.php | 22 ++++++++++++++++++++++ tests/unish/UnishIntegrationTestCase.php | 8 +++++++- 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tests/integration/IntegrationTestsTest.php diff --git a/src/SiteAlias/ProcessManager.php b/src/SiteAlias/ProcessManager.php index 4a272c7fe4..081b22bcdc 100644 --- a/src/SiteAlias/ProcessManager.php +++ b/src/SiteAlias/ProcessManager.php @@ -7,7 +7,6 @@ use Consolidation\SiteProcess\SiteProcess; use Drush\Drush; use Drush\Style\DrushStyle; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Process; use Webmozart\PathUtil\Path; @@ -148,8 +147,8 @@ protected static function configureProcess(ProcessBase $process) $process->setSimulated(Drush::simulate()); $process->setVerbose(Drush::verbose()); // Don't let sub-process inherit the verbosity of its parent. - putenv('SHELL_VERBOSITY=' . OutputInterface::VERBOSITY_NORMAL); - $_ENV['SHELL_VERBOSITY'] = OutputInterface::VERBOSITY_NORMAL; + putenv('SHELL_VERBOSITY'); + unset($_ENV['SHELL_VERBOSITY']); $process->setLogger(Drush::logger()); $process->setRealtimeOutput(new DrushStyle(Drush::input(), Drush::output())); $process->setTimeout(Drush::getTimeout()); diff --git a/tests/integration/IntegrationTestsTest.php b/tests/integration/IntegrationTestsTest.php new file mode 100644 index 0000000000..a5d4eba33c --- /dev/null +++ b/tests/integration/IntegrationTestsTest.php @@ -0,0 +1,22 @@ +drush('version', [], ['debug' => null]); + $this->assertStringContainsString('[info] Starting bootstrap to none', $this->getErrorOutputRaw()); + $this->drush('version'); + $this->assertStringNotContainsString('[info] Starting bootstrap to none', $this->getErrorOutputRaw()); + } +} diff --git a/tests/unish/UnishIntegrationTestCase.php b/tests/unish/UnishIntegrationTestCase.php index 3b203bf424..2458a53359 100644 --- a/tests/unish/UnishIntegrationTestCase.php +++ b/tests/unish/UnishIntegrationTestCase.php @@ -8,6 +8,7 @@ use Drush\Runtime\Runtime; use Drush\Symfony\LessStrictArgvInput; use PHPUnit\Framework\TestResult; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Exception\ProcessTimedOutException; use Symfony\Component\Process\Process; use Unish\Controllers\RuntimeController; @@ -95,8 +96,13 @@ public function drush($command, array $args = [], array $options = [], $expected $return = $application->run($input, $output); $this->stdout = $output->fetch(); $this->stderr = $output->getErrorOutput()->fetch(); - $this->assertEquals($expected_return, $return, "Command failed: \n\n" . $this->getErrorOutput()); + // Undo the env variable and verbosity property that Process unhelpfully persists. + putenv('SHELL_VERBOSITY'); + unset($_ENV['SHELL_VERBOSITY']); + $output->setVerbosity(OutputInterface::VERBOSITY_NORMAL); + + $this->assertEquals($expected_return, $return, "Command failed: \n\n" . $this->getErrorOutput()); return $return; } From 88d21dc107642268e4e74f9d905a935834d196b1 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 27 Dec 2021 22:35:30 -0500 Subject: [PATCH 031/125] Briefer homepage, and fix docs site build error on non-annotated command. (#4953) * Briefer homepage, and fix docs site build error on non-annotated command. * Add comma --- docs/index.md | 14 +++++--------- mkdocs_base.yml | 2 ++ src/Commands/core/MkCommands.php | 17 +++++++++++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6abee0c20d..ea8a64774b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,16 +1,16 @@ -Drush is a command line shell and Unix scripting interface for Drupal. Drush core ships with lots of [useful commands](commands/all.md) for interacting with code like modules/themes/profiles. Similarly, it runs update.php, executes SQL queries and DB migrations, and misc utilities like run cron or clear cache. Developers love the [generate command](commands/generate.md), which jump starts your coding project by writing ready-to-customize PHP and YML files. Drush can be extended by [3rd party commandfiles](https://www.drupal.org/project/project_module?f[2]=im_vid_3%3A4654). +Drush is a command line shell and Unix scripting interface for Drupal. Drush core ships with lots of [useful commands](commands/all.md) and [generators](generators/all.md). Similarly, it runs update.php, executes SQL queries, runs content migrations, and misc utilities like cron or cache rebuild. Drush can be extended by [3rd party commandfiles](https://www.drupal.org/project/project_module?f[2]=im_vid_3%3A4654). [![Latest Stable Version](https://poser.pugx.org/drush/drush/v/stable.png)](https://packagist.org/packages/drush/drush) [![Total Downloads](https://poser.pugx.org/drush/drush/downloads.png)](https://packagist.org/packages/drush/drush) [![License](https://poser.pugx.org/drush/drush/license.png)](https://packagist.org/packages/drush/drush) [![Twitter](https://img.shields.io/badge/Twitter-%40DrushCli-blue.svg)](https://twitter.com/intent/user?screen_name=DrushCli) Resources ----------- -* [Installing and Upgrading](install.md) ([Drush 8](https://docs.drush.org/en/8.x/install/)) -* [Usage](usage.md) ([Drush 8](https://docs.drush.org/en/8.x/install/)) -* [Drush Commands](commands/all.md) +* [Installing and Upgrading](install.md) +* [Commands](commands/all.md) and [Generators](generators/all.md) * [API Documentation](https://www.drush.org/latest/api) * [Drush packages available via Composer](https://packagist.org/search/?type=drupal-drush) * [A list of modules that include Drush integration](https://www.drupal.org/project/project_module?f[2]=im_vid_3%3A4654&solrsort=ds_project_latest_release+desc) -* Drush comes with a [full test suite](https://github.com/drush-ops/drush/blob/11.x/docs/contribute/unish.md) powered by [PHPUnit](https://github.com/sebastianbergmann/phpunit). Each commit gets tested by our [CI bots](https://circleci.com/gh/drush-ops/drush/). +* Drush expects all participants to abide by the [Drupal Code of Conduct](https://www.drupal.org/dcoc). +* Drush 8 is no longer supported, but [here are its docs](https://docs.drush.org/en/8.x/install/). Support ----------- @@ -18,10 +18,6 @@ Support * Report bugs and request features in the [GitHub Drush Issue Queue](https://github.com/drush-ops/drush/issues). * Use pull requests (PRs) to contribute to Drush. [Guidelines](contribute/CONTRIBUTING.md). -Code of Conduct ---------------- -The Drush project expects all participants to abide by the [Drupal Code of Conduct](https://www.drupal.org/dcoc). - FAQ ------ diff --git a/mkdocs_base.yml b/mkdocs_base.yml index d160915174..80dfc71cfa 100644 --- a/mkdocs_base.yml +++ b/mkdocs_base.yml @@ -52,6 +52,8 @@ markdown_extensions: startinline: true - pymdownx.inlinehilite: { } - pymdownx.superfences: { } + - pymdownx.tabbed: + alternate_style: true - pymdownx.emoji: emoji_index: '!!python/name:materialx.emoji.twemoji' emoji_generator: '!!python/name:materialx.emoji.to_svg' diff --git a/src/Commands/core/MkCommands.php b/src/Commands/core/MkCommands.php index bfec5ec6c0..cc838513fc 100644 --- a/src/Commands/core/MkCommands.php +++ b/src/Commands/core/MkCommands.php @@ -100,7 +100,7 @@ protected static function appendPostAmble(): string EOT; } - protected static function appendAliases(AnnotatedCommand $command): string + protected static function appendAliases($command): string { if ($aliases = $command->getAliases()) { $body = "#### Aliases\n\n"; @@ -141,7 +141,7 @@ protected static function appendTopics(AnnotatedCommand $command, string $dir_co return ''; } - protected static function appendOptions(AnnotatedCommand $command): string + protected static function appendOptions($command): string { if ($opts = $command->getDefinition()->getOptions()) { $body = ''; @@ -159,7 +159,7 @@ protected static function appendOptions(AnnotatedCommand $command): string return ''; } - protected static function appendArguments(AnnotatedCommand $command): string + protected static function appendArguments($command): string { if ($args = $command->getDefinition()->getArguments()) { $body = "#### Arguments\n\n"; @@ -184,9 +184,12 @@ protected static function appendUsages(AnnotatedCommand $command): string return ''; } - protected static function appendPreamble(AnnotatedCommand $command, $root): string + protected static function appendPreamble($command, $root): string { - $path = Path::makeRelative($command->getAnnotationData()->get('_path'), $root); + $path = ''; + if ($command instanceof AnnotatedCommand) { + $path = Path::makeRelative($command->getAnnotationData()->get('_path'), $root); + } $edit_url = $path ? "https://github.com/drush-ops/drush/blob/11.x/$path" : ''; $body = <<optionsHook(); } $body = self::appendPreamble($command, $dir_root); - $body .= self::appendUsages($command); + if ($command instanceof AnnotatedCommand) { + $body .= self::appendUsages($command); + } $body .= self::appendArguments($command); $body .= self::appendOptions($command); if ($command instanceof AnnotatedCommand) { From 66fa21569b462f6b06d719a2a15ee47c66de0997 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 28 Dec 2021 07:33:02 -0500 Subject: [PATCH 032/125] Add an example in generate command. (#4955) --- src/Commands/generate/GenerateCommands.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Commands/generate/GenerateCommands.php b/src/Commands/generate/GenerateCommands.php index 60f871b047..94b2983897 100644 --- a/src/Commands/generate/GenerateCommands.php +++ b/src/Commands/generate/GenerateCommands.php @@ -32,10 +32,12 @@ class GenerateCommands extends DrushCommands implements AutoloaderAwareInterface * @option destination Absolute path to a base directory for file writing. * @usage drush generate * Pick from available generators and then run it. - * @usage drush generate controller - * Generate a controller class for your module. * @usage drush generate drush-command-file * Generate a Drush commandfile for your module. + * @usage drush generate controller --answer=Example --answer=example + * Generate a controller class and pre-fill the first two questions in the wizard. + * @usage drush generate controller -vvv --dry-run + * Learn all the potential answers so you can re-run with several --answer options. * @topics docs:generators * @bootstrap max * From 1e217feec3d1d7ec10afe3cda5d50dc13b90ec7b Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 28 Dec 2021 09:33:46 -0500 Subject: [PATCH 033/125] More verbosity fix. (#4954) * More verbosity fix. * Surrender --- src/SiteAlias/ProcessManager.php | 4 ++-- tests/integration/IntegrationTestsTest.php | 4 ++++ tests/unish/UnishIntegrationTestCase.php | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/SiteAlias/ProcessManager.php b/src/SiteAlias/ProcessManager.php index 081b22bcdc..2885170934 100644 --- a/src/SiteAlias/ProcessManager.php +++ b/src/SiteAlias/ProcessManager.php @@ -146,9 +146,9 @@ protected static function configureProcess(ProcessBase $process) { $process->setSimulated(Drush::simulate()); $process->setVerbose(Drush::verbose()); - // Don't let sub-process inherit the verbosity of its parent. + // Don't let sub-process inherit the verbosity of its parent https://github.com/symfony/console/blob/3.4/Application.php#L970-L972 putenv('SHELL_VERBOSITY'); - unset($_ENV['SHELL_VERBOSITY']); + unset($_ENV['SHELL_VERBOSITY'], $_SERVER['SHELL_VERBOSITY']); $process->setLogger(Drush::logger()); $process->setRealtimeOutput(new DrushStyle(Drush::input(), Drush::output())); $process->setTimeout(Drush::getTimeout()); diff --git a/tests/integration/IntegrationTestsTest.php b/tests/integration/IntegrationTestsTest.php index a5d4eba33c..8779bed578 100644 --- a/tests/integration/IntegrationTestsTest.php +++ b/tests/integration/IntegrationTestsTest.php @@ -13,6 +13,10 @@ class IntegrationTestsTest extends UnishIntegrationTestCase */ public function testStdErr(): void { + if ($this->isWindows()) { + $this->markTestSkipped('@todo Fails on Windows'); + } + // Ensure that a verbose run does not affect subsequent runs. $this->drush('version', [], ['debug' => null]); $this->assertStringContainsString('[info] Starting bootstrap to none', $this->getErrorOutputRaw()); diff --git a/tests/unish/UnishIntegrationTestCase.php b/tests/unish/UnishIntegrationTestCase.php index 2458a53359..5caa87d06c 100644 --- a/tests/unish/UnishIntegrationTestCase.php +++ b/tests/unish/UnishIntegrationTestCase.php @@ -98,8 +98,9 @@ public function drush($command, array $args = [], array $options = [], $expected $this->stderr = $output->getErrorOutput()->fetch(); // Undo the env variable and verbosity property that Process unhelpfully persists. + // https://github.com/symfony/console/blob/3.4/Application.php#L970-L972 putenv('SHELL_VERBOSITY'); - unset($_ENV['SHELL_VERBOSITY']); + unset($_ENV['SHELL_VERBOSITY'], $_SERVER['SHELL_VERBOSITY']); $output->setVerbosity(OutputInterface::VERBOSITY_NORMAL); $this->assertEquals($expected_return, $return, "Command failed: \n\n" . $this->getErrorOutput()); From 0824e962aab2a1ef9ac8ef01f713e41b5be0e8ac Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 28 Dec 2021 18:42:41 -0500 Subject: [PATCH 034/125] Prep for 11.0.0-rc4 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..d4c39ffbd3 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0-rc4 From d8099892d3b677478428f9306d483a6024d473b2 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 28 Dec 2021 18:44:59 -0500 Subject: [PATCH 035/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index d4c39ffbd3..9ad93d53df 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-rc4 +drush_version=11.0.0-dev From 4b96291b3af0a6c737ad7088e6cdd3d27736a0bc Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 29 Dec 2021 15:41:43 -0500 Subject: [PATCH 036/125] Fix #4880. On docs site add tabs showing Attributes versus Annotations. (#4956) --- docs/commands.md | 53 +++++++++++++++++++++++++++++++----- docs/dependency-injection.md | 3 +- docs/hooks.md | 20 ++++++++++++-- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 8a8f74ccbc..13f53cb36a 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -3,15 +3,54 @@ Creating a new Drush command or porting a legacy command is easy. Follow the steps below. 1. Run `drush generate drush-command-file`. -1. Drush will prompt for the machine name of the module that should "own" the file. +2. Drush will prompt for the machine name of the module that should "own" the file. 1. (optional) Drush will also prompt for the path to a legacy command file to port. See [tips on porting commands to Drush 10](https://weitzman.github.io/blog/port-to-drush9) 1. The module selected must already exist and be enabled. Use `drush generate module-standard` to create a new module. -1. Drush will then report that it created a commandfile, a drush.services.yml file and a composer.json file. Edit those files as needed. -1. Use the classes for the core Drush commands at [/src/Drupal/Commands](https://github.com/drush-ops/drush/tree/11.x/src/Drupal/Commands) as inspiration and documentation. -1. See the [dependency injection docs](dependency-injection.md) for interfaces you can implement to gain access to Drush config, Drupal site aliases, etc. -1. A commandfile that will only be used on PHP8+ can [use Attributes](https://github.com/drush-ops/drush/pull/4821) instead of Annotations. -1. Write PHPUnit tests based on [Drush Test Traits](https://github.com/drush-ops/drush/blob/11.x/docs/contribute/unish.md#drush-test-traits). -1. Once your two files are ready, run `drush cr` to get your command recognized by the Drupal container. +3. Drush will then report that it created a commandfile, a drush.services.yml file and a composer.json file. Edit those files as needed. +4. Use the classes for the core Drush commands at [/src/Drupal/Commands](https://github.com/drush-ops/drush/tree/11.x/src/Drupal/Commands) as inspiration and documentation. +5. See the [dependency injection docs](dependency-injection.md) for interfaces you can implement to gain access to Drush config, Drupal site aliases, etc. +6. Write PHPUnit tests based on [Drush Test Traits](https://github.com/drush-ops/drush/blob/11.x/docs/contribute/unish.md#drush-test-traits). +7. Once your drush.services.yml files is ready, run `drush cr` to get your command recognized by the Drupal container. + +## Attributes or Annotations +The following are both valid ways to declare a command: + +=== "PHP8 Attributes" + + ```php8 + #[Command(name: 'xkcd:fetch-attributes', aliases: ['xkcd-attributes'])] + #[Argument(name: 'search', description: 'Optional argument to retrieve the cartoons matching an index number, keyword search or "random". If omitted the latest cartoon will be retrieved.')] + #[Option(name: 'image-viewer', description: 'Command to use to view images (e.g. xv, firefox). Defaults to "display" (from ImageMagick).')] + #[Option(name: 'google-custom-search-api-key', description: 'Google Custom Search API Key, available from https://code.google.com/apis/console/. Default key limited to 100 queries/day globally.')] + #[Help(description: 'Retrieve and display xkcd cartoons (attribute variant).')] + #[Usage(name: 'drush xkcd', description: 'Retrieve and display the latest cartoon')] + #[Usage(name: 'drush xkcd sandwich', description: 'Retrieve and display cartoons about sandwiches.')] + public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIzaSyDpE01VDNNT73s6CEeJRdSg5jukoG244ek']) { + $this->doFetch($search, $options); + } + ``` + +=== "Annotations" + + ```php + /** + * @command xkcd:fetch + * @param $search Optional argument to retrieve the cartoons matching an index number, keyword search or "random". If omitted the latest cartoon will be retrieved. + * @option image-viewer Command to use to view images (e.g. xv, firefox). Defaults to "display" (from ImageMagick). + * @option google-custom-search-api-key Google Custom Search API Key, available from https://code.google.com/apis/console/. Default key limited to 100 queries/day globally. + * @usage drush xkcd + * Retrieve and display the latest cartoon. + * @usage drush xkcd sandwich + * Retrieve and display cartoons about sandwiches. + * @aliases xkcd + */ + public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIzaSyDpE01VDNNT73s6CEeJRdSg5jukoG244ek']) { + $this->doFetch($search, $options); + } + ``` + +- A commandfile that will only be used on PHP8+ should [use PHP Attributes](https://github.com/drush-ops/drush/pull/4821) instead of Annotations. +- [See all Attributes provided by Drush core](https://www.drush.org/latest/api/Drush/Attributes.html). ## Specifying the Services File diff --git a/docs/dependency-injection.md b/docs/dependency-injection.md index 7a06fa749d..bdfc9b8ee9 100644 --- a/docs/dependency-injection.md +++ b/docs/dependency-injection.md @@ -57,8 +57,9 @@ use Consolidation\SiteAlias\SiteAliasManagerAwareTrait; class MyModuleCommands extends DrushCommands implements SiteAliasManagerAwareInterface { use SiteAliasManagerAwareTrait; + /** - * Prints the currenbt alias name and info. + * Prints the current alias name and info. * * @command mymodule:myAlias * @return \Consolidation\OutputFormatters\StructuredData\ListDataFromKeys diff --git a/docs/hooks.md b/docs/hooks.md index 2c9698f12d..ed980e05d3 100644 --- a/docs/hooks.md +++ b/docs/hooks.md @@ -33,9 +33,23 @@ Then, the command may ask the provided hook manager to return a list of handlers } ``` -Other command handlers may provide implementations by implementing `@hook on-event my-event` or `#[CLI/Hook(type: 'on-event', target: 'my-event')]`. +Other commandfiles may provide implementations via a PHP8 Attribute or an Annotation. -```php +=== "PHP8 Attributes" + + ```php + /** + * #[CLI/Hook(type: 'on-event', target: 'my-event')] + */ + public function hookOne() + { + return 'one'; + } + ``` + +=== "Annotations" + + ```php /** * @hook on-event my-event */ @@ -43,4 +57,4 @@ Other command handlers may provide implementations by implementing `@hook on-eve { return 'one'; } -``` + ``` From 1090847ed2af180af61b8b8c3fc1ba761dfdb155 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 06:42:38 -0500 Subject: [PATCH 037/125] More terse Attributes example and Add last-updated date and authors to bottom of all docs pages. (#4958) * Slightly more terse docs for Attributes * Add last-updated date and authors to bottom of all docs pages. --- .github/workflows/main.yml | 7 +++---- docs/commands.md | 28 +++++++++++++++------------- docs/overrides/main.html | 13 +++++++++++++ mkdocs_base.yml | 5 +++++ 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 88bd837261..ee6f9b1ff0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,12 +1,10 @@ name: Build static sites -# Controls when the action will run. Triggers the workflow on push or pull request +# Controls when the action will run. Triggers the workflow on push # events but only for the 11.x branch on: push: branches: [11.x] -# pull_request: -# branches: [11.x] jobs: build: @@ -21,6 +19,7 @@ jobs: with: ref: gh-pages path: gh-pages + fetch-depth: 0 - name: Set up Python 3.8 uses: actions/setup-python@v2 @@ -30,7 +29,7 @@ jobs: - name: Install Python dependencies run: | python -m pip install --upgrade pip - pip install mkdocs-material pymdown-extensions git+https://gitlab.com/blacs30/mkdocs-edit-url.git + pip install mkdocs-material mkdocs-git-authors-plugin mkdocs-git-revision-date-localized-plugin pymdown-extensions git+https://gitlab.com/blacs30/mkdocs-edit-url.git - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/docs/commands.md b/docs/commands.md index 13f53cb36a..acba65c34e 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -17,15 +17,17 @@ The following are both valid ways to declare a command: === "PHP8 Attributes" - ```php8 - #[Command(name: 'xkcd:fetch-attributes', aliases: ['xkcd-attributes'])] - #[Argument(name: 'search', description: 'Optional argument to retrieve the cartoons matching an index number, keyword search or "random". If omitted the latest cartoon will be retrieved.')] - #[Option(name: 'image-viewer', description: 'Command to use to view images (e.g. xv, firefox). Defaults to "display" (from ImageMagick).')] - #[Option(name: 'google-custom-search-api-key', description: 'Google Custom Search API Key, available from https://code.google.com/apis/console/. Default key limited to 100 queries/day globally.')] - #[Help(description: 'Retrieve and display xkcd cartoons (attribute variant).')] - #[Usage(name: 'drush xkcd', description: 'Retrieve and display the latest cartoon')] - #[Usage(name: 'drush xkcd sandwich', description: 'Retrieve and display cartoons about sandwiches.')] - public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIzaSyDpE01VDNNT73s6CEeJRdSg5jukoG244ek']) { + ```php + use Drush\Attributes as CLI; + + #[CLI\Command(name: 'xkcd:fetch-attributes', aliases: ['xkcd-attributes'])] + #[CLI\Argument(name: 'search', description: 'Optional argument to retrieve the cartoons matching an index, keyword keyword, or "random".')] + #[CLI\Option(name: 'image-viewer', description: 'Command to use to view images (e.g. xv, firefox).')] + #[CLI\Option(name: 'google-custom-search-api-key', description: 'Google Custom Search API Key')] + #[CLI\Help(description: 'Retrieve and display xkcd cartoons (attribute variant).')] + #[CLI\Usage(name: 'drush xkcd', description: 'Retrieve and display the latest cartoon')] + #[CLI\Usage(name: 'drush xkcd sandwich', description: 'Retrieve and display cartoons about sandwiches.')] + public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIza']) { $this->doFetch($search, $options); } ``` @@ -35,16 +37,16 @@ The following are both valid ways to declare a command: ```php /** * @command xkcd:fetch - * @param $search Optional argument to retrieve the cartoons matching an index number, keyword search or "random". If omitted the latest cartoon will be retrieved. - * @option image-viewer Command to use to view images (e.g. xv, firefox). Defaults to "display" (from ImageMagick). - * @option google-custom-search-api-key Google Custom Search API Key, available from https://code.google.com/apis/console/. Default key limited to 100 queries/day globally. + * @param $search Optional argument to retrieve the cartoons matching an index number, keyword, or "random". + * @option image-viewer Command to use to view images (e.g. xv, firefox). + * @option google-custom-search-api-key Google Custom Search API Key. * @usage drush xkcd * Retrieve and display the latest cartoon. * @usage drush xkcd sandwich * Retrieve and display cartoons about sandwiches. * @aliases xkcd */ - public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIzaSyDpE01VDNNT73s6CEeJRdSg5jukoG244ek']) { + public function fetch($search = null, $options = ['image-viewer' => 'open', 'google-custom-search-api-key' => 'AIza']) { $this->doFetch($search, $options); } ``` diff --git a/docs/overrides/main.html b/docs/overrides/main.html index 40c1ebcde4..40bad40486 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -32,6 +32,19 @@ {% endblock %} + +{% block content %} + {{ super() }} + + {% if git_page_authors %} +
+ + Authors: {{ git_page_authors | default('enable mkdocs-git-authors-plugin') }} + +
+ {% endif %} +{% endblock %} + {% block disqus %}
diff --git a/mkdocs_base.yml b/mkdocs_base.yml index 80dfc71cfa..b898270990 100644 --- a/mkdocs_base.yml +++ b/mkdocs_base.yml @@ -24,6 +24,11 @@ extra_css: plugins: - edit_url - search + - git-revision-date-localized + - git-authors: + exclude: + - commands/* + - generators/* extra: social: - icon: fontawesome/brands/twitter From af16151e3d67eb4c0c900667295bbcdadffcee70 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 06:55:50 -0500 Subject: [PATCH 038/125] Add another depth=0 during docs build --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ee6f9b1ff0..45fc305664 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,8 @@ jobs: steps: - name: Checkout 11.x uses: actions/checkout@v2 + with: + - fetch-depth: 0 - name: Checkout gh-pages branch uses: actions/checkout@v2 From fbc4c93755c271e8c360dd8e059fd27bd8a67dd4 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 06:57:30 -0500 Subject: [PATCH 039/125] Syntax fix in Github workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 45fc305664..04b54197ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout 11.x uses: actions/checkout@v2 with: - - fetch-depth: 0 + fetch-depth: 0 - name: Checkout gh-pages branch uses: actions/checkout@v2 From e099ccdc1dfb8aaf0ee0b0380f3d2ea77cc2f50b Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 07:22:15 -0500 Subject: [PATCH 040/125] Also exclude last updated date on generator and command pages. --- mkdocs_base.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkdocs_base.yml b/mkdocs_base.yml index b898270990..e04fc47b61 100644 --- a/mkdocs_base.yml +++ b/mkdocs_base.yml @@ -25,6 +25,9 @@ plugins: - edit_url - search - git-revision-date-localized + exclude: + - commands/* + - generators/* - git-authors: exclude: - commands/* From 9aaf7cec0adb32a8573f992da1e124eae40e1324 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 07:27:05 -0500 Subject: [PATCH 041/125] Also exclude last updated date on generator and command pages. --- mkdocs_base.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs_base.yml b/mkdocs_base.yml index e04fc47b61..1e625cde6e 100644 --- a/mkdocs_base.yml +++ b/mkdocs_base.yml @@ -24,7 +24,7 @@ extra_css: plugins: - edit_url - search - - git-revision-date-localized + - git-revision-date-localized: exclude: - commands/* - generators/* From c71be05c4cd6df6b07eab21da124e00b3d028e8f Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 14:50:24 -0500 Subject: [PATCH 042/125] Add param type hints and return type declarations using Rector on various directories (#4959) * Add param type hints and return type declarations using Rector on various directories * Fixes * Fix? --- composer.json | 4 +- composer.lock | 35 +++-- src/Boot/BaseBoot.php | 20 +-- src/Boot/Boot.php | 6 +- src/Boot/BootstrapHook.php | 2 +- src/Boot/BootstrapManager.php | 62 +++------ src/Boot/DrupalBoot.php | 10 +- src/Boot/DrupalBoot8.php | 37 ++--- src/Boot/DrupalBootLevels.php | 2 +- src/Boot/EmptyBoot.php | 6 +- src/Boot/Kernels.php | 5 +- src/Command/DrushCommandInfoAlterer.php | 2 +- src/Command/GlobalOptionsEventListener.php | 4 +- src/Command/RemoteCommandProxy.php | 2 +- src/Command/ServiceCommandlist.php | 4 +- src/Config/ConfigLocator.php | 86 +++++------- src/Config/Environment.php | 104 +++++--------- src/Config/Loader/YamlConfigLoader.php | 2 +- src/Preflight/ArgsPreprocessor.php | 12 +- src/Preflight/ArgsRemapper.php | 9 +- src/Preflight/LegacyPreflight.php | 4 +- src/Preflight/Preflight.php | 45 +++--- src/Preflight/PreflightArgs.php | 82 +++++------ src/Preflight/PreflightArgsInterface.php | 4 +- src/Preflight/PreflightLog.php | 12 +- src/Preflight/PreflightSiteLocator.php | 10 +- src/Preflight/PreflightVerify.php | 11 +- src/Preflight/RedispatchToSiteLocal.php | 6 +- src/Psysh/DrushCommand.php | 9 +- src/Psysh/DrushHelpCommand.php | 6 +- src/Psysh/Shell.php | 2 +- src/Runtime/DependencyInjection.php | 12 +- src/Runtime/ErrorHandler.php | 2 +- src/Runtime/RedispatchHook.php | 6 +- src/Runtime/Runtime.php | 4 +- src/Runtime/ShutdownHandler.php | 6 +- src/Runtime/TildeExpansionHook.php | 2 +- src/SiteAlias/LegacyAliasConverter.php | 55 ++++---- src/SiteAlias/ProcessManager.php | 27 +--- .../Util/InternalYamlDataFileLoader.php | 2 +- src/Sql/SqlBase.php | 131 +++++++----------- src/Sql/SqlMysql.php | 16 +-- src/Sql/SqlPgsql.php | 23 ++- src/Sql/SqlSqlite.php | 19 ++- src/Sql/SqlTableSelectionTrait.php | 10 +- src/Symfony/BootstrapCompilerPass.php | 2 +- src/Symfony/BufferedConsoleOutput.php | 4 +- src/Symfony/DrushArgvInput.php | 18 +-- src/Symfony/DrushStyleInjector.php | 2 +- src/Symfony/IndiscriminateInputDefinition.php | 6 +- src/Symfony/LessStrictArgvInput.php | 20 +-- src/Utils/FsUtils.php | 25 ++-- src/Utils/StringUtils.php | 25 ++-- tests/unit/MigrateRunnerTest.php | 5 +- 54 files changed, 408 insertions(+), 619 deletions(-) diff --git a/composer.json b/composer.json index 38c1cfae3f..b76b8b176a 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "drupal/core-recommended": "^9", "drupal/semver_example": "2.2.0", "phpunit/phpunit": ">=7.5.20", - "rector/rector": "^0.11.58", + "rector/rector": "^0.12", "squizlabs/php_codesniffer": "^2.7 || ^3", "vlucas/phpdotenv": "^2.4", "yoast/phpunit-polyfills": "^0.2.0" @@ -111,7 +111,7 @@ "api": "php $HOME/bin/doctum.phar --ansi --ignore-parse-errors update doctum-config.php", "doctum-install": "mkdir -p $HOME/bin && curl --output $HOME/bin/doctum.phar https://doctum.long-term.support/releases/latest/doctum.phar && chmod +x $HOME/bin/doctum.phar", "mk:docs": "./drush --uri=dev -v mk:docs", - "rector": "rector process src/Boot src/Preflight src/Runtime src/SiteAlias src/Symfony src/Config", + "rector": "rector process src/Boot src/Command src/Sql src/Preflight src/Psysh src/Runtime src/SiteAlias src/Symfony src/Utils src/Config", "sut": "./drush --uri=dev", "sut:si": "./drush --uri=dev site:install testing --sites-subdir=dev --db-url=${UNISH_DB_URL:-mysql://root:password@mariadb}/unish_dev -v", "phpunit": "php -d sendmail_path='true' vendor/bin/phpunit --colors=always --configuration tests", diff --git a/composer.lock b/composer.lock index 13b19363d4..2ea4b60ecb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a5462ee13843158cf999d6ec578fe401", + "content-hash": "85e6933dec1e53b0952e65a41570f793", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -5550,16 +5550,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.99", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7" + "reference": "ffc5aee6019eeae4ea618d97dd290ab95e77be59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b4d40f1d759942f523be267a1bab6884f46ca3f7", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffc5aee6019eeae4ea618d97dd290ab95e77be59", + "reference": "ffc5aee6019eeae4ea618d97dd290ab95e77be59", "shasum": "" }, "require": { @@ -5575,7 +5575,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -5590,7 +5590,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.99" + "source": "https://github.com/phpstan/phpstan/tree/1.3.0" }, "funding": [ { @@ -5610,7 +5610,7 @@ "type": "tidelift" } ], - "time": "2021-09-12T20:09:55+00:00" + "time": "2021-12-29T17:03:31+00:00" }, { "name": "phpunit/php-code-coverage", @@ -6139,25 +6139,24 @@ }, { "name": "rector/rector", - "version": "0.11.60", + "version": "0.12.9", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "428f593818f8c50fe12c543e8c0a107f9bd899ae" + "reference": "8f7cfa85731bf23cff9571460d88c327c8c1ac4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/428f593818f8c50fe12c543e8c0a107f9bd899ae", - "reference": "428f593818f8c50fe12c543e8c0a107f9bd899ae", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/8f7cfa85731bf23cff9571460d88c327c8c1ac4c", + "reference": "8f7cfa85731bf23cff9571460d88c327c8c1ac4c", "shasum": "" }, "require": { "php": "^7.1|^8.0", - "phpstan/phpstan": "0.12.99" + "phpstan/phpstan": "^1.2" }, "conflict": { - "phpstan/phpdoc-parser": "<=0.5.3", - "phpstan/phpstan": "<=0.12.82", + "phpstan/phpdoc-parser": "<1.2", "rector/rector-cakephp": "*", "rector/rector-doctrine": "*", "rector/rector-laravel": "*", @@ -6173,7 +6172,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.11-dev" + "dev-main": "0.12-dev" } }, "autoload": { @@ -6188,7 +6187,7 @@ "description": "Prefixed and PHP 7.1 downgraded version of rector/rector", "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.11.60" + "source": "https://github.com/rectorphp/rector/tree/0.12.9" }, "funding": [ { @@ -6196,7 +6195,7 @@ "type": "github" } ], - "time": "2021-10-20T13:08:22+00:00" + "time": "2021-12-21T23:30:38+00:00" }, { "name": "sebastian/cli-parser", diff --git a/src/Boot/BaseBoot.php b/src/Boot/BaseBoot.php index b21d16396d..6eacd72d16 100644 --- a/src/Boot/BaseBoot.php +++ b/src/Boot/BaseBoot.php @@ -17,12 +17,12 @@ public function __construct() register_shutdown_function([$this, 'terminate']); } - public function findUri($root, $uri) + public function findUri($root, $uri): string { return 'default'; } - public function getUri() + public function getUri(): string { return $this->uri; } @@ -32,18 +32,12 @@ public function setUri($uri) $this->uri = $uri; } - /** - * @return int - */ - public function getPhase() + public function getPhase(): int { return $this->phase; } - /** - * @param int $phase - */ - public function setPhase($phase) + public function setPhase(int $phase) { $this->phase = $phase; } @@ -65,14 +59,14 @@ public function reportCommandError($command) // No longer used. } - public function bootstrapPhases() + public function bootstrapPhases(): array { return [ DRUSH_BOOTSTRAP_DRUSH => 'bootstrapDrush', ]; } - public function bootstrapPhaseMap() + public function bootstrapPhaseMap(): array { return [ 'none' => DRUSH_BOOTSTRAP_DRUSH, @@ -103,7 +97,7 @@ public function bootstrapDrush() { } - protected function hasRegisteredSymfonyCommand($application, $name) + protected function hasRegisteredSymfonyCommand($application, $name): bool { try { $application->get($name); diff --git a/src/Boot/Boot.php b/src/Boot/Boot.php index 0a87effcb5..e1e06037d4 100644 --- a/src/Boot/Boot.php +++ b/src/Boot/Boot.php @@ -20,7 +20,7 @@ public function findUri($root, $uri); * * @param string $uri Site to bootstrap */ - public function setUri($uri); + public function setUri(string $uri); /** * This function determines if the specified path points to @@ -44,7 +44,7 @@ public function validRoot($path); * @return string|NULL * The version string for the current version of the software, e.g. 8.1.3 */ - public function getVersion($root); + public function getVersion(string $root); /** * Returns an array that determines what bootstrap phases @@ -64,7 +64,7 @@ public function bootstrapPhases(); * strings (e.g. "full") to the corresponding bootstrap * phase index constant (e.g. DRUSH_BOOTSTRAP_DRUPAL_FULL). */ - public function bootstrapPhaseMap(); + public function bootstrapPhaseMap(): array; /** * Convert from a phase shorthand or constant to a phase index. diff --git a/src/Boot/BootstrapHook.php b/src/Boot/BootstrapHook.php index eb3469dd36..ceaa74ce35 100644 --- a/src/Boot/BootstrapHook.php +++ b/src/Boot/BootstrapHook.php @@ -20,7 +20,7 @@ public function __construct(BootstrapManager $bootstrapManager) $this->bootstrapManager = $bootstrapManager; } - public function initialize(InputInterface $input, AnnotationData $annotationData) + public function initialize(InputInterface $input, AnnotationData $annotationData): void { // Get the @bootstrap annotation/attribute. If there isn't one, then assume NONE. $phase_long = $annotationData->get('bootstrap', 'none'); diff --git a/src/Boot/BootstrapManager.php b/src/Boot/BootstrapManager.php index 91ae8e00c1..80776a2d0f 100644 --- a/src/Boot/BootstrapManager.php +++ b/src/Boot/BootstrapManager.php @@ -49,10 +49,7 @@ public function getPhase() return $this->bootstrap()->getPhase(); } - /** - * @param int $phase - */ - protected function setPhase($phase) + protected function setPhase(int $phase): void { if ($this->bootstrap) { $this->bootstrap()->setPhase($phase); @@ -65,14 +62,14 @@ protected function setPhase($phase) * @param \Drush\Boot\Boot|Array * List of boot candidates */ - public function add($candidateList) + public function add($candidateList): void { foreach (func_get_args() as $candidate) { $this->bootstrapCandidates[] = $candidate; } } - public function drupalFinder() + public function drupalFinder(): \DrupalFinder\DrupalFinder { if (!isset($this->drupalFinder)) { $this->drupalFinder = new DrupalFinder(); @@ -80,7 +77,7 @@ public function drupalFinder() return $this->drupalFinder; } - public function setDrupalFinder(DrupalFinder $drupalFinder) + public function setDrupalFinder(DrupalFinder $drupalFinder): void { $this->drupalFinder = $drupalFinder; } @@ -101,7 +98,7 @@ public function getComposerRoot() return $this->drupalFinder()->getComposerRoot(); } - public function locateRoot($root, $start_path = null) + public function locateRoot($root, $start_path = null): void { // TODO: Throw if we already bootstrapped a framework? @@ -133,7 +130,7 @@ public function selectUri($cwd) return $uri; } - public function setUri($uri) + public function setUri($uri): void { // TODO: Throw if we already bootstrapped a framework? // n.b. site-install needs to set the uri. @@ -145,10 +142,8 @@ public function setUri($uri) * be the latched bootstrap object if we have started * bootstrapping; otherwise, it will be whichever bootstrap * object is best for the selected root. - * - * @return \Drush\Boot\Boot */ - public function bootstrap() + public function bootstrap(): \Drush\Boot\Boot { if (!$this->bootstrap) { $this->bootstrap = $this->selectBootstrapClass(); @@ -159,7 +154,7 @@ public function bootstrap() /** * For use in testing */ - public function injectBootstrap($bootstrap) + public function injectBootstrap(\Drush\Boot\Boot $bootstrap): void { $this->inflect($bootstrap); $this->bootstrap = $bootstrap; @@ -172,10 +167,8 @@ public function injectBootstrap($bootstrap) /** * Look up the best bootstrap class for the given location * from the set of available candidates. - * - * @return \Drush\Boot\Boot */ - public function bootstrapObjectForRoot($path) + public function bootstrapObjectForRoot($path): \Drush\Boot\Boot { foreach ($this->bootstrapCandidates as $candidate) { if ($candidate->validRoot($path)) { @@ -198,7 +191,7 @@ public function bootstrapObjectForRoot($path) * be 'latched', and further calls to Drush::bootstrap() * will always return the same object. */ - protected function selectBootstrapClass() + protected function selectBootstrapClass(): \Drush\Boot\Boot { // Once we have selected a Drupal root, we will reduce our bootstrap // candidates down to just the one used to select this site root. @@ -210,7 +203,7 @@ protected function selectBootstrapClass() * object being used, and do not allow it to change any * longer. */ - public function latch($bootstrap) + public function latch(\Drush\Boot\Boot $bootstrap): void { $this->bootstrap = $bootstrap; } @@ -223,11 +216,10 @@ public function latch($bootstrap) * (optional) If TRUE, return an array of method names index by their * corresponding phase values. Otherwise return an array of phase values. * - * @return array * * @see \Drush\Boot\Boot::bootstrapPhases() */ - public function bootstrapPhases($function_names = false) + public function bootstrapPhases(bool $function_names = false): array { $result = []; @@ -256,12 +248,10 @@ public function bootstrapPhases($function_names = false) * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData * Optional annotation data from the command. * - * @return bool * TRUE if the specified bootstrap phase has completed. - * * @see \Drush\Boot\Boot::bootstrapPhases() */ - public function doBootstrap($phase, $phase_max = false, AnnotationData $annotationData = null) + public function doBootstrap(int $phase, $phase_max = false, AnnotationData $annotationData = null): bool { $bootstrap = $this->bootstrap(); $phases = $this->bootstrapPhases(true); @@ -301,7 +291,7 @@ public function doBootstrap($phase, $phase_max = false, AnnotationData $annotati /** * hasBootstrap determines whether the manager has a bootstrap object yet. */ - public function hasBootstrap() + public function hasBootstrap(): bool { return $this->bootstrap != null; } @@ -312,10 +302,9 @@ public function hasBootstrap() * @param int $phase * The bootstrap phase to test * - * @return bool * TRUE if the specified bootstrap phase has completed. */ - public function hasBootstrapped($phase) + public function hasBootstrapped(int $phase): bool { return $this->getPhase() >= $phase; } @@ -334,12 +323,10 @@ public function hasBootstrapped($phase) * @param int $phase * The bootstrap phase to validate to. * - * @return bool * TRUE if bootstrap is possible, FALSE if the validation failed. - * * @see \Drush\Boot\Boot::bootstrapPhases() */ - public function bootstrapValidate($phase) + public function bootstrapValidate(int $phase): bool { $bootstrap = $this->bootstrap(); $phases = $this->bootstrapPhases(true); @@ -370,17 +357,14 @@ public function bootstrapValidate($phase) * * @param string $bootstrapPhase * Name of phase to bootstrap to. Will be converted to appropriate index. - * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData * Optional annotation data from the command. * - * @return bool * TRUE if the specified bootstrap phase has completed. - * * @throws \Exception * Thrown when an unknown bootstrap phase is passed in the annotation * data. */ - public function bootstrapToPhase($bootstrapPhase, AnnotationData $annotationData = null) + public function bootstrapToPhase(string $bootstrapPhase, AnnotationData $annotationData = null): bool { $this->logger->info('Starting bootstrap to {phase}', ['phase' => $bootstrapPhase]); $phase = $this->bootstrap()->lookUpPhaseIndex($bootstrapPhase); @@ -411,13 +395,10 @@ protected function maxPhaseLimit($bootstrap_str) * * @param int $max_phase_index * Only attempt bootstrap to the specified level. - * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData * Optional annotation data from the command. - * - * @return bool * TRUE if the specified bootstrap phase has completed. */ - public function bootstrapToPhaseIndex($max_phase_index, AnnotationData $annotationData = null) + public function bootstrapToPhaseIndex(int $max_phase_index, AnnotationData $annotationData = null): bool { if ($max_phase_index == DRUSH_BOOTSTRAP_MAX) { // Try get a max phase. @@ -463,10 +444,9 @@ public function bootstrapToPhaseIndex($max_phase_index, AnnotationData $annotati * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData * Optional annotation data from the command. * - * @return int * The maximum phase to which we bootstrapped. */ - public function bootstrapMax($max_phase_index = false, AnnotationData $annotationData = null) + public function bootstrapMax($max_phase_index = false, AnnotationData $annotationData = null): int { // Bootstrap as far as we can without throwing an error, but log for // debugging purposes. @@ -506,12 +486,12 @@ public function bootstrapMax($max_phase_index = false, AnnotationData $annotatio /** * Allow those with an instance to us to the BootstrapManager to use its logger */ - public function logger() + public function logger(): ?\Psr\Log\LoggerInterface { return $this->logger; } - public function inflect($object) + public function inflect($object): void { // See \Drush\Runtime\DependencyInjection::addDrushServices and // \Robo\Robo\addInflectors diff --git a/src/Boot/DrupalBoot.php b/src/Boot/DrupalBoot.php index 5ad5dbd055..56824156f8 100644 --- a/src/Boot/DrupalBoot.php +++ b/src/Boot/DrupalBoot.php @@ -11,7 +11,7 @@ abstract class DrupalBoot extends BaseBoot * Select the best URI for the provided cwd. Only called * if the user did not explicitly specify a URI. */ - public function findUri($root, $cwd) + public function findUri($root, $cwd): string { if (Path::isBasePath($root, $cwd)) { $siteDir = $this->scanUpForUri($root, $cwd); @@ -70,7 +70,7 @@ public function confPath($require_settings = true, $reset = false) * method is called, if defined. The validate method name is the * bootstrap method name with "_validate" appended. */ - public function bootstrapPhases() + public function bootstrapPhases(): array { return parent::bootstrapPhases() + [ DRUSH_BOOTSTRAP_DRUPAL_ROOT => 'bootstrapDrupalRoot', @@ -81,7 +81,7 @@ public function bootstrapPhases() ]; } - public function bootstrapPhaseMap() + public function bootstrapPhaseMap(): array { return parent::bootstrapPhaseMap() + [ 'root' => DRUSH_BOOTSTRAP_DRUPAL_ROOT, @@ -99,7 +99,7 @@ public function bootstrapPhaseMap() * * In this function, we will check if a valid Drupal directory is available. */ - public function bootstrapDrupalRootValidate(BootstrapManager $manager) + public function bootstrapDrupalRootValidate(BootstrapManager $manager): bool { $drupal_root = $manager->getRoot(); return (bool) $drupal_root; @@ -115,7 +115,7 @@ public function bootstrapDrupalRootValidate(BootstrapManager $manager) * We can now include files from the Drupal tree, and figure * out more context about the codebase, such as the version of Drupal. */ - public function bootstrapDrupalRoot(BootstrapManager $manager) + public function bootstrapDrupalRoot(BootstrapManager $manager): void { $drupal_root = $manager->getRoot(); chdir($drupal_root); diff --git a/src/Boot/DrupalBoot8.php b/src/Boot/DrupalBoot8.php index 6f2e550aa2..34908c2558 100644 --- a/src/Boot/DrupalBoot8.php +++ b/src/Boot/DrupalBoot8.php @@ -33,26 +33,17 @@ class DrupalBoot8 extends DrupalBoot implements AutoloaderAwareInterface */ protected $request; - /** - * @return \Symfony\Component\HttpFoundation\Request - */ - public function getRequest() + public function getRequest(): \Symfony\Component\HttpFoundation\Request { return $this->request; } - /** - * @param \Symfony\Component\HttpFoundation\Request $request - */ - public function setRequest($request) + public function setRequest(\Symfony\Component\HttpFoundation\Request $request): void { $this->request = $request; } - /** - * @return \Drupal\Core\DrupalKernelInterface - */ - public function getKernel() + public function getKernel(): \Drupal\Core\DrupalKernelInterface { return $this->kernel; } @@ -66,7 +57,7 @@ public function getKernel() * (i.e., after bootstrapping Drupal), then we also need to * update the logger reference in that adapter. */ - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { if ($this->drupalLoggerAdapter) { $this->drupalLoggerAdapter->setLogger($logger); @@ -122,12 +113,12 @@ public function confPath($require_settings = true, $reset = false) return $site_path; } - public function bootstrapDrupalCore(BootstrapManager $manager, $drupal_root) + public function bootstrapDrupalCore(BootstrapManager $manager, $drupal_root): string { return Path::join($drupal_root, 'core'); } - public function bootstrapDrupalSiteValidate(BootstrapManager $manager) + public function bootstrapDrupalSiteValidate(BootstrapManager $manager): bool { parent::bootstrapDrupalSiteValidate($manager); @@ -157,7 +148,7 @@ public function bootstrapDrupalSiteValidate(BootstrapManager $manager) * Called by bootstrapDrupalSite to do the main work * of the drush drupal site bootstrap. */ - public function bootstrapDoDrupalSite(BootstrapManager $manager) + public function bootstrapDoDrupalSite(BootstrapManager $manager): void { $siteConfig = $this->confPath() . '/drush.yml'; @@ -171,7 +162,7 @@ public function bootstrapDoDrupalSite(BootstrapManager $manager) $this->logger->info(dt("Initialized Drupal site !site at !site_root", ['!site' => $this->getRequest()->getHttpHost(), '!site_root' => $this->confPath()])); } - public function bootstrapDrupalConfigurationValidate(BootstrapManager $manager) + public function bootstrapDrupalConfigurationValidate(BootstrapManager $manager): bool { $conf_file = $this->confPath() . '/settings.php'; if (!file_exists($conf_file)) { @@ -183,7 +174,7 @@ public function bootstrapDrupalConfigurationValidate(BootstrapManager $manager) return true; } - public function bootstrapDrupalDatabaseValidate(BootstrapManager $manager) + public function bootstrapDrupalDatabaseValidate(BootstrapManager $manager): bool { // Drupal requires PDO, and Drush requires php 5.6+ which ships with PDO // but PHP may be compiled with --disable-pdo. @@ -208,13 +199,13 @@ public function bootstrapDrupalDatabaseValidate(BootstrapManager $manager) return true; } - public function bootstrapDrupalDatabase(BootstrapManager $manager) + public function bootstrapDrupalDatabase(BootstrapManager $manager): void { // D8 omits this bootstrap level as nothing special needs to be done. parent::bootstrapDrupalDatabase($manager); } - public function bootstrapDrupalConfiguration(BootstrapManager $manager, AnnotationData $annotationData = null) + public function bootstrapDrupalConfiguration(BootstrapManager $manager, AnnotationData $annotationData = null): void { // Coax \Drupal\Core\DrupalKernel::discoverServiceProviders to add our logger. $GLOBALS['conf']['container_service_providers'][] = DrushLoggerServiceProvider::class; @@ -243,7 +234,7 @@ public function bootstrapDrupalConfiguration(BootstrapManager $manager, Annotati parent::bootstrapDrupalConfiguration($manager); } - public function bootstrapDrupalFull(BootstrapManager $manager) + public function bootstrapDrupalFull(BootstrapManager $manager): void { $this->logger->debug(dt('Start bootstrap of the Drupal Kernel.')); $this->kernel->boot(); @@ -254,7 +245,7 @@ public function bootstrapDrupalFull(BootstrapManager $manager) $this->addDrupalModuleDrushCommands($manager); } - public function addDrupalModuleDrushCommands($manager) + public function addDrupalModuleDrushCommands($manager): void { $application = Drush::getApplication(); $runner = Drush::runner(); @@ -297,7 +288,7 @@ public function addDrupalModuleDrushCommands($manager) /** * {@inheritdoc} */ - public function terminate() + public function terminate(): void { parent::terminate(); diff --git a/src/Boot/DrupalBootLevels.php b/src/Boot/DrupalBootLevels.php index 224a19262b..8962dd8ad2 100644 --- a/src/Boot/DrupalBootLevels.php +++ b/src/Boot/DrupalBootLevels.php @@ -80,7 +80,7 @@ class DrupalBootLevels */ const FULL = 5; - public static function getPhaseName($index) + public static function getPhaseName($index): string { $reflection = new \ReflectionClass(self::class); return strtolower(array_search($index, $reflection->getConstants())); diff --git a/src/Boot/EmptyBoot.php b/src/Boot/EmptyBoot.php index dfdcd3f007..6f94607781 100644 --- a/src/Boot/EmptyBoot.php +++ b/src/Boot/EmptyBoot.php @@ -15,19 +15,19 @@ class EmptyBoot extends BaseBoot { - public function validRoot($path) + public function validRoot($path): bool { return false; } - public function bootstrapPhases() + public function bootstrapPhases(): array { return [ DRUSH_BOOTSTRAP_DRUSH => '_drush_bootstrap_drush', ]; } - public function bootstrapInitPhases() + public function bootstrapInitPhases(): array { return [DRUSH_BOOTSTRAP_DRUSH]; } diff --git a/src/Boot/Kernels.php b/src/Boot/Kernels.php index dc7278a9b5..ed0d0e13ae 100644 --- a/src/Boot/Kernels.php +++ b/src/Boot/Kernels.php @@ -36,7 +36,7 @@ final class Kernels /** * Returns the available kernels. */ - public static function availableKernels() + public static function availableKernels(): array { return [ static::DRUPAL, @@ -51,10 +51,9 @@ public static function availableKernels() * @param string $kernel * The kernel to retrieve. * - * @return callable * The factory method. */ - public static function getKernelFactory($kernel) + public static function getKernelFactory(string $kernel): array { $factories = [ Kernels::DRUPAL => [DrushDrupalKernel::class, 'createFromRequest'], diff --git a/src/Command/DrushCommandInfoAlterer.php b/src/Command/DrushCommandInfoAlterer.php index 8b6effabca..520edf7c23 100644 --- a/src/Command/DrushCommandInfoAlterer.php +++ b/src/Command/DrushCommandInfoAlterer.php @@ -6,7 +6,7 @@ class DrushCommandInfoAlterer implements CommandInfoAltererInterface { - public function alterCommandInfo(CommandInfo $commandInfo, $commandFileInstance) + public function alterCommandInfo(CommandInfo $commandInfo, $commandFileInstance): void { // If a command has a @filter-default-field annotation, that // implies that it also has an implicit @filter-output annotation. diff --git a/src/Command/GlobalOptionsEventListener.php b/src/Command/GlobalOptionsEventListener.php index 0cad2d4f81..00dd1ebd4a 100644 --- a/src/Command/GlobalOptionsEventListener.php +++ b/src/Command/GlobalOptionsEventListener.php @@ -12,7 +12,7 @@ class GlobalOptionsEventListener implements EventSubscriberInterface /** * @{@inheritdoc} */ - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { // Register our 'setGlobalOptions' command to run prior to // command dispatch. @@ -26,7 +26,7 @@ public static function getSubscribedEvents() * * @param ConsoleCommandEvent $event */ - public function setGlobalOptions(ConsoleCommandEvent $event) + public function setGlobalOptions(ConsoleCommandEvent $event): void { /* @var Input $input */ $input = $event->getInput(); diff --git a/src/Command/RemoteCommandProxy.php b/src/Command/RemoteCommandProxy.php index 488f4033e3..5e7d6d40ba 100644 --- a/src/Command/RemoteCommandProxy.php +++ b/src/Command/RemoteCommandProxy.php @@ -42,7 +42,7 @@ public function __construct($name, RedispatchHook $redispatchHook) ); } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { $this->redispatchHook->redispatchIfRemote($input); $name = $this->getName(); diff --git a/src/Command/ServiceCommandlist.php b/src/Command/ServiceCommandlist.php index c8dabf9cce..34ffd45286 100644 --- a/src/Command/ServiceCommandlist.php +++ b/src/Command/ServiceCommandlist.php @@ -9,12 +9,12 @@ class ServiceCommandlist { protected $commandList = []; - public function addCommandReference($command) + public function addCommandReference($command): void { $this->commandList[] = $command; } - public function getCommandList() + public function getCommandList(): array { return $this->commandList; } diff --git a/src/Config/ConfigLocator.php b/src/Config/ConfigLocator.php index 35f609f475..3fc2563e13 100644 --- a/src/Config/ConfigLocator.php +++ b/src/Config/ConfigLocator.php @@ -1,6 +1,7 @@ isLocal = $isLocal; } @@ -132,10 +131,9 @@ public function setLocal($isLocal) * then the sources will be accumulated as config files are loaded. Otherwise, * this information will not be saved. * - * @param bool $collect * @return $this */ - public function collectSources($collect = true) + public function collectSources(bool $collect = true): self { $this->sources = $collect ? [] : false; return $this; @@ -160,7 +158,7 @@ public function sources() * * @return string[] */ - public function configFilePaths() + public function configFilePaths(): array { return $this->configFilePaths; } @@ -168,7 +166,7 @@ public function configFilePaths() /** * Accumulate the sources provided by the configuration loader. */ - protected function addToSources(array $sources) + protected function addToSources(array $sources): void { if (!is_array($this->sources)) { return; @@ -179,10 +177,8 @@ protected function addToSources(array $sources) /** * Return the configuration object. Create it and load it with * all identified configuration if necessary. - * - * @return Config */ - public function config() + public function config(): ConfigInterface { return $this->config; } @@ -194,9 +190,8 @@ public function config() * obtained by commands et. al. as needed. @see Environment::exportConfigData() * * @param Environment $environent - * @return $this */ - public function addEnvironment(Environment $environment) + public function addEnvironment(Environment $environment): self { $this->config->getContext(self::ENVIRONMENT_CONTEXT)->import($environment->exportConfigData()); return $this; @@ -206,9 +201,8 @@ public function addEnvironment(Environment $environment) * Add config paths defined in preflight configuration. * * @param array $paths - * @return $this */ - public function addPreflightConfigFiles($filepaths) + public function addPreflightConfigFiles($filepaths): self { $this->addConfigPaths(self::PREFLIGHT_CONTEXT, (array) $filepaths); return $this; @@ -216,10 +210,9 @@ public function addPreflightConfigFiles($filepaths) /** * Take any configuration from the active alias record, and add it - * to our configuratino. - * @return $this + * to our configuration. */ - public function addAliasConfig($aliasConfig) + public function addAliasConfig($aliasConfig): self { $this->config->addContext(self::ALIAS_CONTEXT, $aliasConfig); return $this; @@ -231,9 +224,8 @@ public function addAliasConfig($aliasConfig) * add all of the user configuration paths. * * In 'local' mode, only the --config location is used. - * @return $this */ - public function addUserConfig($configPaths, $systemConfigPath, $userConfigDir) + public function addUserConfig($configPaths, $systemConfigPath, $userConfigDir): self { $paths = $configPaths; if (!$this->isLocal) { @@ -246,10 +238,9 @@ public function addUserConfig($configPaths, $systemConfigPath, $userConfigDir) /** * Add the Drush project directory as a configuration search location. * - * @param $drushProjectDir path to the drush project directory - * @return $this + * @param $drushProjectDir Path to the drush project directory. */ - public function addDrushConfig($drushProjectDir) + public function addDrushConfig($drushProjectDir): self { if (!$this->isLocal) { $this->addConfigPaths(self::DRUSH_CONTEXT, [ $drushProjectDir ]); @@ -262,7 +253,6 @@ public function addDrushConfig($drushProjectDir) * selected site. * * @param Path to the selected Drupal site - * @return $this */ public function addSitewideConfig($siteRoot) { @@ -291,9 +281,8 @@ public function addSitewideConfig($siteRoot) * * @param string $contextName Which context to put all configuration files in. * @param string[] $paths List of paths to search for configuration. - * @return $this */ - public function addConfigPaths($contextName, $paths) + public function addConfigPaths(string $contextName, array $paths): self { $loader = new YamlConfigLoader(); // Make all of the config values parsed so far available in evaluations. @@ -331,13 +320,9 @@ public function addConfigPaths($contextName, $paths) } /** - * Adds $configFiles config files. - * - * @param ConfigProcessor $processor - * @param ConfigLoaderInterface $loader - * @param array $configFiles + * Adds $configFiles to the list of config files. */ - protected function addConfigFiles(ConfigProcessor $processor, ConfigLoaderInterface $loader, array $configFiles) + protected function addConfigFiles(ConfigProcessor $processor, ConfigLoaderInterface $loader, array $configFiles): void { foreach ($configFiles as $configFile) { $processor->extend($loader->load($configFile)); @@ -350,11 +335,9 @@ protected function addConfigFiles(ConfigProcessor $processor, ConfigLoaderInterf * return all of the candidates that can be found. Candidates may be * either directories or files. * - * @param string[] $paths - * @param string[] $candidates * @return string[] paths */ - protected function identifyCandidates($paths, $candidates) + protected function identifyCandidates(array $paths, array $candidates): array { $configFiles = []; foreach ($paths as $path) { @@ -367,11 +350,10 @@ protected function identifyCandidates($paths, $candidates) * Search for all matching candidate locations at a single path. * Candidate locations may be either directories or files. * - * @param string $path * @param string[] $candidates * @return string[] */ - protected function identifyCandidatesAtPath($path, $candidates) + protected function identifyCandidatesAtPath(string $path, array $candidates): array { if (!is_dir($path)) { return []; @@ -392,10 +374,8 @@ protected function identifyCandidatesAtPath($path, $candidates) * * @param $preflightArgs * @param Environment $environment - * - * @return array */ - public function getSiteAliasPaths($paths, Environment $environment) + public function getSiteAliasPaths($paths, Environment $environment): array { // In addition to the paths passed in to us (from --alias-path // commandline options), add some site-local locations. @@ -421,10 +401,8 @@ function ($item) { * Get the commandfile paths according to preflight arguments. * * @param $preflightArgs - * - * @return array */ - public function getCommandFilePaths($commandPaths, $root) + public function getCommandFilePaths($commandPaths, $root): array { $builtin = $this->getBuiltinCommandFilePaths(); $included = $this->getIncludedCommandFilePaths($commandPaths); @@ -440,7 +418,7 @@ public function getCommandFilePaths($commandPaths, $root) /** * Return all of the built-in commandfile locations */ - protected function getBuiltinCommandFilePaths() + protected function getBuiltinCommandFilePaths(): array { return [ dirname(__DIR__), @@ -451,7 +429,7 @@ protected function getBuiltinCommandFilePaths() * Return all of the commandfile locations specified via * an 'include' option. */ - protected function getIncludedCommandFilePaths($commandPaths) + protected function getIncludedCommandFilePaths($commandPaths): array { $searchpath = []; @@ -461,7 +439,7 @@ protected function getIncludedCommandFilePaths($commandPaths) // This indicates an include path that has a namespace, // e.g. `namespace#/path`. if (is_numeric($key) && strpos($commandPath, '#') !== false) { - list($key, $commandPath) = explode('#', $commandPath, 2); + [$key, $commandPath] = explode('#', $commandPath, 2); } $sep = ($this->config->isWindows()) ? ';' : ':'; foreach (explode($sep, $commandPath) as $path) { @@ -484,7 +462,7 @@ protected function getIncludedCommandFilePaths($commandPaths) * 'dirname($root)/drush' directory that contains a composer.json * file or a 'Commands' or 'src/Commands' directory. */ - protected function getSiteCommandFilePaths($root) + protected function getSiteCommandFilePaths($root): array { $directories = ["$root/drush", dirname($root) . '/drush', "$root/sites/all/drush"]; @@ -493,10 +471,8 @@ protected function getSiteCommandFilePaths($root) /** * Sets the composer root. - * - * @param $selectedComposerRoot */ - public function setComposerRoot($selectedComposerRoot) + public function setComposerRoot($selectedComposerRoot): void { $this->composerRoot = $selectedComposerRoot; @@ -508,7 +484,7 @@ public function setComposerRoot($selectedComposerRoot) /** * Double the candidates, adding '$prefix' before each existing one. */ - public function expandCandidates($candidates, $prefix) + public function expandCandidates($candidates, $prefix): array { $additional = array_map( function ($item) use ($prefix) { @@ -528,11 +504,11 @@ function ($item) use ($prefix) { * @param array $candidates * An array filenames that are considered config files. * - * @return array - * An array. The first row is an array of files, the second row is an + * @return + * An array whose first item is an array of files, and the second item is an * array of dirs. */ - protected function findConfigFiles($paths, $candidates) + protected function findConfigFiles(array $paths, array $candidates): array { $files = []; $dirs = []; @@ -549,7 +525,7 @@ protected function findConfigFiles($paths, $candidates) // Search directories for config file candidates. $discovered_config_files = $this->identifyCandidates($dirs, $candidates); - // Merge discoverd candidates with explicitly specified config files. + // Merge discovered candidates with explicitly specified config files. $config_files = array_merge($discovered_config_files, $files); return $config_files; @@ -563,7 +539,7 @@ protected function findConfigFiles($paths, $candidates) * @param $siteConfig * The site-specific config file. * - * @return bool + * @return * Whether the config exists and was processed. */ public static function addSiteSpecificConfig(DrushConfig $config, $siteConfig): bool diff --git a/src/Config/Environment.php b/src/Config/Environment.php index cb8a07f3f4..f6641ae175 100644 --- a/src/Config/Environment.php +++ b/src/Config/Environment.php @@ -43,12 +43,9 @@ public function __construct($homeDir, $cwd, $autoloadFile) } /** - * Load the autoloader for the selected Drupal site - * - * @param string $root - * @return ClassLoader + * Load the autoloader for the selected Drupal site. */ - public function loadSiteAutoloader($root) + public function loadSiteAutoloader(string $root): ClassLoader { $autloadFilePath = "$root/autoload.php"; if (!file_exists($autloadFilePath)) { @@ -82,10 +79,8 @@ public function loadSiteAutoloader($root) /** * Return the name of the user running drush. - * - * @return string */ - protected function getUsername() + protected function getUsername(): string { $name = null; if (!$name = getenv("username")) { // Windows @@ -101,7 +96,7 @@ protected function getUsername() return $name; } - protected function getTmp() + protected function getTmp(): string { $directories = []; @@ -155,9 +150,9 @@ protected function getTmp() * * @see PreflightArgs::applyToConfig(), which also exports information to config. * - * @return array Nested associative array that is overlayed on configuration. + * @return Nested associative array that is overlayed on configuration. */ - public function exportConfigData() + public function exportConfigData(): array { return [ // Information about the environment presented to Drush @@ -192,10 +187,8 @@ public function exportConfigData() /** * The base directory of the Drush application itself * (where composer.json et.al. are found) - * - * @return string */ - public function drushBasePath() + public function drushBasePath(): string { return $this->drushBasePath; } @@ -219,25 +212,21 @@ public function getSiteSetAliasName() /** * User's home directory - * - * @return string */ - public function homeDir() + public function homeDir(): string { return $this->homeDir; } /** * The user's Drush configuration directory, ~/.drush - * - * @return string */ - public function userConfigPath() + public function userConfigPath(): string { return $this->homeDir() . '/.drush'; } - public function setConfigFileVariant($variant) + public function setConfigFileVariant($variant): void { $this->configFileVariant = $variant; } @@ -254,30 +243,24 @@ public function getConfigFileVariant() /** * The original working directory - * - * @return string */ - public function cwd() + public function cwd(): string { return $this->originalCwd; } /** * Return the path to Drush's vendor directory - * - * @return string */ - public function vendorPath() + public function vendorPath(): string { return $this->vendorDir; } /** * The class loader returned when the autoload.php file is included. - * - * @return \Composer\Autoload\ClassLoader */ - public function loader() + public function loader(): ?\Composer\Autoload\ClassLoader { return $this->loader; } @@ -287,17 +270,15 @@ public function loader() * * @param \Composer\Autoload\ClassLoader $loader */ - public function setLoader(ClassLoader $loader) + public function setLoader(ClassLoader $loader): void { $this->loader = $loader; } /** - * Alter our default locations based on the value of environment variables - * - * @return $this + * Alter our default locations based on the value of environment variables. */ - public function applyEnvironment() + public function applyEnvironment(): self { // Copy ETC_PREFIX and SHARE_PREFIX from environment variables if available. // This alters where we check for server-wide config and alias files. @@ -310,12 +291,9 @@ public function applyEnvironment() /** * Set the directory prefix to locate the directory that Drush will - * use as /etc (e.g. during the functional tests) - * - * @param string $etcPrefix - * @return $this + * use as /etc (e.g. during the functional tests). */ - public function setEtcPrefix($etcPrefix) + public function setEtcPrefix(string $etcPrefix): self { if (isset($etcPrefix)) { $this->etcPrefix = $etcPrefix; @@ -325,11 +303,9 @@ public function setEtcPrefix($etcPrefix) /** * Set the directory prefix to locate the directory that Drush will - * use as /user/share (e.g. during the functional tests) - * @param string $sharePrefix - * @return $this + * use as /user/share (e.g. during the functional tests). */ - public function setSharePrefix($sharePrefix) + public function setSharePrefix(string $sharePrefix): self { if (isset($sharePrefix)) { $this->sharePrefix = $sharePrefix; @@ -343,10 +319,8 @@ public function setSharePrefix($sharePrefix) * this is within the Drush application, but some Drush RPM distributions * & c. for Linux platforms slice-and-dice the contents and put the docs * elsewhere. - * - * @return string */ - public function docsPath() + public function docsPath(): ?string { if (!$this->docPrefix) { $this->docPrefix = $this->findDocsPath($this->drushBasePath); @@ -358,10 +332,9 @@ public function docsPath() * Locate the Drush documentation. This is recalculated whenever the * share prefix is changed. * - * @param string $drushBasePath - * @return string + * @return string|bool */ - protected function findDocsPath($drushBasePath) + protected function findDocsPath(string $drushBasePath) { $candidates = [ "$drushBasePath/README.md", @@ -373,10 +346,9 @@ protected function findDocsPath($drushBasePath) /** * Check a list of directories and return the first one that exists. * - * @param array $candidates * @return string|boolean */ - protected function findFromCandidates($candidates) + protected function findFromCandidates(array $candidates) { foreach ($candidates as $candidate) { if (file_exists($candidate)) { @@ -388,11 +360,8 @@ protected function findFromCandidates($candidates) /** * Return the appropriate system path prefix, unless an override is provided. - * @param string $override - * @param string $defaultPrefix - * @return string */ - protected static function systemPathPrefix($override = '', $defaultPrefix = '') + protected static function systemPathPrefix(string $override = '', string $defaultPrefix = ''): string { if ($override) { return $override; @@ -402,30 +371,24 @@ protected static function systemPathPrefix($override = '', $defaultPrefix = '') /** * Return the system configuration path (default: /etc/drush) - * - * @return string */ - public function systemConfigPath() + public function systemConfigPath(): string { return static::systemPathPrefix($this->etcPrefix, '') . '/etc/drush'; } /** * Return the system shared commandfile path (default: /usr/share/drush/commands) - * - * @return string */ - public function systemCommandFilePath() + public function systemCommandFilePath(): string { return static::systemPathPrefix($this->sharePrefix, '/usr') . '/share/drush/commands'; } /** * Determine whether current OS is a Windows variant. - * - * @return boolean */ - public static function isWindows($os = null) + public static function isWindows($os = null): bool { return strtoupper(substr($os ?: PHP_OS, 0, 3)) === 'WIN'; } @@ -433,21 +396,18 @@ public static function isWindows($os = null) /** * Verify that we are running PHP through the command line interface. * - * @return boolean * A boolean value that is true when PHP is being run through the command line, * and false if being run through cgi or mod_php. */ - public function verifyCLI() + public function verifyCLI(): bool { return (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)); } /** * Get terminal width. - * - * @return int */ - public function calculateColumns() + public function calculateColumns(): int { return (new Terminal())->getWidth(); } @@ -455,13 +415,13 @@ public function calculateColumns() /** * Returns the filename for the file that stores the DRUPAL_SITE variable. * - * @param string $filename_prefix + * @param $filename_prefix * An arbitrary string to prefix the filename with. * * @return string|false * Returns the full path to temp file if possible, or FALSE if not. */ - protected function getSiteSetAliasFilePath($filename_prefix = 'drush-drupal-site-') + protected function getSiteSetAliasFilePath(string $filename_prefix = 'drush-drupal-site-') { $shell_pid = getenv('DRUSH_SHELL_PID'); if (!$shell_pid && function_exists('posix_getppid')) { diff --git a/src/Config/Loader/YamlConfigLoader.php b/src/Config/Loader/YamlConfigLoader.php index f7b5c11cc9..c1b6f030bb 100644 --- a/src/Config/Loader/YamlConfigLoader.php +++ b/src/Config/Loader/YamlConfigLoader.php @@ -11,7 +11,7 @@ */ class YamlConfigLoader extends ConfigLoader { - public function load($path) + public function load($path): self { $this->setSourceName($path); diff --git a/src/Preflight/ArgsPreprocessor.php b/src/Preflight/ArgsPreprocessor.php index 061e1c509d..289b6132af 100644 --- a/src/Preflight/ArgsPreprocessor.php +++ b/src/Preflight/ArgsPreprocessor.php @@ -27,7 +27,7 @@ public function __construct() $this->specParser = new SiteSpecParser(); } - public function setArgsRemapper(ArgsRemapper $remapper) + public function setArgsRemapper(ArgsRemapper $remapper): void { $this->remapper = $remapper; } @@ -38,11 +38,10 @@ public function setArgsRemapper(ArgsRemapper $remapper) * @param string[] $argv * Commandline arguments. The first element is * the path to the application, which we will ignore. - * @param PreflightArgsInterface $storage * A storage object to hold the arguments we remove * from argv, plus the remaining argv arguments. */ - public function parse($argv, PreflightArgsInterface $storage) + public function parse(array $argv, PreflightArgsInterface $storage) { $sawArg = false; @@ -94,7 +93,7 @@ public function parse($argv, PreflightArgsInterface $storage) * nextCouldBeValue determines whether there is a next argument that * exists and does not begin with a `-`. */ - protected static function nextCouldBeValue($argv) + protected static function nextCouldBeValue($argv): bool { if (empty($argv)) { return false; @@ -108,9 +107,8 @@ protected static function nextCouldBeValue($argv) * * @param string $arg * Argument to test. - * @return bool */ - protected function isAliasOrSiteSpec($arg) + protected function isAliasOrSiteSpec(string $arg): bool { if (SiteAliasName::isAliasName($arg)) { return true; @@ -157,7 +155,7 @@ protected function findMethodForOptionWithValues($optionsTable, $opt) * to 'true'. * @return [$methodName, $optionValue, $acceptsValueFromNextArg] */ - protected function checkMatchingOption($opt, $keyParam, $methodName) + protected function checkMatchingOption($opt, $keyParam, $methodName): array { // Test to see if $key ends in '='; remove the character if present. // If the char is removed, it means the option accepts a value. diff --git a/src/Preflight/ArgsRemapper.php b/src/Preflight/ArgsRemapper.php index d5abca8452..2cd14dcc84 100644 --- a/src/Preflight/ArgsRemapper.php +++ b/src/Preflight/ArgsRemapper.php @@ -24,7 +24,7 @@ public function __construct($remapOptions, $remapCommandAliases) * * @param string[] $argv */ - public function remap($argv) + public function remap(array $argv): array { $result = []; $sawCommand = false; @@ -45,7 +45,7 @@ public function remap($argv) * @param string $sawCommand True if drush command was found * @return string The altered argument */ - protected function checkRemap($arg, &$sawCommand) + protected function checkRemap(string $arg, string &$sawCommand) { if (!$sawCommand && ctype_alpha($arg[0])) { $sawCommand = true; @@ -78,11 +78,8 @@ protected function remapCommandAlias($arg) * Check to see if the provided single arg matches the candidate. * If the candidate is `--foo`, then we will match the exact string * `--foo`, or the leading substring `--foo=`, and nothing else. - * @param string $arg - * @param string $candidate - * @return bool */ - protected function matches($arg, $candidate) + protected function matches(string $arg, string $candidate): bool { if (strpos($arg, $candidate) !== 0) { return false; diff --git a/src/Preflight/LegacyPreflight.php b/src/Preflight/LegacyPreflight.php index d7c2c5555e..1ffa3d365c 100644 --- a/src/Preflight/LegacyPreflight.php +++ b/src/Preflight/LegacyPreflight.php @@ -19,7 +19,7 @@ class LegacyPreflight /** * Define legacy constants. */ - public static function defineConstants(Environment $environment, $applicationPath) + public static function defineConstants(Environment $environment, $applicationPath): void { // 'define' is undesirable in that it will error if the same identifier // is defined more than once. Ideally we would inject the legacy preflight @@ -64,7 +64,7 @@ public static function defineConstants(Environment $environment, $applicationPat * Include old code. It is an aspirational goal to remove or refactor * all of this into more modular, class-based code. */ - public static function includeCode($drushBasePath) + public static function includeCode($drushBasePath): void { // We still need preflight for drush_shutdown() require_once $drushBasePath . '/includes/preflight.inc'; diff --git a/src/Preflight/Preflight.php b/src/Preflight/Preflight.php index 823e2ff047..044283436e 100644 --- a/src/Preflight/Preflight.php +++ b/src/Preflight/Preflight.php @@ -1,6 +1,7 @@ logger = $preflightLog ?: new PreflightLog(); } - /** - * @return PreflightLog - */ - public function logger() + public function logger(): \Drush\Preflight\PreflightLog { return $this->logger; } @@ -76,7 +74,7 @@ public function logger() /** * @param PreflightLog $logger */ - public function setLogger(PreflightLog $logger) + public function setLogger(PreflightLog $logger): void { $this->logger = $logger; } @@ -85,7 +83,7 @@ public function setLogger(PreflightLog $logger) * Perform preliminary initialization. This mostly involves setting up * legacy systems. */ - public function init() + public function init(): void { // Define legacy constants, and include legacy files that Drush still needs LegacyPreflight::includeCode($this->environment->drushBasePath()); @@ -111,7 +109,7 @@ public function init() * Eventually, we might want to expose this table to some form of * 'help' output, so folks can see the available conversions. */ - protected function remapOptions() + protected function remapOptions(): array { return [ '--ssh-options' => '-Dssh.options', @@ -135,7 +133,7 @@ protected function remapOptions() * * This should be fixed in Symfony Console. */ - protected function remapCommandAliases() + protected function remapCommandAliases(): array { return [ 'si' => 'site:install', @@ -150,7 +148,7 @@ protected function remapCommandAliases() * Arguments and options not used during preflight will be processed * with an ArgvInput. */ - public function preflightArgs($argv) + public function preflightArgs($argv): \Drush\Preflight\PreflightArgs { $argProcessor = new ArgsPreprocessor(); $remapper = new ArgsRemapper($this->remapOptions(), $this->remapCommandAliases()); @@ -167,7 +165,7 @@ public function preflightArgs($argv) * Create the initial config locator object, and inject any needed * settings, paths and so on into it. */ - public function prepareConfig(Environment $environment) + public function prepareConfig(Environment $environment): void { // Make our environment settings available as configuration items $this->configLocator->addEnvironment($environment); @@ -176,12 +174,12 @@ public function prepareConfig(Environment $environment) $this->configLocator->addDrushConfig($environment->drushBasePath()); } - public function createInput() + public function createInput(): \Symfony\Component\Console\Input\InputInterface { return $this->preflightArgs->createInput(); } - public function getCommandFilePaths() + public function getCommandFilePaths(): array { $commandlinePaths = $this->preflightArgs->commandPaths(); $configPaths = $this->config()->get('drush.include', []); @@ -192,22 +190,21 @@ public function getCommandFilePaths() return $this->configLocator->getCommandFilePaths(array_merge($commandlinePaths, $configPaths), $this->drupalFinder()->getDrupalRoot()); } - public function loadSiteAutoloader() + public function loadSiteAutoloader(): \Composer\Autoload\ClassLoader { return $this->environment()->loadSiteAutoloader($this->drupalFinder()->getDrupalRoot()); } - public function config() + public function config(): DrushConfig { return $this->configLocator->config(); } /** * @param $argv - * @return bool * True if the request was successfully redispatched remotely. False if the request should proceed. */ - public function preflight($argv) + public function preflight($argv): bool { // Fail fast if there is anything in our environment that does not check out $this->verify->verify($this->environment); @@ -217,7 +214,7 @@ public function preflight($argv) $this->prepareConfig($this->environment); // Now that we know the value, set debug flag. - $this->logger()->setDebug($this->preflightArgs->get(PreflightArgs::DEBUG)); + $this->logger()->setDebug($this->preflightArgs->get(PreflightArgs::DEBUG, false)); // Do legacy initialization (load static includes, define old constants, etc.) $this->init(); @@ -324,7 +321,7 @@ protected function findSelectedSite() * @param string $selectedRoot The location to being searching for a site * @param string|bool $fallbackPath The secondary location to search (usualy the vendor director) */ - protected function setSelectedSite($selectedRoot, $fallbackPath = false, $originalSelection = null) + protected function setSelectedSite(string $selectedRoot, $fallbackPath = false, $originalSelection = null) { if ($selectedRoot || $fallbackPath) { $foundRoot = $this->drupalFinder->locateRoot($selectedRoot); @@ -347,30 +344,24 @@ protected function setSelectedSite($selectedRoot, $fallbackPath = false, $origin /** * Return the Drupal Finder - * - * @return DrupalFinder */ - public function drupalFinder() + public function drupalFinder(): \DrupalFinder\DrupalFinder { return $this->drupalFinder; } /** * Return the alias manager - * - * @return SiteAliasManager */ - public function aliasManager() + public function aliasManager(): \Consolidation\SiteAlias\SiteAliasManager { return $this->aliasManager; } /** * Return the environment - * - * @return Environment */ - public function environment() + public function environment(): \Drush\Config\Environment { return $this->environment; } diff --git a/src/Preflight/PreflightArgs.php b/src/Preflight/PreflightArgs.php index 7f0d997f19..c4f151923a 100644 --- a/src/Preflight/PreflightArgs.php +++ b/src/Preflight/PreflightArgs.php @@ -31,18 +31,12 @@ class PreflightArgs extends Config implements PreflightArgsInterface protected $commandName; - /** - * @return string - */ - public function homeDir() + public function homeDir(): string { return $this->homeDir; } - /** - * @param string $homeDir - */ - public function setHomeDir($homeDir) + public function setHomeDir(string $homeDir): void { $this->homeDir = $homeDir; } @@ -75,7 +69,7 @@ public function __construct($data = []) /** * @inheritdoc */ - public function optionsWithValues() + public function optionsWithValues(): array { return [ '-r=' => 'setSelectedSite', @@ -105,7 +99,7 @@ public function optionsWithValues() * option away and add a 'help' command to the beginning * of the argument list. */ - public function adjustHelpOption() + public function adjustHelpOption(): void { $drushPath = array_shift($this->args); array_unshift($this->args, $drushPath, 'help'); @@ -116,7 +110,7 @@ public function adjustHelpOption() * preflight option in. The values of the config items in this map * must be BOOLEANS or STRINGS. */ - protected function optionConfigMap() + protected function optionConfigMap(): array { return [ self::SIMULATE => \Robo\Config\Config::SIMULATE, @@ -130,7 +124,7 @@ protected function optionConfigMap() * preflight option in. The values of the items in this map must be * STRINGS or ARRAYS OF STRINGS. */ - protected function optionConfigPathMap() + protected function optionConfigPathMap(): array { return [ self::ALIAS_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::ALIAS_PATH, @@ -144,7 +138,7 @@ protected function optionConfigPathMap() * * @see Environment::exportConfigData(), which also exports information to config. */ - public function applyToConfig(ConfigInterface $config) + public function applyToConfig(ConfigInterface $config): void { // Copy the relevant preflight options to the applicable configuration namespace foreach ($this->optionConfigMap() as $option_key => $config_key) { @@ -171,7 +165,7 @@ public function applyToConfig(ConfigInterface $config) /** * @inheritdoc */ - public function args() + public function args(): array { return $this->args; } @@ -195,14 +189,14 @@ public function commandName() /** * @inheritdoc */ - public function setCommandName($commandName) + public function setCommandName($commandName): void { $this->commandName = $commandName; } /** * @inheritdoc */ - public function addArg($arg) + public function addArg($arg): self { $this->args[] = $arg; return $this; @@ -211,7 +205,7 @@ public function addArg($arg) /** * @inheritdoc */ - public function passArgs($args) + public function passArgs($args): self { $this->args = array_merge($this->args, $args); return $this; @@ -228,7 +222,7 @@ public function alias() /** * @inheritdoc */ - public function hasAlias() + public function hasAlias(): bool { return $this->has(self::ALIAS); } @@ -236,7 +230,7 @@ public function hasAlias() /** * @inheritdoc */ - public function setAlias($alias) + public function setAlias($alias): self { // Treat `drush @self ...` as if an alias had not been used at all. if ($alias == '@self') { @@ -253,7 +247,7 @@ public function selectedSite($default = false) return $this->get(self::ROOT, $default); } - public function setDebug($value) + public function setDebug($value): void { $this->set(self::DEBUG, $value); $this->addArg('-vvv'); @@ -262,7 +256,7 @@ public function setDebug($value) /** * Set the selected site. */ - public function setSelectedSite($root) + public function setSelectedSite($root): self { return $this->set(self::ROOT, StringUtils::replaceTilde($root, $this->homeDir())); } @@ -275,7 +269,7 @@ public function uri($default = false) return $this->get(self::URI, $default); } - public function hasUri() + public function hasUri(): bool { return $this->has(self::URI); } @@ -283,7 +277,7 @@ public function hasUri() /** * Set the uri option */ - public function setUri($uri) + public function setUri($uri): self { return $this->set(self::URI, $uri); } @@ -298,10 +292,8 @@ public function configPaths() /** * Add another location where drush.yml files may be found - * - * @param string $path */ - public function addConfigPath($path) + public function addConfigPath(string $path): self { $paths = $this->configPaths(); $paths[] = StringUtils::replaceTilde($path, $this->homeDir()); @@ -313,7 +305,7 @@ public function addConfigPath($path) * * @param string[] $configPaths */ - public function mergeConfigPaths($configPaths) + public function mergeConfigPaths(array $configPaths): self { $paths = $this->configPaths(); $merged_paths = array_merge($paths, $configPaths); @@ -330,10 +322,8 @@ public function aliasPaths() /** * Set one more path where aliases may be found. - * - * @param string $path */ - public function addAliasPath($path) + public function addAliasPath(string $path): self { $paths = $this->aliasPaths(); $paths[] = StringUtils::replaceTilde($path, $this->homeDir()); @@ -342,10 +332,8 @@ public function addAliasPath($path) /** * Add multiple additional locations for alias paths. - * - * @param string $aliasPaths */ - public function mergeAliasPaths($aliasPaths) + public function mergeAliasPaths(string $aliasPaths): self { $aliasPaths = array_map( function ($item) { @@ -368,10 +356,8 @@ public function commandPaths() /** * Add one more path where commandfiles might be found. - * - * @param string $path */ - public function addCommandPath($path) + public function addCommandPath(string $path): self { $paths = $this->commandPaths(); $paths[] = StringUtils::replaceTilde($path, $this->homeDir()); @@ -383,7 +369,7 @@ public function addCommandPath($path) * * @param $commanPaths */ - public function mergeCommandPaths($commandPaths) + public function mergeCommandPaths($commandPaths): self { $paths = $this->commandPaths(); $merged_paths = array_merge($paths, $commandPaths); @@ -395,15 +381,13 @@ public function mergeCommandPaths($commandPaths) */ public function isLocal() { - return $this->get(self::LOCAL); + return $this->get(self::LOCAL, false); } /** * Set local mode - * - * @param bool $isLocal */ - public function setLocal($isLocal) + public function setLocal(bool $isLocal): self { return $this->set(self::LOCAL, $isLocal); } @@ -421,7 +405,7 @@ public function isSimulated() * * @param bool $simulated */ - public function setSimulate($simulate) + public function setSimulate($simulate): self { return $this->set(self::SIMULATE, $simulate); } @@ -436,10 +420,8 @@ public function isBackend() /** * Set backend mode - * - * @param bool $backend */ - public function setBackend($backend) + public function setBackend(bool $backend) { if ($backend == 'json') { // Remap to --format. See \Drush\Commands\sql\SqlSyncCommands::dump. @@ -462,7 +444,7 @@ public function coverageFile() * * @param string */ - public function setCoverageFile($coverageFile) + public function setCoverageFile($coverageFile): self { return $this->set(self::COVERAGE_FILE, StringUtils::replaceTilde($coverageFile, $this->homeDir())); } @@ -477,10 +459,8 @@ public function isStrict() /** * Set strict mode. - * - * @param bool $strict */ - public function setStrict($strict) + public function setStrict(bool $strict): self { return $this->set(self::STRICT, $strict); } @@ -492,7 +472,7 @@ public function setStrict($strict) * @param array $argv e.g. ['foo', '--bar=baz', 'boz'] * @return string[] e.g. ['bar'] */ - protected function getOptionNameList($argv) + protected function getOptionNameList(array $argv): array { return array_filter( array_map( @@ -516,7 +496,7 @@ function ($item) { /** * Create a Symfony Input object. */ - public function createInput() + public function createInput(): \Symfony\Component\Console\Input\InputInterface { // In strict mode (the default), create an ArgvInput. When // strict mode is disabled, create a more forgiving input object. diff --git a/src/Preflight/PreflightArgsInterface.php b/src/Preflight/PreflightArgsInterface.php index 73e2415df7..b3977d6dd3 100644 --- a/src/Preflight/PreflightArgsInterface.php +++ b/src/Preflight/PreflightArgsInterface.php @@ -53,7 +53,7 @@ public function setCommandName($commandName); * * @param string $arg One argument */ - public function addArg($arg); + public function addArg(string $arg); /** * Add everything in the provided array to the list returned by `args()` @@ -78,5 +78,5 @@ public function hasAlias(); * * @param string $alias The alias name '@site' */ - public function setAlias($alias); + public function setAlias(string $alias); } diff --git a/src/Preflight/PreflightLog.php b/src/Preflight/PreflightLog.php index 4f7072734c..69756c15f7 100644 --- a/src/Preflight/PreflightLog.php +++ b/src/Preflight/PreflightLog.php @@ -14,24 +14,18 @@ public function __construct($output = null) { $this->output = $output ?: new StreamOutput(fopen('php://stderr', 'w')); } - /** - * @return bool - */ - public function getDebug() + public function getDebug(): ?bool { return $this->debug; } - /** - * @param bool $debug - */ - public function setDebug($debug) + public function setDebug(bool $debug): self { $this->debug = $debug; return $this; } - public function log($message) + public function log($message): void { if ($this->getDebug()) { $this->output->write(' [preflight] ' . $message . "\n"); diff --git a/src/Preflight/PreflightSiteLocator.php b/src/Preflight/PreflightSiteLocator.php index 5a2e1f2233..12e5910c9a 100644 --- a/src/Preflight/PreflightSiteLocator.php +++ b/src/Preflight/PreflightSiteLocator.php @@ -34,7 +34,7 @@ public function __construct(SiteAliasManager $siteAliasManager) * * @return \Consolidation\SiteAlias\SiteAlias|false */ - public function findSite(PreflightArgsInterface $preflightArgs, Environment $environment, $root) + public function findSite(PreflightArgsInterface $preflightArgs, Environment $environment, string $root): \Consolidation\SiteAlias\SiteAlias { $self = $this->determineSelf($preflightArgs, $environment, $root); @@ -55,10 +55,8 @@ public function findSite(PreflightArgsInterface $preflightArgs, Environment $env * @param \Drush\Preflight\PreflightArgsInterface $preflightArgs * @param \Drush\Config\Environment $environment * @param $root - * - * @return \Consolidation\SiteAlias\SiteAlias */ - protected function determineSelf(PreflightArgsInterface $preflightArgs, Environment $environment, $root) + protected function determineSelf(PreflightArgsInterface $preflightArgs, Environment $environment, $root): \Consolidation\SiteAlias\SiteAlias { if ($preflightArgs->hasAlias()) { $aliasName = $preflightArgs->alias(); @@ -98,10 +96,8 @@ protected function determineSelf(PreflightArgsInterface $preflightArgs, Environm * * @param \Drush\Preflight\PreflightArgsInterface $preflightArgs * @param $root - * - * @return \Consolidation\SiteAlias\SiteAlias */ - protected function buildSelf(PreflightArgsInterface $preflightArgs, $root) + protected function buildSelf(PreflightArgsInterface $preflightArgs, $root): \Consolidation\SiteAlias\SiteAlias { // If there is no root, then return '@none' if (!$root) { diff --git a/src/Preflight/PreflightVerify.php b/src/Preflight/PreflightVerify.php index 5948826081..8c4218de56 100644 --- a/src/Preflight/PreflightVerify.php +++ b/src/Preflight/PreflightVerify.php @@ -14,7 +14,7 @@ class PreflightVerify * * @param Environment $environment */ - public function verify(Environment $environment) + public function verify(Environment $environment): void { // Fail fast if the PHP version is not at least 7.4.0. // We'll come back and check this again later, in case someone @@ -35,7 +35,7 @@ public function verify(Environment $environment) * @param string $minimumPhpVersion * The minimum allowable php version */ - public function confirmPhpVersion($minimumPhpVersion) + public function confirmPhpVersion(string $minimumPhpVersion): void { if (version_compare(phpversion(), $minimumPhpVersion) < 0 && !getenv('DRUSH_NO_MIN_PHP')) { throw new \Exception(StringUtils::interpolate('Your command line PHP installation is too old. Drush requires at least PHP {version}. To suppress this check, set the environment variable DRUSH_NO_MIN_PHP=1', ['version' => $minimumPhpVersion])); @@ -47,7 +47,7 @@ public function confirmPhpVersion($minimumPhpVersion) * * @param Environment $environment */ - protected function confirmUsingCLI(Environment $environment) + protected function confirmUsingCLI(Environment $environment): void { if (!$environment->verifyCLI()) { throw new \Exception(StringUtils::interpolate('Drush is designed to run via the command line.')); @@ -59,7 +59,7 @@ protected function confirmUsingCLI(Environment $environment) * begins. If the php environment is too restrictive, then * notify the user that a setting change is needed and abort. */ - protected function checkPhpIni() + protected function checkPhpIni(): void { $ini_checks = ['safe_mode' => '', 'open_basedir' => '']; @@ -84,9 +84,8 @@ protected function checkPhpIni() * @param string|string[] $disallowed_value * The value that the ini seting cannot be, or a list of disallowed * values that cannot appear in the setting. - * @return bool */ - protected function invalidIniValue($ini_value, $disallowed_value) + protected function invalidIniValue(string $ini_value, $disallowed_value): bool { if (empty($disallowed_value)) { return !empty($ini_value) && (strcasecmp($ini_value, 'off') != 0); diff --git a/src/Preflight/RedispatchToSiteLocal.php b/src/Preflight/RedispatchToSiteLocal.php index 1e63591942..79d1c8f00d 100644 --- a/src/Preflight/RedispatchToSiteLocal.php +++ b/src/Preflight/RedispatchToSiteLocal.php @@ -25,7 +25,7 @@ class RedispatchToSiteLocal * @return bool * True if redispatch occurred, and was returned successfully. */ - public static function redispatchIfSiteLocalDrush($argv, $root, $vendor, PreflightLog $preflightLog) + public static function redispatchIfSiteLocalDrush(array $argv, string $root, string $vendor, PreflightLog $preflightLog) { // Try to find the site-local Drush. If there is none, we are done. @@ -64,9 +64,9 @@ function ($item) { * Find a site-local Drush, if there is one in the selected site's * vendor directory. * - * @param string $root The selected site root + * @param $root The selected site root */ - protected static function findSiteLocalDrush($root) + protected static function findSiteLocalDrush(string $root) { $candidates = [ "$root/vendor/drush/drush/drush", diff --git a/src/Psysh/DrushCommand.php b/src/Psysh/DrushCommand.php index dbd3f63954..90c2d7bbea 100644 --- a/src/Psysh/DrushCommand.php +++ b/src/Psysh/DrushCommand.php @@ -43,7 +43,7 @@ public function __construct(Command $command) /** * Get the namespace of this command. */ - public function getNamespace() + public function getNamespace(): string { $parts = explode(':', $this->getName()); return count($parts) >= 2 ? array_shift($parts) : 'global'; @@ -52,7 +52,7 @@ public function getNamespace() /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setName($this->command->getName()) @@ -65,7 +65,7 @@ protected function configure() /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { $args = $input->getArguments(); $first = array_shift($args); @@ -100,10 +100,9 @@ protected function execute(InputInterface $input, OutputInterface $output) * * Currently it's a word-wrapped description, plus any examples provided. * - * @return string * The help string. */ - protected function buildHelpFromCommand() + protected function buildHelpFromCommand(): string { $help = wordwrap($this->command->getDescription()); diff --git a/src/Psysh/DrushHelpCommand.php b/src/Psysh/DrushHelpCommand.php index fb3f0a11c3..11653523e0 100644 --- a/src/Psysh/DrushHelpCommand.php +++ b/src/Psysh/DrushHelpCommand.php @@ -39,7 +39,7 @@ class DrushHelpCommand extends BaseCommand /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setName('help') @@ -55,7 +55,7 @@ protected function configure() * * @param \Symfony\Component\Console\Command\Command $command */ - public function setCommand(Command $command) + public function setCommand(Command $command): void { $this->command = $command; } @@ -63,7 +63,7 @@ public function setCommand(Command $command) /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { if ($this->command !== null) { // Help for an individual command. diff --git a/src/Psysh/Shell.php b/src/Psysh/Shell.php index c495b3d952..9924dbb737 100644 --- a/src/Psysh/Shell.php +++ b/src/Psysh/Shell.php @@ -52,7 +52,7 @@ protected function hasCommand(string $input): bool * @return string|NULL * The current command. */ - protected function getCommandFromInput(string $input) + protected function getCommandFromInput(string $input): ?string { // Remove the alias from the start of the string before parsing and // returning the command. Essentially, when choosing a command, we're diff --git a/src/Runtime/DependencyInjection.php b/src/Runtime/DependencyInjection.php index b0b068c17f..384057c227 100644 --- a/src/Runtime/DependencyInjection.php +++ b/src/Runtime/DependencyInjection.php @@ -25,7 +25,7 @@ class DependencyInjection { protected $handlers = []; - public function desiredHandlers($handlerList) + public function desiredHandlers($handlerList): void { $this->handlers = $handlerList; } @@ -41,7 +41,7 @@ public function initContainer( ClassLoader $loader, DrupalFinder $drupalFinder, SiteAliasManager $aliasManager - ) { + ): \League\Container\Container { // Create default input and output objects if they were not provided if (!$input) { @@ -75,7 +75,7 @@ public function initContainer( /** * Make sure we are notified on exit, and when bad things happen. */ - public function installHandlers($container) + public function installHandlers($container): void { foreach ($this->handlers as $handlerId) { $handler = $container->get($handlerId); @@ -84,7 +84,7 @@ public function installHandlers($container) } // Add Drush Services to league/container 3.x - protected function addDrushServices($container, ClassLoader $loader, DrupalFinder $drupalFinder, SiteAliasManager $aliasManager, DrushConfig $config) + protected function addDrushServices($container, ClassLoader $loader, DrupalFinder $drupalFinder, SiteAliasManager $aliasManager, DrushConfig $config): void { // Override Robo's logger with our own $container->share('logger', 'Drush\Log\Logger') @@ -141,7 +141,7 @@ protected function addDrushServices($container, ClassLoader $loader, DrupalFinde ->invokeMethod('setProcessManager', ['process.manager']); } - protected function alterServicesForDrush($container, Application $application) + protected function alterServicesForDrush($container, Application $application): void { $paramInjection = $container->get('parameterInjection'); $paramInjection->register('Symfony\Component\Console\Style\SymfonyStyle', new DrushStyleInjector()); @@ -170,7 +170,7 @@ protected function alterServicesForDrush($container, Application $application) ProcessManager::addTransports($container->get('process.manager')); } - protected function injectApplicationServices($container, Application $application) + protected function injectApplicationServices($container, Application $application): void { $application->setLogger($container->get('logger')); $application->setBootstrapManager($container->get('bootstrap.manager')); diff --git a/src/Runtime/ErrorHandler.php b/src/Runtime/ErrorHandler.php index fb97eb0c33..f7e2d95230 100644 --- a/src/Runtime/ErrorHandler.php +++ b/src/Runtime/ErrorHandler.php @@ -19,7 +19,7 @@ class ErrorHandler implements LoggerAwareInterface, HandlerInterface { use LoggerAwareTrait; - public function installHandler() + public function installHandler(): void { set_error_handler([$this, 'errorHandler']); } diff --git a/src/Runtime/RedispatchHook.php b/src/Runtime/RedispatchHook.php index 3649d5d134..a9f1127061 100644 --- a/src/Runtime/RedispatchHook.php +++ b/src/Runtime/RedispatchHook.php @@ -112,10 +112,8 @@ public function redispatch(InputInterface $input) * Remove anything that is not necessary for the remote side. * At the moment this is limited to configuration options * provided via -D. - * - * @param array $redispatchArgs */ - protected function alterArgsForRedispatch($redispatchArgs) + protected function alterArgsForRedispatch(array $redispatchArgs): array { return array_filter($redispatchArgs, function ($item) { return strpos($item, '-D') !== 0; @@ -128,7 +126,7 @@ protected function alterArgsForRedispatch($redispatchArgs) * * @param int $exit_code. */ - protected function exitEarly($exit_code) + protected function exitEarly(int $exit_code): void { Drush::logger()->debug('Redispatch hook exit early'); diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index fede4b422e..85f2011d48 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -127,7 +127,7 @@ protected function doRun($argv, $output) /** * Mark the current request as having completed successfully. */ - public static function setCompleted() + public static function setCompleted(): void { Drush::config()->set(self::DRUSH_RUNTIME_COMPLETED_NAMESPACE, true); } @@ -139,7 +139,7 @@ public static function setCompleted() * Mark the exit code for current request. * @param int $code */ - public static function setExitCode($code) + public static function setExitCode(int $code): void { Drush::config()->set(self::DRUSH_RUNTIME_EXIT_CODE_NAMESPACE, $code); } diff --git a/src/Runtime/ShutdownHandler.php b/src/Runtime/ShutdownHandler.php index 9b31fa67bc..b85f426b3b 100644 --- a/src/Runtime/ShutdownHandler.php +++ b/src/Runtime/ShutdownHandler.php @@ -26,12 +26,12 @@ class ShutdownHandler implements LoggerAwareInterface, HandlerInterface { use LoggerAwareTrait; - public function installHandler() + public function installHandler(): void { register_shutdown_function([$this, 'shutdownHandler']); } - public function shutdownHandler() + public function shutdownHandler(): void { // Avoid doing anything if our container has not been initialized yet. if (!Drush::hasContainer()) { @@ -55,7 +55,7 @@ public function shutdownHandler() /** * @deprecated. This function will be removed in Drush 10. Throw an exception to indicate an error. */ - public function returnStatus() + public function returnStatus(): void { exit(Runtime::exitCode()); } diff --git a/src/Runtime/TildeExpansionHook.php b/src/Runtime/TildeExpansionHook.php index 93c1342314..eb0b63d58a 100644 --- a/src/Runtime/TildeExpansionHook.php +++ b/src/Runtime/TildeExpansionHook.php @@ -21,7 +21,7 @@ class TildeExpansionHook implements ValidatorInterface, ConfigAwareInterface { use ConfigAwareTrait; - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $input = $commandData->input(); $args = $input->getArguments(); diff --git a/src/SiteAlias/LegacyAliasConverter.php b/src/SiteAlias/LegacyAliasConverter.php index 3bb1e7a00a..51a665d10c 100644 --- a/src/SiteAlias/LegacyAliasConverter.php +++ b/src/SiteAlias/LegacyAliasConverter.php @@ -51,18 +51,12 @@ public function __construct(SiteAliasFileDiscovery $discovery) $this->target = ''; } - /** - * @return bool - */ - public function isSimulate() + public function isSimulate(): bool { return $this->simulate; } - /** - * @param bool $simulate - */ - public function setSimulate($simulate) + public function setSimulate(bool $simulate): void { $this->simulate = $simulate; } @@ -71,7 +65,7 @@ public function setSimulate($simulate) * @param string $target * A directory to write to. If not provided, writes go into same dir as the corresponding legacy file. */ - public function setTargetDir($target) + public function setTargetDir(string $target): void { $this->target = $target; } @@ -102,7 +96,7 @@ public function convert() return $convertedFiles; } - protected function checkAnyNeedsConversion($legacyFiles) + protected function checkAnyNeedsConversion($legacyFiles): bool { foreach ($legacyFiles as $legacyFile) { $convertedFile = $this->determineConvertedFilename($legacyFile); @@ -113,7 +107,7 @@ protected function checkAnyNeedsConversion($legacyFiles) return false; } - protected function convertAll($legacyFiles) + protected function convertAll($legacyFiles): array { $result = []; foreach ($legacyFiles as $legacyFile) { @@ -130,7 +124,7 @@ protected function convertAll($legacyFiles) return $result; } - protected function writeAll($convertedFiles) + protected function writeAll($convertedFiles): void { foreach ($convertedFiles as $path => $data) { $contents = $this->getContents($path, $data); @@ -144,7 +138,7 @@ protected function writeAll($convertedFiles) } } - protected function getContents($path, $data) + protected function getContents($path, $data): string { if (!empty($data)) { $indent = 2; @@ -163,7 +157,7 @@ protected function getContents($path, $data) return $contents; } - protected function writeOne($path, $contents) + protected function writeOne($path, $contents): void { $checksumPath = $this->checksumPath($path); if ($this->safeToWrite($path, $contents, $checksumPath)) { @@ -181,7 +175,7 @@ protected function writeOne($path, $contents) * alias file at the specified path. If the user has modified the target * file, then we will not overwrite it. */ - protected function safeToWrite($path, $contents, $checksumPath) + protected function safeToWrite($path, $contents, $checksumPath): bool { // Bail if simulate mode is enabled. if ($this->isSimulate()) { @@ -214,7 +208,7 @@ protected function safeToWrite($path, $contents, $checksumPath) return $previousChecksum == $previousWrittenChecksum; } - public function saveChecksum($checksumPath, $path, $contents) + public function saveChecksum($checksumPath, $path, $contents): void { $name = basename($path); $comment = <<convertedFileMap[basename($convertedFile)] = basename($legacyFile); } @@ -317,14 +311,14 @@ protected function convertLegacyFile($legacyFile) return $this->convertMultipleAliasesLegacyFile($legacyFile, $aliases, $options); } - protected function convertSingleAliasLegacyFile($legacyFile, $options) + protected function convertSingleAliasLegacyFile($legacyFile, $options): array { $aliasName = basename($legacyFile, '.alias.drushrc.php'); return $this->convertAlias($aliasName, $options, dirname($legacyFile)); } - protected function convertMultipleAliasesLegacyFile($legacyFile, $aliases, $options) + protected function convertMultipleAliasesLegacyFile($legacyFile, $aliases, $options): array { $result = []; foreach ($aliases as $aliasName => $data) { @@ -336,7 +330,7 @@ protected function convertMultipleAliasesLegacyFile($legacyFile, $aliases, $opti return $result; } - protected function convertAlias($aliasName, $data, $dir = '') + protected function convertAlias($aliasName, $data, $dir = ''): array { $env = 'dev'; // We allow $aliasname to be: @@ -358,7 +352,7 @@ protected function convertAlias($aliasName, $data, $dir = '') return $this->convertSingleFileAlias($aliasName, $env, $data, $dir); } - protected function fixSiteData($data) + protected function fixSiteData($data): array { $keyMap = $this->keyConversion(); @@ -391,7 +385,7 @@ protected function fixSiteData($data) return $this->remapData($data); } - protected function remapData($data) + protected function remapData($data): array { $converter = new Data($data); @@ -412,7 +406,7 @@ protected function remapData($data) * Anything NOT identified by the key in the returned array * is moved to the 'options' element. */ - protected function keyConversion() + protected function keyConversion(): array { return [ 'remote-host' => 'host', @@ -432,14 +426,14 @@ protected function keyConversion() * been moved into the 'options' element before this remapping * table is consulted. */ - protected function dataRemap() + protected function dataRemap(): array { return [ 'options.ssh-options' => 'ssh.options', ]; } - protected function removePercentFromKey($data) + protected function removePercentFromKey($data): array { return array_flip( @@ -452,7 +446,7 @@ function ($item) { ); } - protected function convertSingleFileAlias($aliasName, $env, $data, $dir = '') + protected function convertSingleFileAlias($aliasName, $env, $data, $dir = ''): array { $filename = $this->outputFilename($aliasName, '.site.yml', $dir); return [ @@ -479,7 +473,6 @@ protected function outputFilename($name, $extension, $dir = '') * @param array $array1 * @param array $array2 * - * @return array * * @see http://php.net/manual/en/function.array-merge-recursive.php#92195 * @see https://github.com/grasmash/bolt/blob/robo-rebase/src/Robo/Common/ArrayManipulator.php#L22 @@ -487,7 +480,7 @@ protected function outputFilename($name, $extension, $dir = '') protected static function arrayMergeRecursiveDistinct( array &$array1, array &$array2 - ) { + ): array { $merged = $array1; foreach ($array2 as $key => &$value) { $merged[$key] = self::mergeRecursiveValue($merged, $key, $value); diff --git a/src/SiteAlias/ProcessManager.php b/src/SiteAlias/ProcessManager.php index 2885170934..92355e1df9 100644 --- a/src/SiteAlias/ProcessManager.php +++ b/src/SiteAlias/ProcessManager.php @@ -17,15 +17,8 @@ class ProcessManager extends ConsolidationProcessManager { /** * Run a Drush command on a site alias (or @self). - * - * @param SiteAliasInterface $siteAlias - * @param string $command - * @param array $args - * @param array $options - * @param array $options_double_dash - * @return SiteProcess */ - public function drush(SiteAliasInterface $siteAlias, $command, $args = [], $options = [], $options_double_dash = []) + public function drush(SiteAliasInterface $siteAlias, string $command, array $args = [], array $options = [], array $options_double_dash = []): \Consolidation\SiteProcess\ProcessBase { array_unshift($args, $command); return $this->drushSiteProcess($siteAlias, $args, $options, $options_double_dash); @@ -35,14 +28,8 @@ public function drush(SiteAliasInterface $siteAlias, $command, $args = [], $opti * drushSiteProcess should be avoided in favor of the drush method above. * drushSiteProcess exists specifically for use by the RedispatchHook, * which does not have specific knowledge about which argument is the command. - * - * @param SiteAliasInterface $siteAlias - * @param array $args - * @param array $options - * @param array $options_double_dash - * @return ProcessBase */ - public function drushSiteProcess(SiteAliasInterface $siteAlias, $args = [], $options = [], $options_double_dash = []) + public function drushSiteProcess(SiteAliasInterface $siteAlias, array $args = [], array $options = [], array $options_double_dash = []): \Symfony\Component\Process\Process { // Fill in the root and URI from the site alias, if the caller // did not already provide them in $options. @@ -97,7 +84,7 @@ public function drushScript(SiteAliasInterface $siteAlias) * Use Drush::drush() or ProcessManager::drush() instead of this method * when calling Drush. */ - public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options = [], $optionsPassedAsArgs = []) + public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options = [], $optionsPassedAsArgs = []): \Consolidation\SiteProcess\ProcessBase { $process = parent::siteProcess($siteAlias, $args, $options, $optionsPassedAsArgs); return $this->configureProcess($process); @@ -115,10 +102,9 @@ public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input * @param int|float|null $timeout The timeout in seconds or null to disable * - * @return ProcessBase * A wrapper around Symfony Process. */ - public function process($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60) + public function process($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60): \Consolidation\SiteProcess\ProcessBase { $process = parent::process($commandline, $cwd, $env, $input, $timeout); return $this->configureProcess($process); @@ -131,9 +117,8 @@ public function process($commandline, $cwd = null, array $env = null, $input = n * @param array|null $env The environment variables or null to use the same environment as the current PHP process * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input * @param int|float|null $timeout The timeout in seconds or null to disable - * @return Process */ - public function shell($command, $cwd = null, array $env = null, $input = null, $timeout = 60) + public function shell($command, $cwd = null, array $env = null, $input = null, $timeout = 60): \Consolidation\SiteProcess\ProcessBase { $process = parent::shell($command, $cwd, $env, $input, $timeout); return $this->configureProcess($process); @@ -142,7 +127,7 @@ public function shell($command, $cwd = null, array $env = null, $input = null, $ /** * configureProcess sets up a process object so that it is ready to use. */ - protected static function configureProcess(ProcessBase $process) + protected static function configureProcess(ProcessBase $process): \Consolidation\SiteProcess\ProcessBase { $process->setSimulated(Drush::simulate()); $process->setVerbose(Drush::verbose()); diff --git a/src/SiteAlias/Util/InternalYamlDataFileLoader.php b/src/SiteAlias/Util/InternalYamlDataFileLoader.php index 1b516825b7..59096b5396 100644 --- a/src/SiteAlias/Util/InternalYamlDataFileLoader.php +++ b/src/SiteAlias/Util/InternalYamlDataFileLoader.php @@ -9,7 +9,7 @@ class InternalYamlDataFileLoader implements DataFileLoaderInterface /** * @inheritdoc */ - public function load($path) + public function load($path): array { return (array) Yaml::parse(file_get_contents($path)); } diff --git a/src/Sql/SqlBase.php b/src/Sql/SqlBase.php index 48f67b4ffb..7cf51cf216 100644 --- a/src/Sql/SqlBase.php +++ b/src/Sql/SqlBase.php @@ -13,14 +13,14 @@ use Webmozart\PathUtil\Path; use Consolidation\Config\Util\Interpolator; -class SqlBase implements ConfigAwareInterface +abstract class SqlBase implements ConfigAwareInterface { use SqlTableSelectionTrait; use ConfigAwareTrait; // An Drupal style array containing specs for connecting to database. - public $dbSpec; + public array $dbSpec; // Default code appended to sql connections. public $queryExtra = ''; @@ -48,24 +48,20 @@ public function __construct($db_spec, $options) /** * Get environment variables to pass to Process. */ - public function getEnv() + public function getEnv(): array { + return []; } /** * Get the last used Process. - * - * @return Process */ - public function getProcess() + public function getProcess(): \Symfony\Component\Process\Process { return $this->process; } - /** - * @param Process $process - */ - public function setProcess($process) + public function setProcess(\Symfony\Component\Process\Process $process): void { $this->process = $process; } @@ -75,9 +71,8 @@ public function setProcess($process) * * @param $options * An options array as handed to a command callback. - * @return SqlBase */ - public static function create($options = []) + public static function create(array $options = []): SqlBase { // Set defaults in the unfortunate event that caller doesn't provide values. $options += [ @@ -107,7 +102,7 @@ public static function create($options = []) } } - public static function getInstance($db_spec, $options) + public static function getInstance($db_spec, $options): ?self { $driver = $db_spec['driver']; $class_name = 'Drush\Sql\Sql'. ucfirst($driver); @@ -122,27 +117,25 @@ public static function getInstance($db_spec, $options) /* * Get the current $db_spec. */ - public function getDbSpec() + public function getDbSpec(): ?array { return $this->dbSpec; } /** * Set the current db spec. - * - * @param array $dbSpec */ - public function setDbSpec($dbSpec) + public function setDbSpec(array $dbSpec): void { $this->dbSpec = $dbSpec; } /** * The unix command used to connect to the database. - * @return string */ - public function command() + public function command(): string { + return ''; } /** @@ -151,10 +144,8 @@ public function command() * @param bool $hide_password * If TRUE, DBMS should try to hide password from process list. * On mysql, that means using --defaults-file to supply the user+password. - * - * @return string */ - public function connect($hide_password = true) + public function connect(bool $hide_password = true): string { return trim($this->command() . ' ' . $this->creds($hide_password) . ' ' . $this->getOption('extra', $this->queryExtra)); } @@ -163,7 +154,7 @@ public function connect($hide_password = true) /* * Execute a SQL dump and return the path to the resulting dump file. * - * @return string|bool + * @return * Returns path to dump file, or false on failure. */ public function dump() @@ -211,7 +202,7 @@ public function dump() * make pipefail work right in this instance, we must wrap it * in 'bash -c', since pipefail is a bash feature. */ - protected function addPipeFail($cmd, $pipefail) + protected function addPipeFail(string $cmd, string $pipefail): string { if (empty($pipefail)) { return $cmd; @@ -231,12 +222,13 @@ protected function addPipeFail($cmd, $pipefail) * * @param array $table_selection * Supported keys: 'skip', 'structure', 'tables'. - * @return string + * @return * One or more mysqldump/pg_dump/sqlite3/etc statements that are ready for executing. * If multiple statements are needed, enclose in parenthesis. */ - public function dumpCmd($table_selection) + public function dumpCmd($table_selection): string { + return ''; } /* @@ -272,17 +264,17 @@ public function dumpFile($file) * If you don't want to query results to print during --debug then * provide a $result_file whose value can be drush_bit_bucket(). * - * @param string $query + * @param $query * The SQL to be executed. Should be NULL if $input_file is provided. - * @param string $input_file + * @param $input_file * A path to a file containing the SQL to be executed. - * @param string $result_file + * @param $result_file * A path to save query results to. Can be drush_bit_bucket() if desired. * * @return boolean * TRUE on success, FALSE on failure */ - public function query($query, $input_file = null, $result_file = '') + public function query(string $query, $input_file = null, $result_file = ''): ?bool { if (!Drush::simulate()) { return $this->alwaysQuery($query, $input_file, $result_file); @@ -296,17 +288,17 @@ public function query($query, $input_file = null, $result_file = '') * If you don't want results to print during --debug then * provide a $result_file whose value can be drush_bit_bucket(). * - * @param string $query + * @param $query * The SQL to be executed. Should be null if $input_file is provided. - * @param string $input_file + * @param $input_file * A path to a file containing the SQL to be executed. - * @param string $result_file + * @param $result_file * A path to save query results to. Can be drush_bit_bucket() if desired. * - * @return boolean - * TRUE on success, FALSE on failure + * @return + * TRUE on success, FALSE on failure. */ - public function alwaysQuery($query, $input_file = null, $result_file = '') + public function alwaysQuery(string $query, $input_file = null, ?string $result_file = ''): bool { $input_file_original = $input_file; if ($input_file && FsUtils::isTarball($input_file)) { @@ -358,7 +350,7 @@ public function alwaysQuery($query, $input_file = null, $result_file = '') /** * Show the query in debug mode and simulate mode */ - protected function logQueryInDebugMode($query, $input_file_original) + protected function logQueryInDebugMode($query, $input_file_original): void { // In --verbose mode, Drush::process() will show the call to mysql/psql/sqlite, // but the sql query itself is stored in a temp file and not displayed. @@ -371,12 +363,13 @@ protected function logQueryInDebugMode($query, $input_file_original) /* * A string to add to the command when queries should not print their results. */ - public function silent() + public function silent(): ?string { + return null; } - public function queryPrefix($query) + public function queryPrefix($query): ?string { // Inject table prefixes as needed. if (Drush::bootstrapManager()->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_DATABASE)) { @@ -399,10 +392,9 @@ public function queryFormat($query) * * @param array $tables * An array of table names - * @return boolean * True if successful, FALSE if failed. */ - public function drop($tables) + public function drop(array $tables): bool { $return = true; if ($tables) { @@ -420,10 +412,10 @@ public function drop($tables) * @param boolean $quoted * Quote the database name. Mysql uses backticks to quote which can cause problems * in a Windows shell. Set TRUE if the CREATE is not running on the bash command line. - * @return string */ - public function createdbSql($dbname, $quoted = false) + public function createdbSql($dbname, bool $quoted = false): string { + return ''; } /** @@ -432,10 +424,9 @@ public function createdbSql($dbname, $quoted = false) * @param boolean $quoted * Quote the database name. Mysql uses backticks to quote which can cause problems * in a Windows shell. Set TRUE if the CREATE is not running on the bash command line. - * @return boolean * True if successful, FALSE otherwise. */ - public function createdb($quoted = false) + public function createdb(bool $quoted = false): bool { $dbname = $this->getDbSpec()['database']; $sql = $this->createdbSql($dbname, $quoted); @@ -447,10 +438,10 @@ public function createdb($quoted = false) /** * Drop all tables (if DB exists) or CREATE target database. * - * return boolean + * return * TRUE or FALSE depending on success. */ - public function dropOrCreate() + public function dropOrCreate(): bool { if ($this->dbExists()) { return $this->drop($this->listTablesQuoted()); @@ -461,52 +452,48 @@ public function dropOrCreate() /* * Determine if the specified DB already exists. - * - * @return bool */ - public function dbExists() + public function dbExists(): bool { + return false; } /** - * Build a fragment connection parameters. + * Build a string containing connection credentials. * * @param bool $hide_password * If TRUE, DBMS should try to hide password from process list. * On mysql, that means using --defaults-file to supply the user+password. - * @return string */ - public function creds($hide_password = true) + public function creds(bool $hide_password = true): string { + return ''; } /** * The active database driver. - * @return string */ - public function scheme() + public function scheme(): string { return $this->dbSpec['driver']; } /** * Extract the name of all existing tables in the given database. - * - * @return array|null - * An array of table names which exist in the current database. */ - public function listTables() + public function listTables(): array { + return []; } /** * Extract the name of all existing tables in the given database. * - * @return array|null + * @return * An array of table names which exist in the current database, * appropriately quoted for the RDMS. */ - public function listTablesQuoted() + public function listTablesQuoted(): ?array { return $this->listTables(); } @@ -517,7 +504,7 @@ public function listTablesQuoted() * @return string * A bash fragment. */ - public function paramsToOptions($parameters) + public function paramsToOptions($parameters): string { // Turn each parameter into a valid parameter string. $parameter_strings = []; @@ -533,10 +520,8 @@ public function paramsToOptions($parameters) /** * Adjust DB connection with superuser credentials if provided. - * - * @return null */ - public function su() + public function su(): void { $create_db_target = $this->getDbSpec(); @@ -556,10 +541,7 @@ public function su() $this->setDbSpec($create_db_target); } - /** - * @return array - */ - public function getOptions() + public function getOptions(): array { return $this->options; } @@ -570,24 +552,15 @@ public function getOption($name, $default = null) return array_key_exists($name, $options) && !is_null($options[$name]) ? $options[$name] : $default; } - /** - * @deprecated. - */ - public function db_spec() // @codingStandardsIgnoreLine - { - return $this->getDbSpec(); - } - /** * Convert from an old-style database URL to an array of database settings. * * @param db_url * A Drupal 6 db url string to convert, or an array with a 'default' element. - * @return array * An array of database values containing only the 'default' element of * the db url. If the parse fails the array is empty. */ - public static function dbSpecFromDbUrl($db_url) + public static function dbSpecFromDbUrl($db_url): array { $db_spec = []; diff --git a/src/Sql/SqlMysql.php b/src/Sql/SqlMysql.php index 33f53464ab..d62217193c 100644 --- a/src/Sql/SqlMysql.php +++ b/src/Sql/SqlMysql.php @@ -9,12 +9,12 @@ class SqlMysql extends SqlBase public $queryExtra = '-A'; - public function command() + public function command(): string { return 'mysql'; } - public function creds($hide_password = true) + public function creds($hide_password = true): string { $dbSpec = $this->getDbSpec(); if ($hide_password) { @@ -84,12 +84,12 @@ public function creds($hide_password = true) return $this->paramsToOptions($parameters); } - public function silent() + public function silent(): string { return '--silent'; } - public function createdbSql($dbname, $quoted = false) + public function createdbSql($dbname, $quoted = false): string { $dbSpec = $this->getDbSpec(); if ($quoted) { @@ -120,13 +120,13 @@ public function createdbSql($dbname, $quoted = false) /** * @inheritdoc */ - public function dbExists() + public function dbExists(): bool { // Suppress output. We only care about return value. return $this->alwaysQuery("SELECT 1;"); } - public function listTables() + public function listTables(): array { $tables = []; $this->alwaysQuery('SHOW TABLES;'); @@ -136,7 +136,7 @@ public function listTables() return $tables; } - public function listTablesQuoted() + public function listTablesQuoted(): ?array { $tables = $this->listTables(); foreach ($tables as &$table) { @@ -145,7 +145,7 @@ public function listTablesQuoted() return $tables; } - public function dumpCmd($table_selection) + public function dumpCmd($table_selection): string { $dbSpec = $this->getDbSpec(); $parens = false; diff --git a/src/Sql/SqlPgsql.php b/src/Sql/SqlPgsql.php index 2ee044572d..70ec64b793 100644 --- a/src/Sql/SqlPgsql.php +++ b/src/Sql/SqlPgsql.php @@ -41,24 +41,26 @@ private function createPasswordFile() return $this->password_file; } - public function command() + public function command(): string { return 'psql -q'; } - public function getEnv() + public function getEnv(): array { + $return = []; $pw_file = $this->createPasswordFile(); if (isset($pw_file)) { - return ['PGPASSFILE' => $pw_file]; + $return = ['PGPASSFILE' => $pw_file]; } + return $return; } /* * @param $hide_password * Not used in postgres. We always hide via a .pgpass file. */ - public function creds($hide_password = true) + public function creds($hide_password = true): string { $dbSpec = $this->getDbSpec(); // Some drush commands (e.g. site-install) want to connect to the @@ -78,7 +80,7 @@ public function creds($hide_password = true) return $this->paramsToOptions($parameters); } - public function createdbSql($dbname, $quoted = false) + public function createdbSql($dbname, $quoted = false): string { if ($quoted) { $dbname = '"' . $dbname . '"'; @@ -88,7 +90,7 @@ public function createdbSql($dbname, $quoted = false) return implode(' ', $sql); } - public function dbExists() + public function dbExists(): bool { $dbSpec = $this->getDbSpec(); $database = $dbSpec['database']; @@ -111,14 +113,14 @@ public function queryFormat($query) return $query; } - public function listTables() + public function listTables(): array { $return = $this->alwaysQuery(PSQL_SHOW_TABLES); $tables = explode(PHP_EOL, trim($this->getProcess()->getOutput())); return array_filter($tables); } - public function dumpCmd($table_selection) + public function dumpCmd($table_selection): string { $parens = false; $skip_tables = $table_selection['skip']; @@ -171,10 +173,7 @@ public function dumpCmd($table_selection) return $parens ? "($exec)" : $exec; } - /** - * @return string|null - */ - public function getPasswordFile() + public function getPasswordFile(): ?string { return $this->password_file; } diff --git a/src/Sql/SqlSqlite.php b/src/Sql/SqlSqlite.php index c6597e9449..5c4011266e 100644 --- a/src/Sql/SqlSqlite.php +++ b/src/Sql/SqlSqlite.php @@ -3,16 +3,15 @@ namespace Drush\Sql; use Drush\Drush; -use mysql_xdevapi\Exception; class SqlSqlite extends SqlBase { - public function command() + public function command(): string { return 'sqlite3'; } - public function creds($hide_password = true) + public function creds($hide_password = true): string { // SQLite doesn't do user management, instead relying on the filesystem // for that. So the only info we really need is the path to the database @@ -20,7 +19,7 @@ public function creds($hide_password = true) return ' ' . $this->getDbSpec()['database']; } - public function createdbSql($dbname, $quoted = false) + public function createdbSql($dbname, $quoted = false): string { return ''; } @@ -32,7 +31,7 @@ public function createdbSql($dbname, $quoted = false) * Quote the database name. Mysql uses backticks to quote which can cause problems * in a Windows shell. Set TRUE if the CREATE is not running on the bash command line. */ - public function createdb($quoted = false) + public function createdb(bool $quoted = false): bool { $file = $this->getDbSpec()['database']; if (file_exists($file)) { @@ -44,17 +43,17 @@ public function createdb($quoted = false) $path = dirname($file); Drush::logger()->debug("SQLITE: creating '$path' for creating '$file'"); if (!drush_mkdir($path)) { - throw new Exception("SQLITE: Cannot create $path"); + throw new \Exception("SQLITE: Cannot create $path"); } return file_exists($path); } - public function dbExists() + public function dbExists(): bool { return file_exists($this->getDbSpec()['database']); } - public function listTables() + public function listTables(): array { $return = $this->alwaysQuery('.tables'); $tables_raw = explode(PHP_EOL, trim($this->getProcess()->getOutput())); @@ -76,7 +75,7 @@ public function listTables() return $tables; } - public function drop($tables) + public function drop($tables): bool { $return = true; $sql = ''; @@ -91,7 +90,7 @@ public function drop($tables) return $return; } - public function dumpCmd($table_selection) + public function dumpCmd($table_selection): string { // Dumping is usually not necessary in SQLite, since all database data // is stored in a single file which can be copied just diff --git a/src/Sql/SqlTableSelectionTrait.php b/src/Sql/SqlTableSelectionTrait.php index d998db1ff1..19c1224c70 100644 --- a/src/Sql/SqlTableSelectionTrait.php +++ b/src/Sql/SqlTableSelectionTrait.php @@ -22,7 +22,7 @@ trait SqlTableSelectionTrait * An array of tables with each table name in the appropriate * element of the array. */ - public function getExpandedTableSelection($options, $all_tables) + public function getExpandedTableSelection(array $options, array $all_tables) { $table_selection = $this->getTableSelection($options); // Get the existing table names in the specified database. @@ -51,7 +51,7 @@ public function getExpandedTableSelection($options, $all_tables) * @return array * An array of tables with non-existant tables removed. */ - public function expandAndFilterTables($tables, $db_tables) + public function expandAndFilterTables(array $tables, array $db_tables) { $expanded_tables = $this->ExpandWildcardTables($tables, $db_tables); $tables = $this->filterTables(array_merge($tables, $expanded_tables), $db_tables); @@ -70,7 +70,7 @@ public function expandAndFilterTables($tables, $db_tables) * @return * $tables array with wildcards resolved to real table names. */ - public function expandWildcardTables($tables, $db_tables) + public function expandWildcardTables(array $tables, array $db_tables) { // Table name expansion based on `*` wildcard. $expanded_db_tables = []; @@ -97,7 +97,7 @@ public function expandWildcardTables($tables, $db_tables) * An array with only valid table names (i.e. all of which actually exist in * the database). */ - public function filterTables($tables, $db_tables) + public function filterTables(array $tables, array $db_tables) { // Ensure all the tables actually exist in the database. foreach ($tables as $k => $table) { @@ -145,7 +145,7 @@ public function getTableSelection($options) * Returns an array of tables based on the first option * found, or an empty array if there were no matches. */ - public function getRawTableList($option_name, $options) + public function getRawTableList($option_name, array $options) { $key_list = StringUtils::csvToArray($options[$option_name . '-key']); foreach ($key_list as $key) { diff --git a/src/Symfony/BootstrapCompilerPass.php b/src/Symfony/BootstrapCompilerPass.php index 11f0b97173..20765649d4 100644 --- a/src/Symfony/BootstrapCompilerPass.php +++ b/src/Symfony/BootstrapCompilerPass.php @@ -8,7 +8,7 @@ class BootstrapCompilerPass implements CompilerPassInterface { - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { if (!$container->has('bootstrap.manager')) { return; diff --git a/src/Symfony/BufferedConsoleOutput.php b/src/Symfony/BufferedConsoleOutput.php index 7c2e4f7932..0898e16a9d 100644 --- a/src/Symfony/BufferedConsoleOutput.php +++ b/src/Symfony/BufferedConsoleOutput.php @@ -29,7 +29,7 @@ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = fa /** * {@inheritdoc} */ - public function getErrorOutput() + public function getErrorOutput(): \Symfony\Component\Console\Output\BufferedOutput { return $this->stderr; } @@ -37,7 +37,7 @@ public function getErrorOutput() /** * {@inheritdoc} */ - public function setErrorOutput(OutputInterface $error) + public function setErrorOutput(OutputInterface $error): void { $this->stderr = $error; } diff --git a/src/Symfony/DrushArgvInput.php b/src/Symfony/DrushArgvInput.php index 74e533155b..d52deebdcc 100644 --- a/src/Symfony/DrushArgvInput.php +++ b/src/Symfony/DrushArgvInput.php @@ -66,7 +66,7 @@ public function __construct(array $argv = null, InputDefinition $definition = nu parent::__construct($definition); } - protected function setTokens(array $tokens) + protected function setTokens(array $tokens): void { $this->tokens = $tokens; } @@ -74,7 +74,7 @@ protected function setTokens(array $tokens) /** * {@inheritdoc} */ - protected function parse() + protected function parse(): void { $parseOptions = true; $this->parsed = $this->tokens; @@ -98,7 +98,7 @@ protected function parse() * * @param string $token The current token */ - private function parseShortOption($token) + private function parseShortOption($token): void { $name = substr($token, 1); @@ -121,7 +121,7 @@ private function parseShortOption($token) * * @throws RuntimeException When option given doesn't exist */ - private function parseShortOptionSet($name) + private function parseShortOptionSet($name): void { $len = strlen($name); for ($i = 0; $i < $len; ++$i) { @@ -145,7 +145,7 @@ private function parseShortOptionSet($name) * * @param string $token The current token */ - private function parseLongOption($token) + private function parseLongOption($token): void { $name = substr($token, 2); @@ -171,7 +171,7 @@ private function parseLongOption($token) * * @throws RuntimeException When too many arguments are given */ - private function parseArgument($token) + private function parseArgument($token): void { $c = count($this->arguments); @@ -204,7 +204,7 @@ private function parseArgument($token) * * @throws RuntimeException When option given doesn't exist */ - private function addShortOption($shortcut, $value) + private function addShortOption($shortcut, $value): void { if (!$this->definition->hasShortcut($shortcut)) { throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); @@ -221,7 +221,7 @@ private function addShortOption($shortcut, $value) * * @throws RuntimeException When option given doesn't exist */ - private function addLongOption($name, $value) + private function addLongOption($name, $value): void { if (!$this->definition->hasOption($name)) { throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name)); @@ -278,7 +278,7 @@ public function getFirstArgument() /** * {@inheritdoc} */ - public function hasParameterOption($values, $onlyParams = false) + public function hasParameterOption($values, $onlyParams = false): bool { $values = (array) $values; diff --git a/src/Symfony/DrushStyleInjector.php b/src/Symfony/DrushStyleInjector.php index d446ea2b94..1c87c4d549 100644 --- a/src/Symfony/DrushStyleInjector.php +++ b/src/Symfony/DrushStyleInjector.php @@ -8,7 +8,7 @@ class DrushStyleInjector implements ParameterInjector { - public function get(CommandData $commandData, $interfaceName) + public function get(CommandData $commandData, $interfaceName): \Drush\Style\DrushStyle { return new DrushStyle($commandData->input(), $commandData->output()); } diff --git a/src/Symfony/IndiscriminateInputDefinition.php b/src/Symfony/IndiscriminateInputDefinition.php index 9d4713a703..9f237710b3 100644 --- a/src/Symfony/IndiscriminateInputDefinition.php +++ b/src/Symfony/IndiscriminateInputDefinition.php @@ -21,7 +21,7 @@ class IndiscriminateInputDefinition extends InputDefinition /** * @inheritdoc */ - public function hasShortcut($name) + public function hasShortcut($name): bool { return true; } @@ -29,7 +29,7 @@ public function hasShortcut($name) /** * @inheritdoc */ - public function hasOption($name) + public function hasOption($name): bool { return true; } @@ -37,7 +37,7 @@ public function hasOption($name) /** * @inheritdoc */ - public function getOption($name) + public function getOption($name): \Symfony\Component\Console\Input\InputOption { if (parent::hasOption($name)) { return parent::getOption($name); diff --git a/src/Symfony/LessStrictArgvInput.php b/src/Symfony/LessStrictArgvInput.php index 35af060caf..dd6d77cdcc 100644 --- a/src/Symfony/LessStrictArgvInput.php +++ b/src/Symfony/LessStrictArgvInput.php @@ -59,7 +59,7 @@ public function getOption($name) return false; } - protected function setTokens(array $tokens) + protected function setTokens(array $tokens): void { $this->tokens = $tokens; } @@ -67,7 +67,7 @@ protected function setTokens(array $tokens) /** * {@inheritdoc} */ - protected function parse() + protected function parse(): void { $parseOptions = true; $this->parsed = $this->tokens; @@ -93,7 +93,7 @@ protected function parse() * * @param string $token The current token */ - private function parseShortOption($token) + private function parseShortOption($token): void { $name = substr($token, 1); @@ -114,7 +114,7 @@ private function parseShortOption($token) * * @param string $name The current token */ - private function parseShortOptionSet($name) + private function parseShortOptionSet($name): void { $len = strlen($name); for ($i = 0; $i < $len; ++$i) { @@ -138,7 +138,7 @@ private function parseShortOptionSet($name) * * @param string $token The current token */ - private function parseLongOption($token) + private function parseLongOption($token): void { $name = substr($token, 2); @@ -164,7 +164,7 @@ private function parseLongOption($token) * * @throws RuntimeException When too many arguments are given */ - private function parseArgument($token) + private function parseArgument($token): void { $c = count($this->arguments); @@ -197,7 +197,7 @@ private function parseArgument($token) * * @throws RuntimeException When option given doesn't exist */ - private function addShortOption($shortcut, $value) + private function addShortOption($shortcut, $value): void { if (!$this->definition->hasShortcut($shortcut)) { // Hard to know what to do with unknown short options. Maybe @@ -210,7 +210,7 @@ private function addShortOption($shortcut, $value) $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); } - public function injectAdditionalOptions($additionalOptions) + public function injectAdditionalOptions($additionalOptions): void { $this->additionalOptions += $additionalOptions; $this->options += $additionalOptions; @@ -224,7 +224,7 @@ public function injectAdditionalOptions($additionalOptions) * * @throws RuntimeException When option given doesn't exist */ - private function addLongOption($name, $value) + private function addLongOption($name, $value): void { if (!$this->definition->hasOption($name)) { // If we don't know anything about this option, then we'll @@ -284,7 +284,7 @@ public function getFirstArgument() /** * {@inheritdoc} */ - public function hasParameterOption($values, $onlyParams = false) + public function hasParameterOption($values, $onlyParams = false): bool { $values = (array) $values; diff --git a/src/Utils/FsUtils.php b/src/Utils/FsUtils.php index 0913a955a3..7466655cf2 100644 --- a/src/Utils/FsUtils.php +++ b/src/Utils/FsUtils.php @@ -22,7 +22,7 @@ class FsUtils * A path to the backup directory. * @throws \Exception */ - public static function getBackupDir($subdir = null) + public static function getBackupDir($subdir = null): string { $parent = self::getBackupDirParent(); @@ -83,14 +83,15 @@ protected static function getBackupDirParent() } /** - * Description - * @param string $dir - * Path to directory that we are considering using - * @return bool - * True if the specified location is writable, or if a writable + * Determine if the specified location is writable, or if a writable * directory could be created at that path. + * + * @param $dir + * Path to directory that we are considering using + * + * @return bool|string */ - public static function isUsableDirectory($dir) + public static function isUsableDirectory(?string $dir) { // This directory is not usable if it is empty or if it is the root. if (empty($dir) || (dirname($dir) == $dir)) { @@ -118,11 +119,10 @@ public static function isUsableDirectory($dir) * @param string $subdir * A string naming the subdirectory of the backup directory. * - * @return string * Path to the specified backup directory. * @throws \Exception */ - public static function prepareBackupDir($subdir = null) + public static function prepareBackupDir($subdir = null): string { $fs = new Filesystem(); $backup_dir = self::getBackupDir($subdir); @@ -139,10 +139,9 @@ public static function prepareBackupDir($subdir = null) * @param string $path * The path being checked. * - * @return string * The canonicalized absolute pathname. */ - public static function realpath($path) + public static function realpath(string $path): string { $realpath = realpath($path); return $realpath ?: $path; @@ -156,7 +155,7 @@ public static function realpath($path) * @return string|bool * The file content type if it's a tarball. FALSE otherwise. */ - public static function isTarball($path) + public static function isTarball(string $path) { $content_type = self::getMimeContentType($path); $supported = [ @@ -185,7 +184,7 @@ public static function isTarball($path) * @return string|bool|null * The MIME content type of the file. */ - public static function getMimeContentType($path) + public static function getMimeContentType(string $path) { $content_type = false; if (class_exists('finfo')) { diff --git a/src/Utils/StringUtils.php b/src/Utils/StringUtils.php index 5b4b6fd2ee..aa35a78f67 100644 --- a/src/Utils/StringUtils.php +++ b/src/Utils/StringUtils.php @@ -12,12 +12,9 @@ class StringUtils * @param $args * A simple csv string; e.g. 'a,b,c' * or a simple list of items; e.g. array('a','b','c') - * or some combination; e.g. array('a,b','c') or array('a,','b,','c,') - * - * @return array - * A simple list of items (e.g. array('a','b','c') + * or some combination; e.g. array('a,b','c') or array('a,','b,','c,'). */ - public static function csvToArray($args) + public static function csvToArray($args): array { // // Step 1: implode(',',$args) converts from, say, array('a,','b,','c,') to 'a,,b,,c,' @@ -40,10 +37,9 @@ public static function csvToArray($args) * The string with placeholders to be interpolated. * @param array $context * An associative array of values to be inserted into the message. - * @return string * The resulting string with all placeholders filled in. */ - public static function interpolate($message, array $context = []) + public static function interpolate(string $message, array $context = []): string { // Take no action if there is no context if (empty($context)) { @@ -67,10 +63,9 @@ public static function interpolate($message, array $context = []) * * @param string $key * A key from an interpolation context. - * @return string * The key prepared for interpolation. */ - private static function interpolationKey($key) + private static function interpolationKey(string $key): string { if (ctype_alpha($key)) { return sprintf('{%s}', $key); @@ -101,13 +96,11 @@ public static function replaceTilde($path, $home) } /** - * Generate a random alphanumeric password. Copied from user.module. - * - * @param int $length - * - * @return string - */ - public static function generatePassword($length = 10) + * Generate a random alphanumeric password. Copied from user.module. + * + * + */ + public static function generatePassword(int $length = 10): string { // This variable contains the list of allowable characters for the // password. Note that the number 0 and the letter 'O' have been diff --git a/tests/unit/MigrateRunnerTest.php b/tests/unit/MigrateRunnerTest.php index 15f7425ad5..c0e8312bc4 100644 --- a/tests/unit/MigrateRunnerTest.php +++ b/tests/unit/MigrateRunnerTest.php @@ -149,10 +149,7 @@ protected function assertFilteredIdMap(MigrateIdMapFilter $filteredIdMap, array $this->assertEquals($expectedRows, $actualRows); } - /** - * @return \Drupal\Core\Database\Driver\sqlite\Connection - */ - protected function getDatabaseConnection(): Connection + protected function getDatabaseConnection(): \Drupal\Core\Database\Connection { if (!extension_loaded('pdo_sqlite')) { $this->markTestSkipped('The pdo_sqlite extension is not available.'); From bc4d9db8d42ad76b9a2ae0b7371b1f9ab1565c15 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 16:28:20 -0500 Subject: [PATCH 043/125] Fix highest now that DB drivers have own modules in Drupal 9.4 (#4960) * Fix highest now that DB drivers have own modules in Drupal 9.4 * Fix table exists error * Windows fix --- composer.json | 4 +- composer.lock | 118 +++++++++++++++---------------- src/Drupal/DrupalKernelTrait.php | 2 +- tests/unit/MigrateRunnerTest.php | 19 +++-- 4 files changed, 76 insertions(+), 67 deletions(-) diff --git a/composer.json b/composer.json index b76b8b176a..fb6b8f51c1 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "composer/installers": "^1.7", "cweagans/composer-patches": "~1.0", "david-garcia/phpwhois": "4.3.0", - "drupal/core-recommended": "^9", + "drupal/core-recommended": "9.4.x-dev", "drupal/semver_example": "2.2.0", "phpunit/phpunit": ">=7.5.20", "rector/rector": "^0.12", @@ -92,7 +92,7 @@ "sort-packages": true, "process-timeout": 9600, "platform": { - "php": "7.4" + } }, "scripts": { diff --git a/composer.lock b/composer.lock index 2ea4b60ecb..b3684ad7fd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "85e6933dec1e53b0952e65a41570f793", + "content-hash": "e96f01a53cefc68174311111f0b2b8a5", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -151,16 +151,16 @@ }, { "name": "consolidation/annotated-command", - "version": "4.5.0", + "version": "4.5.1", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a" + "reference": "701a7abe8505abe89520837be798e15a3953a367" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", - "reference": "df01c1f1449c6b46bf87051e0b418bd5d5e44a7a", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/701a7abe8505abe89520837be798e15a3953a367", + "reference": "701a7abe8505abe89520837be798e15a3953a367", "shasum": "" }, "require": { @@ -201,9 +201,9 @@ "description": "Initialize Symfony Console commands from annotated command class methods.", "support": { "issues": "https://github.com/consolidation/annotated-command/issues", - "source": "https://github.com/consolidation/annotated-command/tree/4.5.0" + "source": "https://github.com/consolidation/annotated-command/tree/4.5.1" }, - "time": "2021-12-27T19:34:17+00:00" + "time": "2021-12-30T04:00:37+00:00" }, { "name": "consolidation/config", @@ -362,22 +362,22 @@ }, { "name": "consolidation/log", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/consolidation/log.git", - "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1" + "reference": "fc9ec5476ba13a31778695bd2d4f2fa0b0684356" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/log/zipball/82a2aaaa621a7b976e50a745a8d249d5085ee2b1", - "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1", + "url": "https://api.github.com/repos/consolidation/log/zipball/fc9ec5476ba13a31778695bd2d4f2fa0b0684356", + "reference": "fc9ec5476ba13a31778695bd2d4f2fa0b0684356", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/log": "^1.0", - "symfony/console": "^4|^5" + "symfony/console": "^4 || ^5 || ^6" }, "require-dev": { "phpunit/phpunit": ">=7.5.20", @@ -408,22 +408,22 @@ "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", "support": { "issues": "https://github.com/consolidation/log/issues", - "source": "https://github.com/consolidation/log/tree/2.0.2" + "source": "https://github.com/consolidation/log/tree/2.0.4" }, - "time": "2020-12-10T16:26:23+00:00" + "time": "2021-12-30T19:05:18+00:00" }, { "name": "consolidation/output-formatters", - "version": "4.2.0", + "version": "4.2.1", "source": { "type": "git", "url": "https://github.com/consolidation/output-formatters.git", - "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24" + "reference": "4413d7c732afb5d7bdac565c41aa9c8c49c48888" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/27cf221f6e59b1debed0c6c94015e78cd5f10e24", - "reference": "27cf221f6e59b1debed0c6c94015e78cd5f10e24", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/4413d7c732afb5d7bdac565c41aa9c8c49c48888", + "reference": "4413d7c732afb5d7bdac565c41aa9c8c49c48888", "shasum": "" }, "require": { @@ -467,9 +467,9 @@ "description": "Format text by applying transformations provided by plug-in formatters.", "support": { "issues": "https://github.com/consolidation/output-formatters/issues", - "source": "https://github.com/consolidation/output-formatters/tree/4.2.0" + "source": "https://github.com/consolidation/output-formatters/tree/4.2.1" }, - "time": "2021-12-27T14:30:41+00:00" + "time": "2021-12-30T03:58:00+00:00" }, { "name": "consolidation/robo", @@ -572,23 +572,23 @@ }, { "name": "consolidation/self-update", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/consolidation/self-update.git", - "reference": "74289cf9b37d5cf84321ebea47deeea21678b940" + "reference": "117dcc9494dc970a6ae307103c41d654e6253bc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/self-update/zipball/74289cf9b37d5cf84321ebea47deeea21678b940", - "reference": "74289cf9b37d5cf84321ebea47deeea21678b940", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/117dcc9494dc970a6ae307103c41d654e6253bc4", + "reference": "117dcc9494dc970a6ae307103c41d654e6253bc4", "shasum": "" }, "require": { "composer/semver": "^3.2", "php": ">=5.5.0", - "symfony/console": "^2.8|^3|^4|^5", - "symfony/filesystem": "^2.5|^3|^4|^5" + "symfony/console": "^2.8 || ^3 || ^4 || ^5 || ^6", + "symfony/filesystem": "^2.5 || ^3 || ^4 || ^5 || ^6" }, "bin": [ "scripts/release" @@ -621,9 +621,9 @@ "description": "Provides a self:update command for Symfony Console applications.", "support": { "issues": "https://github.com/consolidation/self-update/issues", - "source": "https://github.com/consolidation/self-update/tree/2.0.2" + "source": "https://github.com/consolidation/self-update/tree/2.0.3" }, - "time": "2021-12-17T16:45:58+00:00" + "time": "2021-12-30T19:08:32+00:00" }, { "name": "consolidation/site-alias", @@ -2029,16 +2029,16 @@ }, { "name": "symfony/finder", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590" + "reference": "e77046c252be48c48a40816187ed527703c8f76c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590", - "reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590", + "url": "https://api.github.com/repos/symfony/finder/zipball/e77046c252be48c48a40816187ed527703c8f76c", + "reference": "e77046c252be48c48a40816187ed527703c8f76c", "shasum": "" }, "require": { @@ -2072,7 +2072,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.0" + "source": "https://github.com/symfony/finder/tree/v5.4.2" }, "funding": [ { @@ -2088,7 +2088,7 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:25:38+00:00" + "time": "2021-12-15T11:06:13+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2886,16 +2886,16 @@ }, { "name": "symfony/string", - "version": "v5.4.0", + "version": "v5.4.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d" + "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", - "reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d", + "url": "https://api.github.com/repos/symfony/string/zipball/e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", + "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", "shasum": "" }, "require": { @@ -2952,7 +2952,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.0" + "source": "https://github.com/symfony/string/tree/v5.4.2" }, "funding": [ { @@ -2968,7 +2968,7 @@ "type": "tidelift" } ], - "time": "2021-11-24T10:02:00+00:00" + "time": "2021-12-16T21:52:00+00:00" }, { "name": "symfony/var-dumper", @@ -3993,16 +3993,16 @@ }, { "name": "drupal/core", - "version": "9.3.0", + "version": "9.4.x-dev", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47" + "reference": "16ee0a84af2a044af8ad9e9c53952163f4e4b68c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/1e1bf0e841e11029b21775dd125332d7ffd6fb47", - "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47", + "url": "https://api.github.com/repos/drupal/core/zipball/16ee0a84af2a044af8ad9e9c53952163f4e4b68c", + "reference": "16ee0a84af2a044af8ad9e9c53952163f4e4b68c", "shasum": "" }, "require": { @@ -4136,12 +4136,14 @@ "drupal/migrate_drupal_multilingual": "self.version", "drupal/migrate_drupal_ui": "self.version", "drupal/minimal": "self.version", + "drupal/mysql": "self.version", "drupal/node": "self.version", "drupal/olivero": "self.version", "drupal/options": "self.version", "drupal/page_cache": "self.version", "drupal/path": "self.version", "drupal/path_alias": "self.version", + "drupal/pgsql": "self.version", "drupal/quickedit": "self.version", "drupal/rdf": "self.version", "drupal/responsive_image": "self.version", @@ -4151,6 +4153,7 @@ "drupal/settings_tray": "self.version", "drupal/seven": "self.version", "drupal/shortcut": "self.version", + "drupal/sqlite": "self.version", "drupal/standard": "self.version", "drupal/stark": "self.version", "drupal/statistics": "self.version", @@ -4221,9 +4224,6 @@ "lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php", "lib/Drupal/Core/Database/Connection.php", "lib/Drupal/Core/Database/Database.php", - "lib/Drupal/Core/Database/Driver/mysql/Connection.php", - "lib/Drupal/Core/Database/Driver/pgsql/Connection.php", - "lib/Drupal/Core/Database/Driver/sqlite/Connection.php", "lib/Drupal/Core/Database/Statement.php", "lib/Drupal/Core/Database/StatementInterface.php", "lib/Drupal/Core/DependencyInjection/Container.php", @@ -4244,22 +4244,22 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/9.3.0" + "source": "https://github.com/drupal/core/tree/9.4.x" }, - "time": "2021-12-08T22:09:38+00:00" + "time": "2021-12-30T13:40:51+00:00" }, { "name": "drupal/core-recommended", - "version": "9.3.0", + "version": "9.4.x-dev", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "d65aaa36a8cab54332787a20676f81928f675bb3" + "reference": "8a46b487bdfe78c00a4070a78b542879b66599f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/d65aaa36a8cab54332787a20676f81928f675bb3", - "reference": "d65aaa36a8cab54332787a20676f81928f675bb3", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/8a46b487bdfe78c00a4070a78b542879b66599f4", + "reference": "8a46b487bdfe78c00a4070a78b542879b66599f4", "shasum": "" }, "require": { @@ -4268,7 +4268,7 @@ "doctrine/annotations": "1.13.2", "doctrine/lexer": "1.2.1", "doctrine/reflection": "1.2.2", - "drupal/core": "9.3.0", + "drupal/core": "9.4.x-dev", "egulias/email-validator": "3.1.2", "guzzlehttp/guzzle": "6.5.5", "guzzlehttp/promises": "1.5.1", @@ -4330,9 +4330,9 @@ ], "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/9.3.0" + "source": "https://github.com/drupal/core-recommended/tree/9.4.x" }, - "time": "2021-12-08T22:09:38+00:00" + "time": "2021-11-30T05:41:22+00:00" }, { "name": "drupal/semver_example", @@ -8761,7 +8761,8 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { - "consolidation/site-alias": 0 + "consolidation/site-alias": 0, + "drupal/core-recommended": 20 }, "prefer-stable": true, "prefer-lowest": false, @@ -8770,8 +8771,5 @@ "ext-dom": "*" }, "platform-dev": [], - "platform-overrides": { - "php": "7.4" - }, "plugin-api-version": "2.1.0" } diff --git a/src/Drupal/DrupalKernelTrait.php b/src/Drupal/DrupalKernelTrait.php index 27b3cd9fcc..c7fbfc4344 100644 --- a/src/Drupal/DrupalKernelTrait.php +++ b/src/Drupal/DrupalKernelTrait.php @@ -203,7 +203,7 @@ protected function findAppropriateServicesFile($module, $services, $dir) /** * Add a services.yml file if it exists. */ - protected function addDrushServiceProvider($serviceProviderName, $serviceYmlPath) + protected function addDrushServiceProvider($serviceProviderName, $serviceYmlPath = '') { if (file_exists($serviceYmlPath)) { $this->serviceYamls['app'][$serviceProviderName] = $serviceYmlPath; diff --git a/tests/unit/MigrateRunnerTest.php b/tests/unit/MigrateRunnerTest.php index c0e8312bc4..116ad7f560 100644 --- a/tests/unit/MigrateRunnerTest.php +++ b/tests/unit/MigrateRunnerTest.php @@ -2,11 +2,13 @@ namespace Drush\Drupal\Migrate; +use Composer\Semver\Comparator; use Drupal\Core\Database\Driver\sqlite\Connection; use Drupal\migrate\Plugin\MigrationInterface; use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Unish\TestSqlIdMap; +use Webmozart\PathUtil\Path; class MigrateRunnerTest extends TestCase { @@ -149,20 +151,29 @@ protected function assertFilteredIdMap(MigrateIdMapFilter $filteredIdMap, array $this->assertEquals($expectedRows, $actualRows); } - protected function getDatabaseConnection(): \Drupal\Core\Database\Connection + protected function getDatabaseConnection() { if (!extension_loaded('pdo_sqlite')) { $this->markTestSkipped('The pdo_sqlite extension is not available.'); } $options['database'] = ':memory:'; - $pdo = Connection::open($options); + $pdo = new \PDO("sqlite::memory:"); + if (Comparator::greaterThanOrEqualTo(\Drupal::VERSION, '9.4')) { + /** @var \Composer\Autoload\ClassLoader $loader */ + $loader = require PHPUNIT_COMPOSER_INSTALL; + $loader->addPsr4('Drupal\sqlite\\', Path::join([dirname(__DIR__, 2), 'sut/core/modules/sqlite/src'])); + } $connection = new Connection($pdo, $options); // Create the table and load it with data. $mapTableSchema = $this->getMapTableSchema(); - $connection->schema()->createTable('migrate_map_test_migration', $mapTableSchema); + $table = 'migrate_map_test_migration'; + if ($connection->schema()->tableExists($table)) { + $connection->schema()->dropTable($table); + } + $connection->schema()->createTable($table, $mapTableSchema); $fields = array_keys($mapTableSchema['fields']); - $insert = $connection->insert('migrate_map_test_migration')->fields($fields); + $insert = $connection->insert($table)->fields($fields); $mapTableData = $this->getMapTableData(); $mapTableData = array_map(function (array $row): array { From 79da8825dedb799a9d3d6781c440237d95dc06b3 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 30 Dec 2021 17:39:08 -0500 Subject: [PATCH 044/125] Revert accidental composer.json nd .lock changes (#4961) --- composer.json | 4 ++-- composer.lock | 40 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index fb6b8f51c1..b76b8b176a 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "composer/installers": "^1.7", "cweagans/composer-patches": "~1.0", "david-garcia/phpwhois": "4.3.0", - "drupal/core-recommended": "9.4.x-dev", + "drupal/core-recommended": "^9", "drupal/semver_example": "2.2.0", "phpunit/phpunit": ">=7.5.20", "rector/rector": "^0.12", @@ -92,7 +92,7 @@ "sort-packages": true, "process-timeout": 9600, "platform": { - + "php": "7.4" } }, "scripts": { diff --git a/composer.lock b/composer.lock index b3684ad7fd..5b7a5e5975 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e96f01a53cefc68174311111f0b2b8a5", + "content-hash": "85e6933dec1e53b0952e65a41570f793", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -3993,16 +3993,16 @@ }, { "name": "drupal/core", - "version": "9.4.x-dev", + "version": "9.3.0", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "16ee0a84af2a044af8ad9e9c53952163f4e4b68c" + "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/16ee0a84af2a044af8ad9e9c53952163f4e4b68c", - "reference": "16ee0a84af2a044af8ad9e9c53952163f4e4b68c", + "url": "https://api.github.com/repos/drupal/core/zipball/1e1bf0e841e11029b21775dd125332d7ffd6fb47", + "reference": "1e1bf0e841e11029b21775dd125332d7ffd6fb47", "shasum": "" }, "require": { @@ -4136,14 +4136,12 @@ "drupal/migrate_drupal_multilingual": "self.version", "drupal/migrate_drupal_ui": "self.version", "drupal/minimal": "self.version", - "drupal/mysql": "self.version", "drupal/node": "self.version", "drupal/olivero": "self.version", "drupal/options": "self.version", "drupal/page_cache": "self.version", "drupal/path": "self.version", "drupal/path_alias": "self.version", - "drupal/pgsql": "self.version", "drupal/quickedit": "self.version", "drupal/rdf": "self.version", "drupal/responsive_image": "self.version", @@ -4153,7 +4151,6 @@ "drupal/settings_tray": "self.version", "drupal/seven": "self.version", "drupal/shortcut": "self.version", - "drupal/sqlite": "self.version", "drupal/standard": "self.version", "drupal/stark": "self.version", "drupal/statistics": "self.version", @@ -4224,6 +4221,9 @@ "lib/Drupal/Core/Cache/DatabaseCacheTagsChecksum.php", "lib/Drupal/Core/Database/Connection.php", "lib/Drupal/Core/Database/Database.php", + "lib/Drupal/Core/Database/Driver/mysql/Connection.php", + "lib/Drupal/Core/Database/Driver/pgsql/Connection.php", + "lib/Drupal/Core/Database/Driver/sqlite/Connection.php", "lib/Drupal/Core/Database/Statement.php", "lib/Drupal/Core/Database/StatementInterface.php", "lib/Drupal/Core/DependencyInjection/Container.php", @@ -4244,22 +4244,22 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/9.4.x" + "source": "https://github.com/drupal/core/tree/9.3.0" }, - "time": "2021-12-30T13:40:51+00:00" + "time": "2021-12-08T22:09:38+00:00" }, { "name": "drupal/core-recommended", - "version": "9.4.x-dev", + "version": "9.3.0", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "8a46b487bdfe78c00a4070a78b542879b66599f4" + "reference": "d65aaa36a8cab54332787a20676f81928f675bb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/8a46b487bdfe78c00a4070a78b542879b66599f4", - "reference": "8a46b487bdfe78c00a4070a78b542879b66599f4", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/d65aaa36a8cab54332787a20676f81928f675bb3", + "reference": "d65aaa36a8cab54332787a20676f81928f675bb3", "shasum": "" }, "require": { @@ -4268,7 +4268,7 @@ "doctrine/annotations": "1.13.2", "doctrine/lexer": "1.2.1", "doctrine/reflection": "1.2.2", - "drupal/core": "9.4.x-dev", + "drupal/core": "9.3.0", "egulias/email-validator": "3.1.2", "guzzlehttp/guzzle": "6.5.5", "guzzlehttp/promises": "1.5.1", @@ -4330,9 +4330,9 @@ ], "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/9.4.x" + "source": "https://github.com/drupal/core-recommended/tree/9.3.0" }, - "time": "2021-11-30T05:41:22+00:00" + "time": "2021-12-08T22:09:38+00:00" }, { "name": "drupal/semver_example", @@ -8761,8 +8761,7 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { - "consolidation/site-alias": 0, - "drupal/core-recommended": 20 + "consolidation/site-alias": 0 }, "prefer-stable": true, "prefer-lowest": false, @@ -8771,5 +8770,8 @@ "ext-dom": "*" }, "platform-dev": [], + "platform-overrides": { + "php": "7.4" + }, "plugin-api-version": "2.1.0" } From bd0cfe46c309383028b7fd994d2590cdbaaadcba Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 12:40:06 -0500 Subject: [PATCH 045/125] More type hints and return type declarations. (#4963) * More type hints and return type declarations. * PHPCS * Import class names & add more types * Update Rector config * Revert all changes except for files in src/Commands and src/Drupal * phpcs Co-authored-by: Dieter Holvoet --- composer.json | 2 +- rector.php | 8 ++ src/Commands/DrushCommands.php | 13 +-- src/Commands/ExampleCommands.php | 4 +- src/Commands/LegacyCommands.php | 22 ++-- src/Commands/OptionsCommands.php | 10 +- src/Commands/ValidatorsCommands.php | 20 ++-- src/Commands/config/ConfigPullCommands.php | 5 +- src/Commands/core/CacheCommands.php | 30 ++--- src/Commands/core/CoreCommands.php | 6 +- src/Commands/core/DeployCommands.php | 8 +- src/Commands/core/DocsCommands.php | 36 +++--- src/Commands/core/DrupalDirectoryCommands.php | 2 +- src/Commands/core/DrupliconCommands.php | 4 +- src/Commands/core/EditCommands.php | 12 +- src/Commands/core/LoginCommands.php | 2 +- src/Commands/core/MkCommands.php | 6 +- src/Commands/core/NotifyCommands.php | 15 +-- src/Commands/core/RsyncCommands.php | 12 +- src/Commands/core/RunserverCommands.php | 5 +- src/Commands/core/SiteCommands.php | 17 +-- src/Commands/core/SiteInstallCommands.php | 18 +-- src/Commands/core/SshCommands.php | 2 +- src/Commands/core/StatusCommands.php | 11 +- src/Commands/core/TopicCommands.php | 11 +- src/Commands/core/UpdateDBCommands.php | 36 +++--- src/Commands/core/XhprofCommands.php | 15 ++- src/Commands/generate/ApplicationFactory.php | 8 +- src/Commands/generate/GenerateCommands.php | 4 +- src/Commands/help/DrushHelpDocument.php | 4 +- src/Commands/help/HelpCLIFormatter.php | 14 +-- src/Commands/help/HelpCommands.php | 6 +- src/Commands/help/ListCommands.php | 22 +--- src/Commands/pm/SecurityUpdateCommands.php | 16 ++- src/Commands/sql/SqlCommands.php | 15 ++- src/Commands/sql/SqlSyncCommands.php | 16 +-- src/Drupal/Commands/config/ConfigCommands.php | 52 ++++----- .../Commands/config/ConfigExportCommands.php | 32 ++--- .../Commands/config/ConfigImportCommands.php | 109 ++++++------------ src/Drupal/Commands/core/BatchCommands.php | 4 +- src/Drupal/Commands/core/CliCommands.php | 19 ++- .../Commands/core/DeployHookCommands.php | 24 ++-- src/Drupal/Commands/core/DrupalCommands.php | 28 ++--- src/Drupal/Commands/core/EntityCommands.php | 26 +++-- src/Drupal/Commands/core/ImageCommands.php | 6 +- src/Drupal/Commands/core/JsonapiCommands.php | 4 +- src/Drupal/Commands/core/LanguageCommands.php | 27 ++--- src/Drupal/Commands/core/LocaleCommands.php | 43 +++---- .../Commands/core/MessengerCommands.php | 6 +- .../Commands/core/MigrateRunnerCommands.php | 56 ++++----- src/Drupal/Commands/core/QueueCommands.php | 31 ++--- src/Drupal/Commands/core/RoleCommands.php | 9 +- src/Drupal/Commands/core/StateCommands.php | 17 +-- src/Drupal/Commands/core/TwigCommands.php | 29 ++--- src/Drupal/Commands/core/UserCommands.php | 28 +++-- src/Drupal/Commands/core/ViewsCommands.php | 34 ++---- src/Drupal/Commands/core/WatchdogCommands.php | 20 ++-- src/Drupal/Commands/pm/PmCommands.php | 44 +++---- src/Drupal/Commands/pm/ThemeCommands.php | 6 +- src/Drupal/Commands/sql/SanitizeCommands.php | 2 +- .../Commands/sql/SanitizeCommentsCommands.php | 4 +- .../Commands/sql/SanitizePluginInterface.php | 2 +- .../Commands/sql/SanitizeSessionsCommands.php | 4 +- .../sql/SanitizeUserFieldsCommands.php | 6 +- .../sql/SanitizeUserTableCommands.php | 9 +- src/Drupal/DrupalKernelTrait.php | 3 +- src/Drupal/DrupalUtil.php | 7 +- src/Drupal/DrushLoggerServiceProvider.php | 5 +- src/Drupal/DrushServiceModifier.php | 8 +- src/Drupal/ExtensionDiscovery.php | 2 +- src/Drupal/FindCommandsCompilerPass.php | 2 +- src/Drupal/Migrate/MigrateExecutable.php | 51 ++++---- src/Drupal/Migrate/MigrateIdMapFilter.php | 4 +- src/Drupal/Migrate/MigrateMessage.php | 2 +- .../Migrate/MigrateMissingSourceRowsEvent.php | 6 +- src/Drupal/Migrate/MigratePrepareRowEvent.php | 26 ++--- 76 files changed, 514 insertions(+), 720 deletions(-) diff --git a/composer.json b/composer.json index b76b8b176a..bc581928a5 100644 --- a/composer.json +++ b/composer.json @@ -111,7 +111,7 @@ "api": "php $HOME/bin/doctum.phar --ansi --ignore-parse-errors update doctum-config.php", "doctum-install": "mkdir -p $HOME/bin && curl --output $HOME/bin/doctum.phar https://doctum.long-term.support/releases/latest/doctum.phar && chmod +x $HOME/bin/doctum.phar", "mk:docs": "./drush --uri=dev -v mk:docs", - "rector": "rector process src/Boot src/Command src/Sql src/Preflight src/Psysh src/Runtime src/SiteAlias src/Symfony src/Utils src/Config", + "rector": "rector process", "sut": "./drush --uri=dev", "sut:si": "./drush --uri=dev site:install testing --sites-subdir=dev --db-url=${UNISH_DB_URL:-mysql://root:password@mariadb}/unish_dev -v", "phpunit": "php -d sendmail_path='true' vendor/bin/phpunit --colors=always --configuration tests", diff --git a/rector.php b/rector.php index 05fef6222e..a75c3666be 100644 --- a/rector.php +++ b/rector.php @@ -2,11 +2,19 @@ declare(strict_types=1); +use Rector\Core\Configuration\Option; use Rector\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector; use Rector\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return function (ContainerConfigurator $containerConfigurator): void { + $parameters = $containerConfigurator->parameters(); + $parameters->set(Option::AUTO_IMPORT_NAMES, true); + $parameters->set(Option::IMPORT_SHORT_CLASSES, false); + $parameters->set(Option::PATHS, [ + __DIR__ . '/src', + ]); + $services = $containerConfigurator->services(); $services->set(ParamTypeDeclarationRector::class); $services->set(ReturnTypeDeclarationRector::class); diff --git a/src/Commands/DrushCommands.php b/src/Commands/DrushCommands.php index a9a400538d..d79889fc9f 100644 --- a/src/Commands/DrushCommands.php +++ b/src/Commands/DrushCommands.php @@ -1,6 +1,7 @@ io) { // Specify our own Style class when needed. @@ -64,10 +65,8 @@ protected function io() /** * Returns a logger object. - * - * @return LoggerInterface */ - protected function logger() + protected function logger(): ?LoggerInterface { return $this->logger; } @@ -78,7 +77,7 @@ protected function logger() * @param string $file * Full path to a file. */ - protected function printFile($file) + protected function printFile(string $file): void { if ((substr($file, -4) == ".htm") || (substr($file, -5) == ".html")) { $tmp_file = drush_tempnam(basename($file)); @@ -102,7 +101,7 @@ protected function printFile($file) * * @hook pre-command * * - * @param \Consolidation\AnnotatedCommand\CommandData $commandData + * @param CommandData $commandData */ public function preHook(CommandData $commandData) { @@ -126,7 +125,7 @@ protected function printFileTopic(CommandData $commandData) * * @see https://stackoverflow.com/questions/32681165/how-do-you-log-all-api-calls-using-guzzle-6. */ - protected function getStack(): \GuzzleHttp\HandlerStack + protected function getStack(): HandlerStack { $stack = HandlerStack::create(); $stack->push(Middleware::log($this->logger(), new MessageFormatter(Drush::debug() ? MessageFormatter::DEBUG : MessageFormatter::SHORT))); diff --git a/src/Commands/ExampleCommands.php b/src/Commands/ExampleCommands.php index 11d4a32862..8d44afe4b3 100644 --- a/src/Commands/ExampleCommands.php +++ b/src/Commands/ExampleCommands.php @@ -28,10 +28,8 @@ class ExampleCommands extends DrushCommands * @usage example-table --fields=III,II * @aliases tf * @hidden - * - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function exampleTable($options = ['format' => 'table']) + public function exampleTable($options = ['format' => 'table']): RowsOfFields { $tableData = [ 'en' => [ 'first' => 'One', 'second' => 'Two', 'third' => 'Three' ], diff --git a/src/Commands/LegacyCommands.php b/src/Commands/LegacyCommands.php index 3d382552ed..71b561fe8d 100644 --- a/src/Commands/LegacyCommands.php +++ b/src/Commands/LegacyCommands.php @@ -12,7 +12,7 @@ class LegacyCommands extends DrushCommands * @hidden * @obsolete */ - public function disable() + public function disable(): void { } @@ -24,7 +24,7 @@ public function disable() * @hidden * @obsolete */ - public function info() + public function info(): void { } @@ -37,7 +37,7 @@ public function info() * @hidden * @obsolete */ - public function projectInfo() + public function projectInfo(): void { } @@ -49,7 +49,7 @@ public function projectInfo() * @hidden * @obsolete */ - public function refresh() + public function refresh(): void { } @@ -63,7 +63,7 @@ public function refresh() * @hidden * @obsolete */ - public function updatestatus() + public function updatestatus(): void { } @@ -77,7 +77,7 @@ public function updatestatus() * @hidden * @obsolete */ - public function updatecode() + public function updatecode(): void { } @@ -89,7 +89,7 @@ public function updatecode() * @hidden * @obsolete */ - public function releaseNotes() + public function releaseNotes(): void { } @@ -101,7 +101,7 @@ public function releaseNotes() * @hidden * @obsolete */ - public function releases() + public function releases(): void { } @@ -113,7 +113,7 @@ public function releases() * @hidden * @obsolete */ - public function make() + public function make(): void { } @@ -125,7 +125,7 @@ public function make() * @hidden * @obsolete */ - public function download() + public function download(): void { } @@ -137,7 +137,7 @@ public function download() * @hidden * @obsolete */ - public function execute() + public function execute(): void { } } diff --git a/src/Commands/OptionsCommands.php b/src/Commands/OptionsCommands.php index 35f9aab556..511f425ce3 100644 --- a/src/Commands/OptionsCommands.php +++ b/src/Commands/OptionsCommands.php @@ -16,7 +16,7 @@ class OptionsCommands * @option ssh-options A string of extra options that will be passed to the ssh command (e.g. -p 100) * @option tty Create a tty (e.g. to run an interactive program). */ - public function optionsetProcBuild($options = ['ssh-options' => self::REQ, 'tty' => false]) + public function optionsetProcBuild($options = ['ssh-options' => self::REQ, 'tty' => false]): void { } @@ -25,7 +25,7 @@ public function optionsetProcBuild($options = ['ssh-options' => self::REQ, 'tty' * @option editor A string of bash which launches user's preferred text editor. Defaults to ${VISUAL-${EDITOR-vi}}. * @option bg Launch editor in background process. */ - public function optionsetGetEditor($options = ['editor' => '', 'bg' => false]) + public function optionsetGetEditor($options = ['editor' => '', 'bg' => false]): void { } @@ -33,7 +33,7 @@ public function optionsetGetEditor($options = ['editor' => '', 'bg' => false]) * @hook option @optionset_ssh * @option ssh-options A string appended to ssh command during rsync, sql-sync, etc. */ - public function optionsetSsh($options = ['ssh-options' => self::REQ]) + public function optionsetSsh($options = ['ssh-options' => self::REQ]): void { } @@ -44,7 +44,7 @@ public function optionsetSsh($options = ['ssh-options' => self::REQ]) * @option target The name of a target within the specified database connection. * @option show-passwords Show password on the CLI. Useful for debugging. */ - public function optionsetSql($options = ['database' => 'default', 'target' => 'default', 'db-url' => self::REQ, 'show-passwords' => false]) + public function optionsetSql($options = ['database' => 'default', 'target' => 'default', 'db-url' => self::REQ, 'show-passwords' => false]): void { } @@ -63,7 +63,7 @@ public function optionsetTableSelection($options = [ 'tables-key' => self::REQ, 'skip-tables-list' => self::REQ, 'structure-tables-list' => self::REQ, - 'tables-list' => self::REQ]) + 'tables-list' => self::REQ]): void { } } diff --git a/src/Commands/ValidatorsCommands.php b/src/Commands/ValidatorsCommands.php index f6be086645..7c89710414 100644 --- a/src/Commands/ValidatorsCommands.php +++ b/src/Commands/ValidatorsCommands.php @@ -17,8 +17,8 @@ class ValidatorsCommands * @see \Drush\Commands\core\ViewsCommands::execute for an example. * * @hook validate @validate-entity-load - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validateEntityLoad(CommandData $commandData) { @@ -38,9 +38,9 @@ public function validateEntityLoad(CommandData $commandData) * @see \Drush\Commands\core\WatchdogCommands::show for an example. * * @hook post-init @validate-module-enabled - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @return CommandError|null */ - public function validateModuleEnabled(Input $input, AnnotationData $annotationData) + public function validateModuleEnabled(Input $input, AnnotationData $annotationData): void { $names = StringUtils::csvToArray($annotationData->get('validate-module-enabled')); $loaded = \Drupal::moduleHandler()->getModuleList(); @@ -56,8 +56,8 @@ public function validateModuleEnabled(Input $input, AnnotationData $annotationDa * Annotation value should be the name of the argument containing the path. * * @hook validate @validate-file-exists - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validateFileExists(CommandData $commandData) { @@ -87,8 +87,8 @@ public function validateFileExists(CommandData $commandData) * Annotation value should be extension name. If multiple, delimit by a comma. * * @hook validate @validate-php-extension - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validatePHPExtension(CommandData $commandData) { @@ -112,8 +112,8 @@ public function validatePHPExtension(CommandData $commandData) * Annotation value should be the name of the argument/option containing the permission(s). * * @hook validate @validate-permissions - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validatePermissions(CommandData $commandData) { diff --git a/src/Commands/config/ConfigPullCommands.php b/src/Commands/config/ConfigPullCommands.php index 0b123dcc63..d7cc228451 100644 --- a/src/Commands/config/ConfigPullCommands.php +++ b/src/Commands/config/ConfigPullCommands.php @@ -35,9 +35,8 @@ class ConfigPullCommands extends DrushCommands implements SiteAliasManagerAwareI * @topics docs:aliases,docs:config:exporting * @field-labels * path: Path - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList */ - public function pull($source, $destination, $options = ['safe' => false, 'label' => 'sync', 'runner' => null, 'format' => 'null']) + public function pull(string $source, string $destination, array $options = ['safe' => false, 'label' => 'sync', 'runner' => null, 'format' => 'null']): PropertyList { $global_options = Drush::redispatchOptions() + ['strict' => 0]; $sourceRecord = $this->siteAliasManager()->get($source); @@ -89,7 +88,7 @@ public function pull($source, $destination, $options = ['safe' => false, 'label' /** * @hook validate config-pull */ - public function validateConfigPull(CommandData $commandData) + public function validateConfigPull(CommandData $commandData): void { if ($commandData->input()->getOption('safe')) { $destinationRecord = $this->siteAliasManager()->get($commandData->input()->getArgument('destination')); diff --git a/src/Commands/core/CacheCommands.php b/src/Commands/core/CacheCommands.php index 6b80f6ab2c..413ac5009c 100644 --- a/src/Commands/core/CacheCommands.php +++ b/src/Commands/core/CacheCommands.php @@ -1,6 +1,7 @@ 'json']) + public function get($cid, $bin = 'default', $options = ['format' => 'json']): PropertyList { $result = \Drupal::cache($bin)->get($cid); if (empty($result)) { @@ -69,7 +69,7 @@ public function get($cid, $bin = 'default', $options = ['format' => 'json']) * @usage drush cache:tag node:12,user:4 * Purge content associated with two cache tags. */ - public function tags($tags) + public function tags(string $tags): void { $tags = StringUtils::csvToArray($tags); Cache::invalidateTags($tags); @@ -92,7 +92,7 @@ public function tags($tags) * @usage drush cc bin entity,bootstrap * Clear the entity and bootstrap cache bins. */ - public function clear($type, array $args, $options = ['cache-clear' => true]) + public function clear(string $type, array $args, $options = ['cache-clear' => true]) { $boot_manager = Drush::bootstrapManager(); @@ -114,7 +114,7 @@ public function clear($type, array $args, $options = ['cache-clear' => true]) /** * @hook interact cache-clear */ - public function interact($input, $output) + public function interact($input, $output): void { $boot_manager = Drush::bootstrapManager(); if (empty($input->getArgument('type'))) { @@ -242,7 +242,7 @@ public function rebuild($options = ['cache-clear' => true]) /** * @hook validate cache-clear */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $boot_manager = Drush::bootstrapManager(); $types = $this->getTypes($boot_manager->hasBootstrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)); @@ -270,7 +270,7 @@ public function validate(CommandData $commandData) /** * Types of caches available for clearing. Contrib commands can hook in their own. */ - public function getTypes($include_bootstrapped_types = false) + public function getTypes($include_bootstrapped_types = false): array { $types = [ 'drush' => [$this, 'clearDrush'], @@ -297,7 +297,7 @@ public function getTypes($include_bootstrapped_types = false) /** * Clear caches internal to Drush core. */ - public static function clearDrush() + public static function clearDrush(): void { try { drush_cache_clear_all(null, 'default');// No longer used by Drush core, but still cleared for backward compat. @@ -312,7 +312,7 @@ public static function clearDrush() /** * Clear one or more cache bins. */ - public static function clearBins($args = ['default']) + public static function clearBins($args = ['default']): void { $bins = StringUtils::csvToArray($args); foreach ($bins as $bin) { @@ -321,19 +321,19 @@ public static function clearBins($args = ['default']) } } - public static function clearThemeRegistry() + public static function clearThemeRegistry(): void { \Drupal::service('theme.registry')->reset(); } - public static function clearRouter() + public static function clearRouter(): void { - /** @var \Drupal\Core\Routing\RouteBuilderInterface $router_builder */ + /** @var RouteBuilderInterface $router_builder */ $router_builder = \Drupal::service('router.builder'); $router_builder->rebuild(); } - public static function clearCssJs() + public static function clearCssJs(): void { _drupal_flush_css_js(); \Drupal::service('asset.css.collection_optimizer')->deleteAll(); @@ -343,12 +343,12 @@ public static function clearCssJs() /** * Clears the render cache entries. */ - public static function clearRender() + public static function clearRender(): void { Cache::invalidateTags(['rendered']); } - public static function clearPlugin() + public static function clearPlugin(): void { \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); } diff --git a/src/Commands/core/CoreCommands.php b/src/Commands/core/CoreCommands.php index 8c34134183..7bd82e0957 100644 --- a/src/Commands/core/CoreCommands.php +++ b/src/Commands/core/CoreCommands.php @@ -27,9 +27,8 @@ class CoreCommands extends DrushCommands implements SiteAliasManagerAwareInterfa * @aliases core-global-options * * @filter-default-field name - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function globalOptions($options = ['format' => 'table']) + public function globalOptions($options = ['format' => 'table']): RowsOfFields { $application = Drush::getApplication(); $def = $application->getDefinition(); @@ -68,10 +67,9 @@ public function globalOptions($options = ['format' => 'table']) * @field-labels * drush-version: Drush version * - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList * */ - public function version($options = ['format' => 'table']) + public function version($options = ['format' => 'table']): PropertyList { return new PropertyList(['drush-version' => Drush::getVersion()]); } diff --git a/src/Commands/core/DeployCommands.php b/src/Commands/core/DeployCommands.php index a88571f7bc..ab88271dd5 100644 --- a/src/Commands/core/DeployCommands.php +++ b/src/Commands/core/DeployCommands.php @@ -26,7 +26,7 @@ class DeployCommands extends DrushCommands implements SiteAliasManagerAwareInter * * @throws \Exception */ - public function deploy() + public function deploy(): void { $self = $this->siteAliasManager()->getSelf(); $redispatchOptions = Drush::redispatchOptions(); @@ -51,11 +51,11 @@ public function deploy() } /** - * @param \Consolidation\SiteProcess\ProcessManager $manager - * @param \Consolidation\SiteAlias\SiteAlias $self + * @param ProcessManager $manager + * @param SiteAlias $self * @param array $redispatchOptions */ - public function cacheRebuild(ProcessManager $manager, SiteAlias $self, array $redispatchOptions) + public function cacheRebuild(ProcessManager $manager, SiteAlias $self, array $redispatchOptions): void { // It is possible that no updates were pending and thus no caches cleared yet. $this->logger()->success("Cache rebuild start."); diff --git a/src/Commands/core/DocsCommands.php b/src/Commands/core/DocsCommands.php index db33cff46c..60190ae648 100644 --- a/src/Commands/core/DocsCommands.php +++ b/src/Commands/core/DocsCommands.php @@ -21,7 +21,7 @@ class DocsCommands extends DrushCommands * @hidden * @topic ../../../README.md */ - public function readme() + public function readme(): void { self::printFileTopic($this->commandData); } @@ -34,7 +34,7 @@ public function readme() * @hidden * @topic ../../../examples/git-bisect.example.sh */ - public function bisect() + public function bisect(): void { self::printFileTopic($this->commandData); } @@ -47,7 +47,7 @@ public function bisect() * @hidden * @topic ../../../examples/example.bashrc */ - public function bashrc() + public function bashrc(): void { self::printFileTopic($this->commandData); } @@ -60,7 +60,7 @@ public function bashrc() * @hidden * @topic ../../../docs/using-drush-configuration.md */ - public function config() + public function config(): void { self::printFileTopic($this->commandData); } @@ -73,7 +73,7 @@ public function config() * @hidden * @topic ../../../docs/hooks.md */ - public function hooks() + public function hooks(): void { self::printFileTopic($this->commandData); } @@ -86,7 +86,7 @@ public function hooks() * @hidden * @topic ../../../docs/config-exporting.md */ - public function configExport() + public function configExport(): void { self::printFileTopic($this->commandData); } @@ -100,7 +100,7 @@ public function configExport() * @hidden * @topic ../../../docs/output-formats-filters.md */ - public function outputFormatsFilters() + public function outputFormatsFilters(): void { self::printFileTopic($this->commandData); } @@ -113,7 +113,7 @@ public function outputFormatsFilters() * @hidden * @topic ../../../docs/site-aliases.md */ - public function siteAliases() + public function siteAliases(): void { self::printFileTopic($this->commandData); } @@ -126,7 +126,7 @@ public function siteAliases() * @hidden * @topic ../../../examples/helloworld.script */ - public function script() + public function script(): void { self::printFileTopic($this->commandData); } @@ -139,7 +139,7 @@ public function script() * @hidden * @topic ../../../docs/bootstrap.md */ - public function bootstrap() + public function bootstrap(): void { self::printFileTopic($this->commandData); } @@ -152,7 +152,7 @@ public function bootstrap() * @hidden * @topic ../../../docs/cron.md */ - public function cron() + public function cron(): void { self::printFileTopic($this->commandData); } @@ -165,7 +165,7 @@ public function cron() * @hidden * @topic ../../../docs/commands.md */ - public function commands() + public function commands(): void { self::printFileTopic($this->commandData); } @@ -178,7 +178,7 @@ public function commands() * @hidden * @topic ../../../docs/generators.md */ - public function generators() + public function generators(): void { self::printFileTopic($this->commandData); } @@ -191,7 +191,7 @@ public function generators() * @hidden * @topic ../../../examples/Commands/ArtCommands.php */ - public function exampleCommand() + public function exampleCommand(): void { self::printFileTopic($this->commandData); } @@ -203,7 +203,7 @@ public function exampleCommand() * @hidden * @topic ../../../docs/migrate.md */ - public function migrate() + public function migrate(): void { self::printFileTopic($this->commandData); } @@ -216,7 +216,7 @@ public function migrate() * @hidden * @topic ../../../examples/Commands/SyncViaHttpCommands.php */ - public function syncHttp() + public function syncHttp(): void { self::printFileTopic($this->commandData); } @@ -229,7 +229,7 @@ public function syncHttp() * @hidden * @topic ../../../examples/Commands/PolicyCommands.php */ - public function policy() + public function policy(): void { self::printFileTopic($this->commandData); } @@ -242,7 +242,7 @@ public function policy() * @hidden * @topic ../../../docs/deploycommand.md */ - public function deploy() + public function deploy(): void { self::printFileTopic($this->commandData); } diff --git a/src/Commands/core/DrupalDirectoryCommands.php b/src/Commands/core/DrupalDirectoryCommands.php index 75cb3bab35..b3fd0860f4 100644 --- a/src/Commands/core/DrupalDirectoryCommands.php +++ b/src/Commands/core/DrupalDirectoryCommands.php @@ -39,7 +39,7 @@ public function __construct() * Open devel module in your editor * @aliases dd,drupal-directory */ - public function drupalDirectory($target = 'root', $options = ['local-only' => false]) + public function drupalDirectory(string $target = 'root', $options = ['local-only' => false]) { $path = $this->getPath($target, $options['local-only']); diff --git a/src/Commands/core/DrupliconCommands.php b/src/Commands/core/DrupliconCommands.php index e170066774..60e7d69d19 100644 --- a/src/Commands/core/DrupliconCommands.php +++ b/src/Commands/core/DrupliconCommands.php @@ -12,7 +12,7 @@ class DrupliconCommands extends DrushCommands * @hook option * * @option druplicon Shows the druplicon as glorious ASCII art. */ - public function optionset($options = ['druplicon' => false]) + public function optionset($options = ['druplicon' => false]): void { } @@ -21,7 +21,7 @@ public function optionset($options = ['druplicon' => false]) * * @hook post-command * */ - public function druplicon($result, CommandData $commandData) + public function druplicon($result, CommandData $commandData): void { // If one command does a Drush::drush() to another command, // then this hook will be called multiple times. Only print diff --git a/src/Commands/core/EditCommands.php b/src/Commands/core/EditCommands.php index 333467f1a6..4ee7d1a92a 100644 --- a/src/Commands/core/EditCommands.php +++ b/src/Commands/core/EditCommands.php @@ -34,7 +34,7 @@ class EditCommands extends DrushCommands implements SiteAliasManagerAwareInterfa * Edit the second file in the choice list. * @aliases conf,config,core-edit */ - public function edit($filter = null) + public function edit($filter = null): void { $all = $this->load(); @@ -66,7 +66,7 @@ public function edit($filter = null) $process->mustRun(); } - public function load($headers = true) + public function load($headers = true): array { $php_header = $php = $rcs_header = $rcs = $aliases_header = $aliases = $drupal_header = $drupal = []; $php = $this->phpIniFiles(); @@ -118,13 +118,13 @@ public function load($headers = true) return array_merge($php_header, $php, $bash_header, $bash, $rcs_header, $rcs, $aliases_header, $aliases, $drupal_header, $drupal); } - public static function phpIniFiles() + public static function phpIniFiles(): array { $paths[] = php_ini_loaded_file(); return $paths; } - public function bashFiles() + public function bashFiles(): array { $bashFiles = []; $home = $this->getConfig()->home(); @@ -144,12 +144,12 @@ public function bashFiles() * TODO: Also exists as InitCommands::findBashrc. Decide on class-based * way to share code like this. */ - public static function findBashrc($home) + public static function findBashrc($home): string { return $home . "/.bashrc"; } - public function complete() + public function complete(): array { return ['values' => $this->load(false)]; } diff --git a/src/Commands/core/LoginCommands.php b/src/Commands/core/LoginCommands.php index 3db35557ba..00a5e3d327 100644 --- a/src/Commands/core/LoginCommands.php +++ b/src/Commands/core/LoginCommands.php @@ -38,7 +38,7 @@ class LoginCommands extends DrushCommands implements SiteAliasManagerAwareInterf * @usage drush user:login --mail=foo@bar.com * Open browser and login as user with mail "foo@bar.com". */ - public function login($path = '', $options = ['name' => null, 'uid' => null, 'mail' => null, 'browser' => true, 'redirect-port' => self::REQ]) + public function login(string $path = '', $options = ['name' => null, 'uid' => null, 'mail' => null, 'browser' => true, 'redirect-port' => self::REQ]) { // Redispatch if called against a remote-host so a browser is started on the // the *local* machine. diff --git a/src/Commands/core/MkCommands.php b/src/Commands/core/MkCommands.php index cc838513fc..78974f1438 100644 --- a/src/Commands/core/MkCommands.php +++ b/src/Commands/core/MkCommands.php @@ -35,7 +35,7 @@ class MkCommands extends DrushCommands implements SiteAliasManagerAwareInterface * @usage drush mk:docs * Build many .md files in the docs/commands and docs/generators directories. */ - public function docs() + public function docs(): void { $dir_root = Drush::bootstrapManager()->getComposerRoot(); $destination = 'commands'; @@ -261,7 +261,7 @@ protected function prepare($destination): void /** * Build an array since that's what HelpCLIFormatter expects. * - * @param \Symfony\Component\Console\Input\InputArgument $arg + * @param InputArgument $arg * * @return iterable */ @@ -277,7 +277,7 @@ public static function argToArray(InputArgument $arg): iterable /** * Build an array since that's what HelpCLIFormatter expects. * - * @param \Symfony\Component\Console\Input\InputOption $opt + * @param InputOption $opt * * @return iterable */ diff --git a/src/Commands/core/NotifyCommands.php b/src/Commands/core/NotifyCommands.php index 9cdcc728fb..7164923322 100644 --- a/src/Commands/core/NotifyCommands.php +++ b/src/Commands/core/NotifyCommands.php @@ -13,19 +13,19 @@ class NotifyCommands extends DrushCommands * @hook option * * @option notify Notify upon command completion. If set to a number, commands that finish in fewer seconds won't notify. */ - public function optionsetNotify() + public function optionsetNotify(): void { } /** * @hook pre-command * */ - public function registerShutdown(CommandData $commandData) + public function registerShutdown(CommandData $commandData): void { register_shutdown_function([$this, 'shutdown'], $commandData); } - public function shutdown(CommandData $commandData) + public function shutdown(CommandData $commandData): void { $annotationData = $commandData->annotationData(); @@ -50,7 +50,7 @@ public function shutdown(CommandData $commandData) * @param string $msg * Message to send via notification. */ - public static function shutdownSend($msg, CommandData $commandData) + public static function shutdownSend(string $msg, CommandData $commandData): void { self::shutdownSendText($msg, $commandData); } @@ -64,10 +64,9 @@ public static function shutdownSend($msg, CommandData $commandData) * @param string $msg * Message text for delivery. * - * @return bool * TRUE on success, FALSE on failure */ - public static function shutdownSendText($msg, CommandData $commandData) + public static function shutdownSendText(string $msg, CommandData $commandData): bool { $override = Drush::config()->get('notify.cmd'); @@ -101,10 +100,8 @@ public static function shutdownSendText($msg, CommandData $commandData) /** * Identify if the given Drush request should trigger a notification. - * - * @return bool */ - public static function isAllowed() + public static function isAllowed(): bool { $duration = Drush::config()->get('notify.duration'); $execution = time() - $_SERVER['REQUEST_TIME']; diff --git a/src/Commands/core/RsyncCommands.php b/src/Commands/core/RsyncCommands.php index 515afeb135..74a27a04f6 100644 --- a/src/Commands/core/RsyncCommands.php +++ b/src/Commands/core/RsyncCommands.php @@ -58,7 +58,7 @@ public function __construct() * @aliases rsync,core-rsync * @topics docs:aliases */ - public function rsync($source, $target, array $extra, $options = ['exclude-paths' => self::REQ, 'include-paths' => self::REQ, 'mode' => 'akz']) + public function rsync($source, $target, array $extra, $options = ['exclude-paths' => self::REQ, 'include-paths' => self::REQ, 'mode' => 'akz']): void { // Prompt for confirmation. This is destructive. if (!$this->getConfig()->simulate()) { @@ -83,7 +83,7 @@ public function rsync($source, $target, array $extra, $options = ['exclude-paths } } - public function rsyncOptions($options) + public function rsyncOptions($options): string { $verbose = $paths = ''; // Process --include-paths and --exclude-paths options the same way @@ -117,9 +117,8 @@ public function rsyncOptions($options) * @hook command-event core:rsync * @param ConsoleCommandEvent $event * @throws \Exception - * @return void */ - public function preCommandEvent(ConsoleCommandEvent $event) + public function preCommandEvent(ConsoleCommandEvent $event): void { $input = $event->getInput(); $this->sourceEvaluatedPath = $this->injectAliasPathParameterOptions($input, 'source'); @@ -154,11 +153,10 @@ protected function injectAliasPathParameterOptions($input, $parameterName) * Validate that passed aliases are valid. * * @hook validate core-rsync - * @param \Consolidation\AnnotatedCommand\CommandData $commandData + * @param CommandData $commandData * @throws \Exception - * @return void */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { if ($this->sourceEvaluatedPath->isRemote() && $this->targetEvaluatedPath->isRemote()) { $msg = dt("Cannot specify two remote aliases. Instead, use one of the following alternate options:\n\n `drush {source} rsync @self {target}`\n `drush {source} rsync @self {fulltarget}\n\nUse the second form if the site alias definitions are not available at {source}.", ['source' => $this->sourceEvaluatedPath->getSiteAlias()->name(), 'target' => $this->targetEvaluatedPath->getSiteAlias()->name(), 'fulltarget' => $this->targetEvaluatedPath->fullyQualifiedPath()]); diff --git a/src/Commands/core/RunserverCommands.php b/src/Commands/core/RunserverCommands.php index 92c97479b6..94d7bba0fb 100644 --- a/src/Commands/core/RunserverCommands.php +++ b/src/Commands/core/RunserverCommands.php @@ -86,7 +86,7 @@ public function runserver($uri = null, $options = ['default-server' => self::REQ /** * Determine the URI to use for this server. */ - public function uri($uri, $options) + public function uri($uri, $options): array { $drush_default = [ 'host' => '127.0.0.1', @@ -122,10 +122,9 @@ public function uri($uri, $options) * @param string $uri * String that can contain partial URI. * - * @return array * URI array as returned by parse_url. */ - public function parseUri($uri) + public function parseUri(string $uri): array { if (empty($uri)) { return []; diff --git a/src/Commands/core/SiteCommands.php b/src/Commands/core/SiteCommands.php index 51d4891f45..06fddfe336 100644 --- a/src/Commands/core/SiteCommands.php +++ b/src/Commands/core/SiteCommands.php @@ -42,7 +42,7 @@ class SiteCommands extends DrushCommands implements SiteAliasManagerAwareInterfa * Without an argument, any existing site becomes unset. * @aliases use,site-set */ - public function siteSet($site = '@none') + public function siteSet(string $site = '@none'): void { $filename = $this->getConfig()->get('runtime.site-file-current'); if ($filename) { @@ -101,9 +101,8 @@ public function siteSet($site = '@none') * @command site:alias * * @param string $site Site alias or site specification. - * @param array $options * - * @return \Consolidation\OutputFormatters\StructuredData\UnstructuredListData + * @return UnstructuredListData * @throws \Exception * @aliases sa * @filter-default-field id @@ -112,9 +111,8 @@ public function siteSet($site = '@none') * @usage drush site:alias @dev * Print an alias record for the alias 'dev'. * @topics docs:aliases - * */ - public function siteAlias($site = null, $options = ['format' => 'yaml']) + public function siteAlias($site = null, array $options = ['format' => 'yaml']) { // First check to see if the user provided a specification that matches // multiple sites. @@ -149,9 +147,8 @@ public function siteAlias($site = null, $options = ['format' => 'yaml']) * @bootstrap max * @aliases sa-convert,sac * @topics docs:aliases - * @return array */ - public function siteAliasConvert($destination, $options = ['format' => 'yaml', 'sources' => self::REQ]) + public function siteAliasConvert($destination, $options = ['format' => 'yaml', 'sources' => self::REQ]): array { /** * @todo @@ -195,7 +192,7 @@ public function siteAliasConvert($destination, $options = ['format' => 'yaml', ' /** * @hook interact site:alias-convert */ - public function interactSiteAliasConvert(Input $input, Output $output) + public function interactSiteAliasConvert(Input $input, Output $output): void { if (!$input->getArgument('destination')) { $default = Path::join($this->getConfig()->home(), '.drush/sites'); @@ -208,11 +205,9 @@ public function interactSiteAliasConvert(Input $input, Output $output) } /** - * @param array $aliasList * @param $options - * @return array */ - protected function siteAliasExportList($aliasList, $options) + protected function siteAliasExportList(array $aliasList, $options): array { $result = array_map( function ($aliasRecord) { diff --git a/src/Commands/core/SiteInstallCommands.php b/src/Commands/core/SiteInstallCommands.php index 8219aa7ddb..aaccecedca 100644 --- a/src/Commands/core/SiteInstallCommands.php +++ b/src/Commands/core/SiteInstallCommands.php @@ -58,7 +58,7 @@ class SiteInstallCommands extends DrushCommands implements SiteAliasManagerAware * @aliases si,sin,site-install * */ - public function install(array $profile, $options = ['db-url' => self::REQ, 'db-prefix' => self::REQ, 'db-su' => self::REQ, 'db-su-pw' => self::REQ, 'account-name' => 'admin', 'account-mail' => 'admin@example.com', 'site-mail' => 'admin@example.com', 'account-pass' => self::REQ, 'locale' => 'en', 'site-name' => 'Drush Site-Install', 'site-pass' => self::REQ, 'sites-subdir' => self::REQ, 'config-dir' => self::REQ, 'existing-config' => false]) + public function install(array $profile, $options = ['db-url' => self::REQ, 'db-prefix' => self::REQ, 'db-su' => self::REQ, 'db-su-pw' => self::REQ, 'account-name' => 'admin', 'account-mail' => 'admin@example.com', 'site-mail' => 'admin@example.com', 'account-pass' => self::REQ, 'locale' => 'en', 'site-name' => 'Drush Site-Install', 'site-pass' => self::REQ, 'sites-subdir' => self::REQ, 'config-dir' => self::REQ, 'existing-config' => false]): void { $additional = $profile; $profile = array_shift($additional) ?: ''; @@ -162,7 +162,7 @@ public function install(array $profile, $options = ['db-url' => self::REQ, 'db-p } } - public function taskCallback($install_state) + public function taskCallback($install_state): void { $this->logger()->notice('Performed install task: {task}', ['task' => $install_state['active_task']]); } @@ -226,7 +226,7 @@ protected function determineProfile($profile, $options, $class_loader) * * @hook post-command site-install */ - public function post($result, CommandData $commandData) + public function post($result, CommandData $commandData): void { if ($config = $commandData->input()->getOption('config-dir') && Comparator::lessThan(self::getVersion(), '8.6')) { // Set the destination site UUID to match the source UUID, to bypass a core fail-safe. @@ -245,7 +245,7 @@ public function post($result, CommandData $commandData) /** * Check to see if there are any .yml files in the provided config directory. */ - protected function hasConfigFiles($config) + protected function hasConfigFiles($config): bool { $files = glob("$config/*.yml"); return !empty($files); @@ -254,7 +254,7 @@ protected function hasConfigFiles($config) /** * @hook validate site-install */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $bootstrapManager = Drush::bootstrapManager(); if ($sites_subdir = $commandData->input()->getOption('sites-subdir')) { @@ -311,7 +311,7 @@ public function validate(CommandData $commandData) * * @hook pre-command site-install */ - public function pre(CommandData $commandData) + public function pre(CommandData $commandData): void { $db_spec = []; if ($sql = SqlBase::create($commandData->input()->getOptions())) { @@ -436,7 +436,7 @@ protected function getSitesSubdirFromUri($root, $uri) return false; } - public static function getVersion() + public static function getVersion(): ?string { $drupal_root = Drush::bootstrapManager()->getRoot(); return Drush::bootstrap()->getVersion($drupal_root); @@ -446,7 +446,7 @@ public static function getVersion() * Fake the necessary HTTP headers that the Drupal installer still needs: * @see https://github.com/drupal/drupal/blob/d260101f1ea8a6970df88d2f1899248985c499fc/core/includes/install.core.inc#L287 */ - public function serverGlobals($drupal_base_url) + public function serverGlobals($drupal_base_url): void { $drupal_base_url = parse_url($drupal_base_url); @@ -487,7 +487,7 @@ public function serverGlobals($drupal_base_url) * @param $directory * @throws \Exception */ - protected function validateConfigDir(CommandData $commandData, $directory) + protected function validateConfigDir(CommandData $commandData, $directory): void { if (!file_exists($directory)) { throw new \Exception(dt('The config source directory @config does not exist.', ['@config' => $directory])); diff --git a/src/Commands/core/SshCommands.php b/src/Commands/core/SshCommands.php index 8144326c31..273fff2a6c 100644 --- a/src/Commands/core/SshCommands.php +++ b/src/Commands/core/SshCommands.php @@ -30,7 +30,7 @@ class SshCommands extends DrushCommands implements SiteAliasManagerAwareInterfac * @aliases ssh,site-ssh * @topics docs:aliases */ - public function ssh(array $code, $options = ['cd' => self::REQ, 'tty' => false]) + public function ssh(array $code, $options = ['cd' => self::REQ, 'tty' => false]): void { $alias = $this->siteAliasManager()->getSelf(); diff --git a/src/Commands/core/StatusCommands.php b/src/Commands/core/StatusCommands.php index 8fde7dfc39..e3c5a27ed0 100644 --- a/src/Commands/core/StatusCommands.php +++ b/src/Commands/core/StatusCommands.php @@ -75,10 +75,8 @@ class StatusCommands extends DrushCommands implements SiteAliasManagerAwareInter * @hidden-options project * @bootstrap max * @topics docs:readme - * - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList */ - public function status($filter = '', $options = ['project' => self::REQ, 'format' => 'table']) + public function status($filter = '', $options = ['project' => self::REQ, 'format' => 'table']): PropertyList { $data = $this->getPropertyList($options); @@ -88,7 +86,7 @@ public function status($filter = '', $options = ['project' => self::REQ, 'format return $result; } - public function getPropertyList($options) + public function getPropertyList($options): array { $boot_manager = Drush::bootstrapManager(); $boot_object = Drush::bootstrap(); @@ -180,7 +178,7 @@ public function renderStatusCell($key, $cellData, FormatterOptions $options) /** * @hook pre-command core-status */ - public function adjustStatusOptions(CommandData $commandData) + public function adjustStatusOptions(CommandData $commandData): void { $input = $commandData->input(); $args = $input->getArguments(); @@ -192,9 +190,8 @@ public function adjustStatusOptions(CommandData $commandData) /** * @param array $options * @param BootstrapManager $boot_manager - * @return array */ - public static function pathAliases(array $options, BootstrapManager $boot_manager, $boot) + public static function pathAliases(array $options, BootstrapManager $boot_manager, $boot): array { $paths = []; $site_wide = 'sites/all'; diff --git a/src/Commands/core/TopicCommands.php b/src/Commands/core/TopicCommands.php index 928eab8a07..29bf3a24b6 100644 --- a/src/Commands/core/TopicCommands.php +++ b/src/Commands/core/TopicCommands.php @@ -1,6 +1,7 @@ getArgument('topic_name'); @@ -66,7 +67,7 @@ public function interact(InputInterface $input, OutputInterface $output) /** * @hook validate topic */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $topic_name = $commandData->input()->getArgument('topic_name'); if (!in_array($topic_name, array_keys(self::getAllTopics()))) { @@ -79,14 +80,14 @@ public function validate(CommandData $commandData) * * @return Command[] */ - public static function getAllTopics() + public static function getAllTopics(): array { /** @var Application $application */ $application = Drush::getApplication(); $all = $application->all(); foreach ($all as $key => $command) { if ($command instanceof AnnotatedCommand) { - /** @var \Consolidation\AnnotatedCommand\AnnotationData $annotationData */ + /** @var AnnotationData $annotationData */ $annotationData = $command->getAnnotationData(); if ($annotationData->has('topic')) { $topics[$command->getName()] = $command; diff --git a/src/Commands/core/UpdateDBCommands.php b/src/Commands/core/UpdateDBCommands.php index 0621570eff..79cbd4edb4 100644 --- a/src/Commands/core/UpdateDBCommands.php +++ b/src/Commands/core/UpdateDBCommands.php @@ -35,7 +35,7 @@ class UpdateDBCommands extends DrushCommands implements SiteAliasManagerAwareInt * @kernel update * @aliases updb */ - public function updatedb($options = ['cache-clear' => true, 'entity-updates' => false, 'post-updates' => true]) + public function updatedb($options = ['cache-clear' => true, 'entity-updates' => false, 'post-updates' => true]): int { $this->cache_clear = $options['cache-clear']; require_once DRUPAL_ROOT . '/core/includes/install.inc'; @@ -103,7 +103,7 @@ public function updatedb($options = ['cache-clear' => true, 'entity-updates' => * Use updatedb:status to detect pending updates. * */ - public function entityUpdates($options = ['cache-clear' => true]) + public function entityUpdates($options = ['cache-clear' => true]): void { if ($this->getConfig()->simulate()) { throw new \Exception(dt('entity-updates command does not support --simulate option.')); @@ -142,7 +142,7 @@ public function entityUpdates($options = ['cache-clear' => true]) * type: Type * @default-fields module,update_id,type,description * @filter-default-field type - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields */ public function updatedbStatus($options = ['format'=> 'table', 'entity-updates' => true, 'post-updates' => true]) { @@ -164,10 +164,8 @@ public function updatedbStatus($options = ['format'=> 'table', 'entity-updates' * @bootstrap full * @kernel update * @hidden - * - * @return \Consolidation\OutputFormatters\StructuredData\UnstructuredListData */ - public function process($batch_id, $options = ['format' => 'json']) + public function process(string $batch_id, $options = ['format' => 'json']): UnstructuredListData { $result = drush_batch_command($batch_id); return new UnstructuredListData($result); @@ -195,7 +193,7 @@ public function process($batch_id, $options = ['format' => 'json']) * @param DrushBatchContext $context * The batch context object. */ - public static function updateDoOne($module, $number, array $dependency_map, DrushBatchContext $context) + public static function updateDoOne(string $module, int $number, array $dependency_map, DrushBatchContext $context): void { $function = $module . '_update_' . $number; @@ -289,10 +287,9 @@ public static function updateDoOne($module, $number, array $dependency_map, Drus * * @param string $function * The post-update function to execute. - * @param DrushBatchContext $context * The batch context object. */ - public static function updateDoOnePostUpdate($function, DrushBatchContext $context) + public static function updateDoOnePostUpdate(string $function, DrushBatchContext $context): void { $ret = []; @@ -375,10 +372,8 @@ public static function updateDoOnePostUpdate($function, DrushBatchContext $conte * Batch finished callback. * * @param boolean $success Whether the batch ended without a fatal error. - * @param array $results - * @param array $operations */ - public function updateFinished($success, $results, $operations) + public function updateFinished(bool $success, array $results, array $operations): void { if ($this->cache_clear) { // Flush all caches at the end of the batch operation. When Drupal @@ -392,9 +387,8 @@ public function updateFinished($success, $results, $operations) /** * Start the database update batch process. * @param $options - * @return bool */ - public function updateBatch($options) + public function updateBatch($options): bool { $start = $this->getUpdateList(); // Resolve any update dependencies to determine the actual updates that will @@ -485,7 +479,7 @@ public function updateBatch($options) return $success; } - public static function restoreMaintMode($status) + public static function restoreMaintMode($status): void { \Drupal::service('state')->set('system.maintenance_mode', $status); } @@ -493,7 +487,7 @@ public static function restoreMaintMode($status) /** * Apply entity schema updates. */ - public function updateEntityDefinitions(&$context) + public function updateEntityDefinitions(&$context): void { try { \Drupal::entityDefinitionUpdateManager()->applyupdates(); @@ -511,7 +505,7 @@ public function updateEntityDefinitions(&$context) } // Copy of protected \Drupal\system\Controller\DbUpdateController::getModuleUpdates. - public function getUpdateList() + public function getUpdateList(): array { $return = []; $updates = update_get_update_list(); @@ -535,7 +529,7 @@ public function getUpdateList() * * @see \Drupal\system\Controller\DbUpdateController::triggerBatch() */ - public static function cacheRebuild() + public static function cacheRebuild(): void { drupal_flush_all_caches(); \Drupal::service('kernel')->rebuildContainer(); @@ -551,7 +545,7 @@ public static function cacheRebuild() * - an array where each item is a 4 item associative array describing a pending update. * - an array listing the first update to run, keyed by module. */ - public function getUpdatedbStatus(array $options) + public function getUpdatedbStatus(array $options): array { require_once DRUPAL_ROOT . '/core/includes/update.inc'; $pending = \update_get_update_list(); @@ -618,7 +612,7 @@ public function getUpdatedbStatus(array $options) /** * Apply pending entity schema updates. */ - public function entityUpdatesMain() + public function entityUpdatesMain(): void { $change_summary = \Drupal::entityDefinitionUpdateManager()->getChangeSummary(); if (!empty($change_summary)) { @@ -660,7 +654,7 @@ public function entityUpdatesMain() /** * Log messages for any requirements warnings/errors. */ - public function updateCheckRequirements() + public function updateCheckRequirements(): bool { $return = true; diff --git a/src/Commands/core/XhprofCommands.php b/src/Commands/core/XhprofCommands.php index 6e3adb8d1c..80dff899af 100644 --- a/src/Commands/core/XhprofCommands.php +++ b/src/Commands/core/XhprofCommands.php @@ -37,7 +37,7 @@ class XhprofCommands extends DrushCommands * * @option xh-link URL to your XHProf report site. */ - public function optionsetXhProf($options = ['xh-link' => self::REQ]) + public function optionsetXhProf($options = ['xh-link' => self::REQ]): void { } @@ -46,7 +46,7 @@ public function optionsetXhProf($options = ['xh-link' => self::REQ]) * * @hook post-command * */ - public function xhprofPost($result, CommandData $commandData) + public function xhprofPost($result, CommandData $commandData): void { $config = $this->getConfig(); if (self::xhprofIsEnabled($config)) { @@ -62,7 +62,7 @@ public function xhprofPost($result, CommandData $commandData) * * @hook init * */ - public function xhprofInitialize(InputInterface $input, AnnotationData $annotationData) + public function xhprofInitialize(InputInterface $input, AnnotationData $annotationData): void { $config = $this->getConfig(); if (self::xhprofIsEnabled($config)) { @@ -74,15 +74,14 @@ public function xhprofInitialize(InputInterface $input, AnnotationData $annotati /** * Determines if any profiler could be enabled. * - * @param \Drush\Config\DrushConfig $config + * @param DrushConfig $config * - * @return bool * TRUE when xh.link configured, FALSE otherwise. * * @throws \Exception * When no available profiler extension enabled. */ - public static function xhprofIsEnabled(DrushConfig $config) + public static function xhprofIsEnabled(DrushConfig $config): bool { if (!$config->get('xh.link')) { return false; @@ -100,7 +99,7 @@ public static function xhprofIsEnabled(DrushConfig $config) /** * Determines flags. */ - public static function xhprofFlags(DrushConfig $config) + public static function xhprofFlags(DrushConfig $config): int { if (extension_loaded('tideways_xhprof')) { $map = [ @@ -132,7 +131,7 @@ public static function xhprofFlags(DrushConfig $config) /** * Enable profiling. */ - public static function xhprofEnable($flags) + public static function xhprofEnable($flags): void { if (extension_loaded('tideways_xhprof')) { \tideways_xhprof_enable($flags); diff --git a/src/Commands/generate/ApplicationFactory.php b/src/Commands/generate/ApplicationFactory.php index 330b5e1631..f67963ce98 100644 --- a/src/Commands/generate/ApplicationFactory.php +++ b/src/Commands/generate/ApplicationFactory.php @@ -29,7 +29,7 @@ class ApplicationFactory implements AutoloaderAwareInterface use AutoloaderAwareTrait; /** - * @var \Psr\Log\LoggerInterface + * @var LoggerInterface */ protected $logger; @@ -41,7 +41,7 @@ public function __construct(LoggerInterface $logger, $config) $this->config = $config; } - public function logger() + public function logger(): LoggerInterface { return $this->logger; } @@ -124,7 +124,7 @@ function ($generator) { return $generators; } - protected function discoverGlobalPathsDeprecated() + protected function discoverGlobalPathsDeprecated(): array { $config_paths = $this->getConfig()->get('runtime.commandfile.paths', []); foreach ($config_paths as $path) { @@ -134,7 +134,7 @@ protected function discoverGlobalPathsDeprecated() return array_filter($global_paths, 'file_exists'); } - protected function discoverPsr4Generators() + protected function discoverPsr4Generators(): array { $classes = (new RelativeNamespaceDiscovery($this->autoloader())) ->setRelativeNamespace('Drush\Generators') diff --git a/src/Commands/generate/GenerateCommands.php b/src/Commands/generate/GenerateCommands.php index 94b2983897..db02125df0 100644 --- a/src/Commands/generate/GenerateCommands.php +++ b/src/Commands/generate/GenerateCommands.php @@ -40,10 +40,8 @@ class GenerateCommands extends DrushCommands implements AutoloaderAwareInterface * Learn all the potential answers so you can re-run with several --answer options. * @topics docs:generators * @bootstrap max - * - * @return int */ - public function generate($generator = '', $options = ['answer' => [], 'destination' => self::REQ, 'dry-run' => false]) + public function generate(string $generator = '', $options = ['answer' => [], 'destination' => self::REQ, 'dry-run' => false]): int { // Disallow default Symfony console commands. if ($generator == 'help' || $generator == 'list') { diff --git a/src/Commands/help/DrushHelpDocument.php b/src/Commands/help/DrushHelpDocument.php index 1d28c42e53..8bd2fc0a61 100644 --- a/src/Commands/help/DrushHelpDocument.php +++ b/src/Commands/help/DrushHelpDocument.php @@ -11,7 +11,7 @@ class DrushHelpDocument extends HelpDocument /** * @inheritdoc */ - public function generateBaseHelpDom(Command $command) + public function generateBaseHelpDom(Command $command): \DomDocument { // Global options should not appear in our help output. $command->setApplication(null); @@ -19,7 +19,7 @@ public function generateBaseHelpDom(Command $command) return parent::generateBaseHelpDom($command); } - protected function alterHelpDocument(Command $command, \DomDocument $dom) + protected function alterHelpDocument(Command $command, \DomDocument $dom): \DomDocument { return parent::alterHelpDocument($command, $dom); } diff --git a/src/Commands/help/HelpCLIFormatter.php b/src/Commands/help/HelpCLIFormatter.php index 2b9d686b82..e272dd9455 100644 --- a/src/Commands/help/HelpCLIFormatter.php +++ b/src/Commands/help/HelpCLIFormatter.php @@ -17,7 +17,7 @@ class HelpCLIFormatter implements FormatterInterface /** * @inheritdoc */ - public function write(OutputInterface $output, $data, FormatterOptions $options) + public function write(OutputInterface $output, $data, FormatterOptions $options): void { $formatterManager = new FormatterManager(); @@ -82,11 +82,7 @@ public function write(OutputInterface $output, $data, FormatterOptions $options) } } - /** - * @param iterable $option - * @return string - */ - public static function formatOptionKeys($option) + public static function formatOptionKeys(iterable $option): string { // Remove leading dashes. $option['name'] = substr($option['name'], 2); @@ -108,7 +104,7 @@ public static function formatOptionKeys($option) return $synopsis; } - public static function formatOptionDescription($option) + public static function formatOptionDescription($option): string { $defaults = ''; if (array_key_exists('defaults', $option)) { @@ -138,7 +134,7 @@ public static function formatArgumentName($argument) return $element; } - protected function cleanOptions(&$data) + protected function cleanOptions(&$data): void { if (array_key_exists('options', $data)) { foreach ($data['options'] as $key => $option) { @@ -149,7 +145,7 @@ protected function cleanOptions(&$data) } } - public static function isGlobalOption($name) + public static function isGlobalOption($name): bool { $application = Drush::getApplication(); $def = $application->getDefinition(); diff --git a/src/Commands/help/HelpCommands.php b/src/Commands/help/HelpCommands.php index 46eb304ca8..a10869f308 100644 --- a/src/Commands/help/HelpCommands.php +++ b/src/Commands/help/HelpCommands.php @@ -24,10 +24,8 @@ class HelpCommands extends DrushCommands * All available commands, in JSON format. * @bootstrap max * @topics docs:readme - * - * @return \Consolidation\AnnotatedCommand\Help\HelpDocument */ - public function help($command_name = '', $options = ['format' => 'helpcli', 'include-field-labels' => false, 'table-style' => 'compact']) + public function help($command_name = '', $options = ['format' => 'helpcli', 'include-field-labels' => false, 'table-style' => 'compact']): DrushHelpDocument { $application = Drush::getApplication(); $command = $application->get($command_name); @@ -47,7 +45,7 @@ public function help($command_name = '', $options = ['format' => 'helpcli', 'inc /** * @hook validate help */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $name = $commandData->input()->getArgument('command_name'); if (empty($name)) { diff --git a/src/Commands/help/ListCommands.php b/src/Commands/help/ListCommands.php index 98a7d34def..64a1aa7db9 100644 --- a/src/Commands/help/ListCommands.php +++ b/src/Commands/help/ListCommands.php @@ -1,6 +1,7 @@ 'listcli', 'raw' => false, 'fil /** * @param $namespaced * @param $application - * @return \DOMDocument */ - public function buildDom($namespaced, $application) + public function buildDom($namespaced, $application): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); $rootXml = $dom->createElement('symfony'); @@ -118,13 +118,7 @@ public function buildDom($namespaced, $application) return $dom; } - /** - * @param \Symfony\Component\Console\Application $application - * @param array $namespaced - * @param OutputInterface $output - * @param string $preamble - */ - public static function renderListCLI($application, $namespaced, $output, $preamble) + public static function renderListCLI(Application $application, array $namespaced, OutputInterface $output, string $preamble): void { $output->writeln($application->getHelp()); $output->writeln(''); @@ -163,16 +157,13 @@ function ($aliasName) use ($name) { $formatterManager->write($output, 'table', new RowsOfFields($rows), $formatterOptions); } - public static function getTerminalWidth() + public static function getTerminalWidth(): int { $term = new Terminal(); return $term->getWidth(); } - /** - * @param array $namespaced - */ - public function renderListRaw($namespaced) + public function renderListRaw(array $namespaced): void { $table = new Table($this->output()); $table->setStyle('compact'); @@ -186,11 +177,10 @@ public function renderListRaw($namespaced) /** * @param Command[] $all - * @param string $separator * * @return Command[] */ - public static function categorize($all, $separator = ':') + public static function categorize(array $all, string $separator = ':'): array { foreach ($all as $key => $command) { if (!in_array($key, $command->getAliases()) && !$command->isHidden()) { diff --git a/src/Commands/pm/SecurityUpdateCommands.php b/src/Commands/pm/SecurityUpdateCommands.php index 56e80a0738..f08c2a7eed 100644 --- a/src/Commands/pm/SecurityUpdateCommands.php +++ b/src/Commands/pm/SecurityUpdateCommands.php @@ -1,6 +1,7 @@ false]) /** * Emit suggested Composer command for security updates. */ - public function suggestComposerCommand($updates) + public function suggestComposerCommand($updates): void { $suggested_command = 'composer require '; foreach ($updates as $package) { @@ -101,7 +102,7 @@ public function suggestComposerCommand($updates) protected function fetchAdvisoryComposerJson() { // We use the v2 branch for now, as per https://github.com/drupal-composer/drupal-security-advisories/pull/11. - $client = new \GuzzleHttp\Client(['handler' => $this->getStack()]); + $client = new Client(['handler' => $this->getStack()]); $response = $client->get('https://raw.githubusercontent.com/drupal-composer/drupal-security-advisories/8.x-v2/composer.json'); $security_advisories_composer_json = json_decode($response->getBody(), true); return $security_advisories_composer_json; @@ -110,11 +111,10 @@ protected function fetchAdvisoryComposerJson() /** * Loads the contents of the local Drupal application's composer.lock file. * - * @return array * * @throws \Exception */ - protected function loadSiteComposerLock() + protected function loadSiteComposerLock(): array { $composer_lock_file_path = self::composerLockPath(); $composer_lock_contents = file_get_contents($composer_lock_file_path); @@ -132,10 +132,8 @@ protected function loadSiteComposerLock() * The contents of the local Drupal application's composer.lock file. * @param array $security_advisories_composer_json * The composer.json array from drupal-security-advisories. - * - * @return array */ - protected function calculateSecurityUpdates($composer_lock_data, $security_advisories_composer_json, bool $excludeDev = false) + protected function calculateSecurityUpdates(array $composer_lock_data, array $security_advisories_composer_json, bool $excludeDev = false): array { $updates = []; $packages = $composer_lock_data['packages']; @@ -176,7 +174,7 @@ protected function calculateSecurityUpdates($composer_lock_data, $security_advis * @usage HTTP_PROXY=tcp://localhost:8125 pm:security * Proxy Guzzle requests through an http proxy. */ - public function securityPhp($options = ['format' => 'yaml', 'no-dev' => false]) + public function securityPhp(array $options = ['format' => 'yaml', 'no-dev' => false]) { $result = (new SecurityChecker())->check(self::composerLockPath(), $options['no-dev']); if ($result) { diff --git a/src/Commands/sql/SqlCommands.php b/src/Commands/sql/SqlCommands.php index 43179b4e22..3f468dd484 100644 --- a/src/Commands/sql/SqlCommands.php +++ b/src/Commands/sql/SqlCommands.php @@ -29,7 +29,7 @@ class SqlCommands extends DrushCommands implements StdinAwareInterface * @bootstrap max configuration * @hidden */ - public function conf($options = ['format' => 'yaml', 'all' => false, 'show-passwords' => false]) + public function conf($options = ['format' => 'yaml', 'all' => false, 'show-passwords' => false]): ?array { if ($options['all']) { $return = Database::getAllConnectionInfo(); @@ -63,7 +63,7 @@ public function conf($options = ['format' => 'yaml', 'all' => false, 'show-passw * @usage eval (drush sql-connect) < example.sql * Fish: Import SQL statements from a file into the current database. */ - public function connect($options = ['extra' => self::REQ]) + public function connect($options = ['extra' => self::REQ]): string { $sql = SqlBase::create($options); return $sql->connect(false); @@ -85,7 +85,7 @@ public function connect($options = ['extra' => self::REQ]) * Create the database as specified in the db-url option. * @bootstrap max configuration */ - public function create($options = ['db-su' => self::REQ, 'db-su-pw' => self::REQ]) + public function create($options = ['db-su' => self::REQ, 'db-su-pw' => self::REQ]): void { $sql = SqlBase::create($options); $db_spec = $sql->getDbSpec(); @@ -113,7 +113,7 @@ public function create($options = ['db-su' => self::REQ, 'db-su-pw' => self::REQ * @bootstrap max configuration * @topics docs:policy */ - public function drop($options = []) + public function drop($options = []): void { $sql = SqlBase::create($options); $db_spec = $sql->getDbSpec(); @@ -142,7 +142,7 @@ public function drop($options = []) * @remote-tty * @bootstrap max configuration */ - public function cli(InputInterface $input, $options = ['extra' => self::REQ]) + public function cli(InputInterface $input, $options = ['extra' => self::REQ]): void { $sql = SqlBase::create($options); $process = $this->processManager()->shell($sql->connect(), null, $sql->getEnv()); @@ -180,7 +180,7 @@ public function cli(InputInterface $input, $options = ['extra' => self::REQ]) * @bootstrap max configuration * */ - public function query($query = '', $options = ['result-file' => null, 'file' => self::REQ, 'file-delete' => false, 'extra' => self::REQ, 'db-prefix' => false]) + public function query($query = '', $options = ['result-file' => null, 'file' => self::REQ, 'file-delete' => false, 'extra' => self::REQ, 'db-prefix' => false]): bool { $filename = $options['file']; // Enable prefix processing when db-prefix option is used. @@ -229,12 +229,11 @@ public function query($query = '', $options = ['result-file' => null, 'file' => * @field-labels * path: Path * - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList * * @notes * --createdb is used by sql-sync, since including the DROP TABLE statements interferes with the import when the database is created. */ - public function dump($options = ['result-file' => self::REQ, 'create-db' => false, 'data-only' => false, 'ordered-dump' => false, 'gzip' => false, 'extra' => self::REQ, 'extra-dump' => self::REQ, 'format' => 'null']) + public function dump($options = ['result-file' => self::REQ, 'create-db' => false, 'data-only' => false, 'ordered-dump' => false, 'gzip' => false, 'extra' => self::REQ, 'extra-dump' => self::REQ, 'format' => 'null']): PropertyList { $sql = SqlBase::create($options); $return = $sql->dump(); diff --git a/src/Commands/sql/SqlSyncCommands.php b/src/Commands/sql/SqlSyncCommands.php index 265a6efa5a..b1000ac610 100644 --- a/src/Commands/sql/SqlSyncCommands.php +++ b/src/Commands/sql/SqlSyncCommands.php @@ -40,7 +40,7 @@ class SqlSyncCommands extends DrushCommands implements SiteAliasManagerAwareInte * @topics docs:aliases,docs:policy,docs:configuration,docs:example-sync-via-http * @throws \Exception */ - public function sqlsync($source, $target, $options = ['no-dump' => false, 'no-sync' => false, 'runner' => self::REQ, 'create-db' => false, 'db-su' => self::REQ, 'db-su-pw' => self::REQ, 'target-dump' => self::REQ, 'source-dump' => self::OPT, 'extra-dump' => self::REQ]) + public function sqlsync($source, $target, $options = ['no-dump' => false, 'no-sync' => false, 'runner' => self::REQ, 'create-db' => false, 'db-su' => self::REQ, 'db-su-pw' => self::REQ, 'target-dump' => self::REQ, 'source-dump' => self::OPT, 'extra-dump' => self::REQ]): void { $manager = $this->siteAliasManager(); $sourceRecord = $manager->get($source); @@ -67,7 +67,7 @@ public function sqlsync($source, $target, $options = ['no-dump' => false, 'no-sy * @hook validate sql-sync * @throws \Exception */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $source = $commandData->input()->getArgument('source'); $target = $commandData->input()->getArgument('target'); @@ -107,7 +107,7 @@ public function validate(CommandData $commandData) } } - public function databaseName(SiteAlias $record) + public function databaseName(SiteAlias $record): string { if ($this->processManager()->hasTransport($record) && $this->getConfig()->simulate()) { return 'simulated_db'; @@ -130,11 +130,10 @@ public function databaseName(SiteAlias $record) * @param $global_options * @param $sourceRecord * - * @return string * Path to the source dump file. * @throws \Exception */ - public function dump($options, $global_options, $sourceRecord) + public function dump($options, $global_options, $sourceRecord): string { $dump_options = $global_options + [ 'gzip' => true, @@ -172,14 +171,11 @@ public function dump($options, $global_options, $sourceRecord) /** * @param array $options - * @param SiteAlias $sourceRecord - * @param SiteAlias $targetRecord * @param $source_dump_path - * @return string * Path to the target file. * @throws \Exception */ - public function rsync($options, SiteAlias $sourceRecord, SiteAlias $targetRecord, $source_dump_path) + public function rsync(array $options, SiteAlias $sourceRecord, SiteAlias $targetRecord, $source_dump_path): string { $do_rsync = !$options['no-sync']; // Determine path/to/dump on target. @@ -230,7 +226,7 @@ public function rsync($options, SiteAlias $sourceRecord, SiteAlias $targetRecord * @param $target_dump_path * @param $targetRecord */ - public function import($global_options, $target_dump_path, $targetRecord) + public function import($global_options, $target_dump_path, $targetRecord): void { $this->logger()->notice(dt('Starting to import dump file onto target database.')); $query_options = $global_options + [ diff --git a/src/Drupal/Commands/config/ConfigCommands.php b/src/Drupal/Commands/config/ConfigCommands.php index ac9f78a6c6..10e1342567 100644 --- a/src/Drupal/Commands/config/ConfigCommands.php +++ b/src/Drupal/Commands/config/ConfigCommands.php @@ -1,6 +1,7 @@ configFactory; } @@ -58,7 +56,7 @@ public function getConfigFactory() /** * ConfigCommands constructor. * @param ConfigFactoryInterface $configFactory - * @param \Drupal\Core\Config\StorageInterface $configStorage + * @param StorageInterface $configStorage */ public function __construct($configFactory, StorageInterface $configStorage) { @@ -68,9 +66,9 @@ public function __construct($configFactory, StorageInterface $configStorage) } /** - * @param \Drupal\Core\Config\StorageInterface $exportStorage + * @param StorageInterface $exportStorage */ - public function setExportStorage(StorageInterface $exportStorage) + public function setExportStorage(StorageInterface $exportStorage): void { $this->configStorageExport = $exportStorage; } @@ -86,26 +84,17 @@ public function getConfigStorageExport() return $this->configStorage; } - /** - * @param \Drupal\Core\Config\ImportStorageTransformer $importStorageTransformer - */ - public function setImportTransformer($importStorageTransformer) + public function setImportTransformer(ImportStorageTransformer $importStorageTransformer): void { $this->importStorageTransformer = $importStorageTransformer; } - /** - * @return bool - */ - public function hasImportTransformer() + public function hasImportTransformer(): bool { return isset($this->importStorageTransformer); } - /** - * @return \Drupal\Core\Config\ImportStorageTransformer - */ - public function getImportTransformer() + public function getImportTransformer(): ImportStorageTransformer { return $this->importStorageTransformer; } @@ -224,7 +213,7 @@ public function set($config_name, $key, $value = null, $options = ['input-format * @aliases cedit,config-edit * @validate-module-enabled config */ - public function edit($config_name, $options = []) + public function edit($config_name, $options = []): void { $config = $this->getConfigFactory()->get($config_name); $active_storage = $config->getStorage(); @@ -266,7 +255,7 @@ public function edit($config_name, $options = []) * Delete the 'page.front' key from the system.site object. * @aliases cdel,config-delete */ - public function delete($config_name, $key = null) + public function delete($config_name, $key = null): void { $config = $this->getConfigFactory()->getEditable($config_name); if ($key) { @@ -301,9 +290,8 @@ public function delete($config_name, $key = null) * @default-fields name,state * @aliases cst,config-status * @filter-default-field name - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function status($options = ['state' => 'Only in DB,Only in sync dir,Different', 'prefix' => self::REQ]) + public function status($options = ['state' => 'Only in DB,Only in sync dir,Different', 'prefix' => self::REQ]): ?RowsOfFields { $config_list = array_fill_keys( $this->configFactory->listAll($options['prefix']), @@ -380,7 +368,7 @@ public function status($options = ['state' => 'Only in DB,Only in sync dir,Diffe * @param string $directory * A configuration directory. */ - public static function getDirectory($directory = null) + public static function getDirectory($directory = null): string { $return = null; // If the user provided a directory, use it. @@ -403,7 +391,7 @@ public static function getDirectory($directory = null) /** * Returns the difference in configuration between active storage and target storage. */ - public function getChanges($target_storage) + public function getChanges($target_storage): array { if ($this->hasImportTransformer()) { $target_storage = $this->getImportTransformer()->transform($target_storage); @@ -440,7 +428,7 @@ public function getStorage($directory) * * @return Table A Symfony table object. */ - public static function configChangesTable(array $config_changes, OutputInterface $output, $use_color = true) + public static function configChangesTable(array $config_changes, OutputInterface $output, $use_color = true): Table { $rows = []; foreach ($config_changes as $collection => $changes) { @@ -483,7 +471,7 @@ public static function configChangesTable(array $config_changes, OutputInterface /** * @hook interact @interact-config-name */ - public function interactConfigName($input, $output) + public function interactConfigName($input, $output): void { if (empty($input->getArgument('config_name'))) { $config_names = $this->getConfigFactory()->listAll(); @@ -499,8 +487,8 @@ public function interactConfigName($input, $output) * argument name as the value of the annotation. * * @hook validate @validate-config-name - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validateConfigName(CommandData $commandData) { @@ -522,7 +510,7 @@ public function validateConfigName(CommandData $commandData) * The destination config storage service. * @throws \Exception */ - public static function copyConfig(StorageInterface $source, StorageInterface $destination) + public static function copyConfig(StorageInterface $source, StorageInterface $destination): void { // Make sure the source and destination are on the default collection. if ($source->getCollectionName() != StorageInterface::DEFAULT_COLLECTION) { @@ -560,7 +548,7 @@ public static function copyConfig(StorageInterface $source, StorageInterface $de * @return array|bool * An array of strings containing the diff. */ - public static function getDiff(StorageInterface $destination_storage, StorageInterface $source_storage, OutputInterface $output) + public static function getDiff(StorageInterface $destination_storage, StorageInterface $source_storage, OutputInterface $output): string { // Copy active storage to a temporary directory. $temp_destination_dir = drush_tempdir(); diff --git a/src/Drupal/Commands/config/ConfigExportCommands.php b/src/Drupal/Commands/config/ConfigExportCommands.php index f9b175c145..00eda1d17f 100644 --- a/src/Drupal/Commands/config/ConfigExportCommands.php +++ b/src/Drupal/Commands/config/ConfigExportCommands.php @@ -35,26 +35,20 @@ class ConfigExportCommands extends DrushCommands */ protected $configStorageExport; - /** - * @return ConfigManagerInterface - */ - public function getConfigManager() + public function getConfigManager(): ConfigManagerInterface { return $this->configManager; } /** - * @param \Drupal\Core\Config\StorageInterface $exportStorage + * @param StorageInterface $exportStorage */ - public function setExportStorage(StorageInterface $exportStorage) + public function setExportStorage(StorageInterface $exportStorage): void { $this->configStorageExport = $exportStorage; } - /** - * @return StorageInterface - */ - public function getConfigStorageExport() + public function getConfigStorageExport(): StorageInterface { if (isset($this->configStorageExport)) { return $this->configStorageExport; @@ -62,19 +56,13 @@ public function getConfigStorageExport() return $this->configStorage; } - /** - * @return StorageInterface - */ - public function getConfigStorage() + public function getConfigStorage(): StorageInterface { // @todo: deprecate this method. return $this->getConfigStorageExport(); } - /** - * @return StorageInterface - */ - public function getConfigStorageSync() + public function getConfigStorageSync(): StorageInterface { return $this->configStorageSync; } @@ -107,7 +95,7 @@ public function __construct(ConfigManagerInterface $configManager, StorageInterf * Export configuration; Save files in a backup directory named config-export. * @aliases cex,config-export */ - public function export($options = ['add' => false, 'commit' => false, 'message' => self::REQ, 'destination' => self::OPT, 'diff' => false, 'format' => null]) + public function export($options = ['add' => false, 'commit' => false, 'message' => self::REQ, 'destination' => self::OPT, 'diff' => false, 'format' => null]): array { // Get destination directory. $destination_dir = ConfigCommands::getDirectory($options['destination']); @@ -177,7 +165,7 @@ public function doExport($options, $destination_dir) return isset($preview) ? $preview : 'No existing configuration to diff against.'; } - public function doAddCommit($options, $destination_dir, $preview) + public function doAddCommit($options, $destination_dir, $preview): void { // Commit or add exported configuration if requested. if ($options['commit']) { @@ -200,9 +188,9 @@ public function doAddCommit($options, $destination_dir, $preview) /** * @hook validate config-export - * @param \Consolidation\AnnotatedCommand\CommandData $commandData + * @param CommandData $commandData */ - public function validate(CommandData $commandData) + public function validate(CommandData $commandData): void { $destination = $commandData->input()->getOption('destination'); diff --git a/src/Drupal/Commands/config/ConfigImportCommands.php b/src/Drupal/Commands/config/ConfigImportCommands.php index e81000c6b6..8b60ca7801 100644 --- a/src/Drupal/Commands/config/ConfigImportCommands.php +++ b/src/Drupal/Commands/config/ConfigImportCommands.php @@ -1,6 +1,9 @@ configManager; } - /** - * @return StorageInterface - */ - public function getConfigStorage() + public function getConfigStorage(): StorageInterface { return $this->configStorage; } - /** - * @return StorageInterface - */ - public function getConfigStorageSync() + public function getConfigStorageSync(): StorageInterface { return $this->configStorageSync; } - /** - * @return \Drupal\Core\Cache\CacheBackendInterface - */ - public function getConfigCache() + public function getConfigCache(): CacheBackendInterface { return $this->configCache; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } /** * Note that type hint is changing https://www.drupal.org/project/drupal/issues/3161983 - * - * @return \Symfony\Component\EventDispatcher\EventDispatcherInterface */ - public function getEventDispatcher() + public function getEventDispatcher(): EventDispatcherInterface { return $this->eventDispatcher; } - /** - * @return \Drupal\Core\Lock\LockBackendInterface - */ - public function getLock() + public function getLock(): LockBackendInterface { return $this->lock; } - /** - * @return \Drupal\Core\Config\TypedConfigManagerInterface - */ - public function getConfigTyped() + public function getConfigTyped(): TypedConfigManagerInterface { return $this->configTyped; } - /** - * @return \Drupal\Core\Extension\ModuleInstallerInterface - */ - public function getModuleInstaller() + public function getModuleInstaller(): ModuleInstallerInterface { return $this->moduleInstaller; } - /** - * @return \Drupal\Core\Extension\ThemeHandlerInterface - */ - public function getThemeHandler() + public function getThemeHandler(): ThemeHandlerInterface { return $this->themeHandler; } - /** - * @return \Drupal\Core\StringTranslation\TranslationInterface - */ - public function getStringTranslation() + public function getStringTranslation(): TranslationInterface { return $this->stringTranslation; } - /** - * @param \Drupal\Core\Config\ImportStorageTransformer $importStorageTransformer - */ - public function setImportTransformer($importStorageTransformer) + public function setImportTransformer(ImportStorageTransformer $importStorageTransformer): void { $this->importStorageTransformer = $importStorageTransformer; } - /** - * @return bool - */ - public function hasImportTransformer() + public function hasImportTransformer(): bool { return isset($this->importStorageTransformer); } - /** - * @return \Drupal\Core\Config\ImportStorageTransformer - */ - public function getImportTransformer() + public function getImportTransformer(): ?ImportStorageTransformer { return $this->importStorageTransformer; } /** - * @return \Drupal\Core\Extension\ModuleExtensionList + * @return ModuleExtensionList */ - public function getModuleExtensionList(): \Drupal\Core\Extension\ModuleExtensionList + public function getModuleExtensionList(): ModuleExtensionList { return $this->moduleExtensionList; } @@ -189,15 +151,15 @@ public function getModuleExtensionList(): \Drupal\Core\Extension\ModuleExtension * @param ConfigManagerInterface $configManager * @param StorageInterface $configStorage * @param StorageInterface $configStorageSync - * @param \Drupal\Core\Cache\CacheBackendInterface $configCache - * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler + * @param CacheBackendInterface $configCache + * @param ModuleHandlerInterface $moduleHandler * @param $eventDispatcher - * @param \Drupal\Core\Lock\LockBackendInterface $lock - * @param \Drupal\Core\Config\TypedConfigManagerInterface $configTyped - * @param \Drupal\Core\Extension\ModuleInstallerInterface $moduleInstaller - * @param \Drupal\Core\Extension\ThemeHandlerInterface $themeHandler - * @param \Drupal\Core\StringTranslation\TranslationInterface $stringTranslation - * @param \Drupal\Core\Extension\ModuleExtensionList $moduleExtensionList + * @param LockBackendInterface $lock + * @param TypedConfigManagerInterface $configTyped + * @param ModuleInstallerInterface $moduleInstaller + * @param ThemeHandlerInterface $themeHandler + * @param TranslationInterface $stringTranslation + * @param ModuleExtensionList $moduleExtensionList */ public function __construct( ConfigManagerInterface $configManager, @@ -234,7 +196,6 @@ public function __construct( * * @command config:import * - * @param array $options * * @return bool|void * @option diff Show preview as a diff. @@ -245,10 +206,10 @@ public function __construct( * @topics docs:deploy * @bootstrap full * - * @throws \Drupal\Core\Config\StorageTransformerException - * @throws \Drush\Exceptions\UserAbortException + * @throws StorageTransformerException + * @throws UserAbortException */ - public function import($options = ['preview' => 'list', 'source' => self::REQ, 'partial' => false, 'diff' => false]) + public function import(array $options = ['preview' => 'list', 'source' => self::REQ, 'partial' => false, 'diff' => false]) { // Determine source directory. $source_storage_dir = ConfigCommands::getDirectory($options['source']); @@ -306,7 +267,7 @@ public function import($options = ['preview' => 'list', 'source' => self::REQ, ' } // Copied from submitForm() at /core/modules/config/src/Form/ConfigSync.php - public function doImport($storage_comparer) + public function doImport($storage_comparer): void { $config_importer = new ConfigImporter( $storage_comparer, @@ -362,8 +323,8 @@ public function doImport($storage_comparer) /** * @hook validate config:import - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validate(CommandData $commandData) { diff --git a/src/Drupal/Commands/core/BatchCommands.php b/src/Drupal/Commands/core/BatchCommands.php index 01c625640d..fb0d1654fd 100644 --- a/src/Drupal/Commands/core/BatchCommands.php +++ b/src/Drupal/Commands/core/BatchCommands.php @@ -14,10 +14,8 @@ class BatchCommands extends DrushCommands * @aliases batch-process * @param $batch_id The batch id that will be processed. * @hidden - * - * @return \Consolidation\OutputFormatters\StructuredData\UnstructuredListData */ - public function process($batch_id, $options = ['format' => 'json']) + public function process($batch_id, $options = ['format' => 'json']): UnstructuredListData { $return = drush_batch_command($batch_id); return new UnstructuredListData($return); diff --git a/src/Drupal/Commands/core/CliCommands.php b/src/Drupal/Commands/core/CliCommands.php index f5e6156185..0ceea8d906 100644 --- a/src/Drupal/Commands/core/CliCommands.php +++ b/src/Drupal/Commands/core/CliCommands.php @@ -2,6 +2,7 @@ namespace Drush\Drupal\Commands\core; +use Consolidation\AnnotatedCommand\AnnotatedCommand; use Drush\Commands\DrushCommands; use Drush\Drush; use Drush\Psysh\DrushCommand; @@ -24,7 +25,7 @@ class CliCommands extends DrushCommands * @hidden * @topic ../../../../docs/repl.md */ - public function docs() + public function docs(): void { self::printFileTopic($this->commandData); } @@ -39,7 +40,7 @@ public function docs() * @topics docs:repl * @remote-tty */ - public function cli(array $options = ['version-history' => false, 'cwd' => self::REQ]) + public function cli(array $options = ['version-history' => false, 'cwd' => self::REQ]): void { $configuration = new Configuration(); @@ -99,10 +100,8 @@ public function cli(array $options = ['version-history' => false, 'cwd' => self: /** * Returns a filtered list of Drush commands used for CLI commands. - * - * @return array */ - protected function getDrushCommands() + protected function getDrushCommands(): array { $application = Drush::getApplication(); $commands = $application->all(); @@ -120,7 +119,7 @@ protected function getDrushCommands() ]; $php_keywords = $this->getPhpKeywords(); - /** @var \Consolidation\AnnotatedCommand\AnnotatedCommand $command */ + /** @var AnnotatedCommand $command */ foreach ($commands as $name => $command) { $definition = $command->getDefinition(); @@ -152,7 +151,7 @@ protected function getDrushCommands() * @return array. * An array of caster callbacks keyed by class or interface. */ - protected function getCasters() + protected function getCasters(): array { return [ 'Drupal\Core\Entity\ContentEntityInterface' => 'Drush\Psysh\Caster::castContentEntity', @@ -174,7 +173,7 @@ protected function getCasters() * * @return string. */ - protected function historyPath(array $options) + protected function historyPath(array $options): string { $cli_directory = Path::join($this->getConfig()->cache(), 'cli'); $drupal_major_version = Drush::getMajorVersion(); @@ -213,10 +212,8 @@ protected function historyPath(array $options) * Returns a list of PHP keywords. * * This will act as a blocklist for command and alias names. - * - * @return array */ - protected function getPhpKeywords() + protected function getPhpKeywords(): array { return [ '__halt_compiler', diff --git a/src/Drupal/Commands/core/DeployHookCommands.php b/src/Drupal/Commands/core/DeployHookCommands.php index c43690ad1e..c3e75ec2a3 100644 --- a/src/Drupal/Commands/core/DeployHookCommands.php +++ b/src/Drupal/Commands/core/DeployHookCommands.php @@ -21,10 +21,8 @@ class DeployHookCommands extends DrushCommands implements SiteAliasManagerAwareI /** * Get the deploy hook update registry. - * - * @return UpdateRegistry */ - public static function getRegistry() + public static function getRegistry(): UpdateRegistry { $registry = new class( \Drupal::service('app.root'), @@ -32,7 +30,7 @@ public static function getRegistry() array_keys(\Drupal::service('module_handler')->getModuleList()), \Drupal::service('keyvalue')->get('deploy_hook') ) extends UpdateRegistry { - public function setUpdateType($type) + public function setUpdateType(string $type): void { $this->updateType = $type; } @@ -58,9 +56,8 @@ public function setUpdateType($type) * @topics docs:deploy * * @filter-default-field hook - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function status() + public function status(): RowsOfFields { $updates = self::getRegistry()->getPendingUpdateInformation(); $rows = []; @@ -89,7 +86,7 @@ public function status() * @topics docs:deploy * @version 10.3 */ - public function run() + public function run(): int { $pending = self::getRegistry()->getPendingUpdateFunctions(); @@ -150,10 +147,8 @@ public function run() * @param string $batch_id The batch id that will be processed. * @bootstrap full * @hidden - * - * @return \Consolidation\OutputFormatters\StructuredData\UnstructuredListData */ - public function process($batch_id, $options = ['format' => 'json']) + public function process(string $batch_id, $options = ['format' => 'json']): UnstructuredListData { $result = drush_batch_command($batch_id); return new UnstructuredListData($result); @@ -164,10 +159,9 @@ public function process($batch_id, $options = ['format' => 'json']) * * @param string $function * The deploy-hook function to execute. - * @param DrushBatchContext $context * The batch context object. */ - public static function updateDoOneDeployHook($function, DrushBatchContext $context) + public static function updateDoOneDeployHook(string $function, DrushBatchContext $context): void { $ret = []; @@ -247,10 +241,8 @@ public static function updateDoOneDeployHook($function, DrushBatchContext $conte * Batch finished callback. * * @param boolean $success Whether the batch ended without a fatal error. - * @param array $results - * @param array $operations */ - public function updateFinished($success, $results, $operations) + public function updateFinished(bool $success, array $results, array $operations): void { // In theory there is nothing to do here. } @@ -265,7 +257,7 @@ public function updateFinished($success, $results, $operations) * @topics docs:deploy * @version 10.6.1 */ - public function markComplete() + public function markComplete(): int { $pending = self::getRegistry()->getPendingUpdateFunctions(); self::getRegistry()->registerInvokedUpdates($pending); diff --git a/src/Drupal/Commands/core/DrupalCommands.php b/src/Drupal/Commands/core/DrupalCommands.php index db7a3a2286..de111ac08c 100644 --- a/src/Drupal/Commands/core/DrupalCommands.php +++ b/src/Drupal/Commands/core/DrupalCommands.php @@ -14,46 +14,37 @@ class DrupalCommands extends DrushCommands { /** - * @var \Drupal\Core\CronInterface + * @var CronInterface */ protected $cron; /** - * @var \Drupal\Core\Extension\ModuleHandlerInterface + * @var ModuleHandlerInterface */ protected $moduleHandler; /** - * @var \Drupal\Core\Routing\RouteProviderInterface + * @var RouteProviderInterface */ protected $routeProvider; - /** - * @return \Drupal\Core\CronInterface - */ - public function getCron() + public function getCron(): CronInterface { return $this->cron; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } - /** - * @return \Drupal\Core\Routing\RouteProviderInterface - */ - public function getRouteProvider() + public function getRouteProvider(): RouteProviderInterface { return $this->routeProvider; } /** - * @param \Drupal\Core\CronInterface $cron + * @param CronInterface $cron * @param ModuleHandlerInterface $moduleHandler * @param RouteProviderInterface $routeProvider */ @@ -71,7 +62,7 @@ public function __construct(CronInterface $cron, ModuleHandlerInterface $moduleH * @aliases cron,core-cron * @topics docs:cron */ - public function cron() + public function cron(): void { $this->getCron()->run(); } @@ -96,9 +87,8 @@ public function cron() * value: Summary * @default-fields title,severity,value * @filter-default-field severity - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function requirements($options = ['format' => 'table', 'severity' => -1, 'ignore' => '']) + public function requirements($options = ['format' => 'table', 'severity' => -1, 'ignore' => '']): RowsOfFields { include_once DRUSH_DRUPAL_CORE . '/includes/install.inc'; $severities = [ diff --git a/src/Drupal/Commands/core/EntityCommands.php b/src/Drupal/Commands/core/EntityCommands.php index 7bd556d315..57a35b5ecf 100644 --- a/src/Drupal/Commands/core/EntityCommands.php +++ b/src/Drupal/Commands/core/EntityCommands.php @@ -2,6 +2,10 @@ namespace Drush\Drupal\Commands\core; +use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException; +use Drupal\Component\Plugin\Exception\PluginNotFoundException; +use Drupal\Core\Entity\EntityStorageException; +use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drush\Commands\DrushCommands; use Drush\Utils\StringUtils; @@ -48,7 +52,7 @@ public function __construct(EntityTypeManagerInterface $entityTypeManager) * @aliases edel,entity-delete * @throws \Exception */ - public function delete($entity_type, $ids = null, $options = ['bundle' => self::REQ, 'exclude' => self::REQ, 'chunks' => 50]) + public function delete(string $entity_type, $ids = null, array $options = ['bundle' => self::REQ, 'exclude' => self::REQ, 'chunks' => 50]): void { $query = $this->getQuery($entity_type, $ids, $options); $result = $query->execute(); @@ -77,9 +81,9 @@ public function delete($entity_type, $ids = null, $options = ['bundle' => self:: * @param string $entity_type * @param array $ids * - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException - * @throws \Drupal\Core\Entity\EntityStorageException + * @throws InvalidPluginDefinitionException + * @throws PluginNotFoundException + * @throws EntityStorageException */ public function doDelete(string $entity_type, array $ids): void { @@ -140,9 +144,9 @@ public function loadSave(string $entity_type, $ids = null, array $options = ['bu * @param string $entity_type * @param array $ids * - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException - * @throws \Drupal\Core\Entity\EntityStorageException + * @throws InvalidPluginDefinitionException + * @throws PluginNotFoundException + * @throws EntityStorageException */ public function doSave(string $entity_type, array $ids): void { @@ -157,11 +161,11 @@ public function doSave(string $entity_type, array $ids): void * @param string $entity_type * @param string|null $ids * @param array $options - * @return \Drupal\Core\Entity\Query\QueryInterface - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * @return QueryInterface + * @throws InvalidPluginDefinitionException + * @throws PluginNotFoundException */ - protected function getQuery(string $entity_type, ?string $ids, array $options): \Drupal\Core\Entity\Query\QueryInterface + protected function getQuery(string $entity_type, ?string $ids, array $options): \QueryInterface { $storage = $this->entityTypeManager->getStorage($entity_type); $query = $storage->getQuery(); diff --git a/src/Drupal/Commands/core/ImageCommands.php b/src/Drupal/Commands/core/ImageCommands.php index df71f6f322..c8f764bb65 100644 --- a/src/Drupal/Commands/core/ImageCommands.php +++ b/src/Drupal/Commands/core/ImageCommands.php @@ -27,7 +27,7 @@ class ImageCommands extends DrushCommands * @validate-module-enabled image * @aliases if,image-flush */ - public function flush($style_names, $options = ['all' => false]) + public function flush($style_names, $options = ['all' => false]): void { foreach (ImageStyle::loadMultiple(StringUtils::csvToArray($style_names)) as $style_name => $style) { $style->flush(); @@ -38,7 +38,7 @@ public function flush($style_names, $options = ['all' => false]) /** * @hook interact image-flush */ - public function interactFlush($input, $output) + public function interactFlush($input, $output): void { $styles = array_keys(ImageStyle::loadMultiple()); $style_names = $input->getArgument('style_names'); @@ -58,7 +58,7 @@ public function interactFlush($input, $output) /** * @hook init image-flush */ - public function initFlush(InputInterface $input, AnnotationData $annotationData) + public function initFlush(InputInterface $input, AnnotationData $annotationData): void { // Needed for non-interactive calls. if ($input->getOption('all')) { diff --git a/src/Drupal/Commands/core/JsonapiCommands.php b/src/Drupal/Commands/core/JsonapiCommands.php index 4e157292c7..bb6e664932 100644 --- a/src/Drupal/Commands/core/JsonapiCommands.php +++ b/src/Drupal/Commands/core/JsonapiCommands.php @@ -21,10 +21,8 @@ class JsonapiCommands extends DrushCommands * @usage drush jn:get jsonapi/node/article | jq * Pretty print JSON by piping to jq. See https://stedolan.github.io/jq/ for lots more jq features. * @validate-module-enabled jsonapi - * - * @return UnstructuredData */ - public function get($url, $options = ['format' => 'json']) + public function get($url, $options = ['format' => 'json']): UnstructuredData { $kernel = Drush::bootstrap()->getKernel(); $sub_request = Request::create($url, 'GET'); diff --git a/src/Drupal/Commands/core/LanguageCommands.php b/src/Drupal/Commands/core/LanguageCommands.php index abd84bbb64..d052c1e998 100644 --- a/src/Drupal/Commands/core/LanguageCommands.php +++ b/src/Drupal/Commands/core/LanguageCommands.php @@ -13,27 +13,21 @@ class LanguageCommands extends DrushCommands { /** - * @var \Drupal\Core\Language\LanguageManagerInterface + * @var LanguageManagerInterface */ protected $languageManager; /** - * @var \Drupal\Core\Extension\ModuleHandlerInterface + * @var ModuleHandlerInterface */ protected $moduleHandler; - /** - * @return \Drupal\Core\Language\LanguageManagerInterface - */ - public function getLanguageManager() + public function getLanguageManager(): LanguageManagerInterface { return $this->languageManager; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } @@ -59,7 +53,7 @@ public function __construct(LanguageManagerInterface $languageManager, ModuleHan * @hidden * @throws \Exception */ - public function add($langcode, $options = ['skip-translations' => false]) + public function add($langcode, $options = ['skip-translations' => false]): void { if ($langcodes = StringUtils::csvToArray($langcode)) { $langcodes = array_unique($langcodes); @@ -102,9 +96,8 @@ public function add($langcode, $options = ['skip-translations' => false]) * locked: Locked * @default-fields language,direction,default * @filter-default-field language - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function info() + public function info(): RowsOfFields { $rows = []; $languages = $this->getLanguageManager()->getLanguages(); @@ -126,11 +119,10 @@ public function info() * Filters valid language codes. * * @param $langcodes - * @return array * @throws \Exception * Exception when a language code is not in the standard language list. */ - private function filterValidLangcode($langcodes) + private function filterValidLangcode($langcodes): array { $standardLanguages = $this->getLanguageManager()->getStandardLanguageList(); foreach ($langcodes as $key => $langcode) { @@ -148,9 +140,8 @@ private function filterValidLangcode($langcodes) * Filters new language codes. * * @param $langcodes - * @return array */ - private function filterNewLangcode($langcodes) + private function filterNewLangcode($langcodes): array { $enabledLanguages = $this->getLanguageManager()->getLanguages(); foreach ($langcodes as $key => $langcode) { @@ -170,7 +161,7 @@ private function filterNewLangcode($langcodes) * * @param $langcodes */ - private function setBatchLanguageImport($langcodes) + private function setBatchLanguageImport($langcodes): void { $moduleHandler = $this->getModuleHandler(); $moduleHandler->loadInclude('locale', 'inc', 'locale.translation'); diff --git a/src/Drupal/Commands/core/LocaleCommands.php b/src/Drupal/Commands/core/LocaleCommands.php index e3c32ac84e..a73a282296 100644 --- a/src/Drupal/Commands/core/LocaleCommands.php +++ b/src/Drupal/Commands/core/LocaleCommands.php @@ -26,26 +26,17 @@ class LocaleCommands extends DrushCommands protected $state; - /** - * @return \Drupal\Core\Language\LanguageManagerInterface - */ - protected function getLanguageManager() + protected function getLanguageManager(): LanguageManagerInterface { return $this->languageManager; } - /** - * @return \Drupal\Core\Config\ConfigFactoryInterface - */ - protected function getConfigFactory() + protected function getConfigFactory(): ConfigFactoryInterface { return $this->configFactory; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } @@ -53,7 +44,7 @@ public function getModuleHandler() /** * @return mixed */ - public function getState() + public function getState(): StateInterface { return $this->state; } @@ -73,7 +64,7 @@ public function __construct(LanguageManagerInterface $languageManager, ConfigFac * @aliases locale-check * @validate-module-enabled locale */ - public function check() + public function check(): void { $this->getModuleHandler()->loadInclude('locale', 'inc', 'locale.compare'); @@ -105,7 +96,7 @@ public function check() * @option langcodes A comma-separated list of language codes to update. If omitted, all translations will be updated. * @validate-module-enabled locale */ - public function update($options = ['langcodes' => self::REQ]) + public function update($options = ['langcodes' => self::REQ]): void { $module_handler = $this->getModuleHandler(); $module_handler->loadInclude('locale', 'fetch.inc'); @@ -175,7 +166,7 @@ public function update($options = ['langcodes' => self::REQ]) * @aliases locale-export * @validate-module-enabled locale */ - public function export($langcode = null, $options = ['template' => false, 'types' => self::REQ]) + public function export($langcode = null, $options = ['template' => false, 'types' => self::REQ]): void { $language = $this->getTranslatableLanguage($langcode); $poreader_options = []; @@ -197,7 +188,7 @@ public function export($langcode = null, $options = ['template' => false, 'types * * @hook validate locale:export */ - public function exportValidate(CommandData $commandData) + public function exportValidate(CommandData $commandData): void { $langcode = $commandData->input()->getArgument('langcode'); $template = $commandData->input()->getOption('template'); @@ -234,7 +225,7 @@ public function exportValidate(CommandData $commandData) * @aliases locale-import * @throws \Exception */ - public function import($langcode, $file, $options = ['type' => 'not-customized', 'override' => self::REQ, 'autocreate-language' => false]) + public function import($langcode, $file, $options = ['type' => 'not-customized', 'override' => self::REQ, 'autocreate-language' => false]): void { if (!drush_file_not_empty($file)) { throw new \Exception(dt('File @file not found or empty.', ['@file' => $file])); @@ -273,9 +264,8 @@ public function import($langcode, $file, $options = ['type' => 'not-customized', * Converts input of translation type. * * @param $type - * @return integer */ - private function convertCustomizedType($type) + private function convertCustomizedType($type): int { return $type == 'customized' ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED; } @@ -284,9 +274,8 @@ private function convertCustomizedType($type) * Converts input of override option. * * @param $override - * @return array */ - private function convertOverrideOption($override) + private function convertOverrideOption($override): array { $result = []; @@ -331,7 +320,7 @@ private function convertOverrideOption($override) * @return LanguageInterface|null * @throws \Exception */ - private function getTranslatableLanguage($langcode, $addLanguage = false) + private function getTranslatableLanguage(string $langcode, bool $addLanguage = false) { if (!$langcode) { return null; @@ -367,9 +356,8 @@ private function getTranslatableLanguage($langcode, $addLanguage = false) * Check if language is translatable. * * @param LanguageInterface $language - * @return bool */ - private function isTranslatable(LanguageInterface $language) + private function isTranslatable(LanguageInterface $language): bool { if ($language->isLocked()) { return false; @@ -388,12 +376,11 @@ private function isTranslatable(LanguageInterface $language) * Get PODatabaseReader options for given types. * * @param array $types - * @return array * Options list with value 'true'. * @throws \Exception * Triggered with incorrect types. */ - private function convertTypesToPoDbReaderOptions(array $types = []) + private function convertTypesToPoDbReaderOptions(array $types = []): array { $valid_convertions = [ 'not_customized' => 'not-customized', @@ -426,7 +413,7 @@ private function convertTypesToPoDbReaderOptions(array $types = []) * @param array $options The export options for PoDatabaseReader. * @return bool True if successful. */ - private function writePoFile($file_uri, LanguageInterface $language = null, array $options = []) + private function writePoFile(string $file_uri, LanguageInterface $language = null, array $options = []): bool { $reader = new PoDatabaseReader(); diff --git a/src/Drupal/Commands/core/MessengerCommands.php b/src/Drupal/Commands/core/MessengerCommands.php index fda13a9246..f91f243d3a 100644 --- a/src/Drupal/Commands/core/MessengerCommands.php +++ b/src/Drupal/Commands/core/MessengerCommands.php @@ -21,7 +21,7 @@ public function __construct(MessengerInterface $messenger) /** * @hook pre-command * */ - public function pre() + public function pre(): void { self::log(); } @@ -29,12 +29,12 @@ public function pre() /** * @hook post-command * */ - public function post() + public function post(): void { self::log(); } - public function log() + public function log(): void { if (!\Drupal::hasService('messenger')) { return; diff --git a/src/Drupal/Commands/core/MigrateRunnerCommands.php b/src/Drupal/Commands/core/MigrateRunnerCommands.php index e33cedd9c0..83c678157e 100644 --- a/src/Drupal/Commands/core/MigrateRunnerCommands.php +++ b/src/Drupal/Commands/core/MigrateRunnerCommands.php @@ -2,6 +2,8 @@ namespace Drush\Drupal\Commands\core; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; +use Drupal\Component\Plugin\Exception\PluginException; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\CommandError; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; @@ -28,37 +30,37 @@ class MigrateRunnerCommands extends DrushCommands /** * Migration plugin manager service. * - * @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface + * @var MigrationPluginManagerInterface */ protected $migrationPluginManager; /** * Date formatter service. * - * @var \Drupal\Core\Datetime\DateFormatter + * @var DateFormatter */ protected $dateFormatter; /** * The key-value store service. * - * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + * @var KeyValueStoreInterface */ protected $keyValue; /** * Migrate message service. * - * @var \Drupal\migrate\MigrateMessageInterface + * @var MigrateMessageInterface */ protected $migrateMessage; /** * Constructs a new class instance. * - * @param \Drupal\Core\Datetime\DateFormatter $dateFormatter + * @param DateFormatter $dateFormatter * Date formatter service. - * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $keyValueFactory + * @param KeyValueFactoryInterface $keyValueFactory * The key-value factory service. */ public function __construct(DateFormatter $dateFormatter, KeyValueFactoryInterface $keyValueFactory) @@ -111,7 +113,7 @@ public function __construct(DateFormatter $dateFormatter, KeyValueFactoryInterfa * last_imported: Last Imported * @default-fields id,status,total,imported,unprocessed,last_imported * - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields * Migrations status formatted as table. * @version 10.4 * @@ -202,7 +204,7 @@ public function status(?string $migrationIds = null, array $options = [ /** * Returns the migration source rows count. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * @return int|null * The migration source rows count or null if the source is uncountable or @@ -230,7 +232,7 @@ protected function getMigrationSourceRowsCount(MigrationInterface $migration): ? /** * Returns the number or items that needs update. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * * @return int|null @@ -245,7 +247,7 @@ protected function getMigrationNeedingUpdateCount(MigrationInterface $migration) /** * Returns the number of unprocessed items. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * * @return int|null @@ -263,7 +265,7 @@ protected function getMigrationUnprocessedCount(MigrationInterface $migration): /** * Returns the number of imported items. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * * @return int|null @@ -286,7 +288,7 @@ protected function getMigrationImportedCount(MigrationInterface $migration): ?in /** * Returns the last imported date/time if any. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * * @return string @@ -415,7 +417,7 @@ public function import(?string $migrationIds = null, array $options = ['all' => * If the --execute-dependencies option was given, the migration's * dependencies will also be executed first. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration to execute. * @param string $migrationId * The migration ID (not used, just an artifact of array_walk()). @@ -547,7 +549,7 @@ public function rollback(?string $migrationIds = null, array $options = ['all' = */ public function stop(string $migrationId): void { - /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + /** @var MigrationInterface $migration */ $migration = $this->getMigrationPluginManager()->createInstance($migrationId); switch ($migration->getStatus()) { case MigrationInterface::STATUS_IDLE: @@ -584,7 +586,7 @@ public function stop(string $migrationId): void */ public function resetStatus(string $migrationId): void { - /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + /** @var MigrationInterface $migration */ $migration = $this->getMigrationPluginManager()->createInstance($migrationId); $status = $migration->getStatus(); if ($status == MigrationInterface::STATUS_IDLE) { @@ -630,12 +632,12 @@ public function resetStatus(string $migrationId): void * hash: Source IDs hash * @default-fields level,source_ids,destination_ids,message,hash * - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields * Migration messages status formatted as table. */ public function messages(string $migrationId, array $options = ['idlist' => self::REQ]): RowsOfFields { - /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + /** @var MigrationInterface $migration */ $migration = $this->getMigrationPluginManager()->createInstance($migrationId); $idMap = $migration->getIdMap(); $sourceIdKeys = $this->getSourceIdKeys($idMap); @@ -687,7 +689,7 @@ public function messages(string $migrationId, array $options = ['idlist' => self * * @see \Drupal\migrate\Plugin\MigrateIdMapInterface::getMessages() */ - protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys) + protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys): array { unset($row->msgid); $row = (array) $row; @@ -733,12 +735,12 @@ protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys) * @default-fields machine_name,description * @version 10.4 * - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields * Source fields of the given migration. */ public function fieldsSource(string $migrationId): RowsOfFields { - /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + /** @var MigrationInterface $migration */ $migration = $this->getMigrationPluginManager()->createInstance($migrationId); $source = $migration->getSourcePlugin(); $table = []; @@ -759,11 +761,11 @@ public function fieldsSource(string $migrationId): RowsOfFields * @param string|null $tags * A comma separated list of tags. * - * @return \Drupal\migrate\Plugin\MigrationInterface[][] + * @return MigrationInterface[][] * An array keyed by migration tag, each value containing an array of * migrations or an empty array if no migrations match the input criteria. * - * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws PluginException */ protected function getMigrationList(?string $migrationIds, ?string $tags): array { @@ -814,7 +816,7 @@ protected function getMigrationList(?string $migrationIds, ?string $tags): array /** * Returns the migrate message logger. * - * @return \Drupal\migrate\MigrateMessageInterface + * @return MigrateMessageInterface * The migrate message logger. */ protected function getMigrateMessage(): MigrateMessageInterface @@ -828,7 +830,7 @@ protected function getMigrateMessage(): MigrateMessageInterface /** * Returns the migration plugin manager service. * - * @return \Drupal\migrate\Plugin\MigrationPluginManagerInterface + * @return MigrationPluginManagerInterface * The migration plugin manager service. * * @todo This service cannot be injected as the 'migrate' module might not @@ -851,7 +853,7 @@ protected function getMigrationPluginManager(): MigrationPluginManagerInterface /** * Get the source ID keys. * - * @param \Drupal\migrate\Plugin\MigrateIdMapInterface $idMap + * @param MigrateIdMapInterface $idMap * The migration ID map. * * @return string[] @@ -880,9 +882,9 @@ protected function getSourceIdKeys(MigrateIdMapInterface $idMap): array * * @hook validate @validate-migration-id * - * @param \Consolidation\AnnotatedCommand\CommandData $commandData + * @param CommandData $commandData * - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @return CommandError|null */ public function validateMigrationId(CommandData $commandData) { diff --git a/src/Drupal/Commands/core/QueueCommands.php b/src/Drupal/Commands/core/QueueCommands.php index d7e9b0cd7f..796c1d9c15 100644 --- a/src/Drupal/Commands/core/QueueCommands.php +++ b/src/Drupal/Commands/core/QueueCommands.php @@ -1,6 +1,8 @@ queueService = $queueService; } - /** - * @return \Drupal\Core\Queue\QueueWorkerManager - */ - public function getWorkerManager() + public function getWorkerManager(): QueueWorkerManager { return $this->workerManager; } - /** - * @return \Drupal\Core\Queue\QueueFactory - */ - public function getQueueService() + public function getQueueService(): QueueFactory { return $this->queueService; } @@ -62,7 +58,7 @@ public function getQueueService() * @option items-limit The maximum number of items allowed to run the queue. * @option lease-time The maximum number of seconds that an item remains claimed. */ - public function run($name, $options = ['time-limit' => self::REQ, 'items-limit' => self::REQ, 'lease-time' => self::REQ]) + public function run(string $name, $options = ['time-limit' => self::REQ, 'items-limit' => self::REQ, 'lease-time' => self::REQ]): void { $time_limit = (int) $options['time-limit']; $items_limit = (int) $options['items-limit']; @@ -122,9 +118,8 @@ public function run($name, $options = ['time-limit' => self::REQ, 'items-limit' * class: Class * * @filter-default-field queue - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function qList($options = ['format' => 'table']) + public function qList($options = ['format' => 'table']): RowsOfFields { $result = []; foreach (array_keys($this->getQueues()) as $name) { @@ -146,7 +141,7 @@ public function qList($options = ['format' => 'table']) * @param $name The name of the queue to run, as defined in either hook_queue_info or hook_cron_queue_info. * @validate-queue name */ - public function delete($name) + public function delete($name): void { $queue = $this->getQueue($name); $queue->deleteQueue(); @@ -159,8 +154,8 @@ public function delete($name) * Annotation value should be the name of the argument/option containing the name. * * @hook validate @validate-queue - * @param \Consolidation\AnnotatedCommand\CommandData $commandData - * @return \Consolidation\AnnotatedCommand\CommandError|null + * @param CommandData $commandData + * @return CommandError|null */ public function validateQueueName(CommandData $commandData) { @@ -176,7 +171,7 @@ public function validateQueueName(CommandData $commandData) /** * {@inheritdoc} */ - public function getQueues() + public function getQueues(): array { if (!isset(static::$queues)) { static::$queues = []; @@ -189,10 +184,8 @@ public function getQueues() /** * {@inheritdoc} - * - * @return \Drupal\Core\Queue\QueueInterface */ - public function getQueue($name) + public function getQueue($name): QueueInterface { return $this->getQueueService()->get($name); } diff --git a/src/Drupal/Commands/core/RoleCommands.php b/src/Drupal/Commands/core/RoleCommands.php index 15835ea2b9..59a350c315 100644 --- a/src/Drupal/Commands/core/RoleCommands.php +++ b/src/Drupal/Commands/core/RoleCommands.php @@ -47,7 +47,7 @@ public function create($machine_name, $human_readable_name = null) * Delete the role 'test role'. * @aliases rdel,role-delete */ - public function delete($machine_name) + public function delete($machine_name): void { $role = Role::load($machine_name); $role->delete(); @@ -70,7 +70,7 @@ public function delete($machine_name) * Allow anon users to post comments and access content. * @aliases rap,role-add-perm */ - public function roleAddPerm($machine_name, $permissions) + public function roleAddPerm($machine_name, $permissions): void { $perms = StringUtils::csvToArray($permissions); user_role_grant_permissions($machine_name, $perms); @@ -90,7 +90,7 @@ public function roleAddPerm($machine_name, $permissions) * Remove 2 permissions from anon users. * @aliases rmp,role-remove-perm */ - public function roleRemovePerm($machine_name, $permissions) + public function roleRemovePerm($machine_name, $permissions): void { $perms = StringUtils::csvToArray($permissions); user_role_revoke_permissions($machine_name, $perms); @@ -115,9 +115,8 @@ public function roleRemovePerm($machine_name, $permissions) * perms: Permissions * * @filter-default-field perms - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function roleList($options = ['format' => 'yaml']) + public function roleList($options = ['format' => 'yaml']): RowsOfFields { $rows = []; $roles = Role::loadMultiple(); diff --git a/src/Drupal/Commands/core/StateCommands.php b/src/Drupal/Commands/core/StateCommands.php index 5ab5237356..a2f01b4943 100644 --- a/src/Drupal/Commands/core/StateCommands.php +++ b/src/Drupal/Commands/core/StateCommands.php @@ -20,10 +20,7 @@ public function __construct(StateInterface $state) $this->state = $state; } - /** - * @return \Drupal\Core\State\StateInterface - */ - public function getState() + public function getState(): StateInterface { return $this->state; } @@ -39,10 +36,8 @@ public function getState() * @usage drush state:get drupal_css_cache_files --format=yaml * Displays an array of css files in yaml format. * @aliases sget,state-get - * - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList */ - public function get($key, $options = ['format' => 'string']) + public function get(string $key, $options = ['format' => 'string']): PropertyList { $value = $this->getState()->get($key); return new PropertyList([$key => $value]); @@ -65,10 +60,8 @@ public function get($key, $options = ['format' => 'string']) * @usage php -r "print json_encode(array(\'drupal\', \'simpletest\'));" | drush state-set --input-format=json foo.name - * Set a key to a complex value (e.g. array) * @aliases sset,state-set - * - * @return void */ - public function set($key, $value, $options = ['input-format' => 'auto', 'value' => self::REQ]) + public function set(string $key, $value, $options = ['input-format' => 'auto', 'value' => self::REQ]): void { // A convenient way to pass a multiline value within a backend request. $value = $options['value'] ?: $value; @@ -100,10 +93,8 @@ public function set($key, $value, $options = ['input-format' => 'auto', 'value' * @usage drush state:del system.cron_last * Delete state entry for system.cron_last. * @aliases sdel,state-delete - * - * @return void */ - public function delete($key) + public function delete(string $key): void { $this->getState()->delete($key); } diff --git a/src/Drupal/Commands/core/TwigCommands.php b/src/Drupal/Commands/core/TwigCommands.php index 3f9fe3ea3a..c3176788c1 100644 --- a/src/Drupal/Commands/core/TwigCommands.php +++ b/src/Drupal/Commands/core/TwigCommands.php @@ -15,35 +15,29 @@ class TwigCommands extends DrushCommands { /** - * @var \Drupal\Core\Template\TwigEnvironment - */ + * @var TwigEnvironment + */ protected $twig; /** - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ + * @var ModuleHandlerInterface + */ protected $moduleHandler; - /** - * @return \Drupal\Core\Template\TwigEnvironment - */ - public function getTwig() + public function getTwig(): TwigEnvironment { return $this->twig; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } /** - * @param \Drupal\Core\Template\TwigEnvironment $twig - * @param ModuleHandlerInterface $moduleHandler - */ + * @param TwigEnvironment $twig + * @param ModuleHandlerInterface $moduleHandler + */ public function __construct(TwigEnvironment $twig, ModuleHandlerInterface $moduleHandler) { $this->twig = $twig; @@ -65,11 +59,10 @@ public function __construct(TwigEnvironment $twig, ModuleHandlerInterface $modul * compiled: Compiled * @default-fields template,compiled * @filter-output - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields * * @command twig:unused */ - public function unused($searchpaths) + public function unused($searchpaths): RowsOfFields { $unused = []; $phpstorage = PhpStorageFactory::get('twig'); @@ -104,7 +97,7 @@ public function unused($searchpaths) * @command twig:compile * @aliases twigc,twig-compile */ - public function twigCompile() + public function twigCompile(): void { require_once DRUSH_DRUPAL_CORE . "/themes/engines/twig/twig.engine"; // Scan all enabled modules and themes. diff --git a/src/Drupal/Commands/core/UserCommands.php b/src/Drupal/Commands/core/UserCommands.php index 4bcd0c07cc..12c4dfcca4 100644 --- a/src/Drupal/Commands/core/UserCommands.php +++ b/src/Drupal/Commands/core/UserCommands.php @@ -1,6 +1,7 @@ 'table', 'uid' => self::REQ, 'mail' => self::REQ]) + public function information(string $names = '', $options = ['format' => 'table', 'uid' => self::REQ, 'mail' => self::REQ]): RowsOfFields { $accounts = []; if ($mails = StringUtils::csvToArray($options['mail'])) { @@ -125,7 +125,7 @@ public function renderRolesCell($key, $cellData, FormatterOptions $options) * @usage drush user:block user3 * Block the users whose name is user3 */ - public function block($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) + public function block(string $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]): void { $accounts = $this->getAccounts($names, $options); foreach ($accounts as $id => $account) { @@ -147,7 +147,7 @@ public function block($names = '', $options = ['uid' => self::REQ, 'mail' => sel * @usage drush user:unblock user3 * Unblock the users with name user3 */ - public function unblock($names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) + public function unblock(string $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]): void { $accounts = $this->getAccounts($names, $options); foreach ($accounts as $id => $account) { @@ -171,7 +171,7 @@ public function unblock($names = '', $options = ['uid' => self::REQ, 'mail' => s * @usage drush user-add-role "editor" user3 * Add the editor role to user3 */ - public function addRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) + public function addRole(string $role, string $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]): void { $accounts = $this->getAccounts($names, $options); foreach ($accounts as $id => $account) { @@ -198,7 +198,7 @@ public function addRole($role, $names = '', $options = ['uid' => self::REQ, 'mai * @usage drush user:remove-role "power user" user3 * Remove the "power user" role from user3 */ - public function removeRole($role, $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]) + public function removeRole(string $role, string $names = '', $options = ['uid' => self::REQ, 'mail' => self::REQ]): void { $accounts = $this->getAccounts($names, $options); foreach ($accounts as $id => $account) { @@ -223,7 +223,7 @@ public function removeRole($role, $names = '', $options = ['uid' => self::REQ, ' * @usage drush user:create newuser --mail="person@example.com" --password="letmein" * Create a new user account with the name newuser, the email address person@example.com, and the password letmein */ - public function create($name, $options = ['password' => self::REQ, 'mail' => self::REQ]) + public function create(string $name, $options = ['password' => self::REQ, 'mail' => self::REQ]) { $new_user = [ 'name' => $name, @@ -247,7 +247,7 @@ public function create($name, $options = ['password' => self::REQ, 'mail' => sel * * @hook validate user-create */ - public function createValidate(CommandData $commandData) + public function createValidate(CommandData $commandData): void { if ($mail = $commandData->input()->getOption('mail')) { if (user_load_by_mail($mail)) { @@ -275,7 +275,7 @@ public function createValidate(CommandData $commandData) * @usage drush user:cancel --delete-content username * Delete the user account with the name username and delete all content created by that user. */ - public function cancel($names, $options = ['delete-content' => false, 'uid' => self::REQ, 'mail' => self::REQ]) + public function cancel(string $names, $options = ['delete-content' => false, 'uid' => self::REQ, 'mail' => self::REQ]): void { $accounts = $this->getAccounts($names, $options); foreach ($accounts as $id => $account) { @@ -302,7 +302,7 @@ public function cancel($names, $options = ['delete-content' => false, 'uid' => s * @usage drush user:password someuser "correct horse battery staple" * Set the password for the username someuser. See https://xkcd.com/936 */ - public function password($name, $password) + public function password(string $name, string $password): void { if ($account = user_load_by_name($name)) { if (!$this->getConfig()->simulate()) { @@ -319,9 +319,8 @@ public function password($name, $password) * A flatter and simpler array presentation of a Drupal $user object. * * @param $account A user account - * @return array */ - public function infoArray($account) + public function infoArray($account): array { return [ 'uid' => $account->id(), @@ -349,11 +348,10 @@ public function infoArray($account) * @param string $names * @param array $options * - * @return array * A array of loaded accounts. * @throws \Exception */ - protected function getAccounts($names = '', $options = []) + protected function getAccounts(string $names = '', array $options = []): array { $accounts = []; if ($mails = StringUtils::csvToArray($options['mail'])) { diff --git a/src/Drupal/Commands/core/ViewsCommands.php b/src/Drupal/Commands/core/ViewsCommands.php index 4399de5392..5050222dda 100644 --- a/src/Drupal/Commands/core/ViewsCommands.php +++ b/src/Drupal/Commands/core/ViewsCommands.php @@ -35,34 +35,22 @@ public function __construct(ConfigFactoryInterface $configFactory, ModuleHandler $this->configFactory = $configFactory; } - /** - * @return \Drupal\Core\Config\ConfigFactoryInterface - */ - public function getConfigFactory() + public function getConfigFactory(): ConfigFactoryInterface { return $this->configFactory; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } - /** - * @return \Drupal\Core\Entity\EntityTypeManagerInterface - */ - public function getEntityTypeManager() + public function getEntityTypeManager(): EntityTypeManagerInterface { return $this->entityTypeManager; } - /** - * @return \Drupal\Core\Render\RendererInterface - */ - public function getRenderer() + public function getRenderer(): RendererInterface { return $this->renderer; } @@ -75,7 +63,7 @@ public function getRenderer() * @validate-module-enabled views * @aliases vd,views-dev */ - public function dev() + public function dev(): void { $settings = [ 'ui.show.listing_filters' => true, @@ -141,7 +129,7 @@ public function dev() * @validate-module-enabled views * * @filter-default-field machine-name - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields */ public function vlist($options = ['name' => self::REQ, 'tags' => self::REQ, 'status' => self::REQ, 'format' => 'table']) { @@ -233,7 +221,7 @@ public function vlist($options = ['name' => self::REQ, 'tags' => self::REQ, 'sta * * @return string */ - public function execute($view_name, $display = null, $view_args = null, $options = ['count' => 0, 'show-admin-links' => false]) + public function execute(string $view_name, $display = null, $view_args = null, $options = ['count' => 0, 'show-admin-links' => false]) { $view = Views::getView($view_name); @@ -268,7 +256,7 @@ public function execute($view_name, $display = null, $view_args = null, $options * @aliases va,views-analyze * @validate-module-enabled views * - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields */ public function analyze() { @@ -305,7 +293,7 @@ public function analyze() * Enable the frontpage and taxonomy_term views. * @aliases ven,views-enable */ - public function enable($views) + public function enable(string $views): void { $view_names = StringUtils::csvToArray($views); if ($views = $this->getEntityTypeManager()->getStorage('view')->loadMultiple($view_names)) { @@ -327,7 +315,7 @@ public function enable($views) * Disable the frontpage and taxonomy_term views. * @aliases vdis,views-disable */ - public function disable($views) + public function disable(string $views): void { $view_names = StringUtils::csvToArray($views); if ($views = $this->getEntityTypeManager()->getStorage('view')->loadMultiple($view_names)) { @@ -344,7 +332,7 @@ public function disable($views) * * @hook on-event cache-clear */ - public function cacheClear(&$types, $include_bootstrapped_types) + public function cacheClear(&$types, $include_bootstrapped_types): void { if ($include_bootstrapped_types && $this->getModuleHandler()->moduleExists('views')) { $types['views'] = 'views_invalidate_cache'; diff --git a/src/Drupal/Commands/core/WatchdogCommands.php b/src/Drupal/Commands/core/WatchdogCommands.php index c3da155195..967b239ee5 100644 --- a/src/Drupal/Commands/core/WatchdogCommands.php +++ b/src/Drupal/Commands/core/WatchdogCommands.php @@ -48,7 +48,7 @@ class WatchdogCommands extends DrushCommands * username: Username * @default-fields wid,date,type,severity,message * @filter-default-field message - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields + * @return RowsOfFields */ public function show($substring = '', $options = ['format' => 'table', 'count' => 10, 'severity' => self::REQ, 'type' => self::REQ, 'extended' => false]) { @@ -97,9 +97,8 @@ public function show($substring = '', $options = ['format' => 'table', 'count' = * date: Date * username: Username * @default-fields wid,date,type,severity,message - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function watchdogList($substring = '', $options = ['format' => 'table', 'count' => 10, 'extended' => false]) + public function watchdogList($substring = '', $options = ['format' => 'table', 'count' => 10, 'extended' => false]): RowsOfFields { return $this->show($substring, $options); } @@ -136,7 +135,7 @@ public function watchdogList($substring = '', $options = ['format' => 'table', ' * @filter-default-field message * @version 10.6 */ - public function tail(OutputInterface $output, $substring = '', $options = ['format' => 'table', 'severity' => self::REQ, 'type' => self::REQ, 'extended' => false]) + public function tail(OutputInterface $output, $substring = '', $options = ['format' => 'table', 'severity' => self::REQ, 'type' => self::REQ, 'extended' => false]): void { $where = $this->where($options['type'], $options['severity'], $substring); if (empty($where['where'])) { @@ -176,9 +175,9 @@ public function tail(OutputInterface $output, $substring = '', $options = ['form /** * @hook interact watchdog-list - * @throws \Drush\Exceptions\UserAbortException + * @throws UserAbortException */ - public function interactList($input, $output) + public function interactList($input, $output): void { $choices['-- types --'] = dt('== message types =='); @@ -219,9 +218,8 @@ public function interactList($input, $output) * Delete all messages of type cron. * @aliases wd-del,wd-delete,wd,watchdog-delete * @validate-module-enabled dblog - * @return void */ - public function delete($substring = '', $options = ['severity' => self::REQ, 'type' => self::REQ]) + public function delete($substring = '', $options = ['severity' => self::REQ, 'type' => self::REQ]): void { if ($substring == 'all') { $this->output()->writeln(dt('All watchdog messages will be deleted.')); @@ -264,10 +262,8 @@ public function delete($substring = '', $options = ['severity' => self::REQ, 'ty * @param $id Watchdog Id * @aliases wd-one,watchdog-show-one * @validate-module-enabled dblog - * - * @return \Consolidation\OutputFormatters\StructuredData\PropertyList */ - public function showOne($id, $options = ['format' => 'yaml']) + public function showOne($id, $options = ['format' => 'yaml']): PropertyList { $rsc = Database::getConnection()->select('watchdog', 'w') ->fields('w') @@ -295,7 +291,7 @@ public function showOne($id, $options = ['format' => 'yaml']) * @return * An array with structure ('where' => string, 'args' => array()) */ - protected function where($type = null, $severity = null, $filter = null, $criteria = 'AND') + protected function where($type = null, $severity = null, $filter = null, $criteria = 'AND'): array { $args = []; $conditions = []; diff --git a/src/Drupal/Commands/pm/PmCommands.php b/src/Drupal/Commands/pm/PmCommands.php index 23a0acb647..051bea0160 100644 --- a/src/Drupal/Commands/pm/PmCommands.php +++ b/src/Drupal/Commands/pm/PmCommands.php @@ -37,42 +37,27 @@ public function __construct(ConfigFactoryInterface $configFactory, ModuleInstall $this->extensionListModule = $extensionListModule; } - /** - * @return \Drupal\Core\Config\ConfigFactoryInterface - */ - public function getConfigFactory() + public function getConfigFactory(): ConfigFactoryInterface { return $this->configFactory; } - /** - * @return \Drupal\Core\Extension\ModuleInstallerInterface - */ - public function getModuleInstaller() + public function getModuleInstaller(): ModuleInstallerInterface { return $this->moduleInstaller; } - /** - * @return \Drupal\Core\Extension\ModuleHandlerInterface - */ - public function getModuleHandler() + public function getModuleHandler(): ModuleHandlerInterface { return $this->moduleHandler; } - /** - * @return \Drupal\Core\Extension\ThemeHandlerInterface - */ - public function getThemeHandler() + public function getThemeHandler(): ThemeHandlerInterface { return $this->themeHandler; } - /** - * @return \Drupal\Core\Extension\ModuleExtensionList - */ - public function getExtensionListModule() + public function getExtensionListModule(): ModuleExtensionList { return $this->extensionListModule; } @@ -85,7 +70,7 @@ public function getExtensionListModule() * @aliases en,pm-enable * @bootstrap root */ - public function enable(array $modules) + public function enable(array $modules): void { $modules = StringUtils::csvToArray($modules); $todo = $this->addInstallDependencies($modules); @@ -114,12 +99,12 @@ public function enable(array $modules) * * @hook validate pm:enable * - * @throws \Drush\Exceptions\UserAbortException - * @throws \Drupal\Core\Extension\MissingDependencyException + * @throws UserAbortException + * @throws MissingDependencyException * * @see \drupal_check_module() */ - public function validateEnableModules(CommandData $commandData) + public function validateEnableModules(CommandData $commandData): void { $modules = $commandData->input()->getArgument('modules'); $modules = StringUtils::csvToArray($modules); @@ -164,7 +149,7 @@ public function validateEnableModules(CommandData $commandData) * @param $modules A comma delimited list of modules. * @aliases pmu,pm-uninstall */ - public function uninstall(array $modules) + public function uninstall(array $modules): void { $modules = StringUtils::csvToArray($modules); $list = $this->addUninstallDependencies($modules); @@ -183,7 +168,7 @@ public function uninstall(array $modules) /** * @hook validate pm-uninstall */ - public function validateUninstall(CommandData $commandData) + public function validateUninstall(CommandData $commandData): void { if ($modules = $commandData->input()->getArgument('modules')) { $modules = StringUtils::csvToArray($modules); @@ -219,9 +204,8 @@ public function validateUninstall(CommandData $commandData) * @default-fields package,display_name,status,version * @aliases pml,pm-list * @filter-default-field display_name - * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields */ - public function pmList($options = ['format' => 'table', 'type' => 'module,theme', 'status' => 'enabled,disabled', 'package' => self::REQ, 'core' => false, 'no-core' => false]) + public function pmList($options = ['format' => 'table', 'type' => 'module,theme', 'status' => 'enabled,disabled', 'package' => self::REQ, 'core' => false, 'no-core' => false]): RowsOfFields { $rows = []; @@ -302,12 +286,12 @@ public function pmList($options = ['format' => 'table', 'type' => 'module,theme' * @return * String describing extension status. Values: enabled|disabled. */ - public function extensionStatus($extension) + public function extensionStatus($extension): string { return $extension->status == 1 ? 'enabled' : 'disabled'; } - public function addInstallDependencies($modules) + public function addInstallDependencies($modules): array { $module_data = $this->getExtensionListModule()->reset()->getList(); $module_list = array_combine($modules, $modules); diff --git a/src/Drupal/Commands/pm/ThemeCommands.php b/src/Drupal/Commands/pm/ThemeCommands.php index 039637dff4..dc09ea6d9f 100644 --- a/src/Drupal/Commands/pm/ThemeCommands.php +++ b/src/Drupal/Commands/pm/ThemeCommands.php @@ -20,7 +20,7 @@ public function __construct(ThemeInstallerInterface $themeInstaller) /** * @return mixed */ - public function getThemeInstaller() + public function getThemeInstaller(): ThemeInstallerInterface { return $this->themeInstaller; } @@ -32,7 +32,7 @@ public function getThemeInstaller() * @param $themes A comma delimited list of themes. * @aliases then,theme-enable */ - public function enable(array $themes) + public function enable(array $themes): void { $themes = StringUtils::csvToArray($themes); if (!$this->getThemeInstaller()->install($themes, true)) { @@ -48,7 +48,7 @@ public function enable(array $themes) * @param $themes A comma delimited list of themes. * @aliases thun,theme-uninstall */ - public function uninstall(array $themes) + public function uninstall(array $themes): void { $themes = StringUtils::csvToArray($themes); // The uninstall() method has no return value. Assume it succeeded, and diff --git a/src/Drupal/Commands/sql/SanitizeCommands.php b/src/Drupal/Commands/sql/SanitizeCommands.php index 1b3ba775cc..6c198f489b 100644 --- a/src/Drupal/Commands/sql/SanitizeCommands.php +++ b/src/Drupal/Commands/sql/SanitizeCommands.php @@ -30,7 +30,7 @@ class SanitizeCommands extends DrushCommands implements CustomEventAwareInterfac * Sanitizes database but exempts two user fields from modification. * @topics docs:hooks */ - public function sanitize() + public function sanitize(): void { /** * In order to present only one prompt, collect all confirmations from diff --git a/src/Drupal/Commands/sql/SanitizeCommentsCommands.php b/src/Drupal/Commands/sql/SanitizeCommentsCommands.php index 7d2a685c86..aa2572948c 100644 --- a/src/Drupal/Commands/sql/SanitizeCommentsCommands.php +++ b/src/Drupal/Commands/sql/SanitizeCommentsCommands.php @@ -32,7 +32,7 @@ public function __construct($database, $moduleHandler) * * @inheritdoc */ - public function sanitize($result, CommandData $commandData) + public function sanitize($result, CommandData $commandData): void { if ($this->applies()) { //Update anon. @@ -61,7 +61,7 @@ public function sanitize($result, CommandData $commandData) * * @inheritdoc */ - public function messages(&$messages, InputInterface $input) + public function messages(&$messages, InputInterface $input): void { if ($this->applies()) { $messages[] = dt('Remove comment display names and emails.'); diff --git a/src/Drupal/Commands/sql/SanitizePluginInterface.php b/src/Drupal/Commands/sql/SanitizePluginInterface.php index ddc8a99e35..41c67fbd7a 100644 --- a/src/Drupal/Commands/sql/SanitizePluginInterface.php +++ b/src/Drupal/Commands/sql/SanitizePluginInterface.php @@ -29,5 +29,5 @@ public function sanitize($result, CommandData $commandData); * @return String[] * An array of messages. */ - public function messages(&$messages, InputInterface $input); + public function messages(array &$messages, InputInterface $input); } diff --git a/src/Drupal/Commands/sql/SanitizeSessionsCommands.php b/src/Drupal/Commands/sql/SanitizeSessionsCommands.php index 577e580856..9a8e62493c 100644 --- a/src/Drupal/Commands/sql/SanitizeSessionsCommands.php +++ b/src/Drupal/Commands/sql/SanitizeSessionsCommands.php @@ -33,7 +33,7 @@ public function getDatabase() * * @inheritdoc */ - public function sanitize($result, CommandData $commandData) + public function sanitize($result, CommandData $commandData): void { $this->getDatabase()->truncate('sessions')->execute(); $this->logger()->success(dt('Sessions table truncated.')); @@ -44,7 +44,7 @@ public function sanitize($result, CommandData $commandData) * * @inheritdoc */ - public function messages(&$messages, InputInterface $input) + public function messages(&$messages, InputInterface $input): void { $messages[] = dt('Truncate sessions table.'); } diff --git a/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php b/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php index 02f1e0ad69..522352d8e0 100644 --- a/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php +++ b/src/Drupal/Commands/sql/SanitizeUserFieldsCommands.php @@ -46,7 +46,7 @@ public function getEntityFieldManager() * * @inheritdoc */ - public function sanitize($result, CommandData $commandData) + public function sanitize($result, CommandData $commandData): void { $options = $commandData->options(); $conn = $this->getDatabase(); @@ -128,7 +128,7 @@ public function sanitize($result, CommandData $commandData) * * @inheritdoc */ - public function messages(&$messages, InputInterface $input) + public function messages(&$messages, InputInterface $input): void { $messages[] = dt('Sanitize text fields associated with users.'); } @@ -138,7 +138,7 @@ public function messages(&$messages, InputInterface $input) * @option whitelist-fields Deprecated. Use allowlist-fields instead. * @option allowlist-fields A comma delimited list of fields exempt from sanitization. */ - public function options($options = ['whitelist-fields' => '', 'allowlist-fields' => '']) + public function options($options = ['whitelist-fields' => '', 'allowlist-fields' => '']): void { } } diff --git a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php b/src/Drupal/Commands/sql/SanitizeUserTableCommands.php index c01ffef98c..48350208cf 100644 --- a/src/Drupal/Commands/sql/SanitizeUserTableCommands.php +++ b/src/Drupal/Commands/sql/SanitizeUserTableCommands.php @@ -31,7 +31,7 @@ public function __construct($database, $passwordHasher, $entityTypeManager) * * @inheritdoc */ - public function sanitize($result, CommandData $commandData) + public function sanitize($result, CommandData $commandData): void { $options = $commandData->options(); $query = $this->database->update('users_field_data')->condition('uid', 0, '>'); @@ -92,7 +92,7 @@ public function sanitize($result, CommandData $commandData) * By default, passwords are randomized. Specify no to disable that. Specify any other value to set all passwords * to that value. */ - public function options($options = ['sanitize-email' => 'user+%uid@localhost.localdomain', 'sanitize-password' => null]) + public function options($options = ['sanitize-email' => 'user+%uid@localhost.localdomain', 'sanitize-password' => null]): void { } @@ -101,7 +101,7 @@ public function options($options = ['sanitize-email' => 'user+%uid@localhost.loc * * @inheritdoc */ - public function messages(&$messages, InputInterface $input) + public function messages(&$messages, InputInterface $input): void { $options = $input->getOptions(); if ($this->isEnabled($options['sanitize-password'])) { @@ -115,9 +115,8 @@ public function messages(&$messages, InputInterface $input) /** * Test an option value to see if it is disabled. * @param $value - * @return bool */ - protected function isEnabled($value) + protected function isEnabled($value): bool { return $value != 'no' && $value != '0'; } diff --git a/src/Drupal/DrupalKernelTrait.php b/src/Drupal/DrupalKernelTrait.php index c7fbfc4344..9dfa0f480c 100644 --- a/src/Drupal/DrupalKernelTrait.php +++ b/src/Drupal/DrupalKernelTrait.php @@ -2,6 +2,7 @@ namespace Drush\Drupal; +use Symfony\Component\DependencyInjection\ContainerInterface; use Composer\Semver\Semver; use Drupal\Core\DependencyInjection\ServiceModifierInterface; use Drupal\Core\Site\Settings; @@ -44,7 +45,7 @@ protected function getContainerBuilder() /** * Initializes the service container. * - * @return \Symfony\Component\DependencyInjection\ContainerInterface + * @return ContainerInterface */ protected function initializeContainer() { diff --git a/src/Drupal/DrupalUtil.php b/src/Drupal/DrupalUtil.php index 7346695d5a..21b476ae6c 100644 --- a/src/Drupal/DrupalUtil.php +++ b/src/Drupal/DrupalUtil.php @@ -1,6 +1,8 @@ renderRoot($data); } - $data = \Drupal\Core\Mail\MailFormatHelper::htmlToText($data); + $data = MailFormatHelper::htmlToText($data); return $data; } } diff --git a/src/Drupal/DrushLoggerServiceProvider.php b/src/Drupal/DrushLoggerServiceProvider.php index a03c5d4fa4..15ba28e469 100644 --- a/src/Drupal/DrushLoggerServiceProvider.php +++ b/src/Drupal/DrushLoggerServiceProvider.php @@ -2,6 +2,7 @@ namespace Drush\Drupal; +use Drush\Log\DrushLog; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceProviderInterface; use Drush\Log\LoggerDrupalToDrush; @@ -12,9 +13,9 @@ class DrushLoggerServiceProvider implements ServiceProviderInterface /** * @inheritDoc */ - public function register(ContainerBuilder $container) + public function register(ContainerBuilder $container): void { - $container->register('logger.drupaltodrush', \Drush\Log\DrushLog::class) + $container->register('logger.drupaltodrush', DrushLog::class) ->addArgument(new Reference('logger.log_message_parser')) ->addTag('logger'); } diff --git a/src/Drupal/DrushServiceModifier.php b/src/Drupal/DrushServiceModifier.php index b45f49bc30..e18b0c6dba 100644 --- a/src/Drupal/DrushServiceModifier.php +++ b/src/Drupal/DrushServiceModifier.php @@ -2,6 +2,7 @@ namespace Drush\Drupal; +use DrupalCodeGenerator\Application; use Drush\Drush; use Drupal\Core\DependencyInjection\ServiceModifierInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; @@ -20,7 +21,7 @@ class DrushServiceModifier implements ServiceModifierInterface /** * @inheritdoc */ - public function alter(ContainerBuilder $container) + public function alter(ContainerBuilder $container): void { Drush::logger()->debug(dt("Service modifier alter.")); // http://symfony.com/doc/2.7/components/dependency_injection/tags.html#register-the-pass-with-the-container @@ -31,7 +32,7 @@ public function alter(ContainerBuilder $container) $container->register(self::DRUSH_COMMAND_INFO_ALTERER_SERVICES, 'Drush\Command\ServiceCommandlist'); $container->addCompilerPass(new FindCommandsCompilerPass(self::DRUSH_COMMAND_INFO_ALTERER_SERVICES, 'drush.command_info_alterer')); $container->register(self::DRUSH_GENERATOR_SERVICES, 'Drush\Command\ServiceCommandlist'); - $container->addCompilerPass(new FindCommandsCompilerPass(self::DRUSH_GENERATOR_SERVICES, 'drush.generator.v' . \DrupalCodeGenerator\Application::API)); + $container->addCompilerPass(new FindCommandsCompilerPass(self::DRUSH_GENERATOR_SERVICES, 'drush.generator.v' . Application::API)); } /** @@ -39,9 +40,8 @@ public function alter(ContainerBuilder $container) * * @param $container_definition * Cached container definition - * @return bool */ - public function check($container_definition) + public function check($container_definition): bool { return isset($container_definition['services'][self::DRUSH_CONSOLE_SERVICES]) && diff --git a/src/Drupal/ExtensionDiscovery.php b/src/Drupal/ExtensionDiscovery.php index 3ceda8492c..722c5ce321 100644 --- a/src/Drupal/ExtensionDiscovery.php +++ b/src/Drupal/ExtensionDiscovery.php @@ -6,7 +6,7 @@ class ExtensionDiscovery extends DrupalExtensionDiscovery { - public static function reset() + public static function reset(): void { static::$files = []; } diff --git a/src/Drupal/FindCommandsCompilerPass.php b/src/Drupal/FindCommandsCompilerPass.php index b1b029a085..505702142f 100644 --- a/src/Drupal/FindCommandsCompilerPass.php +++ b/src/Drupal/FindCommandsCompilerPass.php @@ -41,7 +41,7 @@ public function __construct($storageClassId, $tagId) $this->tagId = $tagId; } - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { Drush::logger()->debug(dt("process !storage !tag", ['!storage' => $this->storageClassId, '!tag' => $this->tagId])); // We expect that our called registered the storage diff --git a/src/Drupal/Migrate/MigrateExecutable.php b/src/Drupal/Migrate/MigrateExecutable.php index 2f3927c753..900e7e0ad9 100644 --- a/src/Drupal/Migrate/MigrateExecutable.php +++ b/src/Drupal/Migrate/MigrateExecutable.php @@ -2,6 +2,7 @@ namespace Drush\Drupal\Migrate; +use Drupal\migrate\MigrateException; use Drupal\Component\Utility\Timer; use Drupal\migrate\Event\MigrateEvents; use Drupal\migrate\Event\MigrateImportEvent; @@ -25,7 +26,7 @@ class MigrateExecutable extends MigrateExecutableBase /** * The Symfony console output. * - * @var \Symfony\Component\Console\Output\OutputInterface + * @var OutputInterface */ protected $output; @@ -122,7 +123,7 @@ class MigrateExecutable extends MigrateExecutableBase /** * Static cached ID map. * - * @var \Drush\Drupal\Migrate\MigrateIdMapFilter + * @var MigrateIdMapFilter */ protected $idMap; @@ -136,19 +137,19 @@ class MigrateExecutable extends MigrateExecutableBase /** * The Symfony progress bar. * - * @var \Symfony\Component\Console\Helper\ProgressBar + * @var ProgressBar */ protected $progressBar; /** * Constructs a new migrate executable instance. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * @param \Drupal\migrate\MigrateMessageInterface $message - * @param \Symfony\Component\Console\Output\OutputInterface $output + * @param MigrationInterface $migration + * @param MigrateMessageInterface $message + * @param OutputInterface $output * @param array $options * - * @throws \Drupal\migrate\MigrateException + * @throws MigrateException */ public function __construct(MigrationInterface $migration, MigrateMessageInterface $message, OutputInterface $output, array $options = []) { @@ -207,7 +208,7 @@ public function __construct(MigrationInterface $migration, MigrateMessageInterfa /** * Counts up any map save events. * - * @param \Drupal\migrate\Event\MigrateMapSaveEvent $event + * @param MigrateMapSaveEvent $event * The map event. */ public function onMapSave(MigrateMapSaveEvent $event): void @@ -227,7 +228,7 @@ public function onMapSave(MigrateMapSaveEvent $event): void /** * Counts up any rollback events. * - * @param \Drupal\migrate\Event\MigrateMapDeleteEvent $event + * @param MigrateMapDeleteEvent $event * The map event. */ public function onMapDelete(MigrateMapDeleteEvent $event): void @@ -239,7 +240,7 @@ public function onMapDelete(MigrateMapDeleteEvent $event): void /** * Reacts when the import is about to start. * - * @param \Drupal\migrate\Event\MigrateImportEvent $event + * @param MigrateImportEvent $event * The import event. */ public function onPreImport(MigrateImportEvent $event): void @@ -264,7 +265,7 @@ public function onPreImport(MigrateImportEvent $event): void * propagation, thus avoiding the destination object rollback, even when * the`--delete` option has been passed. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * * @see \Drush\Drupal\Migrate\MigrateExecutable::onMissingSourceRows() */ @@ -297,7 +298,7 @@ protected function handleMissingSourceRows(MigrationInterface $migration): void * destination entity and then stopping the event propagation, thus avoiding * the destination object deletion, even the `--delete` option was passed. * - * @param \Drush\Drupal\Migrate\MigrateMissingSourceRowsEvent $event + * @param MigrateMissingSourceRowsEvent $event * The event object. */ public function onMissingSourceRows(MigrateMissingSourceRowsEvent $event): void @@ -326,7 +327,7 @@ public function onMissingSourceRows(MigrateMissingSourceRowsEvent $event): void /** * Reacts to migration completion. * - * @param \Drupal\migrate\Event\MigrateImportEvent $event + * @param MigrateImportEvent $event * The map event. */ public function onPostImport(MigrateImportEvent $event): void @@ -341,10 +342,8 @@ public function onPostImport(MigrateImportEvent $event): void /** * Emits information on the import progress. - * - * @param bool $done */ - protected function importFeedbackMessage($done = true): void + protected function importFeedbackMessage(bool $done = true): void { $processed = $this->getProcessedCount(); $timer = Timer::read('migrate:' . $this->migration->getPluginId()); @@ -392,7 +391,7 @@ protected function importFeedbackMessage($done = true): void /** * Reacts when the rollback is about to starts. * - * @param \Drupal\migrate\Event\MigrateRollbackEvent $event + * @param MigrateRollbackEvent $event * The map event. */ public function onPreRollback(MigrateRollbackEvent $event): void @@ -403,7 +402,7 @@ public function onPreRollback(MigrateRollbackEvent $event): void /** * Reacts to rollback completion. * - * @param \Drupal\migrate\Event\MigrateRollbackEvent $event + * @param MigrateRollbackEvent $event * The map event. */ public function onPostRollback(MigrateRollbackEvent $event): void @@ -423,10 +422,8 @@ public function onPostRollback(MigrateRollbackEvent $event): void /** * Emits information on the rollback execution progress. - * - * @param bool $done */ - protected function rollbackFeedbackMessage($done = true): void + protected function rollbackFeedbackMessage(bool $done = true): void { $rolledBack = $this->getRollbackCount(); if ($done) { @@ -452,7 +449,7 @@ protected function rollbackFeedbackMessage($done = true): void /** * Reacts to an item about to be imported. * - * @param \Drupal\migrate\Event\MigratePreRowSaveEvent $event + * @param MigratePreRowSaveEvent $event * The pre-save event. */ public function onPreRowSave(MigratePreRowSaveEvent $event): void @@ -468,7 +465,7 @@ public function onPreRowSave(MigratePreRowSaveEvent $event): void /** * Reacts aftre a row has been deleted. * - * @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event + * @param MigratePostRowSaveEvent $event * The event. */ public function onPostRowSave(MigratePostRowSaveEvent $event): void @@ -479,7 +476,7 @@ public function onPostRowSave(MigratePostRowSaveEvent $event): void /** * Reacts to item rollback. * - * @param \Drupal\migrate\Event\MigrateRowDeleteEvent $event + * @param MigrateRowDeleteEvent $event * The post-save event. */ public function onPostRowDelete(MigrateRowDeleteEvent $event): void @@ -493,10 +490,10 @@ public function onPostRowDelete(MigrateRowDeleteEvent $event): void /** * Reacts to a new row being prepared. * - * @param \Drush\Drupal\Migrate\MigratePrepareRowEvent $event + * @param MigratePrepareRowEvent $event * The prepare-row event. * - * @throws \Drupal\migrate\MigrateSkipRowException + * @throws MigrateSkipRowException */ public function onPrepareRow(MigratePrepareRowEvent $event): void { @@ -621,7 +618,7 @@ protected function resetCounters(): void /** * Initializes the command progress bar if possible. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration. */ protected function initProgressBar(MigrationInterface $migration): void diff --git a/src/Drupal/Migrate/MigrateIdMapFilter.php b/src/Drupal/Migrate/MigrateIdMapFilter.php index b50dc00adb..ee12bc8c37 100644 --- a/src/Drupal/Migrate/MigrateIdMapFilter.php +++ b/src/Drupal/Migrate/MigrateIdMapFilter.php @@ -25,7 +25,7 @@ class MigrateIdMapFilter extends \FilterIterator protected $destinationIdList; /** - * @param \Drupal\migrate\Plugin\MigrateIdMapInterface $idMap + * @param MigrateIdMapInterface $idMap * The ID map. * @param array|null $sourceIdList * The source ID list to filter on. @@ -49,7 +49,7 @@ public function accept(): bool return true; } - /** @var \Drupal\migrate\Plugin\MigrateIdMapInterface $idMap */ + /** @var MigrateIdMapInterface $idMap */ $idMap = $this->getInnerIterator(); $acceptedBySourceIdList = $this->sourceIdList && in_array(array_values($idMap->currentSource()), $this->sourceIdList); diff --git a/src/Drupal/Migrate/MigrateMessage.php b/src/Drupal/Migrate/MigrateMessage.php index 98d7fa06c2..a6e24da568 100644 --- a/src/Drupal/Migrate/MigrateMessage.php +++ b/src/Drupal/Migrate/MigrateMessage.php @@ -17,7 +17,7 @@ class MigrateMessage implements MigrateMessageInterface, LoggerAwareInterface /** * Constructs a migrate message class. * - * @param \Psr\Log\LoggerInterface $logger + * @param LoggerInterface $logger */ public function __construct(LoggerInterface $logger) { diff --git a/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php b/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php index 9e72f18918..1054d34a12 100644 --- a/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php +++ b/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php @@ -13,7 +13,7 @@ class MigrateMissingSourceRowsEvent extends Event /** * The migration plugin instance. * - * @var \Drupal\migrate\Plugin\MigrationInterface + * @var MigrationInterface */ protected $migration; @@ -27,7 +27,7 @@ class MigrateMissingSourceRowsEvent extends Event /** * Constructs a new event instance. * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * The migration plugin instance. * @param array[] $destinationIds * Values representing the destination ID. @@ -41,7 +41,7 @@ public function __construct(MigrationInterface $migration, array $destinationIds /** * Gets the migration plugin instance. * - * @return \Drupal\migrate\Plugin\MigrationInterface + * @return MigrationInterface * The migration being rolled back. */ public function getMigration(): MigrationInterface diff --git a/src/Drupal/Migrate/MigratePrepareRowEvent.php b/src/Drupal/Migrate/MigratePrepareRowEvent.php index 07f134fe56..fa6c1e259f 100644 --- a/src/Drupal/Migrate/MigratePrepareRowEvent.php +++ b/src/Drupal/Migrate/MigratePrepareRowEvent.php @@ -20,32 +20,32 @@ final class MigratePrepareRowEvent extends Event /** * Row object. * - * @var \Drupal\migrate\Row + * @var Row */ protected $row; /** * Migration source plugin. * - * @var \Drupal\migrate\Plugin\MigrateSourceInterface + * @var MigrateSourceInterface */ protected $source; /** * Migration plugin. * - * @var \Drupal\migrate\Plugin\MigrationInterface + * @var MigrationInterface */ protected $migration; /** * Constructs a prepare-row event object. * - * @param \Drupal\migrate\Row $row + * @param Row $row * Row of source data to be analyzed/manipulated. - * @param \Drupal\migrate\Plugin\MigrateSourceInterface $source + * @param MigrateSourceInterface $source * Source plugin that is the source of the event. - * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * @param MigrationInterface $migration * Migration entity. */ public function __construct(Row $row, MigrateSourceInterface $source, MigrationInterface $migration) @@ -58,7 +58,7 @@ public function __construct(Row $row, MigrateSourceInterface $source, MigrationI /** * Gets the row object. * - * @return \Drupal\migrate\Row + * @return Row * The row object about to be imported. */ public function getRow(): Row @@ -67,11 +67,11 @@ public function getRow(): Row } /** - * Gets the source plugin. - * - * @return \Drupal\migrate\Plugin\MigrateSourceInterface $source - * The source plugin firing the event. - */ + * Gets the source plugin. + * + * @return MigrateSourceInterface $source + The source plugin firing the event. + */ public function getSource(): MigrateSourceInterface { return $this->source; @@ -80,7 +80,7 @@ public function getSource(): MigrateSourceInterface /** * Gets the migration plugin. * - * @return \Drupal\migrate\Plugin\MigrationInterface + * @return MigrationInterface * The migration entity being imported. */ public function getMigration(): MigrationInterface From c002d7253a0db8b4eab82a1efd4c7d016550fdbb Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 13:25:32 -0500 Subject: [PATCH 046/125] Prep for 11.0.0-rc5 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..36481ac407 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0-rc5 From fbd6184734658ac1749bcb32d2c6357232a50956 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 13:30:05 -0500 Subject: [PATCH 047/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 36481ac407..9ad93d53df 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-rc5 +drush_version=11.0.0-dev From 21eb502f9a2057623f6bd76f62da8c27eaf1fb4a Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 14:52:38 -0500 Subject: [PATCH 048/125] Remove vestiges of Backend invoke system (#4964) * remove vestiges of Backend invoke system. * PHPCS --- includes/backend.inc | 118 ---------------------------- includes/batch.inc | 5 -- src/Config/DrushConfig.php | 8 -- src/Log/Logger.php | 5 -- src/Preflight/LegacyPreflight.php | 1 - src/Preflight/PreflightArgs.php | 123 ++++++------------------------ 6 files changed, 22 insertions(+), 238 deletions(-) delete mode 100644 includes/backend.inc diff --git a/includes/backend.inc b/includes/backend.inc deleted file mode 100644 index e88a0c643c..0000000000 --- a/includes/backend.inc +++ /dev/null @@ -1,118 +0,0 @@ ->>'); -define('DRUSH_BACKEND_OUTPUT_DELIMITER', DRUSH_BACKEND_OUTPUT_START . '%s<<get(\Robo\Config\Config::SIMULATE); } - /** - * Return 'true' if we are in backend mode. - */ - public function backend() - { - return $this->get(PreflightArgs::BACKEND); - } - /** * Return the list of paths to active Drush configuration files. * @return array diff --git a/src/Log/Logger.php b/src/Log/Logger.php index c508bcfbd7..32fd7422df 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -9,11 +9,6 @@ * * This logger is designed such that it can be provided to * other libraries that log to a Psr\Log\LoggerInterface. - * As such, it takes responsibility for passing log messages - * to backend invoke, as necessary (c.f. drush_backend_packet()). - * - * Drush supports all of the required log levels from Psr\Log\LogLevel, - * and also defines its own. See Drush\Log\LogLevel. * * Those who may wish to change the way logging works in Drush * should therefore NOT attempt to replace this logger with their diff --git a/src/Preflight/LegacyPreflight.php b/src/Preflight/LegacyPreflight.php index 1ffa3d365c..05520d3296 100644 --- a/src/Preflight/LegacyPreflight.php +++ b/src/Preflight/LegacyPreflight.php @@ -70,7 +70,6 @@ public static function includeCode($drushBasePath): void require_once $drushBasePath . '/includes/preflight.inc'; require_once $drushBasePath . '/includes/bootstrap.inc'; require_once $drushBasePath . '/includes/environment.inc'; - require_once $drushBasePath . '/includes/backend.inc'; require_once $drushBasePath . '/includes/drush.inc'; require_once $drushBasePath . '/includes/batch.inc'; require_once $drushBasePath . '/includes/drupal.inc'; diff --git a/src/Preflight/PreflightArgs.php b/src/Preflight/PreflightArgs.php index c4f151923a..33de98da41 100644 --- a/src/Preflight/PreflightArgs.php +++ b/src/Preflight/PreflightArgs.php @@ -19,6 +19,7 @@ */ class PreflightArgs extends Config implements PreflightArgsInterface { + /** * @var array $args Remaining arguments not handled by the preprocessor */ @@ -42,18 +43,29 @@ public function setHomeDir(string $homeDir): void } const DRUSH_CONFIG_PATH_NAMESPACE = 'drush.paths'; + const DRUSH_RUNTIME_CONTEXT_NAMESPACE = 'runtime.contxt'; + const ALIAS = 'alias'; + const ALIAS_PATH = 'alias-path'; + const COMMAND_PATH = 'include'; + const CONFIG_PATH = 'config'; + const COVERAGE_FILE = 'coverage-file'; + const LOCAL = 'local'; + const ROOT = 'root'; + const URI = 'uri'; + const SIMULATE = 'simulate'; - const BACKEND = 'backend'; + const STRICT = 'strict'; + const DEBUG = 'preflight-debug'; /** @@ -86,7 +98,6 @@ public function optionsWithValues(): array '--local' => 'setLocal', '--simulate' => 'setSimulate', '-s' => 'setSimulate', - '--backend=' => 'setBackend', '--drush-coverage=' => 'setCoverageFile', '--strict=' => 'setStrict', '--help' => 'adjustHelpOption', @@ -113,9 +124,8 @@ public function adjustHelpOption(): void protected function optionConfigMap(): array { return [ - self::SIMULATE => \Robo\Config\Config::SIMULATE, - self::BACKEND => self::BACKEND, - self::LOCAL => self::DRUSH_RUNTIME_CONTEXT_NAMESPACE . '.' . self::LOCAL, + self::SIMULATE => \Robo\Config\Config::SIMULATE, + self::LOCAL => self::DRUSH_RUNTIME_CONTEXT_NAMESPACE . '.' . self::LOCAL, ]; } @@ -127,9 +137,9 @@ protected function optionConfigMap(): array protected function optionConfigPathMap(): array { return [ - self::ALIAS_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::ALIAS_PATH, - self::CONFIG_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::CONFIG_PATH, - self::COMMAND_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::COMMAND_PATH, + self::ALIAS_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::ALIAS_PATH, + self::CONFIG_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::CONFIG_PATH, + self::COMMAND_PATH => self::DRUSH_CONFIG_PATH_NAMESPACE . '.' . self::COMMAND_PATH, ]; } @@ -147,7 +157,7 @@ public function applyToConfig(ConfigInterface $config): void // Merging as they are lists. foreach ($this->optionConfigPathMap() as $option_key => $config_key) { $cli_paths = $this->get($option_key, []); - $config_paths = (array) $config->get($config_key, []); + $config_paths = (array)$config->get($config_key, []); $merged_paths = array_unique(array_merge($cli_paths, $config_paths)); $config->set($config_key, $merged_paths); @@ -193,6 +203,7 @@ public function setCommandName($commandName): void { $this->commandName = $commandName; } + /** * @inheritdoc */ @@ -410,27 +421,6 @@ public function setSimulate($simulate): self return $this->set(self::SIMULATE, $simulate); } - /** - * Determine whether Drush was placed in simulated mode. - */ - public function isBackend() - { - return $this->get(self::BACKEND); - } - - /** - * Set backend mode - */ - public function setBackend(bool $backend) - { - if ($backend == 'json') { - // Remap to --format. See \Drush\Commands\sql\SqlSyncCommands::dump. - $this->addArg('--format=json'); - } else { - return $this->set(self::BACKEND, true); - } - } - /** * Get the path to the coverage file. */ @@ -470,6 +460,7 @@ public function setStrict(bool $strict): self * just the option name of any item that is an option. * * @param array $argv e.g. ['foo', '--bar=baz', 'boz'] + * * @return string[] e.g. ['bar'] */ protected function getOptionNameList(array $argv): array @@ -500,81 +491,11 @@ public function createInput(): \Symfony\Component\Console\Input\InputInterface { // In strict mode (the default), create an ArgvInput. When // strict mode is disabled, create a more forgiving input object. - if ($this->isStrict() && !$this->isBackend()) { + if ($this->isStrict()) { return new DrushArgvInput($this->args()); } - // If in backend mode, read additional options from stdin. - // TODO: Maybe reading stdin options should be the responsibility of some - // backend manager class? Could be called from preflight and injected here. $input = new LessStrictArgvInput($this->args()); - $input->injectAdditionalOptions($this->readStdinOptions()); - return $input; } - - /** - * Read options fron STDIN during POST requests. - * - * This function will read any text from the STDIN pipe, - * and attempts to generate an associative array if valid - * JSON was received. - * - * @return - * An associative array of options, if successfull. Otherwise an empty array. - */ - protected function readStdinOptions() - { - // If we move this method to a backend manager, then testing for - // backend mode will be the responsibility of the caller. - if (!$this->isBackend()) { - return []; - } - - $fp = fopen('php://stdin', 'r'); - // Windows workaround: we cannot count on stream_get_contents to - // return if STDIN is reading from the keyboard. We will therefore - // check to see if there are already characters waiting on the - // stream (as there always should be, if this is a backend call), - // and if there are not, then we will exit. - // This code prevents drush from hanging forever when called with - // --backend from the commandline; however, overall it is still - // a futile effort, as it does not seem that backend invoke can - // successfully write data to that this function can read, - // so the argument list and command always come out empty. :( - // Perhaps stream_get_contents is the problem, and we should use - // the technique described here: - // http://bugs.php.net/bug.php?id=30154 - // n.b. the code in that issue passes '0' for the timeout in stream_select - // in a loop, which is not recommended. - // Note that the following DOES work: - // drush ev 'print(json_encode(array("test" => "XYZZY")));' | drush status --backend - // So, redirecting input is okay, it is just the proc_open that is a problem. - if (drush_is_windows()) { - // Note that stream_select uses reference parameters, so we need variables (can't pass a constant NULL) - $read = [$fp]; - $write = null; - $except = null; - // Question: might we need to wait a bit for STDIN to be ready, - // even if the process that called us immediately writes our parameters? - // Passing '100' for the timeout here causes us to hang indefinitely - // when called from the shell. - $changed_streams = stream_select($read, $write, $except, 0); - // Return on error or no changed streams (0). - // Oh, according to http://php.net/manual/en/function.stream-select.php, - // stream_select will return FALSE for streams returned by proc_open. - // That is not applicable to us, is it? Our stream is connected to a stream - // created by proc_open, but is not a stream returned by proc_open. - if ($changed_streams < 1) { - return []; - } - } - stream_set_blocking($fp, false); - $string = stream_get_contents($fp); - fclose($fp); - if (trim($string)) { - return json_decode($string, true); - } - return []; - } } From 49446e68995b8efc97fb5d20f4b410610b62f2fa Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 15:25:48 -0500 Subject: [PATCH 049/125] More complete tearDown in test --- tests/integration/ModuleGeneratorTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/integration/ModuleGeneratorTest.php b/tests/integration/ModuleGeneratorTest.php index e67c67c417..d7c25c20b2 100644 --- a/tests/integration/ModuleGeneratorTest.php +++ b/tests/integration/ModuleGeneratorTest.php @@ -23,4 +23,11 @@ public function testModuleGenerators(): void $this->assertStringContainsString('woot:example', $this->getOutput()); $this->assertStringContainsString('Generates a woot.', $this->getOutput()); } + + public function tearDown(): void + { + $this->drush('pm:uninstall', ['woot']); + parent::tearDown(); + } + } From bc8534364c48b43c8f7a37202eea81a19d8f3228 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 15:30:22 -0500 Subject: [PATCH 050/125] PHPCS fix --- tests/integration/ModuleGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/ModuleGeneratorTest.php b/tests/integration/ModuleGeneratorTest.php index d7c25c20b2..8983648ebf 100644 --- a/tests/integration/ModuleGeneratorTest.php +++ b/tests/integration/ModuleGeneratorTest.php @@ -29,5 +29,4 @@ public function tearDown(): void $this->drush('pm:uninstall', ['woot']); parent::tearDown(); } - } From 7baba0d93ef2a343663dcbf7e696c74514dfa33e Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 21:30:55 -0500 Subject: [PATCH 051/125] Remove Drush's cache API. We no longer need to cache annotation parsing. (#4965) * Remove Drush's cache API. We no longer need to cache annotation parsing. * More deletion --- includes/cache.inc | 170 --------------------------- src/Cache/CacheInterface.php | 114 ------------------ src/Cache/CommandCache.php | 64 ---------- src/Cache/FileCache.php | 175 ---------------------------- src/Cache/JSONCache.php | 32 ----- src/Commands/core/CacheCommands.php | 3 +- src/Preflight/LegacyPreflight.php | 1 - src/Runtime/DependencyInjection.php | 6 - 8 files changed, 1 insertion(+), 564 deletions(-) delete mode 100644 includes/cache.inc delete mode 100644 src/Cache/CacheInterface.php delete mode 100644 src/Cache/CommandCache.php delete mode 100644 src/Cache/FileCache.php delete mode 100644 src/Cache/JSONCache.php diff --git a/includes/cache.inc b/includes/cache.inc deleted file mode 100644 index 24fc468fef..0000000000 --- a/includes/cache.inc +++ /dev/null @@ -1,170 +0,0 @@ -get($cid); - $mess = $ret ? "HIT" : "MISS"; - Drush::logger()->debug(dt("Cache !mess cid: !cid", ['!mess' => $mess, '!cid' => $cid])); - return $ret; -} - -/** - * Return data from the persistent cache when given an array of cache IDs. - * - * @param array $cids - * An array of cache IDs for the data to retrieve. This is passed by - * reference, and will have the IDs successfully returned from cache removed. - * @param string $bin - * The cache bin where the data is stored. - * - * @return - * An array of the items successfully returned from cache indexed by cid. - */ -function drush_cache_get_multiple(array &$cids, $bin = 'default') { - return _drush_cache_get_object($bin)->getMultiple($cids); -} - -/** - * Store data in the persistent cache. - * - * @param string $cid - * The cache ID of the data to store. - * - * @param $data - * The data to store in the cache. - * @param string $bin - * The cache bin to store the data in. - * @param $expire - * One of the following values: - * - DRUSH_CACHE_PERMANENT: Indicates that the item should never be removed - * unless explicitly told to using drush_cache_clear_all() with a cache ID. - * - DRUSH_CACHE_TEMPORARY: Indicates that the item should be removed at - * the next general cache wipe. - * - A Unix timestamp: Indicates that the item should be kept at least until - * the given time, after which it behaves like DRUSH_CACHE_TEMPORARY. - * - * @return bool - */ -function drush_cache_set($cid, $data, $bin = 'default', $expire = DRUSH_CACHE_PERMANENT) { - if ($ret = _drush_cache_get_object($bin)->set($cid, $data, $expire)) { - Drush::logger()->debug(dt("Cache SET cid: !cid", ['!cid' => $cid])); - return $ret; - } -} - -/** - * Expire data from the cache. - * - * If called without arguments, expirable entries will be cleared from all known - * cache bins. - * - * @param string $cid - * If set, the cache ID to delete. Otherwise, all cache entries that can - * expire are deleted. - * @param string $bin - * If set, the bin $bin to delete from. Mandatory - * argument if $cid is set. - * @param bool $wildcard - * If $wildcard is TRUE, cache IDs starting with $cid are deleted in - * addition to the exact cache ID specified by $cid. If $wildcard is - * TRUE and $cid is '*' then the entire bin $bin is emptied. - */ -function drush_cache_clear_all($cid = NULL, $bin = 'default', $wildcard = FALSE) { - if (!isset($cid) && !isset($bin)) { - foreach (drush_cache_get_bins() as $bin) { - _drush_cache_get_object($bin)->clear(); - } - return; - } - return _drush_cache_get_object($bin)->clear($cid, $wildcard); -} - -/** - * Check if a cache bin is empty. - * - * A cache bin is considered empty if it does not contain any valid data for any - * cache ID. - * - * @param $bin - * The cache bin to check. - * - * @return - * TRUE if the cache bin specified is empty. - */ -function _drush_cache_is_empty($bin) { - return _drush_cache_get_object($bin)->isEmpty(); -} - -/** - * Return drush cache bins and any bins added by hook_drush_flush_caches(). - */ -function drush_cache_get_bins() { - $drush = ['default']; - return $drush; - // return array_merge(drush_command_invoke_all('drush_flush_caches'), $drush); -} diff --git a/src/Cache/CacheInterface.php b/src/Cache/CacheInterface.php deleted file mode 100644 index 5cf54469e9..0000000000 --- a/src/Cache/CacheInterface.php +++ /dev/null @@ -1,114 +0,0 @@ -cacheBackend = $cacheBackend; - } - - /** - * Test for an entry from the cache - * @param string $key - * @return boolean - */ - public function has($key) - { - $cacheItem = $this->cacheBackend->get($key); - return $this->valid($cacheItem); - } - /** - * Get an entry from the cache - * @param string $key - * @return array - */ - public function get($key) - { - $cacheItem = $this->cacheBackend->get($key); - if (!$this->valid($cacheItem)) { - return []; - } - // TODO: FileCache::get() should just return the - // data element, not the entire cacheItem. Then we - // could make it implement SimpleCacheInterface & do - // away with this adapter class. - return $cacheItem->data; - } - /** - * Store an entry in the cache - * @param string $key - * @param array $data - */ - public function set($key, $data) - { - $this->cacheBackend->set($key, $data); - } - - protected function valid($cacheItem) - { - return is_object($cacheItem) && isset($cacheItem->data); - } -} diff --git a/src/Cache/FileCache.php b/src/Cache/FileCache.php deleted file mode 100644 index 848fdd6f70..0000000000 --- a/src/Cache/FileCache.php +++ /dev/null @@ -1,175 +0,0 @@ -bin = $bin; - $this->directory = $this->cacheDirectory(); - } - - /** - * Returns the cache directory for the given bin. - * - * @param string $bin - */ - public function cacheDirectory($bin = null) - { - $bin = $bin ? $bin : $this->bin; - return Path::join(Drush::config()->cache(), $bin); - } - - public function get($cid) - { - $cids = [$cid]; - $cache = $this->getMultiple($cids); - return reset($cache); - } - - public function getMultiple(&$cids) - { - try { - $cache = []; - foreach ($cids as $cid) { - $filename = $this->getFilePath($cid); - if (!file_exists($filename)) { - return []; - } - - $item = $this->readFile($filename); - if ($item) { - $cache[$cid] = $item; - } - } - $cids = array_diff($cids, array_keys($cache)); - return $cache; - } catch (\Exception $e) { - return []; - } - } - - /** - * Returns the contents of the given filename unserialized. - * - * @param string $filename - * Absolute path to filename to read contents from. - */ - public function readFile($filename) - { - $item = file_get_contents($filename); - return $item ? unserialize($item) : false; - } - - public function set($cid, $data, $expire = DRUSH_CACHE_PERMANENT) - { - $created = time(); - - $cache = new \stdClass; - $cache->cid = $cid; - $cache->data = is_object($data) ? clone $data : $data; - $cache->created = $created; - if ($expire == DRUSH_CACHE_TEMPORARY) { - $cache->expire = $created + 2591999; - } elseif ($expire != DRUSH_CACHE_PERMANENT && $expire < 2592000) { - // Expire time is in seconds if less than 30 days, otherwise is a timestamp. - $cache->expire = $created + $expire; - } else { - $cache->expire = $expire; - } - - // Ensure the cache directory still exists, in case a backend process - // cleared the cache after the cache was initialized. - $fs = new Filesystem(); - $fs->mkdir($this->directory); - - $filename = $this->getFilePath($cid); - return $this->writeFile($filename, $cache); - } - - /** - * Serializes data and write it to the given filename. - * - * @param string $filename - * Absolute path to filename to write cache data. - * @param $cache - * Cache data to serialize and write to $filename. - */ - public function writeFile($filename, $cache) - { - return file_put_contents($filename, serialize($cache)); - } - - public function clear($cid = null, $wildcard = false) - { - $fs = new Filesystem(); - $bin_dir = $this->cacheDirectory(); - $files = []; - if (empty($cid)) { - $fs->remove($bin_dir); - } else { - if ($wildcard) { - if ($cid == '*') { - $fs->remove($bin_dir); - } else { - $files = Finder::create() - ->files() - ->name($cid) - ->in($bin_dir); - } - } else { - $files[] = $this->getFilePath($cid); - } - - $fs->remove($files); - } - } - - public function isEmpty() - { - $files = Finder::create() - ->files() - ->name() - ->exclude() - ->depth(0) - ->in($this->directory); - return empty($files); - } - - /** - * Converts a cache id to a full path. - * - * @param $cid - * The cache ID of the data to retrieve. - * - * @return - * The full path to the cache file. - */ - protected function getFilePath($cid) - { - return $this->directory . '/' . str_replace([':', '\\', '/'], '.', $cid) . self::EXTENSION; - } -} diff --git a/src/Cache/JSONCache.php b/src/Cache/JSONCache.php deleted file mode 100644 index 5f5c8ffd97..0000000000 --- a/src/Cache/JSONCache.php +++ /dev/null @@ -1,32 +0,0 @@ - and &, so we do it with str_replace(). - $json = str_replace(['<', '>', '&'], ['\u003c', '\u003e', '\u0026'], $json); - return file_put_contents($filename, $json); - } -} diff --git a/src/Commands/core/CacheCommands.php b/src/Commands/core/CacheCommands.php index 413ac5009c..b80548af59 100644 --- a/src/Commands/core/CacheCommands.php +++ b/src/Commands/core/CacheCommands.php @@ -300,8 +300,7 @@ public function getTypes($include_bootstrapped_types = false): array public static function clearDrush(): void { try { - drush_cache_clear_all(null, 'default');// No longer used by Drush core, but still cleared for backward compat. - drush_cache_clear_all(null, 'factory'); // command info from annotated-command library (i.e. parsed annotations) + // No longer anything to do here. Left because some commandfiles may try to call this. } catch (IOException $e) { // Sometimes another process writes files into a bin dir and \Drush\Cache\FileCache::clear fails. // That is not considered an error. https://github.com/drush-ops/drush/pull/4535. diff --git a/src/Preflight/LegacyPreflight.php b/src/Preflight/LegacyPreflight.php index 05520d3296..6f062f6f7f 100644 --- a/src/Preflight/LegacyPreflight.php +++ b/src/Preflight/LegacyPreflight.php @@ -74,7 +74,6 @@ public static function includeCode($drushBasePath): void require_once $drushBasePath . '/includes/batch.inc'; require_once $drushBasePath . '/includes/drupal.inc'; require_once $drushBasePath . '/includes/output.inc'; - require_once $drushBasePath . '/includes/cache.inc'; require_once $drushBasePath . '/includes/filesystem.inc'; require_once $drushBasePath . '/includes/legacy.inc'; } diff --git a/src/Runtime/DependencyInjection.php b/src/Runtime/DependencyInjection.php index 384057c227..358e5bb4b7 100644 --- a/src/Runtime/DependencyInjection.php +++ b/src/Runtime/DependencyInjection.php @@ -153,15 +153,9 @@ protected function alterServicesForDrush($container, Application $application): $hookManager->addInitializeHook($container->get('bootstrap.hook')); $hookManager->addPreValidator($container->get('tildeExpansion.hook')); - // Install our command cache into the command factory - // TODO: Create class-based implementation of our cache management functions. - $cacheBackend = _drush_cache_get_object('factory'); - $commandCacheDataStore = new CommandCache($cacheBackend); - $factory = $container->get('commandFactory'); $factory->setIncludeAllPublicMethods(false); $factory->setIgnoreCommandsInTraits(true); - $factory->setDataStore($commandCacheDataStore); $factory->addCommandInfoAlterer(new DrushCommandInfoAlterer()); $commandProcessor = $container->get('commandProcessor'); From 700c15cc6291b65fc33d480928fa472e010cb3a4 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 22:46:14 -0500 Subject: [PATCH 052/125] Remove drupal versions functions. (#4967) * Remove drupal versions functions. * remove include --- includes/drupal.inc | 47 ------------------------------- src/Boot/DrupalBoot8.php | 8 ++---- src/Preflight/LegacyPreflight.php | 1 - src/Runtime/ErrorHandler.php | 2 +- 4 files changed, 3 insertions(+), 55 deletions(-) delete mode 100644 includes/drupal.inc diff --git a/includes/drupal.inc b/includes/drupal.inc deleted file mode 100644 index 0f3b3afd4f..0000000000 --- a/includes/drupal.inc +++ /dev/null @@ -1,47 +0,0 @@ -getRoot())) { - $bootstrap = Drush::bootstrapManager()->bootstrapObjectForRoot($drupal_root); - if ($bootstrap) { - $version = $bootstrap->getVersion($drupal_root); - } - } - } - return $version; -} - -/** - * Returns the Drupal major version number (6, 7, 8 ...) - */ -function drush_drupal_major_version($drupal_root = NULL) { - $major_version = FALSE; - if ($version = drush_drupal_version($drupal_root)) { - $version_parts = explode('.', $version); - if (is_numeric($version_parts[0])) { - $major_version = (integer)$version_parts[0]; - } - } - return $major_version; -} diff --git a/src/Boot/DrupalBoot8.php b/src/Boot/DrupalBoot8.php index 34908c2558..3e1dd6c708 100644 --- a/src/Boot/DrupalBoot8.php +++ b/src/Boot/DrupalBoot8.php @@ -83,13 +83,9 @@ public function getVersion($drupal_root) { // Are the class constants available? if (!$this->hasAutoloader()) { - throw new \Exception('Cannot access Drupal 8 class constants - Drupal autoloader not loaded yet.'); - } - // Drush depends on bootstrap being loaded at this point. - require_once $drupal_root .'/core/includes/bootstrap.inc'; - if (defined('\Drupal::VERSION')) { - return \Drupal::VERSION; + throw new \Exception('Cannot access Drupal class constants - Drupal autoloader not loaded yet.'); } + return \Drupal::VERSION; } /** diff --git a/src/Preflight/LegacyPreflight.php b/src/Preflight/LegacyPreflight.php index 6f062f6f7f..2c2b619ae9 100644 --- a/src/Preflight/LegacyPreflight.php +++ b/src/Preflight/LegacyPreflight.php @@ -72,7 +72,6 @@ public static function includeCode($drushBasePath): void require_once $drushBasePath . '/includes/environment.inc'; require_once $drushBasePath . '/includes/drush.inc'; require_once $drushBasePath . '/includes/batch.inc'; - require_once $drushBasePath . '/includes/drupal.inc'; require_once $drushBasePath . '/includes/output.inc'; require_once $drushBasePath . '/includes/filesystem.inc'; require_once $drushBasePath . '/includes/legacy.inc'; diff --git a/src/Runtime/ErrorHandler.php b/src/Runtime/ErrorHandler.php index f7e2d95230..c0fc33e553 100644 --- a/src/Runtime/ErrorHandler.php +++ b/src/Runtime/ErrorHandler.php @@ -37,7 +37,7 @@ public function errorHandler($errno, $message, $filename, $line) if ($errno & error_reporting()) { // By default we log notices. $type = Drush::config()->get('runtime.php.notices', LogLevel::INFO); - $halt_on_error = Drush::config()->get('runtime.php.halt-on-error', (drush_drupal_major_version() != 6)); + $halt_on_error = Drush::config()->get('runtime.php.halt-on-error', true); // Bitmask value that constitutes an error needing to be logged. $error = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR; From 328339d97370c0b041478d8260c1bb80a366e59a Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 31 Dec 2021 23:00:49 -0500 Subject: [PATCH 053/125] Remove deprecated code (#4968) * Remove deprecated code * Remove include --- includes/drush.inc | 4 -- includes/environment.inc | 45 ---------------------- src/Commands/ValidatorsCommands.php | 4 +- src/Drupal/Commands/core/ViewsCommands.php | 2 +- src/Preflight/LegacyPreflight.php | 1 - 5 files changed, 3 insertions(+), 53 deletions(-) delete mode 100644 includes/environment.inc diff --git a/includes/drush.inc b/includes/drush.inc index fbb038fdf9..5229c0bb83 100644 --- a/includes/drush.inc +++ b/includes/drush.inc @@ -127,16 +127,12 @@ function drush_get_global_options($brief = FALSE) { $options['include'] = ['short-form' => 'i', 'short-has-arg' => TRUE, 'context' => 'DRUSH_INCLUDE', 'never-post' => TRUE, 'propagate-cli-value' => TRUE, 'merge-pathlist' => TRUE, 'description' => "A list of additional directory paths to search for Drush commands. Commandfiles should be placed in a subfolder called 'Commands'.", 'example-value' => '/path/dir']; $options['exclude'] = ['propagate-cli-value' => TRUE, 'never-post' => TRUE, 'merge-pathlist' => TRUE, 'description' => "A list of files and directory paths to exclude from consideration when searching for drush commandfiles.", 'example-value' => '/path/dir']; $options['config'] = ['short-form' => 'c', 'short-has-arg' => TRUE, 'context' => 'DRUSH_CONFIG', 'never-post' => TRUE, 'propagate-cli-value' => TRUE, 'merge-pathlist' => TRUE, 'description' => "Specify an additional config file to load. See example.drush.yml", 'example-value' => '/path/file']; - $options['backend'] = ['hidden' => TRUE, 'short-form' => 'b', 'never-propagate' => TRUE, 'description' => "Hide all output and return structured data."]; $options['choice'] = ['description' => "Provide an answer to a multiple-choice prompt.", 'example-value' => 'number']; $options['search-depth'] = ['description' => "Control the depth that drush will search for alias files.", 'example-value' => 'number']; $options['ignored-modules'] = ['description' => "Exclude some modules from consideration when searching for drush command files.", 'example-value' => 'token,views']; $options['no-label'] = ['description' => "Remove the site label that drush includes in multi-site command output (e.g. `drush @site1,@site2 status`)."]; $options['label-separator'] = ['description' => "Specify the separator to use in multi-site command output (e.g. `drush @sites pm-list --label-separator=',' --format=csv`).", 'example-value' => ',']; $options['show-invoke'] = ['description' => "Show all function names which could have been called for the current command. See drush_invoke()."]; - $options['cache-default-class'] = ['description' => "A cache backend class that implements CacheInterface. Defaults to JSONCache.", 'example-value' => 'JSONCache']; - $options['cache-class-'] = ['description' => "A cache backend class that implements CacheInterface to use for a specific cache bin.", 'example-value' => 'className']; - $options['early'] = ['description' => "Include a file (with relative or full path) and call the drush_early_hook() function (where 'hook' is the filename)"]; $options['alias-path'] = ['context' => 'ALIAS_PATH', 'local-context-only' => TRUE, 'merge-pathlist' => TRUE, 'propagate-cli-value' => TRUE, 'description' => "Specifies the list of paths where drush will search for alias files.", 'example-value' => '/path/alias1:/path/alias2']; $options['confirm-rollback'] = ['description' => 'Wait for confirmation before doing a rollback when something goes wrong.']; $options['php-options'] = ['hidden' => TRUE, 'description' => "Options to pass to `php` when running drush. Only effective when specified in a site alias definition.", 'never-propagate' => TRUE, 'example-value' => '-d error_reporting="E_ALL"']; diff --git a/includes/environment.inc b/includes/environment.inc deleted file mode 100644 index e5bf8dfa16..0000000000 --- a/includes/environment.inc +++ /dev/null @@ -1,45 +0,0 @@ -annotationData()->get('validate-file-exists', null)); + $arg_names = StringUtils::csvToArray($commandData->annotationData()->get('validate-file-exists', null)); foreach ($arg_names as $arg_name) { if ($commandData->input()->hasArgument($arg_name)) { $path = $commandData->input()->getArgument($arg_name); @@ -93,7 +93,7 @@ public function validateFileExists(CommandData $commandData) public function validatePHPExtension(CommandData $commandData) { $missing = []; - $arg_names = _convert_csv_to_array($commandData->annotationData()->get('validate-php-extension', null)); + $arg_names = StringUtils::csvToArray($commandData->annotationData()->get('validate-php-extension', null)); foreach ($arg_names as $arg_name) { if (!extension_loaded($arg_name)) { $missing[] = $arg_name; diff --git a/src/Drupal/Commands/core/ViewsCommands.php b/src/Drupal/Commands/core/ViewsCommands.php index 5050222dda..3df757ff2d 100644 --- a/src/Drupal/Commands/core/ViewsCommands.php +++ b/src/Drupal/Commands/core/ViewsCommands.php @@ -143,7 +143,7 @@ public function vlist($options = ['name' => self::REQ, 'tags' => self::REQ, 'sta $with_name = !empty($name) ? true : false; // Get the --tags option. - $tags = \_convert_csv_to_array($options['tags']); + $tags = StringUtils::csvToArray($options['tags']); $with_tags = !empty($tags) ? true : false; // Get the --status option. Store user input apart to reuse it after. diff --git a/src/Preflight/LegacyPreflight.php b/src/Preflight/LegacyPreflight.php index 2c2b619ae9..cda54ff026 100644 --- a/src/Preflight/LegacyPreflight.php +++ b/src/Preflight/LegacyPreflight.php @@ -69,7 +69,6 @@ public static function includeCode($drushBasePath): void // We still need preflight for drush_shutdown() require_once $drushBasePath . '/includes/preflight.inc'; require_once $drushBasePath . '/includes/bootstrap.inc'; - require_once $drushBasePath . '/includes/environment.inc'; require_once $drushBasePath . '/includes/drush.inc'; require_once $drushBasePath . '/includes/batch.inc'; require_once $drushBasePath . '/includes/output.inc'; From 5a1c1b2b297a8d26ec01e7fa242259c9f768f417 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 1 Jan 2022 01:12:27 -0500 Subject: [PATCH 054/125] Remove example.bashrc (#4969) --- docs/examples/example.bashrc.md | 6 - examples/example.bashrc | 239 ----------------------------- mkdocs_base.yml | 1 - src/Commands/core/DocsCommands.php | 13 -- 4 files changed, 259 deletions(-) delete mode 100644 docs/examples/example.bashrc.md delete mode 100644 examples/example.bashrc diff --git a/docs/examples/example.bashrc.md b/docs/examples/example.bashrc.md deleted file mode 100644 index 3a4bcf6067..0000000000 --- a/docs/examples/example.bashrc.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -edit_url: https://github.com/drush-ops/drush/blob/11.x/examples/example.bashrc ---- -```shell ---8<-- "examples/example.bashrc" -``` diff --git a/examples/example.bashrc b/examples/example.bashrc deleted file mode 100644 index a312046165..0000000000 --- a/examples/example.bashrc +++ /dev/null @@ -1,239 +0,0 @@ -# -*- mode: shell-script; mode: flyspell-prog; ispell-local-dictionary: "american" -*- -# -# Example bash aliases to improve your Drush experience with bash. -# Use `drush init` to copy this file to your home directory, rename and -# customize it to suit, and source it from your ~/.bashrc file. -# -# Creates aliases to common Drush commands that work in a global context: -# -# dr - drush -# ddd - drush drupal-directory -# ev - drush php-eval -# sa - drush site-alias -# sa - drush site-alias --local-only (show local site aliases) -# st - drush core-status -# use - drush site-set -# -# Aliases for Drush commands that work on the current drupal site: -# -# cr - drush cache-rebuild -# en - drush pm-enable -# pml - drush pm-list -# unin - drush pm-uninstall -# updb - drush updatedb -# q - drush sql-query -# -# Provides several common shell commands to work better with Drush: -# -# ddd @dev - print the path to the root directory of @dev -# cdd @dev - change the current working directory to @dev -# lsd @dev - ls root folder of @dev -# lsd %files - ls "files" directory of current site -# lsd @dev:%devel - ls devel module directory in @dev -# @dev st - drush @dev core-status -# dssh @live - ssh to the remote server @live points at -# gitd @live pull - run `git pull` on the drupal root of @live -# -# Drush site alias expansion is also done for the cpd command: -# -# cpd -R @site1:%files @site2:%files -# -# Note that the 'cpd' alias only works for local sites. Use -# `drush rsync` or gitd` to move files between remote sites. -# -# Aliases are also possible for the following standard -# commands. Uncomment their definitions below as desired. -# -# cd - cddl [*] -# ls - lsd -# cp - cpd -# ssh - dssh -# git - gitd -# -# These standard commands behave exactly the same as they always -# do, unless a Drush site specification such as @dev or @live:%files -# is used in one of the arguments. - -# Aliases for common Drush commands that work in a global context. -alias dr='drush' -alias ddd='drush drupal:directory' -alias ev='drush php:eval' -alias sa='drush site:alias' -alias st='drush core:status' -alias use='drush site:set' - -# Aliases for Drush commands that work on the current drupal site -alias cr='drush cache:rebuild' -alias en='drush pm:enable' -alias pml='drush pm:list' -alias unin='drush pm:uninstall' -alias updb='drush updatedb' -alias q='drush sql:query' - -# Overrides for standard shell commands. Uncomment to enable. Alias -# cd='cdd' if you want to be able to use cd @remote to ssh to a -# remote site. - -# alias cd='cddl' -# alias ls='lsd' -# alias cp='cpd' -# alias ssh='dssh' -# alias git='gitd' - -# We extend the cd command to allow convenient -# shorthand notations, such as: -# cd @site1 -# cd %modules -# cd %devel -# cd @site2:%files -# You must use 'cddl' instead of 'cd' if you are not using -# the optional 'cd' alias from above. -# This is the "local-only" version of the function; -# see the cdd function, below, for an expanded implementation -# that will ssh to the remote server when a remote site -# specification is used. -function cddl() { - fastcddl "$1" - use @self -} - -# Use this function instead of 'cddl' if you have a very large number -# of alias files, and the 'cddl' function is getting too slow as a result. -# This function does not automatically set your prompt to the site that -# you 'cd' to, as 'cddl' does. -function fastcddl() { - s="$1" - if [ -z "$s" ] - then - builtin cd - elif [ "${s:0:1}" == "@" ] || [ "${s:0:1}" == "%" ] - then - d="$(drush drupal:directory $1 --local-only 2>/dev/null)" - if [ $? == 0 ] - then - echo "cd $d"; - builtin cd "$d"; - else - t="$(drush site-alias $1 >/dev/null 2>/dev/null)" - if [ $? == 0 ] - then - echo "Cannot cd to remote site $s" - else - echo "Cannot cd to $s" - fi - fi - else - builtin cd "$s"; - fi -} - -# Works just like the `cddl` shell alias above, with one additional -# feature: `cdd @remote-site` works like `ssh @remote-site`, -# whereas cd above will fail unless the site alias is local. If -# you prefer this behavior, you can add `alias cd='cdd'` to your .bashrc -function cdd() { - s="$1" - if [ -z "$s" ] - then - builtin cd - elif [ "${s:0:1}" == "@" ] || [ "${s:0:1}" == "%" ] - then - d="$(drush drupal:directory $s 2>/dev/null)" - rh="$(drush sa ${s%%:*} --fields=host --format=list)" - if [ -z "$rh" ] - then - echo "cd $d" - builtin cd "$d" - else - if [ -n "$d" ] - then - c="cd \"$d\" \; bash" - drush -s ${s%%:*} ssh --tty - drush ${s%%:*} ssh --tty - else - drush ssh ${s%%:*} - fi - fi - else - builtin cd "$s" - fi -} - -# Allow `git @site gitcommand` as a shortcut for `cd @site; git gitcommand`. -# Also works on remote sites, though. -function gitd() { - s="$1" - if [ -n "$s" ] && [ ${s:0:1} == "@" ] || [ ${s:0:1} == "%" ] - then - d="$(drush drupal-directory $s 2>/dev/null)" - rh="$(drush sa ${s%%:*} --fields=host --format=list)" - if [ -n "$rh" ] - then - drush ${s%%:*} ssh "cd '$d' ; git ${@:2}" - else - echo cd "$d" \; git "${@:2}" - ( - cd "$d" - "git" "${@:2}" - ) - fi - else - "git" "$@" - fi -} - -# Get a directory listing on @site or @site:%files, etc, for local or remote sites. -function lsd() { - p=() - r= - for a in "$@" ; do - if [ ${a:0:1} == "@" ] || [ ${a:0:1} == "%" ] - then - p[${#p[@]}]="$(drush drupal:directory $a 2>/dev/null)" - if [ ${a:0:1} == "@" ] - then - rh="$(drush sa ${a%:*} --fields=host --format=list)" - if [ -n "$rh" ] - then - r=${a%:*} - fi - fi - elif [ -n "$a" ] - then - p[${#p[@]}]="$a" - fi - done - if [ -n "$r" ] - then - drush $r ssh 'ls "${p[@]}"' - else - "ls" "${p[@]}" - fi -} - -# Copy files from or to @site or @site:%files, etc; local sites only. -function cpd() { - p=() - for a in "$@" ; do - if [ ${a:0:1} == "@" ] || [ ${a:0:1} == "%" ] - then - p[${#p[@]}]="$(drush drupal:directory $a --local-only 2>/dev/null)" - elif [ -n "$a" ] - then - p[${#p[@]}]="$a" - fi - done - "cp" "${p[@]}" -} - -# This alias allows `dssh @site` to work like `drush @site ssh`. -# Ssh commands, such as `dssh @site ls /tmp`, are also supported. -function dssh() { - d="$1" - if [ ${d:0:1} == "@" ] - then - drush "$d" ssh "${@:2}" - else - "ssh" "$@" - fi -} diff --git a/mkdocs_base.yml b/mkdocs_base.yml index 1e625cde6e..5d59469ea2 100644 --- a/mkdocs_base.yml +++ b/mkdocs_base.yml @@ -96,7 +96,6 @@ nav: - examples/SiteAliasAlterCommands.php.md - examples/SyncViaHttpCommands.php.md - examples/XkcdCommands.php.md - - .bashrc: examples/example.bashrc.md - prompt.sh: examples/example.prompt.sh.md - git-bisect.sh: examples/git-bisect.example.sh.md - Contribute: diff --git a/src/Commands/core/DocsCommands.php b/src/Commands/core/DocsCommands.php index 60190ae648..6dd733100d 100644 --- a/src/Commands/core/DocsCommands.php +++ b/src/Commands/core/DocsCommands.php @@ -39,19 +39,6 @@ public function bisect(): void self::printFileTopic($this->commandData); } - /** - * Bashrc customization examples for Drush. - * - * @command docs:bashrc - * @aliases docs-bashrc - * @hidden - * @topic ../../../examples/example.bashrc - */ - public function bashrc(): void - { - self::printFileTopic($this->commandData); - } - /** * Drush configuration. * From 52fdffec7535acbc37a0f18f7f018ca429a03187 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sat, 1 Jan 2022 16:32:08 +0100 Subject: [PATCH 055/125] Only show fieldable entity types when asking for entity type in field commands (#4970) --- src/Drupal/Commands/field/EntityTypeBundleAskTrait.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php index 649fc68a25..685d81e64a 100644 --- a/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php +++ b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php @@ -3,7 +3,9 @@ namespace Drush\Drupal\Commands\field; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Symfony\Component\Console\Input\InputInterface; use function t; @@ -17,7 +19,12 @@ trait EntityTypeBundleAskTrait { protected function askEntityType(): ?string { - $entityTypeDefinitions = $this->entityTypeManager->getDefinitions(); + $entityTypeDefinitions = array_filter( + $this->entityTypeManager->getDefinitions(), + function (EntityTypeInterface $entityType) { + return $entityType->entityClassImplements(FieldableEntityInterface::class); + } + ); $choices = []; foreach ($entityTypeDefinitions as $entityTypeDefinition) { From a29d8c8809a5777d009c4c039d8c40fd99ee0c69 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 1 Jan 2022 20:21:14 -0500 Subject: [PATCH 056/125] More removal of cache dir (#4971) * More removal of cache dir * Simplify test --- docs/using-drush-configuration.md | 7 ------- src/Commands/core/CacheCommands.php | 6 +----- src/Commands/core/StatusCommands.php | 4 +--- src/Config/DrushConfig.php | 20 -------------------- tests/functional/CoreTest.php | 21 ++++++--------------- 5 files changed, 8 insertions(+), 50 deletions(-) diff --git a/docs/using-drush-configuration.md b/docs/using-drush-configuration.md index f77ea8d7ad..8f862af3ac 100644 --- a/docs/using-drush-configuration.md +++ b/docs/using-drush-configuration.md @@ -74,13 +74,6 @@ drush: ``` - View all loaded site aliases: `drush site:alias` -#### Cache directory -Specify a folder where Drush should store its file based caches. If unspecified, defaults to `$HOME/.drush`. -```yml -drush: - cache-directory: /tmp/.drush -``` - #### Backup directory Specify a folder where Drush should store backup files, including temporary sql dump files created during [sql:sync](https://www.drush.org/latest/commands/sql_sync/). If unspecified, diff --git a/src/Commands/core/CacheCommands.php b/src/Commands/core/CacheCommands.php index b80548af59..67f9c3c701 100644 --- a/src/Commands/core/CacheCommands.php +++ b/src/Commands/core/CacheCommands.php @@ -233,10 +233,6 @@ public function rebuild($options = ['cache-clear' => true]) // drupal_rebuild() calls drupal_flush_all_caches() itself, so we don't do it manually. drupal_rebuild($autoloader, $request); $this->logger()->success(dt('Cache rebuild complete.')); - - // As this command replaces `drush cache-clear all` for Drupal 8 users, clear - // the Drush cache as well, for consistency with that behavior. - CacheCommands::clearDrush(); } /** @@ -300,7 +296,7 @@ public function getTypes($include_bootstrapped_types = false): array public static function clearDrush(): void { try { - // No longer anything to do here. Left because some commandfiles may try to call this. + Drush::logger()->info(dt('Deprecation notice - Drush no longer caches anything.')); } catch (IOException $e) { // Sometimes another process writes files into a bin dir and \Drush\Cache\FileCache::clear fails. // That is not considered an error. https://github.com/drush-ops/drush/pull/4535. diff --git a/src/Commands/core/StatusCommands.php b/src/Commands/core/StatusCommands.php index e3c5a27ed0..843e721bba 100644 --- a/src/Commands/core/StatusCommands.php +++ b/src/Commands/core/StatusCommands.php @@ -52,7 +52,6 @@ class StatusCommands extends DrushCommands implements SiteAliasManagerAwareInter * drush-script: Drush script * drush-version: Drush version * drush-temp: Drush temp - * drush-cache-directory: Drush cache folder * drush-conf: Drush configs * drush-alias-files: Drush aliases * alias-searchpaths: Alias search paths @@ -139,7 +138,6 @@ public function getPropertyList($options): array $status_table['drush-script'] = $this->getConfig()->get('runtime.drush-script'); $status_table['drush-version'] = Drush::getVersion(); $status_table['drush-temp'] = $this->getConfig()->tmp(); - $status_table['drush-cache-directory'] = $this->getConfig()->cache(); $status_table['drush-conf'] = $this->getConfig()->configPaths(); // List available alias files $alias_files = $this->siteAliasManager()->listAllFilePaths(); @@ -160,7 +158,7 @@ public function getPropertyList($options): array } // Store the paths into the '%paths' index; this will be - // used by other code, but will not be included in the output + // used by other code, but will not be included in the default output // of the drush status command. $status_table['%paths'] = $paths; diff --git a/src/Config/DrushConfig.php b/src/Config/DrushConfig.php index 82ae7ade82..0daf3ac54e 100644 --- a/src/Config/DrushConfig.php +++ b/src/Config/DrushConfig.php @@ -65,24 +65,4 @@ public function configPaths() { return $this->get('runtime.config.paths', []); } - - public function cache() - { - $candidates = [ - $this->get('drush.paths.cache-directory'), - Path::join($this->home(), '.drush/cache'), - Path::join($this->tmp(), 'drush-' . $this->user() . '/cache'), - ]; - - $fs = new Filesystem(); - foreach (array_filter($candidates) as $candidate) { - try { - $fs->mkdir($candidate); - return $candidate; - } catch (IOException $ioException) { - // Do nothing. Jump to the next candidate. - } - } - throw new \Exception('Cannot create the Drush cache directory. Tried next candidates: ' . implode(', ', $candidates)); - } } diff --git a/tests/functional/CoreTest.php b/tests/functional/CoreTest.php index cd5ab915bd..db825c9ed5 100644 --- a/tests/functional/CoreTest.php +++ b/tests/functional/CoreTest.php @@ -176,37 +176,28 @@ public function testSiteSpecificConfigLoading() { $sandbox = $this->getSandbox(); - foreach (['default', 'dev', 'stage'] as $site) { - $site_cache_dir = "{$sandbox}/tmp/{$site}"; + foreach (['dev', 'stage'] as $site) { + $site_tmp_dir = "{$sandbox}/tmp/{$site}"; $drush_config_file = Path::join($this->webroot(), "/sites/{$site}/drush.yml"); $drush_config_yml = [ - 'drush' => [ - 'paths' => [ - 'cache-directory' => $site_cache_dir, - ] - ] + 'drush' => [] ]; file_put_contents($drush_config_file, Yaml::dump($drush_config_yml, PHP_INT_MAX, 2)); - // Don't use the uri option for the default site. $options = [ - 'uri' => ($site == 'default') ? 'OMIT' : $site, + 'uri' => $site, 'format' => 'json', ]; - // Test that the config file is loaded. + // Test that the site-specific config file is loaded. $this->drush('core-status', [], $options); $output = $this->getOutputFromJSON(); $loaded = array_flip($output['drush-conf']); $this->assertArrayHasKey("sites/{$site}/drush.yml", $loaded); - // Test that the cache directory config is set. The field option - // forces format to string. - $this->drush('core-status', [], $options + ['field' => 'drush-cache-directory']); - $output = $this->getOutput(); - $this->assertEquals($site_cache_dir, $output); + unlink($drush_config_file); } } } From 786948bc5b9b8902342cd625b6de1fc9c5d84eee Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sun, 2 Jan 2022 11:14:12 +0100 Subject: [PATCH 057/125] Fix PHP 8.1 deprecation notice (#4972) * Fix PHP 8.1 deprecation notice * Add an extra set of parens --- src/Drupal/DrupalKernelTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/DrupalKernelTrait.php b/src/Drupal/DrupalKernelTrait.php index 9dfa0f480c..9718f039f6 100644 --- a/src/Drupal/DrupalKernelTrait.php +++ b/src/Drupal/DrupalKernelTrait.php @@ -206,7 +206,7 @@ protected function findAppropriateServicesFile($module, $services, $dir) */ protected function addDrushServiceProvider($serviceProviderName, $serviceYmlPath = '') { - if (file_exists($serviceYmlPath)) { + if (($serviceYmlPath !== null) && file_exists($serviceYmlPath)) { $this->serviceYamls['app'][$serviceProviderName] = $serviceYmlPath; } } From 7d016bcd22c0e6cce7bf13bd9960e6ed4ea5a03c Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sun, 2 Jan 2022 14:35:36 +0100 Subject: [PATCH 058/125] Stop asking for bundle in the field commands if the entity type isn't able to have bundles --- .../Commands/field/EntityTypeBundleAskTrait.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php index 685d81e64a..e6565fb60c 100644 --- a/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php +++ b/src/Drupal/Commands/field/EntityTypeBundleAskTrait.php @@ -48,14 +48,15 @@ protected function askBundle(): ?string $bundleInfo = $this->entityTypeBundleInfo->getBundleInfo($entityTypeId); $choices = []; - if (empty($bundleInfo)) { - if ($bundleEntityType) { - throw new \InvalidArgumentException( - t('Entity type with id \':entityType\' does not have any bundles.', [':entityType' => $entityTypeId]) - ); - } + if ($bundleEntityType && $bundleInfo === []) { + throw new \InvalidArgumentException( + t('Entity type with id \':entityType\' does not have any bundles.', [':entityType' => $entityTypeId]) + ); + } - return null; + if (!$bundleEntityType && count($bundleInfo) === 1) { + // eg. User + return $entityTypeId; } foreach ($bundleInfo as $bundle => $data) { From 3d6fdea5fe64ae1a4f48b2f189f8fdff94f717cb Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Sun, 2 Jan 2022 16:39:35 +0100 Subject: [PATCH 059/125] Fix tests --- tests/functional/FieldTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/FieldTest.php b/tests/functional/FieldTest.php index 2c96b619df..3274839d6f 100644 --- a/tests/functional/FieldTest.php +++ b/tests/functional/FieldTest.php @@ -30,7 +30,7 @@ public function testFieldCreate() $this->assertStringContainsString('The entityType argument is required', $this->getErrorOutputRaw()); $this->drush('field:create', ['foo'], [], null, null, self::EXIT_ERROR); $this->assertStringContainsString('Entity type with id \'foo\' does not exist.', $this->getErrorOutputRaw()); - $this->drush('field:create', ['user'], [], null, null, self::EXIT_ERROR); + $this->drush('field:create', ['unish_article'], [], null, null, self::EXIT_ERROR); $this->assertStringContainsString('The bundle argument is required.', $this->getErrorOutputRaw()); $this->drush('field:create', ['user', 'user'], [], null, null, self::EXIT_ERROR); $this->assertStringNotContainsString('bundle', $this->getErrorOutputRaw()); From ca9e31d8bb1d6138c91bee1b2445d013842f2008 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea Date: Mon, 3 Jan 2022 18:27:18 +0200 Subject: [PATCH 060/125] Convert migrate tests to integration tests (#4834) --- .docker/zz-php.ini | 1 + docs/commands.md | 4 +- docs/deploycommand.md | 2 +- docs/generators.md | 6 +- src/Drupal/Commands/core/EntityCommands.php | 2 +- .../Commands/core/MigrateRunnerCommands.php | 2 +- src/Drupal/Migrate/MigrateExecutable.php | 2 +- src/Drupal/Migrate/MigrateUtils.php | 2 +- .../modules}/woot/composer.json | 0 .../modules}/woot/drush.services.yml | 0 .../woot/migrations/test_migration.yml | 2 +- .../test_migration_source_issues.yml | 0 .../woot/migrations/test_migration_tagged.yml | 0 .../migrations/test_migration_untagged.yml | 0 .../src/Commands/AnnotatedGreetCommand.php | 0 .../woot/src/Commands/GreetCommand.php | 0 .../woot/src/Commands/WootCommands.php | 0 .../woot/src/Controller/WootController.php | 0 .../modules}/woot/src/DependingService.php | 0 .../src/EventSubscriber/ConfigSubscriber.php | 0 .../PreRowDeleteTestSubscriber.php | 2 +- .../ProcessRowTestSubscriber.php | 2 +- .../woot/src/Generators/ExampleGenerator.php | 0 .../src/Generators/example-generator.twig | 0 .../Plugin/QueueWorker/CustomException.php | 0 .../QueueWorker/WootCustomException.php | 0 .../QueueWorker/WootRequeueException.php | 0 .../migrate/process/TestFailProcess.php | 2 +- .../TestSourceWithMissedRequirements.php | 0 .../woot/src/WootCommandInfoAlterer.php | 0 .../modules}/woot/src/WootManager.php | 0 .../modules}/woot/woot.deploy.php | 0 .../modules}/woot/woot.info.yml | 3 +- .../d8 => fixtures/modules}/woot/woot.install | 0 .../d8 => fixtures/modules}/woot/woot.module | 6 +- .../modules}/woot/woot.post_update.php | 0 .../modules}/woot/woot.routing.yml | 0 .../modules}/woot/woot.services.yml | 0 tests/functional/CommandInfoAlterTest.php | 2 +- tests/functional/ConfigTest.php | 2 +- tests/functional/ContainerTest.php | 2 +- tests/functional/DeployHookTest.php | 4 +- tests/functional/QueueTest.php | 4 +- tests/functional/UpdateDBTest.php | 14 +-- .../MigrateRunnerTest.php | 86 ++++++++++++------- tests/integration/ModuleGeneratorTest.php | 2 +- 46 files changed, 90 insertions(+), 64 deletions(-) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/composer.json (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/drush.services.yml (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/migrations/test_migration.yml (80%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/migrations/test_migration_source_issues.yml (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/migrations/test_migration_tagged.yml (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/migrations/test_migration_untagged.yml (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Commands/AnnotatedGreetCommand.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Commands/GreetCommand.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Commands/WootCommands.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Controller/WootController.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/DependingService.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/EventSubscriber/ConfigSubscriber.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php (90%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/EventSubscriber/ProcessRowTestSubscriber.php (93%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Generators/ExampleGenerator.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Generators/example-generator.twig (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Plugin/QueueWorker/CustomException.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Plugin/QueueWorker/WootCustomException.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Plugin/QueueWorker/WootRequeueException.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Plugin/migrate/process/TestFailProcess.php (94%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/Plugin/migrate/source/TestSourceWithMissedRequirements.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/WootCommandInfoAlterer.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/src/WootManager.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.deploy.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.info.yml (59%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.install (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.module (89%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.post_update.php (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.routing.yml (100%) rename tests/{functional/resources/modules/d8 => fixtures/modules}/woot/woot.services.yml (100%) rename tests/{functional => integration}/MigrateRunnerTest.php (90%) diff --git a/.docker/zz-php.ini b/.docker/zz-php.ini index 1b2cb8baa5..10b9fbc77c 100644 --- a/.docker/zz-php.ini +++ b/.docker/zz-php.ini @@ -3,3 +3,4 @@ variables_order = GPCS error_reporting = E_ALL & ~E_DEPRECATED date.timezone = "UTC" sendmail_path = "true" +memory_limit = 256M diff --git a/docs/commands.md b/docs/commands.md index acba65c34e..ed1b25564f 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -93,10 +93,10 @@ In order to alter an existing command info, follow the steps below: 1. In that class, implement the alteration logic in the `alterCommandInfo()` method. 1. Along with the alter code, it's strongly recommended to log a debug message explaining what exactly was altered. This makes things easier on others who may need to debug the interaction of the alter code with other modules. Also it's a good practice to inject the the logger in the class constructor. -For an example, see the alterer class provided by the testing 'woot' module: `tests/functional/resources/modules/d8/woot/src/WootCommandInfoAlterer.php`. +For an example, see the alterer class provided by the testing 'woot' module: `tests/fixtures/modules/woot/src/WootCommandInfoAlterer.php`. ## Symfony Console Commands -Drush lists and runs Symfony Console commands, in addition to more typical annotated commands. See [this test](https://github.com/drush-ops/drush/blob/eed106ae4510d5a2df89f8e7fd54b41ffb0aa5fa/tests/integration/AnnotatedCommandCase.php#L178-L180) and this [commandfile](https://github.com/drush-ops/drush/blob/049d2a4b36338178c0c7cf89b8e7caf9769524c9/tests/functional/resources/modules/d8/woot/src/Commands/GreetCommand.php). +Drush lists and runs Symfony Console commands, in addition to more typical annotated commands. See [this test](https://github.com/drush-ops/drush/blob/eed106ae4510d5a2df89f8e7fd54b41ffb0aa5fa/tests/integration/AnnotatedCommandCase.php#L178-L180) and this [commandfile](https://github.com/drush-ops/drush/tree/HEAD/tests/fixtures/modules/woot/src/Commands/GreetCommand.php). ## Site-Wide Drush Commands Commandfiles that are installed in a Drupal site and are not bundled inside a Drupal module are called 'site-wide' commandfiles. Site-wide commands may either be added directly to the Drupal site's repository (e.g. for site-specific policy files), or via `composer require`. See the [examples/Commands](https://github.com/drush-ops/drush/tree/11.x/examples/Commands) folder for examples. In general, it's better to use modules to carry your Drush commands, as module-based commands may [participate in Drupal's dependency injection via the drush.services.yml](#specifying-the-services-file). diff --git a/docs/deploycommand.md b/docs/deploycommand.md index 7863109ee1..297022757d 100644 --- a/docs/deploycommand.md +++ b/docs/deploycommand.md @@ -20,7 +20,7 @@ Below are the 3 types of update functions run by this command, in order. Choose | --- | --- | --- | | [HOOK_update_n()](https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Extension!module.api.php/function/hook_update_N) | Not allowed | Low level changes. | | [HOOK_post_update_NAME()](https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Extension!module.api.php/function/hook_post_update_NAME) | Allowed | Runs *before* config is imported. | -| [HOOK_deploy_NAME()](https://github.com/drush-ops/drush/blob/11.x/tests/functional/resources/modules/d8/woot/woot.deploy.php) | Allowed | Runs *after* config is imported. | +| [HOOK_deploy_NAME()](https://github.com/drush-ops/drush/tree/HEAD/tests/fixtures/modules/woot/woot.deploy.php) | Allowed | Runs *after* config is imported. | ## Configuration diff --git a/docs/generators.md b/docs/generators.md index 55f51fc2da..3a436a25dc 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -6,11 +6,11 @@ Drush's generators reuse classes provided by the excellent [Drupal Code Generato ## Writing Custom Generators Drupal modules may supply their own Generators, just like they can supply Commands. -See [Woot module](https://github.com/drush-ops/drush/blob/11.x/tests/functional/resources/modules/d8/woot), which Drush uses for testing. Specifically, +See [Woot module](https://github.com/drush-ops/drush/blob/11.x/tests/fixtures/modules/woot), which Drush uses for testing. Specifically, - 1. Write a class similar to [ExampleGenerator](https://github.com/drush-ops/drush/tree/11.x/tests/functional/resources/modules/d8/woot/src/Generators/). Implement your custom logic in the generate() method. Typically this class is placed under the src/Generators directory. + 1. Write a class similar to [ExampleGenerator](https://github.com/drush-ops/drush/tree/11.x/tests/fixtures/modules/woot/src/Generators/). Implement your custom logic in the generate() method. Typically this class is placed under the src/Generators directory. 2. Add a .twig file to the same directory. This template specifies what gets output from the generator. - 4. Add your class to your module's drush.services.yml file ([example](https://github.com/drush-ops/drush/blob/11.x/tests/functional/resources/modules/d8/woot/drush.services.yml)). Use the tag `drush.generator.v2` instead of `drush.command`. + 4. Add your class to your module's drush.services.yml file ([example](https://github.com/drush-ops/drush/blob/11.x/tests/fixtures/modules/woot/drush.services.yml)). Use the tag `drush.generator.v2` instead of `drush.command`. 5. Perform a `drush cache-rebuild` to compile your drush.services.yml changes into the Drupal container. ## Global Generators diff --git a/src/Drupal/Commands/core/EntityCommands.php b/src/Drupal/Commands/core/EntityCommands.php index 57a35b5ecf..4b53e4a696 100644 --- a/src/Drupal/Commands/core/EntityCommands.php +++ b/src/Drupal/Commands/core/EntityCommands.php @@ -165,7 +165,7 @@ public function doSave(string $entity_type, array $ids): void * @throws InvalidPluginDefinitionException * @throws PluginNotFoundException */ - protected function getQuery(string $entity_type, ?string $ids, array $options): \QueryInterface + protected function getQuery(string $entity_type, ?string $ids, array $options): QueryInterface { $storage = $this->entityTypeManager->getStorage($entity_type); $query = $storage->getQuery(); diff --git a/src/Drupal/Commands/core/MigrateRunnerCommands.php b/src/Drupal/Commands/core/MigrateRunnerCommands.php index 83c678157e..85443f3afd 100644 --- a/src/Drupal/Commands/core/MigrateRunnerCommands.php +++ b/src/Drupal/Commands/core/MigrateRunnerCommands.php @@ -769,7 +769,7 @@ public function fieldsSource(string $migrationId): RowsOfFields */ protected function getMigrationList(?string $migrationIds, ?string $tags): array { - $migrationIds = StringUtils::csvToArray($migrationIds); + $migrationIds = StringUtils::csvToArray((string) $migrationIds); $migrations = $this->getMigrationPluginManager()->createInstances($migrationIds); // Check for invalid migration IDs. diff --git a/src/Drupal/Migrate/MigrateExecutable.php b/src/Drupal/Migrate/MigrateExecutable.php index 900e7e0ad9..94f07dd52d 100644 --- a/src/Drupal/Migrate/MigrateExecutable.php +++ b/src/Drupal/Migrate/MigrateExecutable.php @@ -509,7 +509,7 @@ public function onPrepareRow(MigratePrepareRowEvent $event): void } } if ($skip) { - throw new MigrateSkipRowException(null, false); + throw new MigrateSkipRowException('', false); } } diff --git a/src/Drupal/Migrate/MigrateUtils.php b/src/Drupal/Migrate/MigrateUtils.php index 093ab550fa..90744a3e0b 100644 --- a/src/Drupal/Migrate/MigrateUtils.php +++ b/src/Drupal/Migrate/MigrateUtils.php @@ -20,7 +20,7 @@ class MigrateUtils */ public static function parseIdList(?string $idlist): array { - $idlist = array_filter(str_getcsv($idlist)); + $idlist = array_filter(str_getcsv((string) $idlist)); array_walk($idlist, function (string &$value) { $value = str_getcsv(trim($value), ':'); }); diff --git a/tests/functional/resources/modules/d8/woot/composer.json b/tests/fixtures/modules/woot/composer.json similarity index 100% rename from tests/functional/resources/modules/d8/woot/composer.json rename to tests/fixtures/modules/woot/composer.json diff --git a/tests/functional/resources/modules/d8/woot/drush.services.yml b/tests/fixtures/modules/woot/drush.services.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/drush.services.yml rename to tests/fixtures/modules/woot/drush.services.yml diff --git a/tests/functional/resources/modules/d8/woot/migrations/test_migration.yml b/tests/fixtures/modules/woot/migrations/test_migration.yml similarity index 80% rename from tests/functional/resources/modules/d8/woot/migrations/test_migration.yml rename to tests/fixtures/modules/woot/migrations/test_migration.yml index ab585436ad..7f08ef501c 100644 --- a/tests/functional/resources/modules/d8/woot/migrations/test_migration.yml +++ b/tests/fixtures/modules/woot/migrations/test_migration.yml @@ -4,7 +4,7 @@ migration_tags: - tag1 source: plugin: embedded_data - # Source data is set dynamically in woot_migrate_source_info_alter(). + # Source data is set dynamically in woot_migration_plugins_alter(). data_rows: [] ids: id: diff --git a/tests/functional/resources/modules/d8/woot/migrations/test_migration_source_issues.yml b/tests/fixtures/modules/woot/migrations/test_migration_source_issues.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/migrations/test_migration_source_issues.yml rename to tests/fixtures/modules/woot/migrations/test_migration_source_issues.yml diff --git a/tests/functional/resources/modules/d8/woot/migrations/test_migration_tagged.yml b/tests/fixtures/modules/woot/migrations/test_migration_tagged.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/migrations/test_migration_tagged.yml rename to tests/fixtures/modules/woot/migrations/test_migration_tagged.yml diff --git a/tests/functional/resources/modules/d8/woot/migrations/test_migration_untagged.yml b/tests/fixtures/modules/woot/migrations/test_migration_untagged.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/migrations/test_migration_untagged.yml rename to tests/fixtures/modules/woot/migrations/test_migration_untagged.yml diff --git a/tests/functional/resources/modules/d8/woot/src/Commands/AnnotatedGreetCommand.php b/tests/fixtures/modules/woot/src/Commands/AnnotatedGreetCommand.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Commands/AnnotatedGreetCommand.php rename to tests/fixtures/modules/woot/src/Commands/AnnotatedGreetCommand.php diff --git a/tests/functional/resources/modules/d8/woot/src/Commands/GreetCommand.php b/tests/fixtures/modules/woot/src/Commands/GreetCommand.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Commands/GreetCommand.php rename to tests/fixtures/modules/woot/src/Commands/GreetCommand.php diff --git a/tests/functional/resources/modules/d8/woot/src/Commands/WootCommands.php b/tests/fixtures/modules/woot/src/Commands/WootCommands.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Commands/WootCommands.php rename to tests/fixtures/modules/woot/src/Commands/WootCommands.php diff --git a/tests/functional/resources/modules/d8/woot/src/Controller/WootController.php b/tests/fixtures/modules/woot/src/Controller/WootController.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Controller/WootController.php rename to tests/fixtures/modules/woot/src/Controller/WootController.php diff --git a/tests/functional/resources/modules/d8/woot/src/DependingService.php b/tests/fixtures/modules/woot/src/DependingService.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/DependingService.php rename to tests/fixtures/modules/woot/src/DependingService.php diff --git a/tests/functional/resources/modules/d8/woot/src/EventSubscriber/ConfigSubscriber.php b/tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/EventSubscriber/ConfigSubscriber.php rename to tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php diff --git a/tests/functional/resources/modules/d8/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php b/tests/fixtures/modules/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php similarity index 90% rename from tests/functional/resources/modules/d8/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php rename to tests/fixtures/modules/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php index 5192c248a4..b5b7ea9d7e 100644 --- a/tests/functional/resources/modules/d8/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php +++ b/tests/fixtures/modules/woot/src/EventSubscriber/PreRowDeleteTestSubscriber.php @@ -24,7 +24,7 @@ public static function getSubscribedEvents(): array public function onPreRowDelete(MigrateRowDeleteEvent $event): void { // @see \Unish\MigrateRunnerTest::testMigrateImportAndRollback() - if (\Drupal::state()->get('woot.test_migrate_trigger_failures')) { + if (\Drupal::state()->get('woot.migrate_runner.trigger_failures')) { throw new \RuntimeException('Earthquake while rolling back'); } } diff --git a/tests/functional/resources/modules/d8/woot/src/EventSubscriber/ProcessRowTestSubscriber.php b/tests/fixtures/modules/woot/src/EventSubscriber/ProcessRowTestSubscriber.php similarity index 93% rename from tests/functional/resources/modules/d8/woot/src/EventSubscriber/ProcessRowTestSubscriber.php rename to tests/fixtures/modules/woot/src/EventSubscriber/ProcessRowTestSubscriber.php index 7ea64f8b25..fd55068d45 100644 --- a/tests/functional/resources/modules/d8/woot/src/EventSubscriber/ProcessRowTestSubscriber.php +++ b/tests/fixtures/modules/woot/src/EventSubscriber/ProcessRowTestSubscriber.php @@ -28,7 +28,7 @@ public function onPrepareRow(MigratePrepareRowEvent $event) { // Log only in MigrateRunnerTest::testMigrateImportAndRollback() test. // @see \Unish\MigrateRunnerTest::testMigrateImportAndRollback() - if (\Drupal::state()->get('woot.test_migrate_trigger_failures')) { + if (\Drupal::state()->get('woot.migrate_runner.trigger_failures')) { \Drush\Drush::logger() ->notice("MigrateEvents::DRUSH_MIGRATE_PREPARE_ROW fired for row with ID {$event->getRow()->getSourceProperty('id')}"); } diff --git a/tests/functional/resources/modules/d8/woot/src/Generators/ExampleGenerator.php b/tests/fixtures/modules/woot/src/Generators/ExampleGenerator.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Generators/ExampleGenerator.php rename to tests/fixtures/modules/woot/src/Generators/ExampleGenerator.php diff --git a/tests/functional/resources/modules/d8/woot/src/Generators/example-generator.twig b/tests/fixtures/modules/woot/src/Generators/example-generator.twig similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Generators/example-generator.twig rename to tests/fixtures/modules/woot/src/Generators/example-generator.twig diff --git a/tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/CustomException.php b/tests/fixtures/modules/woot/src/Plugin/QueueWorker/CustomException.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/CustomException.php rename to tests/fixtures/modules/woot/src/Plugin/QueueWorker/CustomException.php diff --git a/tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/WootCustomException.php b/tests/fixtures/modules/woot/src/Plugin/QueueWorker/WootCustomException.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/WootCustomException.php rename to tests/fixtures/modules/woot/src/Plugin/QueueWorker/WootCustomException.php diff --git a/tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/WootRequeueException.php b/tests/fixtures/modules/woot/src/Plugin/QueueWorker/WootRequeueException.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Plugin/QueueWorker/WootRequeueException.php rename to tests/fixtures/modules/woot/src/Plugin/QueueWorker/WootRequeueException.php diff --git a/tests/functional/resources/modules/d8/woot/src/Plugin/migrate/process/TestFailProcess.php b/tests/fixtures/modules/woot/src/Plugin/migrate/process/TestFailProcess.php similarity index 94% rename from tests/functional/resources/modules/d8/woot/src/Plugin/migrate/process/TestFailProcess.php rename to tests/fixtures/modules/woot/src/Plugin/migrate/process/TestFailProcess.php index 91bde4f418..a876dc9d96 100644 --- a/tests/functional/resources/modules/d8/woot/src/Plugin/migrate/process/TestFailProcess.php +++ b/tests/fixtures/modules/woot/src/Plugin/migrate/process/TestFailProcess.php @@ -21,7 +21,7 @@ public function transform($value, MigrateExecutableInterface $migrate_executable { // Fail only in MigrateRunnerTest::testMigrateImportAndRollback() test. // @see \Unish\MigrateRunnerTest::testMigrateImportAndRollback() - if (in_array($value, [2, 9, 17]) && \Drupal::state()->get('woot.test_migrate_trigger_failures')) { + if (in_array($value, [2, 9, 17]) && \Drupal::state()->get('woot.migrate_runner.trigger_failures')) { throw new MigrateException("ID {$value} should fail"); } return $value; diff --git a/tests/functional/resources/modules/d8/woot/src/Plugin/migrate/source/TestSourceWithMissedRequirements.php b/tests/fixtures/modules/woot/src/Plugin/migrate/source/TestSourceWithMissedRequirements.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/Plugin/migrate/source/TestSourceWithMissedRequirements.php rename to tests/fixtures/modules/woot/src/Plugin/migrate/source/TestSourceWithMissedRequirements.php diff --git a/tests/functional/resources/modules/d8/woot/src/WootCommandInfoAlterer.php b/tests/fixtures/modules/woot/src/WootCommandInfoAlterer.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/WootCommandInfoAlterer.php rename to tests/fixtures/modules/woot/src/WootCommandInfoAlterer.php diff --git a/tests/functional/resources/modules/d8/woot/src/WootManager.php b/tests/fixtures/modules/woot/src/WootManager.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/src/WootManager.php rename to tests/fixtures/modules/woot/src/WootManager.php diff --git a/tests/functional/resources/modules/d8/woot/woot.deploy.php b/tests/fixtures/modules/woot/woot.deploy.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/woot.deploy.php rename to tests/fixtures/modules/woot/woot.deploy.php diff --git a/tests/functional/resources/modules/d8/woot/woot.info.yml b/tests/fixtures/modules/woot/woot.info.yml similarity index 59% rename from tests/functional/resources/modules/d8/woot/woot.info.yml rename to tests/fixtures/modules/woot/woot.info.yml index 67be3af9f2..e1c43e11df 100644 --- a/tests/functional/resources/modules/d8/woot/woot.info.yml +++ b/tests/fixtures/modules/woot/woot.info.yml @@ -1,6 +1,5 @@ name: Woot type: module description: Woot Mightily. -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 package: Other diff --git a/tests/functional/resources/modules/d8/woot/woot.install b/tests/fixtures/modules/woot/woot.install similarity index 100% rename from tests/functional/resources/modules/d8/woot/woot.install rename to tests/fixtures/modules/woot/woot.install diff --git a/tests/functional/resources/modules/d8/woot/woot.module b/tests/fixtures/modules/woot/woot.module similarity index 89% rename from tests/functional/resources/modules/d8/woot/woot.module rename to tests/fixtures/modules/woot/woot.module index 37252e01ae..9ce7730131 100644 --- a/tests/functional/resources/modules/d8/woot/woot.module +++ b/tests/fixtures/modules/woot/woot.module @@ -49,7 +49,7 @@ function woot_get_taxonomy_term_entity_type_id() function woot_migration_plugins_alter(array &$migration_plugins): void { // Dynamically create the test_migration source data. - $size = \Drupal::state()->get('woot.test_migration_source_data_amount', 2); + $size = \Drupal::state()->get('woot.migrate_runner.source_data_amount', 2); foreach (range(1, $size) as $id) { $migration_plugins['test_migration']['source']['data_rows'][] = [ 'id' => $id, @@ -58,7 +58,7 @@ function woot_migration_plugins_alter(array &$migration_plugins): void } // Allow tests to remove rows from the source. - if ($removedRows = \Drupal::state()->get('woot.test_migration_source_removed_rows')) { + if ($removedRows = \Drupal::state()->get('woot.migrate_runner.removed_source_rows')) { $removedRows = explode(',', $removedRows); $migration_plugins['test_migration']['source']['data_rows'] = array_filter( $migration_plugins['test_migration']['source']['data_rows'], @@ -69,7 +69,7 @@ function woot_migration_plugins_alter(array &$migration_plugins): void $migration_plugins['test_migration']['source']['data_rows'] = array_values($migration_plugins['test_migration']['source']['data_rows']); } - if (\Drupal::state()->get('woot.test_command_progress_bar.skip_count')) { + if (\Drupal::state()->get('woot.migrate_runner.progress_bar_skip_count')) { // Test the command progress bar for sources that skip count. // @see \Unish\MigrateRunnerTest::testCommandProgressBar() $migration_plugins['test_migration']['source']['skip_count'] = true; diff --git a/tests/functional/resources/modules/d8/woot/woot.post_update.php b/tests/fixtures/modules/woot/woot.post_update.php similarity index 100% rename from tests/functional/resources/modules/d8/woot/woot.post_update.php rename to tests/fixtures/modules/woot/woot.post_update.php diff --git a/tests/functional/resources/modules/d8/woot/woot.routing.yml b/tests/fixtures/modules/woot/woot.routing.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/woot.routing.yml rename to tests/fixtures/modules/woot/woot.routing.yml diff --git a/tests/functional/resources/modules/d8/woot/woot.services.yml b/tests/fixtures/modules/woot/woot.services.yml similarity index 100% rename from tests/functional/resources/modules/d8/woot/woot.services.yml rename to tests/fixtures/modules/woot/woot.services.yml diff --git a/tests/functional/CommandInfoAlterTest.php b/tests/functional/CommandInfoAlterTest.php index 1c5e1b23f9..d0a3b0d8c8 100644 --- a/tests/functional/CommandInfoAlterTest.php +++ b/tests/functional/CommandInfoAlterTest.php @@ -18,7 +18,7 @@ class CommandInfoAlterTest extends CommandUnishTestCase public function testCommandInfoAlter() { $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot']); $this->drush('woot:altered', [], ['help' => true, 'debug' => true]); $this->assertStringNotContainsString('woot-initial-alias', $this->getOutput()); diff --git a/tests/functional/ConfigTest.php b/tests/functional/ConfigTest.php index 8be7c82def..0935d2a4e7 100644 --- a/tests/functional/ConfigTest.php +++ b/tests/functional/ConfigTest.php @@ -103,7 +103,7 @@ public function testConfigImport() $options = [ 'include' => __DIR__, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Export the configuration. diff --git a/tests/functional/ContainerTest.php b/tests/functional/ContainerTest.php index 91653ef5be..9b034e23ce 100644 --- a/tests/functional/ContainerTest.php +++ b/tests/functional/ContainerTest.php @@ -23,7 +23,7 @@ public function testContainer() $this->setUpDrupal(1, true); // Copy the 'woot' module over to the Drupal site we just set up. - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); // Enable our module. $this->drush('pm-enable', ['woot']); diff --git a/tests/functional/DeployHookTest.php b/tests/functional/DeployHookTest.php index 99336ce4a6..ac2efbe853 100644 --- a/tests/functional/DeployHookTest.php +++ b/tests/functional/DeployHookTest.php @@ -19,7 +19,7 @@ public function testDeployHooks() $options = [ 'yes' => null, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Run deploy hooks. @@ -59,7 +59,7 @@ public function testDeployHooks() public function testSkipDeployHooks() { $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], ['yes' => null]); $options = [ diff --git a/tests/functional/QueueTest.php b/tests/functional/QueueTest.php index 67900cbde1..4a32aee3b2 100644 --- a/tests/functional/QueueTest.php +++ b/tests/functional/QueueTest.php @@ -69,7 +69,7 @@ public function testRequeueException() $sites = $this->setUpDrupal(1, true); // Copy the 'woot' module over to the Drupal site we just set up. - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); // Enable woot module, which contains a queue worker that throws a // RequeueException. @@ -110,7 +110,7 @@ public function testCustomException() $this->setUpDrupal(1, true); // Copy the 'woot' module over to the Drupal site we just set up. - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); // Enable woot module, which contains a queue worker that throws a // custom exception. diff --git a/tests/functional/UpdateDBTest.php b/tests/functional/UpdateDBTest.php index 7e52ebacae..230702543f 100644 --- a/tests/functional/UpdateDBTest.php +++ b/tests/functional/UpdateDBTest.php @@ -63,7 +63,7 @@ public function testFailedUpdate($last_successful_update, $expected_status_repor $options = [ 'yes' => null, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Force a pending update. @@ -147,7 +147,7 @@ public function testFailedPostUpdate() $options = [ 'yes' => null, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Force re-run of woot_update_8104(). @@ -197,7 +197,7 @@ public function testUpdateModuleWithServiceDependency() $options = [ 'include' => __DIR__, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Force re-run of the post-update woot_post_update_install_drush_empty_module(). @@ -243,7 +243,7 @@ public function testSuccessfulUpdate() $options = [ 'yes' => null, ]; - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm-enable', ['woot'], $options); // Force re-run of woot_update_8104() which is expected to be completed successfully. @@ -274,7 +274,7 @@ public function testBatchUpdateLogMessages() 'yes' => null, ]; $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm:enable', ['woot'], $options); // Force re-run of woot_update_8105(). @@ -317,7 +317,7 @@ public function testEnableModuleViaUpdate() 'yes' => null, ]; $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm:enable', ['woot'], $options); // Force re-run of woot_update_8106(). @@ -343,7 +343,7 @@ public function testEnableModuleViaPostUpdate() 'yes' => null, ]; $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm:enable', ['woot'], $options); // Force re-run of woot_post_update_install_taxonomy(). diff --git a/tests/functional/MigrateRunnerTest.php b/tests/integration/MigrateRunnerTest.php similarity index 90% rename from tests/functional/MigrateRunnerTest.php rename to tests/integration/MigrateRunnerTest.php index 5c5f0e8132..bf16206804 100644 --- a/tests/functional/MigrateRunnerTest.php +++ b/tests/integration/MigrateRunnerTest.php @@ -2,14 +2,14 @@ namespace Unish; +use Drupal\migrate\Plugin\MigrationInterface; use Webmozart\PathUtil\Path; /** - * @group slow * @group commands * @coversDefaultClass \Drush\Drupal\Commands\core\MigrateRunnerCommands */ -class MigrateRunnerTest extends CommandUnishTestCase +class MigrateRunnerTest extends UnishIntegrationTestCase { use TestModuleHelperTrait; @@ -19,8 +19,7 @@ class MigrateRunnerTest extends CommandUnishTestCase protected function setUp(): void { parent::setUp(); - $this->setUpDrupal(1, true); - $this->setupModulesForTests(['woot'], Path::join(__DIR__, 'resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm:enable', ['migrate', 'node', 'woot']); } @@ -96,7 +95,7 @@ public function testMigrateStatus(): void $this->drush('migrate:status', [], [ 'field' => 'status', 'names-only' => null, - ], null, null, self::EXIT_ERROR); + ], self::EXIT_ERROR); $this->assertStringContainsString('Cannot use --names-only with --field=status.', $this->getErrorOutput()); $actualIds = array_column($output, 'id'); @@ -106,7 +105,7 @@ public function testMigrateStatus(): void $this->assertContains('test_migration_untagged', $actualIds); // Check that invalid migration IDs are reported. - $this->drush('migrate:status', ['non_existing,test_migration,another_invalid'], [], null, null, self::EXIT_ERROR); + $this->drush('migrate:status', ['non_existing,test_migration,another_invalid'], [], self::EXIT_ERROR); $this->assertStringContainsString('Invalid migration IDs: non_existing, another_invalid', $this->getErrorOutput()); // Check --fields option. @@ -146,7 +145,7 @@ public function testMigrateImportAndRollback(): void // Trigger logging in ProcessRowTestSubscriber::onPrepareRow(). // @see \Drupal\woot\EventSubscriber\ProcessRowTestSubscriber::onPrepareRow() // @see \Drupal\woot\EventSubscriber\PreRowDeleteTestSubscriber::onPreRowDelete() - $this->drush('state:set', ['woot.test_migrate_trigger_failures', true]); + $this->drush('state:set', ['woot.migrate_runner.trigger_failures', true]); // Warm-up the 'migrate_prepare_row' hook implementations cache to test // that system_migrate_prepare_row() is picked-up during import. See @@ -157,7 +156,7 @@ public function testMigrateImportAndRollback(): void // Expect that this command will fail because the 2nd row fails. // @see \Drupal\woot\Plugin\migrate\process\TestFailProcess - $this->drush('migrate:import', ['test_migration'], [], null, null, self::EXIT_ERROR); + $this->drush('migrate:import', ['test_migration'], [], self::EXIT_ERROR); // Check for the expected command output. $output = $this->getErrorOutput(); @@ -175,12 +174,12 @@ public function testMigrateImportAndRollback(): void // Check that an appropriate error is logged when rollback fails. // @see \Drupal\woot\EventSubscriber\PreRowDeleteTestSubscriber::onPreRowDelete() - $this->drush('migrate:rollback', [], ['all' => null], null, null, self::EXIT_ERROR); + $this->drush('migrate:rollback', [], ['all' => null], self::EXIT_ERROR); $this->assertStringContainsString('Earthquake while rolling back', $this->getErrorOutputRaw()); $this->drush('migrate:reset', ['test_migration']); // Reset the flag, so we won't fail the rollback again. - $this->drush('state:delete', ['woot.test_migrate_trigger_failures']); + $this->drush('state:delete', ['woot.migrate_runner.trigger_failures']); $this->drush('migrate:rollback', ['test_migration']); // Note that item with source ID 2, which failed to import, was already @@ -214,14 +213,15 @@ public function testMigrateImportAndRollback(): void public function testMigrateImportAndRollbackWithIdList(): void { // Enlarge the source recordset to 50 rows. - $this->drush('state:set', ['woot.test_migration_source_data_amount', 50]); + $this->drush('state:set', ['woot.migrate_runner.source_data_amount', 50]); $this->drush('migrate:import', ['test_migration'], [ // Intentionally added 56, which is out of bounds. - 'idlist' => '4,12,29,34,56', + 'idlist' => '4,12,29,34,56', ]); + $this->drush('migrate:status', ['test_migration'], [ - 'format' => 'json', + 'format' => 'json', ]); // Check that only rows with ID 4, 12, 29, 34 were imported. @@ -233,11 +233,9 @@ public function testMigrateImportAndRollbackWithIdList(): void $this->drush('migrate:rollback', ['test_migration'], [ // Intentionally added 56, which is out of bounds. - 'idlist' => '4,34,56', - ]); - $this->drush('migrate:status', ['test_migration'], [ - 'format' => 'json', + 'idlist' => '4,34,56', ]); + $this->drush('migrate:status', ['test_migration'], ['format' => 'json']); // Check that only rows with ID 4 and 34 were rolled back. $this->assertSame(50, $this->getOutputFromJSON(0)['total']); @@ -253,15 +251,15 @@ public function testMigrateImportAndRollbackWithIdList(): void */ public function testMissingSourceRows(): void { - $this->drush('state:set', ['woot.test_migration_source_data_amount', 5]); + $this->drush('state:set', ['woot.migrate_runner.source_data_amount', 5]); $this->drush('migrate:import', ['test_migration']); $this->assertStringContainsString('[notice] Processed 5 items (5 created, 0 updated, 0 failed, 0 ignored)', $this->getErrorOutput()); $this->drush('sql:query', ['SELECT title FROM node_field_data']); $this->assertSame(['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'], $this->getOutputAsList()); - $this->drush('state:set', ['woot.test_migration_source_removed_rows', '2,4']); - // Rebuild cache to get the new source plugin definition. - $this->drush('cache:rebuild'); + $this->drush('state:set', ['woot.migrate_runner.removed_source_rows', '2,4']); + // Get fresh plugin definitions. + drupal_flush_all_caches(); $this->drush('migrate:import', ['test_migration'], ['delete' => null]); @@ -293,12 +291,12 @@ public function testMigrateStopAndResetStatus(): void */ public function testMigrateMessagesAndFieldSource(): void { - $this->drush('state:set', ['woot.test_migration_source_data_amount', 20]); - $this->drush('state:set', ['woot.test_migrate_trigger_failures', true]); + $this->drush('state:set', ['woot.migrate_runner.source_data_amount', 20]); + $this->drush('state:set', ['woot.migrate_runner.trigger_failures', true]); $this->drush('migrate:import', ['test_migration'], [ 'no-progress' => null, - ], null, null, self::EXIT_ERROR); + ], self::EXIT_ERROR); // All messages together. $this->drush('migrate:messages', ['test_migration'], ['format' => 'json']); @@ -363,8 +361,8 @@ public function testMigrateMessagesAndFieldSource(): void public function testImportingWithLimitAndFeedback(): void { // Set the test_migration source to 300 records. - // @see woot_migrate_source_info_alter() - $this->drush('state:set', ['woot.test_migration_source_data_amount', 300]); + // @see woot_migration_plugins_alter() + $this->drush('state:set', ['woot.migrate_runner.source_data_amount', 300]); $this->drush('migrate:import', ['test_migration'], [ 'feedback' => 20, 'limit' => 199, @@ -432,7 +430,7 @@ public function testImportingWithUpdateAndIdlist(): void */ public function testCommandProgressBar(): void { - $this->drush('state:set', ['woot.test_migration_source_data_amount', 50]); + $this->drush('state:set', ['woot.migrate_runner.source_data_amount', 50]); // Check an import and rollback with progress bar. $this->drush('migrate:import', ['test_migration']); @@ -453,9 +451,10 @@ public function testCommandProgressBar(): void $this->assertNoProgressBar(); // Set the 'test_migration' source plugin to skip count. - // @see woot_migrate_source_info_alter() - $this->drush('state:set', ['woot.test_command_progress_bar.skip_count', true]); - $this->drush('cache:rebuild'); + // @see woot_migration_plugins_alter() + $this->drush('state:set', ['woot.migrate_runner.progress_bar_skip_count', true]); + // Get fresh plugin definitions. + drupal_flush_all_caches(); // Check that progress bar won't show when the source skips count. $this->drush('migrate:import', ['test_migration']); @@ -519,4 +518,31 @@ protected function progressBarAssertionHelper(bool $assertHasProgressBar): void } } } + + /** + * {@inheritdoc} + */ + protected function tearDown(): void + { + // Cleanup any created content. + $this->drush('entity:delete', ['node']); + + // Uninstalling Migrate module doesn't automatically drop the tables. + // @see https://www.drupal.org/project/drupal/issues/2713327 + $migrations = \Drupal::service('plugin.manager.migration')->createInstances([]); + array_walk($migrations, function (MigrationInterface $migration): void { + $migration->getIdMap()->destroy(); + }); + + // Uninstall test modules. + $this->drush('pm:uninstall', ['migrate', 'node', 'woot']); + + // Cleanup any testing state vars. + $state = \Drupal::state(); + foreach (['trigger_failures', 'source_data_amount', 'removed_source_rows', 'progress_bar_skip_count'] as $var) { + $state->delete("woot.migrate_runner.$var"); + } + + parent::tearDown(); + } } diff --git a/tests/integration/ModuleGeneratorTest.php b/tests/integration/ModuleGeneratorTest.php index 8983648ebf..5efc8d9911 100644 --- a/tests/integration/ModuleGeneratorTest.php +++ b/tests/integration/ModuleGeneratorTest.php @@ -16,7 +16,7 @@ class ModuleGeneratorTest extends UnishIntegrationTestCase */ public function testModuleGenerators(): void { - $this->setupModulesForTests(['woot'], Path::join(__DIR__, '../functional/resources/modules/d8')); + $this->setupModulesForTests(['woot'], Path::join(__DIR__, '/../fixtures/modules')); $this->drush('pm:enable', ['woot']); $this->drush('cc', ['drush']); $this->drush('generate', ['list']); From f8ac2cc6572b562393f992e58a6ded79b248f047 Mon Sep 17 00:00:00 2001 From: Claudiu Cristea Date: Mon, 3 Jan 2022 21:40:01 +0200 Subject: [PATCH 061/125] PHP 8.1 deprecations (#4973) * PHP 8.1 deprecations * PHP 8.1 deprecations * Update site-alias dependency and reverty discovery constructor calls * Fully revert change Co-authored-by: Moshe Weitzman --- composer.json | 2 +- composer.lock | 18 ++++++++---------- src/Commands/core/RsyncCommands.php | 2 +- src/Drupal/Commands/core/DrupalCommands.php | 5 ++--- src/Preflight/Preflight.php | 1 + 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index bc581928a5..327b423df2 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ "consolidation/config": "^1.2", "consolidation/filter-via-dot-access-data": "^1", "consolidation/robo": "^3", - "consolidation/site-alias": "^3.0.0@stable", + "consolidation/site-alias": "^3.1.3", "consolidation/site-process": "^4", "enlightn/security-checker": "^1", "grasmash/yaml-expander": "^1.1.1", diff --git a/composer.lock b/composer.lock index 5b7a5e5975..431d89365a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "85e6933dec1e53b0952e65a41570f793", + "content-hash": "36d9350ed6ce1833e94b85180c1e26b4", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -627,16 +627,16 @@ }, { "name": "consolidation/site-alias", - "version": "3.1.2", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/consolidation/site-alias.git", - "reference": "2d514a1b278a1c5f28df20df317631f9829a88f2" + "reference": "e2784362e98f315c996fb2b9ed80a9118a0ba8b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/site-alias/zipball/2d514a1b278a1c5f28df20df317631f9829a88f2", - "reference": "2d514a1b278a1c5f28df20df317631f9829a88f2", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/e2784362e98f315c996fb2b9ed80a9118a0ba8b7", + "reference": "e2784362e98f315c996fb2b9ed80a9118a0ba8b7", "shasum": "" }, "require": { @@ -679,9 +679,9 @@ "description": "Manage alias records for local and remote sites.", "support": { "issues": "https://github.com/consolidation/site-alias/issues", - "source": "https://github.com/consolidation/site-alias/tree/3.1.2" + "source": "https://github.com/consolidation/site-alias/tree/3.1.3" }, - "time": "2021-10-29T17:58:54+00:00" + "time": "2022-01-03T19:00:28+00:00" }, { "name": "consolidation/site-process", @@ -8760,9 +8760,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "consolidation/site-alias": 0 - }, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { diff --git a/src/Commands/core/RsyncCommands.php b/src/Commands/core/RsyncCommands.php index 74a27a04f6..d48d5b39fa 100644 --- a/src/Commands/core/RsyncCommands.php +++ b/src/Commands/core/RsyncCommands.php @@ -90,7 +90,7 @@ public function rsyncOptions($options): string foreach (['include', 'exclude'] as $include_exclude) { // Get the option --include-paths or --exclude-paths and explode to an array of paths // that we will translate into an --include or --exclude option to pass to rsync - $inc_ex_path = explode(PATH_SEPARATOR, @$options[$include_exclude . '-paths']); + $inc_ex_path = explode(PATH_SEPARATOR, (string) @$options[$include_exclude . '-paths']); foreach ($inc_ex_path as $one_path_to_inc_ex) { if (!empty($one_path_to_inc_ex)) { $paths .= ' --' . $include_exclude . '="' . $one_path_to_inc_ex . '"'; diff --git a/src/Drupal/Commands/core/DrupalCommands.php b/src/Drupal/Commands/core/DrupalCommands.php index de111ac08c..a33043750e 100644 --- a/src/Drupal/Commands/core/DrupalCommands.php +++ b/src/Drupal/Commands/core/DrupalCommands.php @@ -119,12 +119,11 @@ public function requirements($options = ['format' => 'table', 'severity' => -1, $min_severity = $options['severity']; foreach ($requirements as $key => $info) { - $info += ['value' => '', 'description' => '']; $severity = array_key_exists('severity', $info) ? $info['severity'] : -1; $rows[$key] = [ 'title' => self::styleRow((string) $info['title'], $options['format'], $severity), - 'value' => self::styleRow(DrupalUtil::drushRender($info['value']), $options['format'], $severity), - 'description' => self::styleRow(DrupalUtil::drushRender($info['description']), $options['format'], $severity), + 'value' => self::styleRow(DrupalUtil::drushRender($info['value'] ?? ''), $options['format'], $severity), + 'description' => self::styleRow(DrupalUtil::drushRender($info['description'] ?? ''), $options['format'], $severity), 'sid' => self::styleRow($severity, $options['format'], $severity), 'severity' => self::styleRow(@$severities[$severity], $options['format'], $severity) ]; diff --git a/src/Preflight/Preflight.php b/src/Preflight/Preflight.php index 044283436e..8d9ba75a10 100644 --- a/src/Preflight/Preflight.php +++ b/src/Preflight/Preflight.php @@ -1,6 +1,7 @@ Date: Mon, 3 Jan 2022 22:32:21 +0200 Subject: [PATCH 062/125] leftover from #4973 (#4976) --- src/Preflight/Preflight.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Preflight/Preflight.php b/src/Preflight/Preflight.php index 8d9ba75a10..044283436e 100644 --- a/src/Preflight/Preflight.php +++ b/src/Preflight/Preflight.php @@ -1,7 +1,6 @@ Date: Tue, 4 Jan 2022 21:56:30 +0200 Subject: [PATCH 063/125] Inject migration plugin manager (#4980) * Inject migration plugin manager. * Strict typing & tidy-up * PHPCS * Don't pass the event name anymore * Fix PHP 8.1 deprecation notices * Prevent float convert PHP8 deprecation notice --- src/Drupal/Commands/core/EntityCommands.php | 2 +- .../Commands/core/MigrateRunnerCommands.php | 126 ++++++++---------- src/Drupal/Commands/core/drush.services.yml | 2 +- src/Drupal/Migrate/MigrateExecutable.php | 61 +++------ src/Drupal/Migrate/MigrateIdMapFilter.php | 8 +- .../Migrate/MigrateMissingSourceRowsEvent.php | 8 +- src/Drupal/Migrate/MigratePrepareRowEvent.php | 18 +-- src/Drupal/Migrate/MigrateUtils.php | 3 +- 8 files changed, 85 insertions(+), 143 deletions(-) diff --git a/src/Drupal/Commands/core/EntityCommands.php b/src/Drupal/Commands/core/EntityCommands.php index 4b53e4a696..38408d6617 100644 --- a/src/Drupal/Commands/core/EntityCommands.php +++ b/src/Drupal/Commands/core/EntityCommands.php @@ -169,7 +169,7 @@ protected function getQuery(string $entity_type, ?string $ids, array $options): { $storage = $this->entityTypeManager->getStorage($entity_type); $query = $storage->getQuery(); - if ($ids = StringUtils::csvToArray($ids)) { + if ($ids = StringUtils::csvToArray((string) $ids)) { $idKey = $this->entityTypeManager->getDefinition($entity_type)->getKey('id'); $query = $query->condition($idKey, $ids, 'IN'); } elseif ($options['bundle'] || $options['exclude']) { diff --git a/src/Drupal/Commands/core/MigrateRunnerCommands.php b/src/Drupal/Commands/core/MigrateRunnerCommands.php index 85443f3afd..0b2544241c 100644 --- a/src/Drupal/Commands/core/MigrateRunnerCommands.php +++ b/src/Drupal/Commands/core/MigrateRunnerCommands.php @@ -2,13 +2,13 @@ namespace Drush\Drupal\Commands\core; -use Drupal\Core\KeyValueStore\KeyValueStoreInterface; -use Drupal\Component\Plugin\Exception\PluginException; use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\CommandError; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\KeyValueStore\KeyValueFactoryInterface; +use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\migrate\Exception\RequirementsException; use Drupal\migrate\MigrateMessageInterface; use Drupal\migrate\Plugin\MigrateIdMapInterface; @@ -29,31 +29,23 @@ class MigrateRunnerCommands extends DrushCommands { /** * Migration plugin manager service. - * - * @var MigrationPluginManagerInterface */ - protected $migrationPluginManager; + protected ?MigrationPluginManagerInterface $migrationPluginManager; /** * Date formatter service. - * - * @var DateFormatter */ - protected $dateFormatter; + protected DateFormatter $dateFormatter; /** * The key-value store service. - * - * @var KeyValueStoreInterface */ - protected $keyValue; + protected KeyValueStoreInterface $keyValue; /** * Migrate message service. - * - * @var MigrateMessageInterface */ - protected $migrateMessage; + protected MigrateMessageInterface $migrateMessage; /** * Constructs a new class instance. @@ -62,12 +54,15 @@ class MigrateRunnerCommands extends DrushCommands * Date formatter service. * @param KeyValueFactoryInterface $keyValueFactory * The key-value factory service. + * @param MigrationPluginManagerInterface|null $migrationPluginManager + * The migration plugin manager service. */ - public function __construct(DateFormatter $dateFormatter, KeyValueFactoryInterface $keyValueFactory) + public function __construct(DateFormatter $dateFormatter, KeyValueFactoryInterface $keyValueFactory, ?MigrationPluginManagerInterface $migrationPluginManager = null) { parent::__construct(); $this->dateFormatter = $dateFormatter; $this->keyValue = $keyValueFactory->get('migrate_last_imported'); + $this->migrationPluginManager = $migrationPluginManager; } /** @@ -230,13 +225,13 @@ protected function getMigrationSourceRowsCount(MigrationInterface $migration): ? } /** - * Returns the number or items that needs update. + * Returns the number of items that needs update. * * @param MigrationInterface $migration * The migration plugin instance. * * @return int|null - * The number or items that needs update. + * The number of items that needs update. */ protected function getMigrationNeedingUpdateCount(MigrationInterface $migration): int { @@ -297,7 +292,7 @@ protected function getMigrationImportedCount(MigrationInterface $migration): ?in protected function getMigrationLastImportedTime(MigrationInterface $migration): string { if ($lastImported = $this->keyValue->get($migration->id(), '')) { - $lastImported = $this->dateFormatter->format($lastImported / 1000, 'custom', 'Y-m-d H:i:s'); + $lastImported = $this->dateFormatter->format(round($lastImported / 1000), 'custom', 'Y-m-d H:i:s'); } return $lastImported; } @@ -436,7 +431,7 @@ protected function executeMigration(MigrationInterface $migration, string $migra // Remove already executed migrations. $dependencies = array_diff($dependencies, $executedMigrations); if ($dependencies) { - $requiredMigrations = $this->getMigrationPluginManager()->createInstances($dependencies); + $requiredMigrations = $this->migrationPluginManager->createInstances($dependencies); array_walk($requiredMigrations, [static::class, __FUNCTION__], $userData); } } @@ -546,11 +541,13 @@ public function rollback(?string $migrationIds = null, array $options = ['all' = * @validate-module-enabled migrate * @validate-migration-id * @version 10.4 + * + * @throws \Drupal\Component\Plugin\Exception\PluginException */ public function stop(string $migrationId): void { /** @var MigrationInterface $migration */ - $migration = $this->getMigrationPluginManager()->createInstance($migrationId); + $migration = $this->migrationPluginManager->createInstance($migrationId); switch ($migration->getStatus()) { case MigrationInterface::STATUS_IDLE: $this->logger()->warning(dt('Migration @id is idle', ['@id' => $migrationId])); @@ -583,11 +580,13 @@ public function stop(string $migrationId): void * @validate-module-enabled migrate * @validate-migration-id * @version 10.4 + * + * @throws \Drupal\Component\Plugin\Exception\PluginException */ public function resetStatus(string $migrationId): void { /** @var MigrationInterface $migration */ - $migration = $this->getMigrationPluginManager()->createInstance($migrationId); + $migration = $this->migrationPluginManager->createInstance($migrationId); $status = $migration->getStatus(); if ($status == MigrationInterface::STATUS_IDLE) { $this->logger()->warning(dt('Migration @id is already Idle', ['@id' => $migrationId])); @@ -605,16 +604,20 @@ public function resetStatus(string $migrationId): void * @param string $migrationId * The ID of the migration. * - * @option idlist Comma-separated list of IDs to import. As an ID may have more than one column, concatenate the columns with the colon ':' separator. + * @option idlist Comma-separated list of IDs to import. As an ID may have + * more than one column, concatenate the columns with the colon ':' + * separator. * * @usage migrate:messages article * Show all messages for the article migration * @usage migrate:messages article --idlist=5 * Show messages related to article record with source ID 5. * @usage migrate:messages node_revision --idlist=1:2,2:3,3:5 - * Show messages related to node revision records with source IDs [1,2], [2,3], and [3,5]. + * Show messages related to node revision records with source IDs [1,2], + * [2,3], and [3,5]. * @usage migrate:messages custom_node_revision --idlist=1:"r:1",2:"r:3" - * Show messages related to node revision records with source IDs [1,"r:1"], and [2,"r:3"]. + * Show messages related to node revision records with source IDs + * [1,"r:1"], and [2,"r:3"]. * * @aliases mmsg,migrate-messages * @@ -634,11 +637,13 @@ public function resetStatus(string $migrationId): void * * @return RowsOfFields * Migration messages status formatted as table. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException */ public function messages(string $migrationId, array $options = ['idlist' => self::REQ]): RowsOfFields { /** @var MigrationInterface $migration */ - $migration = $this->getMigrationPluginManager()->createInstance($migrationId); + $migration = $this->migrationPluginManager->createInstance($migrationId); $idMap = $migration->getIdMap(); $sourceIdKeys = $this->getSourceIdKeys($idMap); $table = []; @@ -648,20 +653,18 @@ public function messages(string $migrationId, array $options = ['idlist' => self return new RowsOfFields($table); } if (!empty($options['idlist'])) { - // There is not way to retreive a filtered set of messages from an - // ID map on Drupal core, right now. - // Even if using \Drush\Drupal\Migrate\MigrateIdMapFilter does the - // right thing filtering the data on the ID map, sadly its - // getMessages() method does not take it into account the iterator, - // and retrieves data directly, e.g. at SQL ID map plugin. - // On the other side Drupal core's - // \Drupal\migrate\Plugin\MigrateIdMapInterface only allows to - // filter by one source IDs set, and not by multiple, on - // getMessages(). - // For now, go over known IDs passed directly, one at a time a - // work-around, at the cost of more queries in the usual SQL ID map, - // which is likely OK for its use, to show only few source IDs - // messages. + // There is no way to retrieve a filtered set of messages from an ID + // map on Drupal core, right now. Even if using + // \Drush\Drupal\Migrate\MigrateIdMapFilter does the right thing + // filtering the data on the ID map, sadly its getMessages() method + // does not take it into account the iterator, and retrieves data + // directly, e.g. at SQL ID map plugin. On the other side Drupal + // core's \Drupal\migrate\Plugin\MigrateIdMapInterface only allows + // to filter by one source IDs set, and not by multiple, on + // getMessages(). For now, go over known IDs passed directly, one at + // a time a workaround, at the cost of more queries in the usual SQL + // ID map, which is likely OK for its use, to show only few source + // IDs messages. foreach (MigrateUtils::parseIdList($options['idlist']) as $sourceIdValues) { foreach ($idMap->getMessages($sourceIdValues) as $row) { $table[] = $this->preprocessMessageRow($row, $sourceIdKeys); @@ -669,7 +672,6 @@ public function messages(string $migrationId, array $options = ['idlist' => self } return new RowsOfFields($table); } - $table = []; foreach ($idMap->getMessages() as $row) { $table[] = $this->preprocessMessageRow($row, $sourceIdKeys); } @@ -699,10 +701,10 @@ protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys): ar } $sourceIds = $destinationIds = []; foreach ($row as $key => $value) { - if (substr($key, 0, 4) === 'src_') { + if (str_starts_with($key, 'src_')) { $sourceIds[$key] = $value; } - if (substr($key, 0, 5) === 'dest_') { + if (str_starts_with($key, 'dest_')) { $destinationIds[$key] = $value; } } @@ -737,11 +739,13 @@ protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys): ar * * @return RowsOfFields * Source fields of the given migration. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException */ public function fieldsSource(string $migrationId): RowsOfFields { /** @var MigrationInterface $migration */ - $migration = $this->getMigrationPluginManager()->createInstance($migrationId); + $migration = $this->migrationPluginManager->createInstance($migrationId); $source = $migration->getSourcePlugin(); $table = []; foreach ($source->fields() as $machineName => $description) { @@ -770,7 +774,7 @@ public function fieldsSource(string $migrationId): RowsOfFields protected function getMigrationList(?string $migrationIds, ?string $tags): array { $migrationIds = StringUtils::csvToArray((string) $migrationIds); - $migrations = $this->getMigrationPluginManager()->createInstances($migrationIds); + $migrations = $this->migrationPluginManager->createInstances($migrationIds); // Check for invalid migration IDs. if ($invalidMigrations = array_diff_key(array_flip($migrationIds), $migrations)) { @@ -784,7 +788,7 @@ protected function getMigrationList(?string $migrationIds, ?string $tags): array $sourcePlugin->checkRequirements(); } } catch (RequirementsException $exception) { - $this->logger()->debug("Migration '{$migrationId}' is skipped as its source plugin has missed requirements: " . $exception->getRequirementsString()); + $this->logger()->debug("Migration '$migrationId' is skipped as its source plugin has missed requirements: {$exception->getRequirementsString()}"); unset($migrations[$migrationId]); } } @@ -798,7 +802,7 @@ protected function getMigrationList(?string $migrationIds, ?string $tags): array $list = []; foreach ($migrations as $migrationId => $migration) { - $migrationTags = (array)$migration->getMigrationTags(); + $migrationTags = $migration->getMigrationTags(); $commonTags = array_intersect($tags, $migrationTags); if (!$commonTags) { // Skip if migration is not tagged with any of the passed tags. @@ -827,29 +831,6 @@ protected function getMigrateMessage(): MigrateMessageInterface return $this->migrateMessage; } - /** - * Returns the migration plugin manager service. - * - * @return MigrationPluginManagerInterface - * The migration plugin manager service. - * - * @todo This service cannot be injected as the 'migrate' module might not - * be enabled and will throw the following exception: - * > Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException - * > The service "migrate_runner.commands" has a dependency on a - * > non-existent service "plugin.manager.migration". - * Unfortunately, we cannot avoid the class instantiation, via an - * annotation (as @validate-module-enabled for methods), if a specific - * module is not installed. Open a followup to tackle this issue. - */ - protected function getMigrationPluginManager(): MigrationPluginManagerInterface - { - if (!isset($this->migrationPluginManager)) { - $this->migrationPluginManager = \Drupal::service('plugin.manager.migration'); - } - return $this->migrationPluginManager; - } - /** * Get the source ID keys. * @@ -869,7 +850,7 @@ protected function getSourceIdKeys(MigrateIdMapInterface $idMap): array $idMap->rewind(); $columns = $idMap->currentSource(); $sourceIdKeys = array_map(static function ($id) { - return "src_{$id}"; + return "src_$id"; }, array_keys($columns)); return array_combine($sourceIdKeys, $sourceIdKeys); } @@ -886,12 +867,13 @@ protected function getSourceIdKeys(MigrateIdMapInterface $idMap): array * * @return CommandError|null */ - public function validateMigrationId(CommandData $commandData) + public function validateMigrationId(CommandData $commandData): ?CommandError { $argName = $commandData->annotationData()->get('validate-migration-id') ?: 'migrationId'; $migrationId = $commandData->input()->getArgument($argName); - if (!$this->getMigrationPluginManager()->hasDefinition($migrationId)) { + if (!$this->migrationPluginManager->hasDefinition($migrationId)) { return new CommandError(dt('Migration "@id" does not exist', ['@id' => $migrationId])); } + return null; } } diff --git a/src/Drupal/Commands/core/drush.services.yml b/src/Drupal/Commands/core/drush.services.yml index 915e5e1232..597a732759 100644 --- a/src/Drupal/Commands/core/drush.services.yml +++ b/src/Drupal/Commands/core/drush.services.yml @@ -52,7 +52,7 @@ services: - { name: drush.command } migrate_runner.commands: class: Drush\Drupal\Commands\core\MigrateRunnerCommands - arguments: ['@date.formatter', '@keyvalue'] + arguments: ['@date.formatter', '@keyvalue', '@?plugin.manager.migration'] tags: - { name: drush.command } queue.commands: diff --git a/src/Drupal/Migrate/MigrateExecutable.php b/src/Drupal/Migrate/MigrateExecutable.php index 94f07dd52d..00f027bf84 100644 --- a/src/Drupal/Migrate/MigrateExecutable.php +++ b/src/Drupal/Migrate/MigrateExecutable.php @@ -25,18 +25,13 @@ class MigrateExecutable extends MigrateExecutableBase { /** * The Symfony console output. - * - * @var OutputInterface */ - protected $output; + protected OutputInterface $output; /** * Counters of map statuses. - * - * @var array - * Set of counters, keyed by MigrateIdMapInterface::STATUS_* constant. */ - protected $saveCounters = [ + protected array $saveCounters = [ MigrateIdMapInterface::STATUS_FAILED => 0, MigrateIdMapInterface::STATUS_IGNORED => 0, MigrateIdMapInterface::STATUS_IMPORTED => 0, @@ -45,10 +40,8 @@ class MigrateExecutable extends MigrateExecutableBase /** * Counter of map deletions. - * - * @var int */ - protected $deleteCounter = 0; + protected int $deleteCounter = 0; /** * Maximum number of items to process in this migration. @@ -66,80 +59,60 @@ class MigrateExecutable extends MigrateExecutableBase /** * Show timestamp in progress message. - * - * @var bool */ - protected $showTimestamp; + protected bool $showTimestamp; /** * Show internal counter in progress message. - * - * @var bool */ - protected $showTotal; + protected bool $showTotal; /** * List of specific source IDs to import. - * - * @var array */ - protected $idlist; + protected array $idlist; /** * List of all source IDs that are found in source during this migration. - * - * @var array */ - protected $allSourceIdValues = []; + protected array $allSourceIdValues = []; /** * Count of number of items processed so far in this migration. - * - * @var int */ - protected $counter = 0; + protected int $counter = 0; /** * Whether the destination item exists before saving. - * - * @var bool */ - protected $preExistingItem = false; + protected bool $preExistingItem = false; /** * List of event listeners we have registered. * * @var callable[] */ - protected $listeners = []; + protected array $listeners = []; /** * Whether to delete rows missing from source after an import. - * - * @var bool */ - protected $deleteMissingSourceRows; + protected bool $deleteMissingSourceRows; /** * Static cached ID map. - * - * @var MigrateIdMapFilter */ - protected $idMap; + protected ?MigrateIdMapFilter $idMap; /** - * If the execution exposes an progress bar. - * - * @var bool + * If the execution exposes a progress bar. */ - protected $exposeProgressBar; + protected bool $exposeProgressBar; /** * The Symfony progress bar. - * - * @var ProgressBar */ - protected $progressBar; + protected ?ProgressBar $progressBar; /** * Constructs a new migrate executable instance. @@ -185,7 +158,7 @@ public function __construct(MigrationInterface $migration, MigrateMessageInterfa // Cannot use the progress bar when: // - `--no-progress` option is used, // - `--feedback` option is used, - // - The migration source plugin is configured to skips count. + // - The migration source plugin is configured to skip count. $this->exposeProgressBar = $options['progress'] && !$this->feedback && empty($migration->getSourceConfiguration()['skip_count']); $this->listeners[MigrateEvents::MAP_SAVE] = [$this, 'onMapSave']; @@ -286,7 +259,7 @@ protected function handleMissingSourceRows(MigrationInterface $migration): void if ($destinationIds) { $missingSourceEvent = new MigrateMissingSourceRowsEvent($migration, $destinationIds); - $this->getEventDispatcher()->dispatch(MigrateMissingSourceRowsEvent::class, $missingSourceEvent); + $this->getEventDispatcher()->dispatch($missingSourceEvent); } } diff --git a/src/Drupal/Migrate/MigrateIdMapFilter.php b/src/Drupal/Migrate/MigrateIdMapFilter.php index ee12bc8c37..81e9863b7b 100644 --- a/src/Drupal/Migrate/MigrateIdMapFilter.php +++ b/src/Drupal/Migrate/MigrateIdMapFilter.php @@ -12,17 +12,13 @@ class MigrateIdMapFilter extends \FilterIterator /** * List of specific source IDs to filter on. - * - * @var array */ - protected $sourceIdList; + protected array $sourceIdList; /** * List of specific destination IDs to filter on. - * - * @var array */ - protected $destinationIdList; + protected array $destinationIdList; /** * @param MigrateIdMapInterface $idMap diff --git a/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php b/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php index 1054d34a12..58d4e452d0 100644 --- a/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php +++ b/src/Drupal/Migrate/MigrateMissingSourceRowsEvent.php @@ -3,7 +3,7 @@ namespace Drush\Drupal\Migrate; use Drupal\migrate\Plugin\MigrationInterface; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; /** * Missing source rows event. @@ -12,17 +12,15 @@ class MigrateMissingSourceRowsEvent extends Event { /** * The migration plugin instance. - * - * @var MigrationInterface */ - protected $migration; + protected MigrationInterface $migration; /** * Values representing the destination IDs. * * @var array[] */ - protected $destinationIds; + protected array $destinationIds; /** * Constructs a new event instance. diff --git a/src/Drupal/Migrate/MigratePrepareRowEvent.php b/src/Drupal/Migrate/MigratePrepareRowEvent.php index fa6c1e259f..6ec7d57563 100644 --- a/src/Drupal/Migrate/MigratePrepareRowEvent.php +++ b/src/Drupal/Migrate/MigratePrepareRowEvent.php @@ -5,7 +5,7 @@ use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\MigrateSourceInterface; use Drupal\migrate\Row; -use Symfony\Component\EventDispatcher\Event; +use Symfony\Contracts\EventDispatcher\Event; /** * Wraps a prepare-row event for event listeners. @@ -19,24 +19,18 @@ final class MigratePrepareRowEvent extends Event { /** * Row object. - * - * @var Row */ - protected $row; + protected Row $row; /** * Migration source plugin. - * - * @var MigrateSourceInterface */ - protected $source; + protected MigrateSourceInterface $source; /** * Migration plugin. - * - * @var MigrationInterface */ - protected $migration; + protected MigrationInterface $migration; /** * Constructs a prepare-row event object. @@ -69,8 +63,8 @@ public function getRow(): Row /** * Gets the source plugin. * - * @return MigrateSourceInterface $source - The source plugin firing the event. + * @return MigrateSourceInterface $source + * The source plugin firing the event. */ public function getSource(): MigrateSourceInterface { diff --git a/src/Drupal/Migrate/MigrateUtils.php b/src/Drupal/Migrate/MigrateUtils.php index 90744a3e0b..fa2259ecb4 100644 --- a/src/Drupal/Migrate/MigrateUtils.php +++ b/src/Drupal/Migrate/MigrateUtils.php @@ -7,12 +7,11 @@ */ class MigrateUtils { - /** * Parses as an array the list of IDs received from console. * * IDs are delimited by comma. Each ID consists in one are many ID columns, - * separated by a colon (:). + * separated by a colon (":"). * * @param string|null $idlist * From 5fb1302f75e828a528c9b8fa3966e9b0024ff24c Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 08:19:09 -0500 Subject: [PATCH 064/125] Prep for 11.0.0-rc6 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..ad202223e3 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0-rc6 From b497267e0a9ecf7e9044a79be8c80f6281904fe6 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 08:23:04 -0500 Subject: [PATCH 065/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index ad202223e3..9ad93d53df 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-rc6 +drush_version=11.0.0-dev From 5a666e7d338829e8561aa04a0fb4f6573e876879 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 12:16:47 -0500 Subject: [PATCH 066/125] Remove deprecated option --preview in config:export (#4982) --- src/Drupal/Commands/config/ConfigImportCommands.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Drupal/Commands/config/ConfigImportCommands.php b/src/Drupal/Commands/config/ConfigImportCommands.php index 8b60ca7801..f73203230a 100644 --- a/src/Drupal/Commands/config/ConfigImportCommands.php +++ b/src/Drupal/Commands/config/ConfigImportCommands.php @@ -199,7 +199,6 @@ public function __construct( * * @return bool|void * @option diff Show preview as a diff. - * @option preview Deprecated. Format for displaying proposed changes. Recognized values: list, diff. * @option source An arbitrary directory that holds the configuration files. An alternative to label argument * @option partial Allows for partial config imports from the source directory. Only updates and new configs will be processed with this flag (missing configs will not be deleted). No config transformation happens. * @aliases cim,config-import @@ -209,7 +208,7 @@ public function __construct( * @throws StorageTransformerException * @throws UserAbortException */ - public function import(array $options = ['preview' => 'list', 'source' => self::REQ, 'partial' => false, 'diff' => false]) + public function import(array $options = ['source' => self::REQ, 'partial' => false, 'diff' => false]) { // Determine source directory. $source_storage_dir = ConfigCommands::getDirectory($options['source']); @@ -247,7 +246,7 @@ public function import(array $options = ['preview' => 'list', 'source' => self:: return; } - if ($options['preview'] == 'list' && !$options['diff']) { + if (!$options['diff']) { $change_list = []; foreach ($storage_comparer->getAllCollectionNames() as $collection) { $change_list[$collection] = $storage_comparer->getChangelist(null, $collection); From a1917ee3268fcf5785d8af29bf7f59c38822444f Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 15:01:27 -0500 Subject: [PATCH 067/125] Let config:set change multiple top-level keys. Add docs and tests. (#4983) * Let config:set change multiple top-level keys. Add docs and tests. * Also get rid of unused --value option in state:set --- src/Drupal/Commands/config/ConfigCommands.php | 43 +++++++++++-------- src/Drupal/Commands/core/StateCommands.php | 6 +-- tests/functional/ConfigTest.php | 29 ++++++++++++- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/Drupal/Commands/config/ConfigCommands.php b/src/Drupal/Commands/config/ConfigCommands.php index 10e1342567..e8c85f86d6 100644 --- a/src/Drupal/Commands/config/ConfigCommands.php +++ b/src/Drupal/Commands/config/ConfigCommands.php @@ -126,59 +126,64 @@ public function get($config_name, $key = '', $options = ['format' => 'yaml', 'so } /** - * Set config value directly. Does not perform a config import. + * Save a config value directly. Does not perform a config import. * * @command config:set * @validate-config-name * @todo @interact-config-name deferred until we have interaction for key. * @param $config_name The config object name, for example system.site. - * @param $key The config key, for example page.front. + * @param $key The config key, for example page.front. Use ? if you are updating multiple keys. * @param $value The value to assign to the config key. Use - to read from STDIN. - * @option input-format Format to parse the object. Recognized values: string, yaml - * @option value The value to assign to the config key (if any). - * @hidden-options value + * @option input-format Format to parse the object. Recognized values: string, yaml. Since JSON is a subset of YAML, $value may be in JSON format. + * @usage drush config:set system.site name MySite + * Sets a value for the key name of system.site config object. * @usage drush config:set system.site page.front '/path/to/page' * Sets the given URL path as value for the config item with key page.front of system.site config object. * @usage drush config:set system.site '[]' * Sets the given key to an empty array. + * @usage drush config:set --input-format=yaml user.role.authenticated permissions [foo,bar] + * Use a sequence as value for the key permissions of user.role.authenticated config object. + * @usage drush config:set --input-format=yaml system.site page {403: '403', front: home} + * Use a mapping as value for the key page of system.site config object. + * @usage drush config:set --input-format=yaml user.role.authenticated ? "{label: 'Auth user', weight: 5}" + * Update two top level keys (label, weight) in the system.site config object. * @aliases cset,config-set */ - public function set($config_name, $key, $value = null, $options = ['input-format' => 'string', 'value' => self::REQ]) + public function set($config_name, $key, $value = null, $options = ['input-format' => 'string']) { - // This hidden option is a convenient way to pass a value without passing a key. - $data = $options['value'] ?: $value; + $data = $value; if (!isset($data)) { throw new \Exception(dt('No config value specified.')); } - $config = $this->getConfigFactory()->getEditable($config_name); - // Check to see if config key already exists. - $new_key = $config->get($key) === null; - // Special flag indicating that the value has been passed via STDIN. if ($data === '-') { $data = $this->stdin()->contents(); } - // Special handling for empty array. if ($data == '[]') { $data = []; } - // Now, we parse the value. + // Parse the value if needed. switch ($options['input-format']) { case 'yaml': $parser = new Parser(); $data = $parser->parse($data, true); } - if (is_array($data) && !empty($data) && $this->io()->confirm(dt('Do you want to update or set multiple keys on !name config.', ['!name' => $config_name]))) { - foreach ($data as $data_key => $value) { - $config->set("$key.$data_key", $value); + $config = $this->getConfigFactory()->getEditable($config_name); + // Check to see if config key already exists. + $new_key = $config->get($key) === null; + $simulate = $this->getConfig()->simulate(); + + if ($key == '?' && !empty($data) && $this->io()->confirm(dt('Do you want to update or set multiple keys on !name config.', ['!name' => $config_name]))) { + foreach ($data as $data_key => $val) { + $config->set($data_key, $val); } - return $config->save(); + return $simulate ? self::EXIT_SUCCESS : $config->save(); } else { $confirmed = false; if ($config->isNew() && $this->io()->confirm(dt('!name config does not exist. Do you want to create a new config object?', ['!name' => $config_name]))) { @@ -188,7 +193,7 @@ public function set($config_name, $key, $value = null, $options = ['input-format } elseif ($this->io()->confirm(dt('Do you want to update !key key in !name config?', ['!key' => $key, '!name' => $config_name]))) { $confirmed = true; } - if ($confirmed && !$this->getConfig()->simulate()) { + if ($confirmed && !$simulate) { return $config->set($key, $data)->save(); } } diff --git a/src/Drupal/Commands/core/StateCommands.php b/src/Drupal/Commands/core/StateCommands.php index a2f01b4943..5c3febc6f5 100644 --- a/src/Drupal/Commands/core/StateCommands.php +++ b/src/Drupal/Commands/core/StateCommands.php @@ -51,8 +51,6 @@ public function get(string $key, $options = ['format' => 'string']): PropertyLis * @param string $key The state key, for example: system.cron_last. * @param mixed $value The value to assign to the state key. Use - to read from STDIN. * @option input-format Type for the value. Other recognized values: string, integer, float, boolean, json, yaml. - * @option value For internal use only. - * @hidden-options value * @usage drush sset system.maintenance_mode 1 --input-format=integer * Put site into Maintenance mode. * @usage drush state:set system.cron_last 1406682882 --input-format=integer @@ -61,10 +59,8 @@ public function get(string $key, $options = ['format' => 'string']): PropertyLis * Set a key to a complex value (e.g. array) * @aliases sset,state-set */ - public function set(string $key, $value, $options = ['input-format' => 'auto', 'value' => self::REQ]): void + public function set(string $key, $value, $options = ['input-format' => 'auto']): void { - // A convenient way to pass a multiline value within a backend request. - $value = $options['value'] ?: $value; if (!isset($value)) { throw new \Exception(dt('No state value specified.')); diff --git a/tests/functional/ConfigTest.php b/tests/functional/ConfigTest.php index 0935d2a4e7..690a9d3dbe 100644 --- a/tests/functional/ConfigTest.php +++ b/tests/functional/ConfigTest.php @@ -25,11 +25,38 @@ public function setup(): void } } + /** + * @todo If this becomes an integration test, add test for stdin handling. + */ public function testConfigGetSet() { + // Simple value $this->drush('config:set', ['system.site', 'name', 'config_test']); $this->drush('config:get', ['system.site', 'name']); - $this->assertEquals("'system.site:name': config_test", $this->getOutput(), 'Config was successfully set and get.'); + $this->assertEquals("'system.site:name': config_test", $this->getOutput()); + + // Nested value + $this->drush('config:set', ['system.site', 'page.front', 'llama']); + $this->drush('config:get', ['system.site', 'page.front']); + $this->assertEquals("'system.site:page.front': llama", $this->getOutput()); + + // Simple sequence value + $this->drush('config:set', ['user.role.authenticated', 'permissions', '[foo,bar]'], ['input-format' => 'yaml']); + $this->drush('config:get', ['user.role.authenticated', 'permissions'], ['format' => 'json']); + $output = $this->getOutputFromJSON('user.role.authenticated:permissions'); + + // Mapping value + $this->drush('config:set', ['system.site', 'page', "{403: '403', front: home}"], ['input-format' => 'yaml']); + $this->drush('config:get', ['system.site', 'page'], ['format' => 'json']); + $output = $this->getOutputFromJSON('system.site:page'); + $this->assertSame(['403' => '403', 'front' => 'home'], $output); + + // Multiple top-level keys + $this->drush('config:set', ['user.role.authenticated', '?', "{label: 'Auth user', weight: 5}"], ['input-format' => 'yaml']); + $this->drush('config:get', ['user.role.authenticated'], ['format' => 'json']); + $output = $this->getOutputFromJSON(); + $this->assertSame('Auth user', $output['label']); + $this->assertSame(5, $output['weight']); } public function testConfigExportImportStatusExistingConfig() From 661e4a039f894a7f67ab96938faef988fe19f6db Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 15:07:35 -0500 Subject: [PATCH 068/125] Minor config:set and state:set doc tweaks --- src/Drupal/Commands/config/ConfigCommands.php | 6 +++--- src/Drupal/Commands/core/StateCommands.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Drupal/Commands/config/ConfigCommands.php b/src/Drupal/Commands/config/ConfigCommands.php index e8c85f86d6..d3116d5ac6 100644 --- a/src/Drupal/Commands/config/ConfigCommands.php +++ b/src/Drupal/Commands/config/ConfigCommands.php @@ -132,8 +132,8 @@ public function get($config_name, $key = '', $options = ['format' => 'yaml', 'so * @validate-config-name * @todo @interact-config-name deferred until we have interaction for key. * @param $config_name The config object name, for example system.site. - * @param $key The config key, for example page.front. Use ? if you are updating multiple keys. - * @param $value The value to assign to the config key. Use - to read from STDIN. + * @param $key The config key, for example page.front. Use ? if you are updating multiple top-level keys. + * @param $value The value to assign to the config key. Use - to read from Stdin. * @option input-format Format to parse the object. Recognized values: string, yaml. Since JSON is a subset of YAML, $value may be in JSON format. * @usage drush config:set system.site name MySite * Sets a value for the key name of system.site config object. @@ -149,7 +149,7 @@ public function get($config_name, $key = '', $options = ['format' => 'yaml', 'so * Update two top level keys (label, weight) in the system.site config object. * @aliases cset,config-set */ - public function set($config_name, $key, $value = null, $options = ['input-format' => 'string']) + public function set($config_name, $key, $value, $options = ['input-format' => 'string']) { $data = $value; diff --git a/src/Drupal/Commands/core/StateCommands.php b/src/Drupal/Commands/core/StateCommands.php index 5c3febc6f5..1b4bf6d480 100644 --- a/src/Drupal/Commands/core/StateCommands.php +++ b/src/Drupal/Commands/core/StateCommands.php @@ -49,7 +49,7 @@ public function get(string $key, $options = ['format' => 'string']): PropertyLis * @command state:set * * @param string $key The state key, for example: system.cron_last. - * @param mixed $value The value to assign to the state key. Use - to read from STDIN. + * @param mixed $value The value to assign to the state key. Use - to read from Stdin. * @option input-format Type for the value. Other recognized values: string, integer, float, boolean, json, yaml. * @usage drush sset system.maintenance_mode 1 --input-format=integer * Put site into Maintenance mode. From 0254f34469820ed93858bbe69424b32e8b31adfc Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 18:19:15 -0500 Subject: [PATCH 069/125] Rector simplifies class names (#4984) * Rector simplifies class names * Fix param hint * Not nullable array --- rector.php | 3 - src/Boot/BootstrapManager.php | 57 +++++++++++-------- src/Boot/DrupalBoot8.php | 15 ++--- src/Config/ConfigAwareTrait.php | 2 +- src/Config/ConfigLocator.php | 8 ++- src/Config/DrushConfig.php | 3 +- src/Config/Environment.php | 4 +- src/Preflight/ArgsPreprocessor.php | 2 +- src/Preflight/Preflight.php | 19 ++++--- src/Preflight/PreflightArgs.php | 3 +- src/Preflight/PreflightSiteLocator.php | 16 +++--- src/Runtime/DependencyInjection.php | 26 ++++++--- src/Runtime/Runtime.php | 6 +- src/SiteAlias/ProcessManager.php | 12 ++-- src/Sql/SqlBase.php | 12 ++-- src/Sql/SqlMysql.php | 2 +- src/Symfony/BufferedConsoleOutput.php | 2 +- src/Symfony/DrushStyleInjector.php | 2 +- src/Symfony/IndiscriminateInputDefinition.php | 2 +- 19 files changed, 110 insertions(+), 86 deletions(-) diff --git a/rector.php b/rector.php index a75c3666be..c7161c9b5d 100644 --- a/rector.php +++ b/rector.php @@ -11,9 +11,6 @@ $parameters = $containerConfigurator->parameters(); $parameters->set(Option::AUTO_IMPORT_NAMES, true); $parameters->set(Option::IMPORT_SHORT_CLASSES, false); - $parameters->set(Option::PATHS, [ - __DIR__ . '/src', - ]); $services = $containerConfigurator->services(); $services->set(ParamTypeDeclarationRector::class); diff --git a/src/Boot/BootstrapManager.php b/src/Boot/BootstrapManager.php index 80776a2d0f..11857635b6 100644 --- a/src/Boot/BootstrapManager.php +++ b/src/Boot/BootstrapManager.php @@ -2,6 +2,15 @@ namespace Drush\Boot; +use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Input\InputAwareInterface; +use Robo\Contract\OutputAwareInterface; +use Robo\Contract\ProgressIndicatorAwareInterface; +use Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface; +use Robo\Contract\VerbosityThresholdInterface; +use Consolidation\SiteAlias\SiteAliasManagerAwareInterface; +use Consolidation\SiteProcess\ProcessManagerAwareInterface; +use Consolidation\AnnotatedCommand\Input\StdinAwareInterface; use Consolidation\AnnotatedCommand\AnnotationData; use DrupalFinder\DrupalFinder; use Drush\Config\ConfigAwareTrait; @@ -24,12 +33,12 @@ class BootstrapManager implements LoggerAwareInterface, AutoloaderAwareInterface protected $drupalFinder; /** - * @var \Drush\Boot\Boot[] + * @var Boot[] */ protected $bootstrapCandidates = []; /** - * @var \Drush\Boot\Boot + * @var Boot */ protected $bootstrap; @@ -69,7 +78,7 @@ public function add($candidateList): void } } - public function drupalFinder(): \DrupalFinder\DrupalFinder + public function drupalFinder(): DrupalFinder { if (!isset($this->drupalFinder)) { $this->drupalFinder = new DrupalFinder(); @@ -85,7 +94,7 @@ public function setDrupalFinder(DrupalFinder $drupalFinder): void /** * Return the framework root selected by the user. */ - public function getRoot() + public function getRoot(): string { return $this->drupalFinder()->getDrupalRoot(); } @@ -93,7 +102,7 @@ public function getRoot() /** * Return the composer root for the selected Drupal site. */ - public function getComposerRoot() + public function getComposerRoot(): string { return $this->drupalFinder()->getComposerRoot(); } @@ -143,7 +152,7 @@ public function setUri($uri): void * bootstrapping; otherwise, it will be whichever bootstrap * object is best for the selected root. */ - public function bootstrap(): \Drush\Boot\Boot + public function bootstrap(): Boot { if (!$this->bootstrap) { $this->bootstrap = $this->selectBootstrapClass(); @@ -154,7 +163,7 @@ public function bootstrap(): \Drush\Boot\Boot /** * For use in testing */ - public function injectBootstrap(\Drush\Boot\Boot $bootstrap): void + public function injectBootstrap(Boot $bootstrap): void { $this->inflect($bootstrap); $this->bootstrap = $bootstrap; @@ -168,7 +177,7 @@ public function injectBootstrap(\Drush\Boot\Boot $bootstrap): void * Look up the best bootstrap class for the given location * from the set of available candidates. */ - public function bootstrapObjectForRoot($path): \Drush\Boot\Boot + public function bootstrapObjectForRoot($path): Boot { foreach ($this->bootstrapCandidates as $candidate) { if ($candidate->validRoot($path)) { @@ -191,7 +200,7 @@ public function bootstrapObjectForRoot($path): \Drush\Boot\Boot * be 'latched', and further calls to Drush::bootstrap() * will always return the same object. */ - protected function selectBootstrapClass(): \Drush\Boot\Boot + protected function selectBootstrapClass(): Boot { // Once we have selected a Drupal root, we will reduce our bootstrap // candidates down to just the one used to select this site root. @@ -203,7 +212,7 @@ protected function selectBootstrapClass(): \Drush\Boot\Boot * object being used, and do not allow it to change any * longer. */ - public function latch(\Drush\Boot\Boot $bootstrap): void + public function latch(Boot $bootstrap): void { $this->bootstrap = $bootstrap; } @@ -245,7 +254,7 @@ public function bootstrapPhases(bool $function_names = false): array * function itself but can be useful for other code called from within this * function, to know if e.g. a caller is in the process of booting to the * specified level. If specified, it should never be lower than $phase. - * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData + * @param AnnotationData $annotationData * Optional annotation data from the command. * * TRUE if the specified bootstrap phase has completed. @@ -441,7 +450,7 @@ public function bootstrapToPhaseIndex(int $max_phase_index, AnnotationData $anno * * @param int $max_phase_index * (optional) Only attempt bootstrap to the specified level. - * @param \Consolidation\AnnotatedCommand\AnnotationData $annotationData + * @param AnnotationData $annotationData * Optional annotation data from the command. * * The maximum phase to which we bootstrapped. @@ -486,7 +495,7 @@ public function bootstrapMax($max_phase_index = false, AnnotationData $annotatio /** * Allow those with an instance to us to the BootstrapManager to use its logger */ - public function logger(): ?\Psr\Log\LoggerInterface + public function logger(): ?LoggerInterface { return $this->logger; } @@ -496,37 +505,37 @@ public function inflect($object): void // See \Drush\Runtime\DependencyInjection::addDrushServices and // \Robo\Robo\addInflectors $container = $this->getContainer(); - if ($object instanceof \Robo\Contract\ConfigAwareInterface) { + if ($object instanceof ConfigAwareInterface) { $object->setConfig($container->get('config')); } - if ($object instanceof \Psr\Log\LoggerAwareInterface) { + if ($object instanceof LoggerAwareInterface) { $object->setLogger($container->get('logger')); } - if ($object instanceof \League\Container\ContainerAwareInterface) { + if ($object instanceof ContainerAwareInterface) { $object->setContainer($container->get('container')); } - if ($object instanceof \Symfony\Component\Console\Input\InputAwareInterface) { + if ($object instanceof InputAwareInterface) { $object->setInput($container->get('input')); } - if ($object instanceof \Robo\Contract\OutputAwareInterface) { + if ($object instanceof OutputAwareInterface) { $object->setOutput($container->get('output')); } - if ($object instanceof \Robo\Contract\ProgressIndicatorAwareInterface) { + if ($object instanceof ProgressIndicatorAwareInterface) { $object->setProgressIndicator($container->get('progressIndicator')); } - if ($object instanceof \Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface) { + if ($object instanceof CustomEventAwareInterface) { $object->setHookManager($container->get('hookManager')); } - if ($object instanceof \Robo\Contract\VerbosityThresholdInterface) { + if ($object instanceof VerbosityThresholdInterface) { $object->setOutputAdapter($container->get('outputAdapter')); } - if ($object instanceof \Consolidation\SiteAlias\SiteAliasManagerAwareInterface) { + if ($object instanceof SiteAliasManagerAwareInterface) { $object->setSiteAliasManager($container->get('site.alias.manager')); } - if ($object instanceof \Consolidation\SiteProcess\ProcessManagerAwareInterface) { + if ($object instanceof ProcessManagerAwareInterface) { $object->setProcessManager($container->get('process.manager')); } - if ($object instanceof \Consolidation\AnnotatedCommand\Input\StdinAwareInterface) { + if ($object instanceof StdinAwareInterface) { $object->setStdinHandler($container->get('stdinHandler')); } } diff --git a/src/Boot/DrupalBoot8.php b/src/Boot/DrupalBoot8.php index 3e1dd6c708..47f54a37e7 100644 --- a/src/Boot/DrupalBoot8.php +++ b/src/Boot/DrupalBoot8.php @@ -2,6 +2,7 @@ namespace Drush\Boot; +use Drupal\Core\DrupalKernelInterface; use Consolidation\AnnotatedCommand\AnnotationData; use Drupal\Core\Database\Database; use Drupal\Core\DrupalKernel; @@ -24,26 +25,26 @@ class DrupalBoot8 extends DrupalBoot implements AutoloaderAwareInterface protected $drupalLoggerAdapter; /** - * @var \Drupal\Core\DrupalKernelInterface + * @var DrupalKernelInterface */ protected $kernel; /** - * @var \Symfony\Component\HttpFoundation\Request + * @var Request */ protected $request; - public function getRequest(): \Symfony\Component\HttpFoundation\Request + public function getRequest(): Request { return $this->request; } - public function setRequest(\Symfony\Component\HttpFoundation\Request $request): void + public function setRequest(Request $request): void { $this->request = $request; } - public function getKernel(): \Drupal\Core\DrupalKernelInterface + public function getKernel(): DrupalKernelInterface { return $this->kernel; } @@ -79,7 +80,7 @@ public function validRoot($path) } } - public function getVersion($drupal_root) + public function getVersion($drupal_root): string { // Are the class constants available? if (!$this->hasAutoloader()) { @@ -215,7 +216,7 @@ public function bootstrapDrupalConfiguration(BootstrapManager $manager, Annotati $request = $this->getRequest(); $kernel_factory = Kernels::getKernelFactory($kernel); $allow_dumping = $kernel !== Kernels::UPDATE; - /** @var \Drupal\Core\DrupalKernelInterface kernel */ + /** @var DrupalKernelInterface kernel */ $this->kernel = $kernel_factory($request, $classloader, 'prod', $allow_dumping, $manager->getRoot()); // Include Drush services in the container. // @see Drush\Drupal\DrupalKernel::addServiceModifier() diff --git a/src/Config/ConfigAwareTrait.php b/src/Config/ConfigAwareTrait.php index c0f317c84f..47e8464da8 100644 --- a/src/Config/ConfigAwareTrait.php +++ b/src/Config/ConfigAwareTrait.php @@ -13,7 +13,7 @@ trait ConfigAwareTrait * * @see https://stackoverflow.com/a/37687295. * - * @return \Drush\Config\DrushConfig + * @return DrushConfig */ public function getConfig() { diff --git a/src/Config/ConfigLocator.php b/src/Config/ConfigLocator.php index 3fc2563e13..e115593cb5 100644 --- a/src/Config/ConfigLocator.php +++ b/src/Config/ConfigLocator.php @@ -2,6 +2,7 @@ namespace Drush\Config; use Consolidation\Config\ConfigInterface; +use Robo\Config\Config; use Consolidation\Config\Loader\ConfigLoaderInterface; use Drush\Config\Loader\YamlConfigLoader; use Consolidation\Config\Loader\ConfigProcessor; @@ -30,7 +31,7 @@ class ConfigLocator { /** - * @var \Robo\Config + * @var Config */ protected $config; @@ -372,7 +373,7 @@ protected function identifyCandidatesAtPath(string $path, array $candidates): ar /** * Get the site aliases according to preflight arguments and environment. * - * @param $preflightArgs + * @param $paths * @param Environment $environment */ public function getSiteAliasPaths($paths, Environment $environment): array @@ -400,7 +401,8 @@ function ($item) { /** * Get the commandfile paths according to preflight arguments. * - * @param $preflightArgs + * @param $commandPaths + * @param $root */ public function getCommandFilePaths($commandPaths, $root): array { diff --git a/src/Config/DrushConfig.php b/src/Config/DrushConfig.php index 0daf3ac54e..460bd697c1 100644 --- a/src/Config/DrushConfig.php +++ b/src/Config/DrushConfig.php @@ -1,6 +1,7 @@ get(\Robo\Config\Config::SIMULATE); + return $this->get(Config::SIMULATE); } /** diff --git a/src/Config/Environment.php b/src/Config/Environment.php index f6641ae175..69b21eeb69 100644 --- a/src/Config/Environment.php +++ b/src/Config/Environment.php @@ -260,7 +260,7 @@ public function vendorPath(): string /** * The class loader returned when the autoload.php file is included. */ - public function loader(): ?\Composer\Autoload\ClassLoader + public function loader(): ?ClassLoader { return $this->loader; } @@ -268,7 +268,7 @@ public function loader(): ?\Composer\Autoload\ClassLoader /** * Set the class loader from the autload.php file, if available. * - * @param \Composer\Autoload\ClassLoader $loader + * @param ClassLoader $loader */ public function setLoader(ClassLoader $loader): void { diff --git a/src/Preflight/ArgsPreprocessor.php b/src/Preflight/ArgsPreprocessor.php index 289b6132af..891feb7403 100644 --- a/src/Preflight/ArgsPreprocessor.php +++ b/src/Preflight/ArgsPreprocessor.php @@ -125,7 +125,7 @@ protected function isAliasOrSiteSpec(string $arg): bool * @param $opt The option string to check * @return [$methodName, $optionValue, $acceptsValueFromNextArg] */ - protected function findMethodForOptionWithValues($optionsTable, $opt) + protected function findMethodForOptionWithValues($optionsTable, $opt): array { // Skip $opt if it is empty, or if it is not an option. if (empty($opt) || ($opt[0] != '-')) { diff --git a/src/Preflight/Preflight.php b/src/Preflight/Preflight.php index 044283436e..c87419e68a 100644 --- a/src/Preflight/Preflight.php +++ b/src/Preflight/Preflight.php @@ -1,6 +1,9 @@ logger = $preflightLog ?: new PreflightLog(); } - public function logger(): \Drush\Preflight\PreflightLog + public function logger(): PreflightLog { return $this->logger; } @@ -148,7 +151,7 @@ protected function remapCommandAliases(): array * Arguments and options not used during preflight will be processed * with an ArgvInput. */ - public function preflightArgs($argv): \Drush\Preflight\PreflightArgs + public function preflightArgs($argv): PreflightArgs { $argProcessor = new ArgsPreprocessor(); $remapper = new ArgsRemapper($this->remapOptions(), $this->remapCommandAliases()); @@ -174,7 +177,7 @@ public function prepareConfig(Environment $environment): void $this->configLocator->addDrushConfig($environment->drushBasePath()); } - public function createInput(): \Symfony\Component\Console\Input\InputInterface + public function createInput(): InputInterface { return $this->preflightArgs->createInput(); } @@ -190,7 +193,7 @@ public function getCommandFilePaths(): array return $this->configLocator->getCommandFilePaths(array_merge($commandlinePaths, $configPaths), $this->drupalFinder()->getDrupalRoot()); } - public function loadSiteAutoloader(): \Composer\Autoload\ClassLoader + public function loadSiteAutoloader(): ClassLoader { return $this->environment()->loadSiteAutoloader($this->drupalFinder()->getDrupalRoot()); } @@ -237,7 +240,7 @@ public function preflight($argv): bool $paths = $this->configLocator->getSiteAliasPaths($this->preflightArgs->aliasPaths(), $this->environment); // Configure alias manager. - $aliasFileLoader = new \Drush\SiteAlias\SiteAliasFileLoader(); + $aliasFileLoader = new SiteAliasFileLoader(); $this->aliasManager = (new SiteAliasManager($aliasFileLoader))->addSearchLocations($paths); $this->aliasManager->setReferenceData($config->export()); @@ -345,7 +348,7 @@ protected function setSelectedSite(string $selectedRoot, $fallbackPath = false, /** * Return the Drupal Finder */ - public function drupalFinder(): \DrupalFinder\DrupalFinder + public function drupalFinder(): DrupalFinder { return $this->drupalFinder; } @@ -353,7 +356,7 @@ public function drupalFinder(): \DrupalFinder\DrupalFinder /** * Return the alias manager */ - public function aliasManager(): \Consolidation\SiteAlias\SiteAliasManager + public function aliasManager(): SiteAliasManager { return $this->aliasManager; } @@ -361,7 +364,7 @@ public function aliasManager(): \Consolidation\SiteAlias\SiteAliasManager /** * Return the environment */ - public function environment(): \Drush\Config\Environment + public function environment(): Environment { return $this->environment; } diff --git a/src/Preflight/PreflightArgs.php b/src/Preflight/PreflightArgs.php index 33de98da41..fe26b44f8b 100644 --- a/src/Preflight/PreflightArgs.php +++ b/src/Preflight/PreflightArgs.php @@ -1,6 +1,7 @@ determineSelf($preflightArgs, $environment, $root); @@ -52,11 +52,11 @@ public function findSite(PreflightArgsInterface $preflightArgs, Environment $env * or, if those are invalid, then generate one from * the provided root and URI. * - * @param \Drush\Preflight\PreflightArgsInterface $preflightArgs - * @param \Drush\Config\Environment $environment + * @param PreflightArgsInterface $preflightArgs + * @param Environment $environment * @param $root */ - protected function determineSelf(PreflightArgsInterface $preflightArgs, Environment $environment, $root): \Consolidation\SiteAlias\SiteAlias + protected function determineSelf(PreflightArgsInterface $preflightArgs, Environment $environment, $root): SiteAlias { if ($preflightArgs->hasAlias()) { $aliasName = $preflightArgs->alias(); @@ -94,10 +94,10 @@ protected function determineSelf(PreflightArgsInterface $preflightArgs, Environm /** * Generate @self from the provided root and URI. * - * @param \Drush\Preflight\PreflightArgsInterface $preflightArgs + * @param PreflightArgsInterface $preflightArgs * @param $root */ - protected function buildSelf(PreflightArgsInterface $preflightArgs, $root): \Consolidation\SiteAlias\SiteAlias + protected function buildSelf(PreflightArgsInterface $preflightArgs, $root): SiteAlias { // If there is no root, then return '@none' if (!$root) { diff --git a/src/Runtime/DependencyInjection.php b/src/Runtime/DependencyInjection.php index 358e5bb4b7..f90d0d1e23 100644 --- a/src/Runtime/DependencyInjection.php +++ b/src/Runtime/DependencyInjection.php @@ -1,6 +1,14 @@ addDrushServices($container, $loader, $drupalFinder, $aliasManager, $config); // Robo has the same signature for configureContainer in 1.x, 2.x and 3.x. - \Robo\Robo::configureContainer($container, $application, $config, $input, $output); + Robo::configureContainer($container, $application, $config, $input, $output); $container->add('container', $container); // Store the container in the \Drush object @@ -100,7 +108,7 @@ protected function addDrushServices($container, ClassLoader $loader, DrupalFinde // Override Robo's formatter manager with our own // @todo not sure that we'll use this. Maybe remove it. - $container->share('formatterManager', \Drush\Formatters\DrushFormatterManager::class) + $container->share('formatterManager', DrushFormatterManager::class) ->addMethodCall('addDefaultFormatters', []) ->addMethodCall('addDefaultSimplifiers', []); @@ -133,11 +141,11 @@ protected function addDrushServices($container, ClassLoader $loader, DrupalFinde $container->share('shutdownHandler', 'Drush\Runtime\ShutdownHandler'); // Add inflectors. @see \Drush\Boot\BaseBoot::inflect - $container->inflector(\Drush\Boot\AutoloaderAwareInterface::class) + $container->inflector(AutoloaderAwareInterface::class) ->invokeMethod('setAutoloader', ['loader']); - $container->inflector(\Consolidation\SiteAlias\SiteAliasManagerAwareInterface::class) + $container->inflector(SiteAliasManagerAwareInterface::class) ->invokeMethod('setSiteAliasManager', ['site.alias.manager']); - $container->inflector(\Consolidation\SiteProcess\ProcessManagerAwareInterface::class) + $container->inflector(ProcessManagerAwareInterface::class) ->invokeMethod('setProcessManager', ['process.manager']); } diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index 85f2011d48..87155bf7f4 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -1,6 +1,8 @@ doRun($argv, $output); } catch (\Exception $e) { // Fallback to status 1 if the Exception has not indicated otherwise. @@ -79,7 +81,7 @@ protected function doRun($argv, $output) // Create the Symfony Application et. al. $input = $this->preflight->createInput(); - $application = new \Drush\Application('Drush Commandline Tool', Drush::getVersion()); + $application = new Application('Drush Commandline Tool', Drush::getVersion()); // Set up the DI container. $container = $this->di->initContainer( diff --git a/src/SiteAlias/ProcessManager.php b/src/SiteAlias/ProcessManager.php index 92355e1df9..4709307938 100644 --- a/src/SiteAlias/ProcessManager.php +++ b/src/SiteAlias/ProcessManager.php @@ -18,7 +18,7 @@ class ProcessManager extends ConsolidationProcessManager /** * Run a Drush command on a site alias (or @self). */ - public function drush(SiteAliasInterface $siteAlias, string $command, array $args = [], array $options = [], array $options_double_dash = []): \Consolidation\SiteProcess\ProcessBase + public function drush(SiteAliasInterface $siteAlias, string $command, array $args = [], array $options = [], array $options_double_dash = []): ProcessBase { array_unshift($args, $command); return $this->drushSiteProcess($siteAlias, $args, $options, $options_double_dash); @@ -29,7 +29,7 @@ public function drush(SiteAliasInterface $siteAlias, string $command, array $arg * drushSiteProcess exists specifically for use by the RedispatchHook, * which does not have specific knowledge about which argument is the command. */ - public function drushSiteProcess(SiteAliasInterface $siteAlias, array $args = [], array $options = [], array $options_double_dash = []): \Symfony\Component\Process\Process + public function drushSiteProcess(SiteAliasInterface $siteAlias, array $args = [], array $options = [], array $options_double_dash = []): ProcessBase { // Fill in the root and URI from the site alias, if the caller // did not already provide them in $options. @@ -84,7 +84,7 @@ public function drushScript(SiteAliasInterface $siteAlias) * Use Drush::drush() or ProcessManager::drush() instead of this method * when calling Drush. */ - public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options = [], $optionsPassedAsArgs = []): \Consolidation\SiteProcess\ProcessBase + public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options = [], $optionsPassedAsArgs = []): ProcessBase { $process = parent::siteProcess($siteAlias, $args, $options, $optionsPassedAsArgs); return $this->configureProcess($process); @@ -104,7 +104,7 @@ public function siteProcess(SiteAliasInterface $siteAlias, $args = [], $options * * A wrapper around Symfony Process. */ - public function process($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60): \Consolidation\SiteProcess\ProcessBase + public function process($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60): ProcessBase { $process = parent::process($commandline, $cwd, $env, $input, $timeout); return $this->configureProcess($process); @@ -118,7 +118,7 @@ public function process($commandline, $cwd = null, array $env = null, $input = n * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input * @param int|float|null $timeout The timeout in seconds or null to disable */ - public function shell($command, $cwd = null, array $env = null, $input = null, $timeout = 60): \Consolidation\SiteProcess\ProcessBase + public function shell($command, $cwd = null, array $env = null, $input = null, $timeout = 60): ProcessBase { $process = parent::shell($command, $cwd, $env, $input, $timeout); return $this->configureProcess($process); @@ -127,7 +127,7 @@ public function shell($command, $cwd = null, array $env = null, $input = null, $ /** * configureProcess sets up a process object so that it is ready to use. */ - protected static function configureProcess(ProcessBase $process): \Consolidation\SiteProcess\ProcessBase + protected static function configureProcess(ProcessBase $process): ProcessBase { $process->setSimulated(Drush::simulate()); $process->setVerbose(Drush::verbose()); diff --git a/src/Sql/SqlBase.php b/src/Sql/SqlBase.php index 7cf51cf216..a6a5911205 100644 --- a/src/Sql/SqlBase.php +++ b/src/Sql/SqlBase.php @@ -56,12 +56,12 @@ public function getEnv(): array /** * Get the last used Process. */ - public function getProcess(): \Symfony\Component\Process\Process + public function getProcess(): Process { return $this->process; } - public function setProcess(\Symfony\Component\Process\Process $process): void + public function setProcess(Process $process): void { $this->process = $process; } @@ -117,7 +117,7 @@ public static function getInstance($db_spec, $options): ?self /* * Get the current $db_spec. */ - public function getDbSpec(): ?array + public function getDbSpec(): array { return $this->dbSpec; } @@ -394,7 +394,7 @@ public function queryFormat($query) * An array of table names * True if successful, FALSE if failed. */ - public function drop(array $tables): bool + public function drop(array $tables): ?bool { $return = true; if ($tables) { @@ -426,7 +426,7 @@ public function createdbSql($dbname, bool $quoted = false): string * in a Windows shell. Set TRUE if the CREATE is not running on the bash command line. * True if successful, FALSE otherwise. */ - public function createdb(bool $quoted = false): bool + public function createdb(bool $quoted = false): ?bool { $dbname = $this->getDbSpec()['database']; $sql = $this->createdbSql($dbname, $quoted); @@ -493,7 +493,7 @@ public function listTables(): array * An array of table names which exist in the current database, * appropriately quoted for the RDMS. */ - public function listTablesQuoted(): ?array + public function listTablesQuoted(): array { return $this->listTables(); } diff --git a/src/Sql/SqlMysql.php b/src/Sql/SqlMysql.php index d62217193c..1a693804b1 100644 --- a/src/Sql/SqlMysql.php +++ b/src/Sql/SqlMysql.php @@ -136,7 +136,7 @@ public function listTables(): array return $tables; } - public function listTablesQuoted(): ?array + public function listTablesQuoted(): array { $tables = $this->listTables(); foreach ($tables as &$table) { diff --git a/src/Symfony/BufferedConsoleOutput.php b/src/Symfony/BufferedConsoleOutput.php index 0898e16a9d..cddabd0f9f 100644 --- a/src/Symfony/BufferedConsoleOutput.php +++ b/src/Symfony/BufferedConsoleOutput.php @@ -29,7 +29,7 @@ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = fa /** * {@inheritdoc} */ - public function getErrorOutput(): \Symfony\Component\Console\Output\BufferedOutput + public function getErrorOutput(): BufferedOutput { return $this->stderr; } diff --git a/src/Symfony/DrushStyleInjector.php b/src/Symfony/DrushStyleInjector.php index 1c87c4d549..41c7f3fcab 100644 --- a/src/Symfony/DrushStyleInjector.php +++ b/src/Symfony/DrushStyleInjector.php @@ -8,7 +8,7 @@ class DrushStyleInjector implements ParameterInjector { - public function get(CommandData $commandData, $interfaceName): \Drush\Style\DrushStyle + public function get(CommandData $commandData, $interfaceName): DrushStyle { return new DrushStyle($commandData->input(), $commandData->output()); } diff --git a/src/Symfony/IndiscriminateInputDefinition.php b/src/Symfony/IndiscriminateInputDefinition.php index 9f237710b3..0bfc534239 100644 --- a/src/Symfony/IndiscriminateInputDefinition.php +++ b/src/Symfony/IndiscriminateInputDefinition.php @@ -37,7 +37,7 @@ public function hasOption($name): bool /** * @inheritdoc */ - public function getOption($name): \Symfony\Component\Console\Input\InputOption + public function getOption($name): InputOption { if (parent::hasOption($name)) { return parent::getOption($name); From 366e0c32ace90ca9b2296c8bd6225b80b7dbaea2 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 6 Jan 2022 22:38:49 -0500 Subject: [PATCH 070/125] More rector - quality set. (#4988) --- rector.php | 12 +++++++++++- src/Boot/BootstrapManager.php | 6 +----- src/Boot/DrupalBoot.php | 2 +- src/Config/ConfigLocator.php | 5 ++--- src/Drupal/Commands/core/DrupalCommands.php | 3 +-- src/Drupal/Commands/core/MigrateRunnerCommands.php | 8 ++++---- src/Drupal/Commands/core/QueueCommands.php | 5 ++--- src/Drupal/Commands/core/StateCommands.php | 4 ++-- src/Drupal/Commands/core/ViewsCommands.php | 4 ++-- src/Drupal/Commands/core/WatchdogCommands.php | 10 +++------- src/Preflight/ArgsPreprocessor.php | 4 ++-- src/Preflight/ArgsRemapper.php | 2 +- src/Preflight/Preflight.php | 2 +- src/Preflight/PreflightArgs.php | 4 +--- src/Preflight/RedispatchToSiteLocal.php | 2 +- src/Runtime/ErrorHandler.php | 2 +- src/Runtime/Runtime.php | 2 +- src/Runtime/TildeExpansionHook.php | 4 ++-- src/SiteAlias/LegacyAliasConverter.php | 9 ++++----- src/Sql/SqlBase.php | 6 +----- src/Sql/SqlMysql.php | 2 +- src/Utils/FsUtils.php | 2 +- 22 files changed, 46 insertions(+), 54 deletions(-) diff --git a/rector.php b/rector.php index c7161c9b5d..5742cfdb37 100644 --- a/rector.php +++ b/rector.php @@ -3,15 +3,25 @@ declare(strict_types=1); use Rector\Core\Configuration\Option; +use Rector\Set\ValueObject\SetList; use Rector\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector; use Rector\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return function (ContainerConfigurator $containerConfigurator): void { $parameters = $containerConfigurator->parameters(); + $containerConfigurator->import(SetList::CODE_QUALITY); $parameters->set(Option::AUTO_IMPORT_NAMES, true); $parameters->set(Option::IMPORT_SHORT_CLASSES, false); - + $src = [__DIR__ . '/src']; + $parameters->set(Option::SKIP, [ + \Rector\CodeQuality\Rector\Identical\StrlenZeroToIdenticalEmptyStringRector::class => $src, + \Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector::class => $src, + \Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector::class => $src, + \Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector::class => $src, + \Rector\CodeQuality\Rector\If_\CombineIfRector::class => $src, + \Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector::class => $src, + ]); $services = $containerConfigurator->services(); $services->set(ParamTypeDeclarationRector::class); $services->set(ReturnTypeDeclarationRector::class); diff --git a/src/Boot/BootstrapManager.php b/src/Boot/BootstrapManager.php index 11857635b6..6b7644072f 100644 --- a/src/Boot/BootstrapManager.php +++ b/src/Boot/BootstrapManager.php @@ -349,11 +349,7 @@ public function bootstrapValidate(int $phase): bool } if ($phase_index > $validated_phase) { $current_phase .= 'Validate'; - if (method_exists($bootstrap, $current_phase)) { - $result_cache[$phase_index] = $bootstrap->{$current_phase}($this); - } else { - $result_cache[$phase_index] = true; - } + $result_cache[$phase_index] = method_exists($bootstrap, $current_phase) ? $bootstrap->{$current_phase}($this) : true; $validated_phase = $phase_index; } } diff --git a/src/Boot/DrupalBoot.php b/src/Boot/DrupalBoot.php index 56824156f8..197a9e045c 100644 --- a/src/Boot/DrupalBoot.php +++ b/src/Boot/DrupalBoot.php @@ -36,7 +36,7 @@ protected function scanUpForUri($root, $scan) return false; } $scan = $next; - if ($scan == $root) { + if ($scan === $root) { return false; } } diff --git a/src/Config/ConfigLocator.php b/src/Config/ConfigLocator.php index e115593cb5..361dadb63f 100644 --- a/src/Config/ConfigLocator.php +++ b/src/Config/ConfigLocator.php @@ -31,7 +31,7 @@ class ConfigLocator { /** - * @var Config + * @var ConfigInterface */ protected $config; @@ -393,9 +393,8 @@ function ($item) { }, array_unique($base_dirs) ); - $paths = array_merge($paths, $site_local_paths); - return $paths; + return array_merge($paths, $site_local_paths); } /** diff --git a/src/Drupal/Commands/core/DrupalCommands.php b/src/Drupal/Commands/core/DrupalCommands.php index a33043750e..a4b615d2a5 100644 --- a/src/Drupal/Commands/core/DrupalCommands.php +++ b/src/Drupal/Commands/core/DrupalCommands.php @@ -131,8 +131,7 @@ public function requirements($options = ['format' => 'table', 'severity' => -1, unset($rows[$key]); } } - $result = new RowsOfFields($rows); - return $result; + return new RowsOfFields($rows); } /** diff --git a/src/Drupal/Commands/core/MigrateRunnerCommands.php b/src/Drupal/Commands/core/MigrateRunnerCommands.php index 0b2544241c..caabf6050b 100644 --- a/src/Drupal/Commands/core/MigrateRunnerCommands.php +++ b/src/Drupal/Commands/core/MigrateRunnerCommands.php @@ -542,7 +542,7 @@ public function rollback(?string $migrationIds = null, array $options = ['all' = * @validate-migration-id * @version 10.4 * - * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws PluginException */ public function stop(string $migrationId): void { @@ -581,7 +581,7 @@ public function stop(string $migrationId): void * @validate-migration-id * @version 10.4 * - * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws PluginException */ public function resetStatus(string $migrationId): void { @@ -638,7 +638,7 @@ public function resetStatus(string $migrationId): void * @return RowsOfFields * Migration messages status formatted as table. * - * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws PluginException */ public function messages(string $migrationId, array $options = ['idlist' => self::REQ]): RowsOfFields { @@ -740,7 +740,7 @@ protected function preprocessMessageRow(\StdClass $row, array $sourceIdKeys): ar * @return RowsOfFields * Source fields of the given migration. * - * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws PluginException */ public function fieldsSource(string $migrationId): RowsOfFields { diff --git a/src/Drupal/Commands/core/QueueCommands.php b/src/Drupal/Commands/core/QueueCommands.php index 796c1d9c15..76a483870f 100644 --- a/src/Drupal/Commands/core/QueueCommands.php +++ b/src/Drupal/Commands/core/QueueCommands.php @@ -84,7 +84,7 @@ public function run(string $name, $options = ['time-limit' => self::REQ, 'items- // If the worker indicates there is a problem with the whole queue, // release the item. $queue->releaseItem($item); - throw new \Exception($e->getMessage()); + throw new \Exception($e->getMessage(), $e->getCode(), $e); } catch (DelayedRequeueException $e) { // The worker requested the task not be immediately re-queued. // - If the queue doesn't support ::delayItem(), we should leave the @@ -161,8 +161,7 @@ public function validateQueueName(CommandData $commandData) { $arg_name = $commandData->annotationData()->get('validate-queue', null); $name = $commandData->input()->getArgument($arg_name); - $all = array_keys(self::getQueues()); - if (!in_array($name, $all)) { + if (!array_key_exists($name, self::getQueues())) { $msg = dt('Queue not found: !name', ['!name' => $name]); return new CommandError($msg); } diff --git a/src/Drupal/Commands/core/StateCommands.php b/src/Drupal/Commands/core/StateCommands.php index 1b4bf6d480..66c3dfedd9 100644 --- a/src/Drupal/Commands/core/StateCommands.php +++ b/src/Drupal/Commands/core/StateCommands.php @@ -109,7 +109,7 @@ public static function format($value, $format) { if ($format == 'auto') { if (is_numeric($value)) { - $value = $value + 0; // http://php.net/manual/en/function.is-numeric.php#107326 + $value += 0; // http://php.net/manual/en/function.is-numeric.php#107326 $format = gettype($value); } elseif (($value == 'TRUE') || ($value == 'FALSE')) { $format = 'bool'; @@ -141,7 +141,7 @@ public static function format($value, $format) $value = json_decode($value, true); break; case 'yaml': - $value = Yaml::parse($value, false, true); + $value = Yaml::parse($value, false); break; } return $value; diff --git a/src/Drupal/Commands/core/ViewsCommands.php b/src/Drupal/Commands/core/ViewsCommands.php index 3df757ff2d..dfffc46115 100644 --- a/src/Drupal/Commands/core/ViewsCommands.php +++ b/src/Drupal/Commands/core/ViewsCommands.php @@ -140,11 +140,11 @@ public function vlist($options = ['name' => self::REQ, 'tags' => self::REQ, 'sta // Get the --name option. $name = StringUtils::csvToArray($options['name']); - $with_name = !empty($name) ? true : false; + $with_name = !empty($name); // Get the --tags option. $tags = StringUtils::csvToArray($options['tags']); - $with_tags = !empty($tags) ? true : false; + $with_tags = !empty($tags); // Get the --status option. Store user input apart to reuse it after. $status = $options['status']; diff --git a/src/Drupal/Commands/core/WatchdogCommands.php b/src/Drupal/Commands/core/WatchdogCommands.php index 967b239ee5..b09792793a 100644 --- a/src/Drupal/Commands/core/WatchdogCommands.php +++ b/src/Drupal/Commands/core/WatchdogCommands.php @@ -228,7 +228,7 @@ public function delete($substring = '', $options = ['severity' => self::REQ, 'ty } $ret = Database::getConnection()->truncate('watchdog')->execute(); $this->logger()->success(dt('All watchdog messages have been deleted.')); - } else if (is_numeric($substring)) { + } elseif (is_numeric($substring)) { $this->output()->writeln(dt('Watchdog message #!wid will be deleted.', ['!wid' => $substring])); if (!$this->io()->confirm(dt('Do you want to continue?'))) { throw new UserAbortException(); @@ -297,7 +297,7 @@ protected function where($type = null, $severity = null, $filter = null, $criter $conditions = []; if ($type) { $types = $this->messageTypes(); - if (array_search($type, $types) === false) { + if (!in_array($type, $types)) { $msg = "Unrecognized message type: !type.\nRecognized types are: !types."; throw new \Exception(dt($msg, ['!type' => $type, '!types' => implode(', ', $types)])); } @@ -374,11 +374,7 @@ protected function formatResult($result, $extended = false) unset($result->referer); } // Username. - if ($account = User::load($result->uid)) { - $result->username = $account->name; - } else { - $result->username = dt('Anonymous'); - } + $result->username = ($account = User::load($result->uid)) ? $account->name : dt('Anonymous'); unset($result->uid); $message_length = PHP_INT_MAX; } diff --git a/src/Preflight/ArgsPreprocessor.php b/src/Preflight/ArgsPreprocessor.php index 891feb7403..8d39f13980 100644 --- a/src/Preflight/ArgsPreprocessor.php +++ b/src/Preflight/ArgsPreprocessor.php @@ -164,7 +164,7 @@ protected function checkMatchingOption($opt, $keyParam, $methodName): array $acceptsValueFromNextArg = $keyParam[strlen($keyParam) - 1] != '~'; // If $opt does not begin with $key, then it cannot be a match. - if ($key != substr($opt, 0, strlen($key))) { + if ($key !== substr($opt, 0, strlen($key))) { return [false, false, false]; } @@ -173,7 +173,7 @@ protected function checkMatchingOption($opt, $keyParam, $methodName): array // a value; in this case, the value will be provided from the next // argument in the calling function. If this option does not take a // supplied value, then we set its value to 'true' - if (strlen($key) == strlen($opt)) { + if (strlen($key) === strlen($opt)) { return [$methodName, $acceptsValue ? null: true, $acceptsValueFromNextArg]; } diff --git a/src/Preflight/ArgsRemapper.php b/src/Preflight/ArgsRemapper.php index 2cd14dcc84..55237e7a4e 100644 --- a/src/Preflight/ArgsRemapper.php +++ b/src/Preflight/ArgsRemapper.php @@ -85,7 +85,7 @@ protected function matches(string $arg, string $candidate): bool return false; } - if (strlen($arg) == strlen($candidate)) { + if (strlen($arg) === strlen($candidate)) { return true; } diff --git a/src/Preflight/Preflight.php b/src/Preflight/Preflight.php index c87419e68a..fcdbd6226e 100644 --- a/src/Preflight/Preflight.php +++ b/src/Preflight/Preflight.php @@ -266,7 +266,7 @@ public function preflight($argv): bool // NOTE: termination handlers have not been set yet, so it is okay // to exit early without taking special action. $status = RedispatchToSiteLocal::redispatchIfSiteLocalDrush($argv, $root, $this->environment->vendorPath(), $this->logger()); - if ($status !== false) { + if ($status) { return $status; } diff --git a/src/Preflight/PreflightArgs.php b/src/Preflight/PreflightArgs.php index fe26b44f8b..f9dae5c847 100644 --- a/src/Preflight/PreflightArgs.php +++ b/src/Preflight/PreflightArgs.php @@ -495,8 +495,6 @@ public function createInput(): InputInterface if ($this->isStrict()) { return new DrushArgvInput($this->args()); } - - $input = new LessStrictArgvInput($this->args()); - return $input; + return new LessStrictArgvInput($this->args()); } } diff --git a/src/Preflight/RedispatchToSiteLocal.php b/src/Preflight/RedispatchToSiteLocal.php index 79d1c8f00d..76b52d3ff4 100644 --- a/src/Preflight/RedispatchToSiteLocal.php +++ b/src/Preflight/RedispatchToSiteLocal.php @@ -41,7 +41,7 @@ public static function redispatchIfSiteLocalDrush(array $argv, string $root, str // Do another special check to detect symlinked Drush folder similar // to what the SUT sets up for Drush functional tests. - if (dirname($vendor) == dirname($siteLocalDrush)) { + if (dirname($vendor) === dirname($siteLocalDrush)) { return false; } diff --git a/src/Runtime/ErrorHandler.php b/src/Runtime/ErrorHandler.php index c0fc33e553..c83937bd85 100644 --- a/src/Runtime/ErrorHandler.php +++ b/src/Runtime/ErrorHandler.php @@ -29,7 +29,7 @@ public function errorHandler($errno, $message, $filename, $line) // E_DEPRECATED was added in PHP 5.3. Drupal 6 will not fix all the // deprecated errors, but suppresses them. So we suppress them as well. if (defined('E_DEPRECATED')) { - $errno = $errno & ~E_DEPRECATED; + $errno &= ~E_DEPRECATED; } // "error_reporting" is usually set in php.ini, but may be changed by diff --git a/src/Runtime/Runtime.php b/src/Runtime/Runtime.php index 87155bf7f4..47d61996c4 100644 --- a/src/Runtime/Runtime.php +++ b/src/Runtime/Runtime.php @@ -68,7 +68,7 @@ protected function doRun($argv, $output) $status = $this->preflight->preflight($argv); // If preflight signals that we are done, then exit early. - if ($status !== false) { + if ($status) { return $status; } diff --git a/src/Runtime/TildeExpansionHook.php b/src/Runtime/TildeExpansionHook.php index eb0b63d58a..9377383c36 100644 --- a/src/Runtime/TildeExpansionHook.php +++ b/src/Runtime/TildeExpansionHook.php @@ -30,7 +30,7 @@ public function validate(CommandData $commandData): void foreach ($options as $name => $value) { if (is_string($value)) { $replaced = StringUtils::replaceTilde($value, $this->getConfig()->home()); - if ($value != $replaced) { + if ($value !== $replaced) { $input->setOption($name, $replaced); } } @@ -38,7 +38,7 @@ public function validate(CommandData $commandData): void foreach ($args as $name => $value) { if (is_string($value)) { $replaced = StringUtils::replaceTilde($value, $this->getConfig()->home()); - if ($value != $replaced) { + if ($value !== $replaced) { $input->setArgument($name, $replaced); } } diff --git a/src/SiteAlias/LegacyAliasConverter.php b/src/SiteAlias/LegacyAliasConverter.php index 51a665d10c..9e3280a718 100644 --- a/src/SiteAlias/LegacyAliasConverter.php +++ b/src/SiteAlias/LegacyAliasConverter.php @@ -142,19 +142,18 @@ protected function getContents($path, $data): string { if (!empty($data)) { $indent = 2; - return Yaml::dump($data, PHP_INT_MAX, $indent, false, true); + return Yaml::dump($data, PHP_INT_MAX, $indent, false); } $recoverSource = $this->recoverLegacyFile($path); if (!$recoverSource) { $recoverSource = 'the source alias file'; } - $contents = <<getDbSpec(); if ($hide_password) { // Default to unix socket if configured. - $unixSocket = !empty($dbSpec['unix_socket']) ? 'socket="' . $dbSpec['unix_socket'] . '"' : ''; + $unixSocket = empty($dbSpec['unix_socket']) ? '' : 'socket="' . $dbSpec['unix_socket'] . '"'; // EMPTY password is not the same as NO password, and is valid. $contents = << Date: Thu, 6 Jan 2022 23:14:02 -0500 Subject: [PATCH 071/125] More Rector in /src (#4989) * A bit more Rector in /src * Fix fail --- src/Drush.php | 39 ++++++++++++++++------------- src/Exec/ExecTrait.php | 14 +++++------ src/Log/DrushLog.php | 9 ++++--- src/Log/Logger.php | 6 ++--- src/Style/DrushStyle.php | 12 ++++----- src/TestTraits/CliTestTrait.php | 12 ++++----- src/TestTraits/DrushTestTrait.php | 4 +-- src/TestTraits/OutputUtilsTrait.php | 2 +- 8 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/Drush.php b/src/Drush.php index e3577ab6ba..8c38f399cc 100644 --- a/src/Drush.php +++ b/src/Drush.php @@ -6,6 +6,11 @@ */ namespace Drush; +use Robo\Runner; +use Robo\Robo; +use Drush\Config\DrushConfig; +use Drush\Boot\BootstrapManager; +use Drush\Boot\Boot; use Consolidation\AnnotatedCommand\AnnotatedCommandFactory; use Consolidation\SiteAlias\SiteAliasInterface; use Consolidation\SiteAlias\SiteAliasManager; @@ -59,7 +64,7 @@ class Drush /** * The Robo Runner -- manages and constructs all commandfile classes * - * @var \Robo\Runner + * @var Runner */ protected static $runner; @@ -90,7 +95,7 @@ public static function getVersion() return self::$version; } - public static function getMajorVersion() + public static function getMajorVersion(): string { if (!self::$majorVersion) { $drush_version = self::getVersion(); @@ -100,7 +105,7 @@ public static function getMajorVersion() return self::$majorVersion; } - public static function getMinorVersion() + public static function getMinorVersion(): string { if (!self::$minorVersion) { $drush_version = self::getVersion(); @@ -113,17 +118,17 @@ public static function getMinorVersion() /** * Sets a new global container. */ - public static function setContainer($container) + public static function setContainer($container): void { - \Robo\Robo::setContainer($container); + Robo::setContainer($container); } /** * Unsets the global container. */ - public static function unsetContainer() + public static function unsetContainer(): void { - \Robo\Robo::unsetContainer(); + Robo::unsetContainer(); } /** @@ -131,12 +136,12 @@ public static function unsetContainer() * * @throws RuntimeException */ - public static function getContainer() + public static function getContainer(): \Psr\Container\ContainerInterface { - if (!\Robo\Robo::hasContainer()) { + if (!Robo::hasContainer()) { throw new RuntimeException('Drush::$container is not initialized yet. \Drush::setContainer() must be called with a real container.'); } - return \Robo\Robo::getContainer(); + return Robo::getContainer(); } /** @@ -144,7 +149,7 @@ public static function getContainer() */ public static function hasContainer(): bool { - return \Robo\Robo::hasContainer(); + return Robo::hasContainer(); } /** @@ -158,10 +163,10 @@ public static function getApplication(): Application /** * Return the Robo runner. */ - public static function runner(): \Robo\Runner + public static function runner(): Runner { if (!isset(self::$runner)) { - self::$runner = new \Robo\Runner(); + self::$runner = new Runner(); } return self::$runner; } @@ -213,7 +218,7 @@ public static function logger(): LoggerInterface * * @internal Commands should use $this->config() instead. */ - public static function config(): Config\DrushConfig + public static function config(): DrushConfig { return self::service('config'); } @@ -356,7 +361,7 @@ public static function process($commandline, $cwd = null, $env = null, $input = * @return * A wrapper around Symfony Process. */ - public static function shell($command, $cwd = null, array $env = null, $input = null, $timeout = 60): Process + public static function shell(string $command, $cwd = null, array $env = null, $input = null, $timeout = 60): ProcessBase { return self::processManager()->shell($command, $cwd, $env, $input, $timeout); } @@ -418,7 +423,7 @@ public static function debug(): bool /** * Return the Bootstrap Manager. */ - public static function bootstrapManager(): Boot\BootstrapManager + public static function bootstrapManager(): BootstrapManager { return self::service('bootstrap.manager'); } @@ -426,7 +431,7 @@ public static function bootstrapManager(): Boot\BootstrapManager /** * Return the Bootstrap object. */ - public static function bootstrap(): Boot\Boot + public static function bootstrap(): Boot { return self::bootstrapManager()->bootstrap(); } diff --git a/src/Exec/ExecTrait.php b/src/Exec/ExecTrait.php index b7ec6c2d75..10177ee999 100644 --- a/src/Exec/ExecTrait.php +++ b/src/Exec/ExecTrait.php @@ -16,14 +16,14 @@ trait ExecTrait * Optional URI or site path to open in browser. If omitted, or if a site path * is specified, the current site home page uri will be prepended if the site's * hostname resolves. - * @param int $sleep - * @param bool $port - * @param bool $browser - * @return bool + * @param $sleep + * @param $port + * @param string|bool $browser + * @return * TRUE if browser was opened. FALSE if browser was disabled by the user or a * default browser could not be found. */ - public function startBrowser($uri = null, $sleep = 0, $port = false, $browser = true) + public function startBrowser($uri = null, int $sleep = 0, ?int $port = null, $browser = false): bool { if ($browser) { // We can only open a browser if we have a DISPLAY environment variable on @@ -54,9 +54,9 @@ public function startBrowser($uri = null, $sleep = 0, $port = false, $browser = // See if we can find an OS helper to open URLs in default browser. if (self::programExists('xdg-open')) { $browser = 'xdg-open'; - } else if (self::programExists('open')) { + } elseif (self::programExists('open')) { $browser = 'open'; - } else if (self::programExists('start')) { + } elseif (self::programExists('start')) { $browser = 'start'; } else { // Can't find a valid browser. diff --git a/src/Log/DrushLog.php b/src/Log/DrushLog.php index 7a3398dde1..12240d7e2f 100644 --- a/src/Log/DrushLog.php +++ b/src/Log/DrushLog.php @@ -16,6 +16,7 @@ namespace Drush\Log; +use Robo\Robo; use Drupal\Core\Logger\LogMessageParserInterface; use Drupal\Core\Logger\RfcLoggerTrait; use Drupal\Core\Logger\RfcLogLevel; @@ -41,14 +42,14 @@ class DrushLog implements LoggerInterface, LoggerAwareInterface /** * The message's placeholders parser. * - * @var \Drupal\Core\Logger\LogMessageParserInterface + * @var LogMessageParserInterface */ protected $parser; /** * Constructs a DrushLog object. * - * @param \Drupal\Core\Logger\LogMessageParserInterface $parser + * @param LogMessageParserInterface $parser * The parser to use when extracting message variables. */ public function __construct(LogMessageParserInterface $parser) @@ -59,10 +60,10 @@ public function __construct(LogMessageParserInterface $parser) /** * {@inheritdoc} */ - public function log($level, $message, array $context = []) + public function log($level, $message, array $context = []): void { // Only log during Drush requests, not web requests. - if (!\Robo\Robo::hasContainer()) { + if (!Robo::hasContainer()) { return; } diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 32fd7422df..72c6de9446 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -32,7 +32,7 @@ public function __construct(OutputInterface $output) parent::__construct($output); } - public function log($level, $message, array $context = []) + public function log($level, $message, array $context = []): void { // Append timer and memory values. if (Drush::debug()) { @@ -52,7 +52,7 @@ public static function formatSize($size) // format_plural() not always available. return dt('@count bytes', ['@count' => $size]); } else { - $size = $size / DRUSH_KILOBYTE; // Convert bytes to kilobytes. + $size /= DRUSH_KILOBYTE; // Convert bytes to kilobytes. $units = [ dt('@size KB', []), dt('@size MB', []), @@ -65,7 +65,7 @@ public static function formatSize($size) ]; foreach ($units as $unit) { if (round($size, 2) >= DRUSH_KILOBYTE) { - $size = $size / DRUSH_KILOBYTE; + $size /= DRUSH_KILOBYTE; } else { break; } diff --git a/src/Style/DrushStyle.php b/src/Style/DrushStyle.php index cbf564a032..c09c92efbd 100644 --- a/src/Style/DrushStyle.php +++ b/src/Style/DrushStyle.php @@ -9,7 +9,7 @@ class DrushStyle extends SymfonyStyle { - public function confirm($question, $default = true) + public function confirm($question, $default = true): bool { // Automatically accept confirmations if the --yes argument was supplied. if (Drush::affirmative()) { @@ -20,9 +20,7 @@ public function confirm($question, $default = true) $this->warning($question . ': no.'); return false; } - - $return = parent::confirm($question, $default); - return $return; + return parent::confirm($question, $default); } public function choice($question, array $choices, $default = null) @@ -34,17 +32,17 @@ public function choice($question, array $choices, $default = null) return array_search($return, $choices); } - public function warning($message) + public function warning($message): void { $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ! ', true); } - public function note($message) + public function note($message): void { $this->block($message, 'NOTE', 'fg=black;bg=yellow', ' ! '); } - public function caution($message) + public function caution($message): void { $this->block($message, 'CAUTION', 'fg=black;bg=yellow', ' ! ', true); } diff --git a/src/TestTraits/CliTestTrait.php b/src/TestTraits/CliTestTrait.php index ebe2063c23..95e703afb5 100644 --- a/src/TestTraits/CliTestTrait.php +++ b/src/TestTraits/CliTestTrait.php @@ -87,7 +87,7 @@ public function getErrorOutputRaw() * @param string $input * A string representing the STDIN that is piped to the command. */ - public function startExecute($command, $cd = null, $env = null, $input = null) + public function startExecute(string $command, $cd = null, $env = null, $input = null) { try { // Process uses a default timeout of 60 seconds, set it to 0 (none). @@ -107,7 +107,7 @@ public function startExecute($command, $cd = null, $env = null, $input = null) } else { $message = 'Command had no output for ' . $this->idleTimeout . " seconds:\n" . $command; } - throw new \Exception($message . $this->buildProcessMessage()); + throw new \Exception($message . $this->buildProcessMessage(), $e->getCode(), $e); } } @@ -125,7 +125,7 @@ public function startExecute($command, $cd = null, $env = null, $input = null) * @param string $input * A string representing the STDIN that is piped to the command. */ - public function execute($command, $expected_return = 0, $cd = null, $env = null, $input = null) + public function execute($command, int $expected_return = 0, $cd = null, $env = null, $input = null) { try { // Process uses a default timeout of 60 seconds, set it to 0 (none). @@ -166,7 +166,7 @@ public function execute($command, $expected_return = 0, $cd = null, $env = null, } else { $message = 'Command had no output for ' . $this->idleTimeout . " seconds:\n" . $command; } - throw new \Exception($message . $this->buildProcessMessage()); + throw new \Exception($message . $this->buildProcessMessage(), $e->getCode(), $e); } } @@ -243,7 +243,7 @@ public function buildProcessMessage() * Optional regular expression that should be ignored in the error output. */ - protected function assertOutputEquals($expected, $filter = '') + protected function assertOutputEquals(string $expected, string $filter = '') { $output = $this->getSimplifiedOutput(); if (!empty($filter)) { @@ -264,7 +264,7 @@ protected function assertOutputEquals($expected, $filter = '') * @param string $filter * Optional regular expression that should be ignored in the error output. */ - protected function assertErrorOutputEquals($expected, $filter = '') + protected function assertErrorOutputEquals(string $expected, string $filter = '') { $output = $this->getSimplifiedErrorOutput(); if (!empty($filter)) { diff --git a/src/TestTraits/DrushTestTrait.php b/src/TestTraits/DrushTestTrait.php index bfa2c000eb..2a1e565650 100644 --- a/src/TestTraits/DrushTestTrait.php +++ b/src/TestTraits/DrushTestTrait.php @@ -39,7 +39,7 @@ public function getPathToDrush() * @param array $env * Environment variables to pass along to the subprocess. */ - public function drush($command, array $args = [], array $options = [], $site_specification = null, $cd = null, $expected_return = 0, $suffix = null, $env = []) + public function drush($command, array $args = [], array $options = [], $site_specification = null, $cd = null, $expected_return = 0, $suffix = null, array $env = []) { // Set UA for SimpleTests which typically extend BrowserTestCase (i.e. contrib modules). if (isset($this->databasePrefix) && function_exists('drupal_generate_test_ua') && !isset($env['HTTP_USER_AGENT'])) { @@ -89,7 +89,7 @@ public function drush($command, array $args = [], array $options = [], $site_spe * @param string $value The option value (or empty) * @return string */ - protected function convertKeyValueToFlag($key, $value) + protected function convertKeyValueToFlag(string $key, string $value) { if (!isset($value)) { return "--$key"; diff --git a/src/TestTraits/OutputUtilsTrait.php b/src/TestTraits/OutputUtilsTrait.php index d8d1ab524f..c5b58c4386 100644 --- a/src/TestTraits/OutputUtilsTrait.php +++ b/src/TestTraits/OutputUtilsTrait.php @@ -59,7 +59,7 @@ protected function getSimplifiedErrorOutput() * @return string * The simplified output. */ - protected function simplifyOutput($output) + protected function simplifyOutput(string $output) { // We do not care if Drush inserts a -t or not in the string. Depends on whether there is a tty. $output = preg_replace('# -t #', ' ', $output); From 8a4a5f75a363c62677920721c03cda9a874eee26 Mon Sep 17 00:00:00 2001 From: Joachim Date: Fri, 7 Jan 2022 12:23:31 +0000 Subject: [PATCH 072/125] Fixed sites.php file included without $sites variable defined. Fixes #4987. (#4991) Co-authored-by: Joachim Noreiko --- src/Commands/core/SiteInstallCommands.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Commands/core/SiteInstallCommands.php b/src/Commands/core/SiteInstallCommands.php index aaccecedca..8326523605 100644 --- a/src/Commands/core/SiteInstallCommands.php +++ b/src/Commands/core/SiteInstallCommands.php @@ -423,9 +423,10 @@ protected function getSitesSubdirFromUri($root, $uri) // Find the dir from sites.php file $sites_file = $root . '/sites/sites.php'; if (file_exists($sites_file)) { - include $sites_file; /** @var array $sites */ - if (isset($sites) && array_key_exists($uri, $sites)) { + $sites = []; + include $sites_file; + if (!empty($sites) && array_key_exists($uri, $sites)) { return $sites[$uri]; } } From 6528aa99f868d8667794ca31c75d0e60c4e81d42 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 7 Jan 2022 07:33:52 -0500 Subject: [PATCH 073/125] Remove deprecated trait (#4990) --- src/SiteAlias/SiteAliasManagerAwareTrait.php | 36 -------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/SiteAlias/SiteAliasManagerAwareTrait.php diff --git a/src/SiteAlias/SiteAliasManagerAwareTrait.php b/src/SiteAlias/SiteAliasManagerAwareTrait.php deleted file mode 100644 index f77a8fe6fc..0000000000 --- a/src/SiteAlias/SiteAliasManagerAwareTrait.php +++ /dev/null @@ -1,36 +0,0 @@ -siteAliasManager = $siteAliasManager; - } - - /** - * @return SiteAliasManager - */ - public function siteAliasManager() - { - return $this->siteAliasManager; - } - - /** - * @inheritdoc - */ - public function hasSiteAliasManager() - { - return isset($this->siteAliasManager); - } -} From 9e67c0fa58043c750c0af8989186532ee1718eb7 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 7 Jan 2022 08:04:21 -0500 Subject: [PATCH 074/125] Fix #4711. CacheCommands::rebuild() can omit include of includes/bootstrap.inc in Drupal 9.1+ (#4992) --- src/Commands/core/CacheCommands.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Commands/core/CacheCommands.php b/src/Commands/core/CacheCommands.php index 67f9c3c701..c3665c4c59 100644 --- a/src/Commands/core/CacheCommands.php +++ b/src/Commands/core/CacheCommands.php @@ -221,8 +221,6 @@ public function rebuild($options = ['cache-clear' => true]) require_once DRUSH_DRUPAL_CORE . '/includes/utility.inc'; $request = Drush::bootstrap()->getRequest(); - // Manually resemble early bootstrap of DrupalKernel::boot(). - require_once DRUSH_DRUPAL_CORE . '/includes/bootstrap.inc'; DrupalKernel::bootEnvironment(); // Avoid 'Only variables should be passed by reference' From 1214ec20a76cb445eb7c33916cd522c6b6be4fb0 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 8 Jan 2022 11:12:23 -0500 Subject: [PATCH 075/125] Update rector (#4993) --- composer.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/composer.lock b/composer.lock index 431d89365a..4905951065 100644 --- a/composer.lock +++ b/composer.lock @@ -5550,16 +5550,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.3.0", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ffc5aee6019eeae4ea618d97dd290ab95e77be59" + "reference": "151a51f6149855785fbd883e79768c0abc96b75f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffc5aee6019eeae4ea618d97dd290ab95e77be59", - "reference": "ffc5aee6019eeae4ea618d97dd290ab95e77be59", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/151a51f6149855785fbd883e79768c0abc96b75f", + "reference": "151a51f6149855785fbd883e79768c0abc96b75f", "shasum": "" }, "require": { @@ -5590,7 +5590,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.3.0" + "source": "https://github.com/phpstan/phpstan/tree/1.3.3" }, "funding": [ { @@ -5610,7 +5610,7 @@ "type": "tidelift" } ], - "time": "2021-12-29T17:03:31+00:00" + "time": "2022-01-07T09:49:03+00:00" }, { "name": "phpunit/php-code-coverage", @@ -6139,21 +6139,21 @@ }, { "name": "rector/rector", - "version": "0.12.9", + "version": "0.12.12", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "8f7cfa85731bf23cff9571460d88c327c8c1ac4c" + "reference": "efcc6f135a76bfd031c31fc182ce7a6fd02b3ce5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/8f7cfa85731bf23cff9571460d88c327c8c1ac4c", - "reference": "8f7cfa85731bf23cff9571460d88c327c8c1ac4c", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/efcc6f135a76bfd031c31fc182ce7a6fd02b3ce5", + "reference": "efcc6f135a76bfd031c31fc182ce7a6fd02b3ce5", "shasum": "" }, "require": { "php": "^7.1|^8.0", - "phpstan/phpstan": "^1.2" + "phpstan/phpstan": "^1.3" }, "conflict": { "phpstan/phpdoc-parser": "<1.2", @@ -6187,7 +6187,7 @@ "description": "Prefixed and PHP 7.1 downgraded version of rector/rector", "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.12.9" + "source": "https://github.com/rectorphp/rector/tree/0.12.12" }, "funding": [ { @@ -6195,7 +6195,7 @@ "type": "github" } ], - "time": "2021-12-21T23:30:38+00:00" + "time": "2022-01-07T16:49:17+00:00" }, { "name": "sebastian/cli-parser", From 4a514c9ecf75a1810a26187002a7733908fb3550 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 8 Jan 2022 11:37:10 -0500 Subject: [PATCH 076/125] Move from PSR2 to PSR12 (#4994) * Move to PSR12 from PSR2 for coding standard.. * A few more fixes. --- examples/Commands/ArtCommands.php | 2 +- examples/Commands/PolicyCommands.php | 2 +- examples/Commands/SiteAliasAlterCommands.php | 2 +- examples/Commands/SyncViaHttpCommands.php | 2 +- examples/Commands/XkcdCommands.php | 2 +- phpcs.xml | 3 ++- src/.editorconfig | 4 ++-- src/Application.php | 1 + src/Backend/BackendPathEvaluator.php | 1 + src/Boot/AutoloaderAwareInterface.php | 1 + src/Boot/AutoloaderAwareTrait.php | 1 + src/Boot/EmptyBoot.php | 1 - src/Boot/Kernels.php | 1 - src/Command/DrushCommandInfoAlterer.php | 1 + src/Command/GlobalOptionsEventListener.php | 2 +- src/Command/RemoteCommandProxy.php | 2 +- src/Command/ServiceCommandlist.php | 1 + src/Commands/DrushCommands.php | 16 ++++++++-------- src/Commands/ExampleCommands.php | 7 +------ src/Commands/LegacyCommands.php | 2 +- src/Commands/OptionsCommands.php | 4 ++-- src/Commands/ValidatorsCommands.php | 1 + src/Commands/config/ConfigPullCommands.php | 1 + src/Commands/core/BrowseCommands.php | 1 + src/Commands/core/CacheCommands.php | 4 ++-- src/Commands/core/CoreCommands.php | 4 ++-- src/Commands/core/DeployCommands.php | 1 + src/Commands/core/DocsCommands.php | 1 + src/Commands/core/DrupalDirectoryCommands.php | 3 +-- src/Commands/core/DrupliconCommands.php | 1 + src/Commands/core/EditCommands.php | 1 + src/Commands/core/LoginCommands.php | 2 +- src/Commands/core/NotifyCommands.php | 1 + src/Commands/core/PhpCommands.php | 1 + src/Commands/core/RsyncCommands.php | 5 +++-- src/Commands/core/RunserverCommands.php | 2 +- src/Commands/core/SiteCommands.php | 1 + src/Commands/core/SiteInstallCommands.php | 1 + src/Commands/core/SshCommands.php | 1 + src/Commands/core/TopicCommands.php | 2 +- src/Commands/core/UpdateDBCommands.php | 13 ++++++++----- src/Commands/core/XhprofCommands.php | 1 - src/Commands/generate/ApplicationFactory.php | 2 +- src/Commands/generate/GenerateCommands.php | 1 - src/Commands/help/DrushHelpDocument.php | 1 - src/Commands/help/HelpCLIFormatter.php | 10 +++++----- src/Commands/help/HelpCommands.php | 2 +- src/Commands/help/ListCommands.php | 1 + src/Commands/pm/SecurityUpdateCommands.php | 2 +- src/Commands/sql/SqlCommands.php | 1 + src/Commands/sql/SqlSyncCommands.php | 1 + src/Config/ConfigAwareTrait.php | 1 + src/Config/ConfigLocator.php | 1 + src/Config/DrushConfig.php | 2 +- src/Config/Environment.php | 2 +- src/Drupal/Commands/config/ConfigCommands.php | 1 + .../Commands/config/ConfigExportCommands.php | 3 ++- .../Commands/config/ConfigImportCommands.php | 2 +- src/Drupal/Commands/core/BatchCommands.php | 2 +- src/Drupal/Commands/core/CliCommands.php | 1 - src/Drupal/Commands/core/DeployHookCommands.php | 2 +- src/Drupal/Commands/core/DrupalCommands.php | 12 +++++++----- src/Drupal/Commands/core/EntityCommands.php | 1 - src/Drupal/Commands/core/ImageCommands.php | 1 - src/Drupal/Commands/core/JsonapiCommands.php | 2 +- src/Drupal/Commands/core/LanguageCommands.php | 1 - src/Drupal/Commands/core/LinkHooks.php | 6 ++++-- src/Drupal/Commands/core/LocaleCommands.php | 1 - src/Drupal/Commands/core/QueueCommands.php | 2 +- src/Drupal/Commands/core/RoleCommands.php | 1 + src/Drupal/Commands/core/StateCommands.php | 2 +- src/Drupal/Commands/core/UserCommands.php | 2 +- src/Drupal/Commands/core/ViewsCommands.php | 2 +- src/Drupal/Commands/core/WatchdogCommands.php | 6 +++--- .../Commands/field/FieldCreateCommands.php | 3 ++- src/Drupal/Commands/pm/PmCommands.php | 4 ++-- src/Drupal/Commands/pm/ThemeCommands.php | 2 +- src/Drupal/Commands/sql/SanitizeCommands.php | 1 - .../Commands/sql/SanitizeCommentsCommands.php | 1 + .../Commands/sql/SanitizeSessionsCommands.php | 1 + .../Commands/sql/SanitizeUserFieldsCommands.php | 1 + .../Commands/sql/SanitizeUserTableCommands.php | 1 + src/Drupal/DrupalUtil.php | 2 +- src/Drupal/FindCommandsCompilerPass.php | 1 + src/Drupal/InstallerKernel.php | 1 + src/Drupal/Migrate/MigrateIdMapFilter.php | 1 - src/Drupal/UpdateKernel.php | 1 + src/Drush.php | 3 +-- src/Exec/ExecTrait.php | 1 + src/Formatters/DrushFormatterManager.php | 2 +- src/Log/Logger.php | 1 - src/Preflight/ArgsPreprocessor.php | 3 ++- src/Preflight/ArgsRemapper.php | 1 + src/Preflight/LegacyPreflight.php | 1 + src/Preflight/Preflight.php | 1 + src/Preflight/PreflightArgs.php | 3 +-- src/Preflight/PreflightArgsInterface.php | 1 + src/Preflight/PreflightVerify.php | 1 + src/Preflight/RedispatchToSiteLocal.php | 1 - src/Psysh/Caster.php | 1 - src/Psysh/DrushCommand.php | 2 +- src/Psysh/DrushHelpCommand.php | 1 - src/Psysh/Shell.php | 1 - src/Runtime/DependencyInjection.php | 1 + src/Runtime/ErrorHandler.php | 6 +----- src/Runtime/HandlerInterface.php | 1 + src/Runtime/Runtime.php | 1 + src/Runtime/ShutdownHandler.php | 6 +----- src/SiteAlias/HostPath.php | 1 + src/SiteAlias/LegacyAliasConverter.php | 1 + src/SiteAlias/ProcessManager.php | 1 + src/SiteAlias/SiteAliasFileLoader.php | 1 + src/SiteAlias/SiteAliasManagerAwareInterface.php | 1 + src/SiteAlias/SiteAliasName.php | 1 + src/SiteAlias/SiteSpecParser.php | 1 + .../Util/InternalYamlDataFileLoader.php | 1 + src/Sql/SqlBase.php | 7 +++---- src/Sql/SqlMysql.php | 3 +-- src/Sql/SqlPgsql.php | 3 +-- src/Sql/SqlTableSelectionTrait.php | 2 +- src/Symfony/DrushArgvInput.php | 6 +++--- src/Symfony/DrushStyleInjector.php | 1 + src/Symfony/LessStrictArgvInput.php | 7 +++---- src/TestTraits/CliTestTrait.php | 1 + src/TestTraits/DrushTestTrait.php | 1 + src/TestTraits/OutputUtilsTrait.php | 1 + src/Utils/FsUtils.php | 1 - src/Utils/StringUtils.php | 1 - .../woot/src/Commands/AnnotatedGreetCommand.php | 3 ++- .../modules/woot/src/Commands/GreetCommand.php | 3 ++- .../modules/woot/src/Commands/WootCommands.php | 1 + .../modules/woot/src/DependingService.php | 1 - .../src/EventSubscriber/ConfigSubscriber.php | 1 - .../Plugin/QueueWorker/WootCustomException.php | 1 - .../Plugin/QueueWorker/WootRequeueException.php | 1 - .../legacy/pantheon.aliases.drushrc.php | 1 + tests/functional/BatchTest.php | 1 - .../functional/Commands/TestFixtureCommands.php | 4 ++-- tests/functional/ConfigPullTest.php | 2 +- tests/functional/ConfigTest.php | 4 ++-- tests/functional/CoreTest.php | 14 +++++++++----- tests/functional/FieldTest.php | 1 - tests/functional/PmEnDisUnListInfoTest.php | 1 - tests/functional/PmEnLocaleImportTest.php | 1 - tests/functional/RedispatchTest.php | 1 - tests/functional/RsyncTest.php | 1 - tests/functional/SiteInstallTest.php | 1 - tests/functional/SiteSetTest.php | 1 - tests/functional/SiteSshTest.php | 1 - tests/functional/SqlConnectTest.php | 1 - tests/functional/SqlDumpTest.php | 1 - tests/functional/SqlSyncTest.php | 2 +- tests/functional/UserTest.php | 1 - tests/functional/WatchdogTailTest.php | 1 - tests/integration/CacheCommandTest.php | 2 +- tests/integration/CoreTest.php | 4 ++-- tests/integration/DeployTest.php | 3 +-- tests/integration/SecurityUpdatesTest.php | 1 - tests/integration/SiteAliasConvertTest.php | 1 - tests/integration/SqlCliTest.php | 1 - tests/integration/WatchdogTest.php | 1 - .../Commands/ExampleAttributesCommands.php | 1 + tests/unish/UnishIntegrationTestCase.php | 1 + tests/unish/UnishTestCase.php | 2 +- tests/unish/Utils/FSUtils.php | 1 + tests/unish/Utils/Fixtures.php | 3 ++- tests/unish/Utils/FunctionUtils.php | 1 + tests/unit/ArgsPreprocessorTest.php | 1 + tests/unit/ArgsRemapperTest.php | 3 +-- tests/unit/ConfigLocatorTest.php | 1 + tests/unit/EnvironmentTest.php | 1 + tests/unit/ExpandWildcardTablesTest.php | 3 +-- tests/unit/LegacyAliasConverterTest.php | 1 + tests/unit/SiteAliasFileDiscoveryTest.php | 1 + tests/unit/SiteAliasFileLoaderTest.php | 2 +- tests/unit/SiteAliasNameTest.php | 1 + tests/unit/SiteSpecParserTest.php | 1 + tests/unit/TestSqlIdMap.php | 1 - tests/unit/XhProfTest.php | 1 - 179 files changed, 197 insertions(+), 177 deletions(-) diff --git a/examples/Commands/ArtCommands.php b/examples/Commands/ArtCommands.php index c45d88f214..b1f24145b9 100644 --- a/examples/Commands/ArtCommands.php +++ b/examples/Commands/ArtCommands.php @@ -1,4 +1,5 @@ src examples tests - + 0 + 0 diff --git a/src/.editorconfig b/src/.editorconfig index 64b60abd04..1f11b458d9 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -1,8 +1,8 @@ # This file is for unifying the coding style for different editors and IDEs # editorconfig.org -# PHP PSR-2 Coding Standards -# http://www.php-fig.org/psr/psr-2/ +# PHP PSR-12 Coding Standards +# http://www.php-fig.org/psr/psr-12/ [*.php] charset = utf-8 diff --git a/src/Application.php b/src/Application.php index dea7e9b4db..c54da5ef30 100644 --- a/src/Application.php +++ b/src/Application.php @@ -1,4 +1,5 @@ 'table']): RowsOfFields $application = Drush::getApplication(); $def = $application->getDefinition(); foreach ($def->getOptions() as $key => $value) { - $name = '--'. $key; + $name = '--' . $key; if ($value->getShortcut()) { $name = '-' . $value->getShortcut() . ', ' . $name; } diff --git a/src/Commands/core/DeployCommands.php b/src/Commands/core/DeployCommands.php index ab88271dd5..6029bf88d4 100644 --- a/src/Commands/core/DeployCommands.php +++ b/src/Commands/core/DeployCommands.php @@ -1,4 +1,5 @@ targetEvaluatedPath->fullyQualifiedPath()); $ssh_options = $this->getConfig()->get('ssh.options', ''); - $exec = "rsync -e 'ssh $ssh_options'". ' '. implode(' ', array_filter($parameters)); + $exec = "rsync -e 'ssh $ssh_options'" . ' ' . implode(' ', array_filter($parameters)); $process = $this->processManager()->shell($exec); $process->run($process->showRealtime()); @@ -98,7 +99,7 @@ public function rsyncOptions($options): string } } - $mode = '-'. $options['mode']; + $mode = '-' . $options['mode']; if ($this->output()->isVerbose()) { $mode .= 'v'; $verbose = ' --stats --progress'; diff --git a/src/Commands/core/RunserverCommands.php b/src/Commands/core/RunserverCommands.php index 94d7bba0fb..362cbebbb1 100644 --- a/src/Commands/core/RunserverCommands.php +++ b/src/Commands/core/RunserverCommands.php @@ -1,4 +1,5 @@ true]): void * @filter-default-field type * @return RowsOfFields */ - public function updatedbStatus($options = ['format'=> 'table', 'entity-updates' => true, 'post-updates' => true]) + public function updatedbStatus($options = ['format' => 'table', 'entity-updates' => true, 'post-updates' => true]) { require_once DRUSH_DRUPAL_CORE . '/includes/install.inc'; drupal_load_updates(); @@ -563,7 +564,7 @@ public function getUpdatedbStatus(array $options): array 'module' => $module, 'update_id' => $update_id, 'description' => $description, - 'type'=> 'hook_update_n' + 'type' => 'hook_update_n' ]; } if (isset($updates['start'])) { @@ -574,8 +575,10 @@ public function getUpdatedbStatus(array $options): array // Append row(s) for pending entity definition updates. if ($options['entity-updates']) { - foreach (\Drupal::entityDefinitionUpdateManager() - ->getChangeSummary() as $entity_type_id => $changes) { + foreach ( + \Drupal::entityDefinitionUpdateManager() + ->getChangeSummary() as $entity_type_id => $changes + ) { foreach ($changes as $change) { $return[] = [ 'module' => dt('@type entity type', ['@type' => $entity_type_id]), @@ -671,7 +674,7 @@ public function updateCheckRequirements(): bool if (isset($requirement['severity']) && $requirement['severity'] != REQUIREMENT_OK) { $message = isset($requirement['description']) ? DrupalUtil::drushRender($requirement['description']) : ''; if (isset($requirement['value']) && $requirement['value']) { - $message .= ' (Currently using '. $requirement['title'] .' '. DrupalUtil::drushRender($requirement['value']) .')'; + $message .= ' (Currently using ' . $requirement['title'] . ' ' . DrupalUtil::drushRender($requirement['value']) . ')'; } $log_level = $requirement['severity'] === REQUIREMENT_ERROR ? LogLevel::ERROR : LogLevel::WARNING; $this->logger()->log($log_level, $message); diff --git a/src/Commands/core/XhprofCommands.php b/src/Commands/core/XhprofCommands.php index 80dff899af..af401a3d73 100644 --- a/src/Commands/core/XhprofCommands.php +++ b/src/Commands/core/XhprofCommands.php @@ -23,7 +23,6 @@ */ class XhprofCommands extends DrushCommands { - const XH_PROFILE_MEMORY = false; const XH_PROFILE_CPU = false; const XH_PROFILE_BUILTINS = true; diff --git a/src/Commands/generate/ApplicationFactory.php b/src/Commands/generate/ApplicationFactory.php index f67963ce98..c4ee7a3270 100644 --- a/src/Commands/generate/ApplicationFactory.php +++ b/src/Commands/generate/ApplicationFactory.php @@ -176,7 +176,7 @@ protected function getGenerators(array $classes): array { return array_map( function (string $class): Generator { - return new $class; + return new $class(); }, array_filter($classes, function (string $class): bool { $reflectionClass = new \ReflectionClass($class); diff --git a/src/Commands/generate/GenerateCommands.php b/src/Commands/generate/GenerateCommands.php index db02125df0..412f5ee58b 100644 --- a/src/Commands/generate/GenerateCommands.php +++ b/src/Commands/generate/GenerateCommands.php @@ -13,7 +13,6 @@ */ class GenerateCommands extends DrushCommands implements AutoloaderAwareInterface { - use AutoloaderAwareTrait; /** diff --git a/src/Commands/help/DrushHelpDocument.php b/src/Commands/help/DrushHelpDocument.php index 8bd2fc0a61..dfe51f9216 100644 --- a/src/Commands/help/DrushHelpDocument.php +++ b/src/Commands/help/DrushHelpDocument.php @@ -7,7 +7,6 @@ class DrushHelpDocument extends HelpDocument { - /** * @inheritdoc */ diff --git a/src/Commands/help/HelpCLIFormatter.php b/src/Commands/help/HelpCLIFormatter.php index e272dd9455..3c63fc1e92 100644 --- a/src/Commands/help/HelpCLIFormatter.php +++ b/src/Commands/help/HelpCLIFormatter.php @@ -1,4 +1,5 @@ processManager()->process(['git', 'add', '-A', '.'], $destination_dir); $process->mustRun(); - $comment_file = drush_save_data_to_temp_file($options['message'] ?: 'Exported configuration.'. $preview); + $comment_file = drush_save_data_to_temp_file($options['message'] ?: 'Exported configuration.' . $preview); $process = $this->processManager()->process(['git', 'commit', "--file=$comment_file"], $destination_dir); $process->mustRun(); } diff --git a/src/Drupal/Commands/config/ConfigImportCommands.php b/src/Drupal/Commands/config/ConfigImportCommands.php index f73203230a..3279d4cb54 100644 --- a/src/Drupal/Commands/config/ConfigImportCommands.php +++ b/src/Drupal/Commands/config/ConfigImportCommands.php @@ -1,4 +1,5 @@ getModuleList()), diff --git a/src/Drupal/Commands/core/DrupalCommands.php b/src/Drupal/Commands/core/DrupalCommands.php index a4b615d2a5..d39630cece 100644 --- a/src/Drupal/Commands/core/DrupalCommands.php +++ b/src/Drupal/Commands/core/DrupalCommands.php @@ -1,4 +1,5 @@ 'table', 'severity' => -1, * @option path An internal path. * @version 10.5 */ - public function route($options = ['name' => self::REQ, 'path' =>self::REQ, 'format' => 'yaml']) + public function route($options = ['name' => self::REQ, 'path' => self::REQ, 'format' => 'yaml']) { $route = $items = null; $provider = $this->getRouteProvider(); @@ -182,13 +182,15 @@ public function route($options = ['name' => self::REQ, 'path' =>self::REQ, 'form } return $items; } - + private static function styleRow($content, $format, $severity): ?string { - if (!in_array($format, [ + if ( + !in_array($format, [ 'sections', 'table', - ])) { + ]) + ) { return $content; } diff --git a/src/Drupal/Commands/core/EntityCommands.php b/src/Drupal/Commands/core/EntityCommands.php index 38408d6617..f857e82f01 100644 --- a/src/Drupal/Commands/core/EntityCommands.php +++ b/src/Drupal/Commands/core/EntityCommands.php @@ -12,7 +12,6 @@ class EntityCommands extends DrushCommands { - protected $entityTypeManager; /** diff --git a/src/Drupal/Commands/core/ImageCommands.php b/src/Drupal/Commands/core/ImageCommands.php index c8f764bb65..7593e03717 100644 --- a/src/Drupal/Commands/core/ImageCommands.php +++ b/src/Drupal/Commands/core/ImageCommands.php @@ -10,7 +10,6 @@ class ImageCommands extends DrushCommands { - /** * Flush all derived images for a given style. * diff --git a/src/Drupal/Commands/core/JsonapiCommands.php b/src/Drupal/Commands/core/JsonapiCommands.php index bb6e664932..02ea0efbf4 100644 --- a/src/Drupal/Commands/core/JsonapiCommands.php +++ b/src/Drupal/Commands/core/JsonapiCommands.php @@ -1,4 +1,5 @@ isInstalled() + if ( + !$this->isInstalled() || $input->getOption('field-type') !== 'link' ) { return; @@ -66,7 +67,8 @@ public function hookSetOptions(InputInterface $input): void /** @hook on-event field-create-field-config */ public function hookFieldConfig(array $values, InputInterface $input): array { - if (!$this->isInstalled() + if ( + !$this->isInstalled() || $values['field_type'] !== 'link' ) { return $values; diff --git a/src/Drupal/Commands/core/LocaleCommands.php b/src/Drupal/Commands/core/LocaleCommands.php index a73a282296..6649a30799 100644 --- a/src/Drupal/Commands/core/LocaleCommands.php +++ b/src/Drupal/Commands/core/LocaleCommands.php @@ -17,7 +17,6 @@ class LocaleCommands extends DrushCommands { - protected $languageManager; protected $configFactory; diff --git a/src/Drupal/Commands/core/QueueCommands.php b/src/Drupal/Commands/core/QueueCommands.php index 76a483870f..5761ccc937 100644 --- a/src/Drupal/Commands/core/QueueCommands.php +++ b/src/Drupal/Commands/core/QueueCommands.php @@ -1,4 +1,5 @@ self::REQ, 'ty throw new \Exception(dt('Watchdog message #!wid does not exist.', ['!wid' => $substring])); } } else { - if ((empty($substring))&&(!isset($options['type']))&&(!isset($options['severity']))) { + if ((empty($substring)) && (!isset($options['type'])) && (!isset($options['severity']))) { throw new \Exception(dt('No options provided.')); } $where = $this->where($options['type'], $options['severity'], $substring, 'OR'); @@ -325,7 +325,7 @@ protected function where($type = null, $severity = null, $filter = null, $criter } if ($filter) { $conditions[] = "message LIKE :filter"; - $args[':filter'] = '%'.$filter.'%'; + $args[':filter'] = '%' . $filter . '%'; } $where = implode(" $criteria ", $conditions); diff --git a/src/Drupal/Commands/field/FieldCreateCommands.php b/src/Drupal/Commands/field/FieldCreateCommands.php index 326eedd56d..395b73baad 100644 --- a/src/Drupal/Commands/field/FieldCreateCommands.php +++ b/src/Drupal/Commands/field/FieldCreateCommands.php @@ -607,7 +607,8 @@ protected function getExistingFieldStorageOptions(string $entityType, string $bu ? $fieldTypes[$fieldType]['id'] : $fieldTypes[$fieldType]['label']; - if ($fieldStorage instanceof FieldStorageConfigInterface + if ( + $fieldStorage instanceof FieldStorageConfigInterface && !$fieldStorage->isLocked() && empty($fieldTypes[$fieldType]['no_ui']) && !in_array($bundle, $fieldStorage->getBundles(), true) diff --git a/src/Drupal/Commands/pm/PmCommands.php b/src/Drupal/Commands/pm/PmCommands.php index 051bea0160..1e00ac2087 100644 --- a/src/Drupal/Commands/pm/PmCommands.php +++ b/src/Drupal/Commands/pm/PmCommands.php @@ -1,4 +1,5 @@ 'table', 'type' => 'module,theme' $row = [ 'package' => $extension->info['package'], 'project' => isset($extension->info['project']) ? $extension->info['project'] : '', - 'display_name' => $extension->info['name']. ' ('. $extension->getName(). ')', + 'display_name' => $extension->info['name'] . ' (' . $extension->getName() . ')', 'name' => $extension->getName(), 'type' => $extension->getType(), 'path' => $extension->getPath(), diff --git a/src/Drupal/Commands/pm/ThemeCommands.php b/src/Drupal/Commands/pm/ThemeCommands.php index dc09ea6d9f..55be734b9e 100644 --- a/src/Drupal/Commands/pm/ThemeCommands.php +++ b/src/Drupal/Commands/pm/ThemeCommands.php @@ -1,4 +1,5 @@ '. Escape::shellArg($result_file); + $exec .= ' > ' . Escape::shellArg($result_file); } // In --verbose mode, Process will show the call to mysql/psql/sqlite, @@ -398,7 +397,7 @@ public function drop(array $tables): ?bool { $return = true; if ($tables) { - $sql = 'DROP TABLE '. implode(', ', $tables); + $sql = 'DROP TABLE ' . implode(', ', $tables); $return = $this->query($sql); } return $return; diff --git a/src/Sql/SqlMysql.php b/src/Sql/SqlMysql.php index 61af74a8a9..1cb6964be1 100644 --- a/src/Sql/SqlMysql.php +++ b/src/Sql/SqlMysql.php @@ -6,7 +6,6 @@ class SqlMysql extends SqlBase { - public $queryExtra = '-A'; public function command(): string @@ -186,7 +185,7 @@ public function dumpCmd($table_selection): string $ignores[] = '--ignore-table=' . $dbSpec['database'] . '.' . $table; $parens = true; } - $exec .= ' '. implode(' ', $ignores); + $exec .= ' ' . implode(' ', $ignores); // Run mysqldump again and append output if we need some structure only tables. if (!empty($structure_tables)) { diff --git a/src/Sql/SqlPgsql.php b/src/Sql/SqlPgsql.php index 70ec64b793..89d7c6059f 100644 --- a/src/Sql/SqlPgsql.php +++ b/src/Sql/SqlPgsql.php @@ -8,7 +8,6 @@ class SqlPgsql extends SqlBase { - public $queryExtra = "--no-align --field-separator=\"\t\" --pset tuples_only=on"; public $queryFile = "--file"; @@ -158,7 +157,7 @@ public function dumpCmd($table_selection): string foreach ($skip_tables as $table) { $ignores[] = "--exclude-table=$table"; } - $exec .= ' '. implode(' ', $ignores); + $exec .= ' ' . implode(' ', $ignores); // Run pg_dump again and append output if we need some structure only tables. if (!empty($structure_tables)) { $parens = true; diff --git a/src/Sql/SqlTableSelectionTrait.php b/src/Sql/SqlTableSelectionTrait.php index 19c1224c70..2354ecc889 100644 --- a/src/Sql/SqlTableSelectionTrait.php +++ b/src/Sql/SqlTableSelectionTrait.php @@ -1,4 +1,5 @@ escapeToken($match[2]); + return $match[1] . $this->escapeToken($match[2]); } if ($token && '-' !== $token[0]) { diff --git a/src/Symfony/DrushStyleInjector.php b/src/Symfony/DrushStyleInjector.php index 41c7f3fcab..2f000eef8c 100644 --- a/src/Symfony/DrushStyleInjector.php +++ b/src/Symfony/DrushStyleInjector.php @@ -1,4 +1,5 @@ escapeToken($match[2]); + return $match[1] . $this->escapeToken($match[2]); } if ($token && $token[0] !== '-') { diff --git a/src/TestTraits/CliTestTrait.php b/src/TestTraits/CliTestTrait.php index 95e703afb5..dc3db23d57 100644 --- a/src/TestTraits/CliTestTrait.php +++ b/src/TestTraits/CliTestTrait.php @@ -1,4 +1,5 @@ getArgument('name'); if ($name) { - $text = 'Hello '.$name; + $text = 'Hello ' . $name; } else { $text = 'Hello'; } diff --git a/tests/fixtures/modules/woot/src/Commands/GreetCommand.php b/tests/fixtures/modules/woot/src/Commands/GreetCommand.php index cd52c0ce24..39fca6af0e 100644 --- a/tests/fixtures/modules/woot/src/Commands/GreetCommand.php +++ b/tests/fixtures/modules/woot/src/Commands/GreetCommand.php @@ -1,4 +1,5 @@ getArgument('name'); if ($name) { - $text = 'Hello '.$name; + $text = 'Hello ' . $name; } else { $text = 'Hello'; } diff --git a/tests/fixtures/modules/woot/src/Commands/WootCommands.php b/tests/fixtures/modules/woot/src/Commands/WootCommands.php index 9f8596eb22..feed2432d8 100644 --- a/tests/fixtures/modules/woot/src/Commands/WootCommands.php +++ b/tests/fixtures/modules/woot/src/Commands/WootCommands.php @@ -1,4 +1,5 @@ setUpDrupal(1, true); diff --git a/tests/functional/Commands/TestFixtureCommands.php b/tests/functional/Commands/TestFixtureCommands.php index e35819196f..50a9ec506b 100644 --- a/tests/functional/Commands/TestFixtureCommands.php +++ b/tests/functional/Commands/TestFixtureCommands.php @@ -4,6 +4,7 @@ * @file * Commands which are useful for unit tests. */ + namespace Drush\Commands; use Drupal\Core\DrupalKernel; @@ -14,7 +15,6 @@ class TestFixtureCommands extends DrushCommands implements AutoloaderAwareInterface { - use AutoloaderAwareTrait; // Obsolete: @@ -126,7 +126,7 @@ protected function loadDrupalAutoloader($drupal_root) { static $autoloader = false; - $autoloadFilePath = $drupal_root .'/autoload.php'; + $autoloadFilePath = $drupal_root . '/autoload.php'; if (!$autoloader && file_exists($autoloadFilePath)) { $autoloader = require $autoloadFilePath; } diff --git a/tests/functional/ConfigPullTest.php b/tests/functional/ConfigPullTest.php index efe76609bd..711e70c3e5 100644 --- a/tests/functional/ConfigPullTest.php +++ b/tests/functional/ConfigPullTest.php @@ -1,4 +1,5 @@ setUpDrupal(2, true); diff --git a/tests/functional/ConfigTest.php b/tests/functional/ConfigTest.php index 690a9d3dbe..36520171fe 100644 --- a/tests/functional/ConfigTest.php +++ b/tests/functional/ConfigTest.php @@ -118,7 +118,7 @@ public function testConfigExportImportStatusExistingConfig() $contents = preg_replace('/front: .*/', 'front: unish partial', $contents); $partial_path = self::getSandbox() . '/partial'; $this->mkdir($partial_path); - $contents = file_put_contents($partial_path. '/system.site.yml', $contents); + $contents = file_put_contents($partial_path . '/system.site.yml', $contents); $this->drush('config-import', [], ['partial' => null, 'source' => $partial_path]); $this->drush('config-get', ['system.site', 'page'], ['format' => 'json']); $page = $this->getOutputFromJSON('system.site:page'); @@ -186,6 +186,6 @@ class: Drupal\woot\DependingService protected function getConfigSyncDir() { $this->drush('core:status', [], ['format' => 'json', 'fields' => 'config-sync']); - return $this->webroot().'/'.$this->getOutputFromJSON('config-sync'); + return $this->webroot() . '/' . $this->getOutputFromJSON('config-sync'); } } diff --git a/tests/functional/CoreTest.php b/tests/functional/CoreTest.php index db825c9ed5..80d5f034e8 100644 --- a/tests/functional/CoreTest.php +++ b/tests/functional/CoreTest.php @@ -47,7 +47,8 @@ public function testOptionsUri() 'format' => 'json', 'uri' => 'OMIT', // A special value which causes --uri to not be specified. ]; - foreach ([ + foreach ( + [ 'test.uri' => ['http://test.uri', 'sites/dev'], 'test.uri/' => ['http://test.uri/', 'sites/dev'], 'test.uri/subpath' => ['http://test.uri/subpath', 'sites/stage'], @@ -60,7 +61,8 @@ public function testOptionsUri() 'https://test.uri/' => ['https://test.uri/', 'sites/dev'], 'https://test.uri/subpath' => ['https://test.uri/subpath', 'sites/stage'], 'https://test.uri/subpath/' => ['https://test.uri/subpath/', 'sites/stage'], - ] as $test_uri => $expected) { + ] as $test_uri => $expected + ) { // Put a yml file in the drush folder. $config_options = [ 'options' => [ @@ -84,7 +86,8 @@ public function testOptionsUriRequestUrl() $command_options = [ 'uri' => 'OMIT', // A special value which causes --uri to not be specified. ]; - foreach ([ + foreach ( + [ 'test.uri' => 'http://test.uri', 'test.uri/' => 'http://test.uri', 'test.uri/subpath' => 'http://test.uri/subpath', @@ -97,7 +100,8 @@ public function testOptionsUriRequestUrl() 'https://test.uri/' => 'https://test.uri', 'https://test.uri/subpath' => 'https://test.uri/subpath', 'https://test.uri/subpath/' => 'https://test.uri/subpath', - ] as $test_uri => $expected) { + ] as $test_uri => $expected + ) { // Put a yml file in the drush folder. $config_options = [ 'options' => [ @@ -109,7 +113,7 @@ public function testOptionsUriRequestUrl() unlink($drush_config_file); $output = $this->getOutputRaw(); // Include the test URI, for some context in errors. - $i=10; + $i = 10; $this->assertEquals([$test_uri => $expected], [$test_uri => trim($output)]); } } diff --git a/tests/functional/FieldTest.php b/tests/functional/FieldTest.php index 3274839d6f..80bbc45df3 100644 --- a/tests/functional/FieldTest.php +++ b/tests/functional/FieldTest.php @@ -10,7 +10,6 @@ */ class FieldTest extends CommandUnishTestCase { - public function setup(): void { parent::setup(); diff --git a/tests/functional/PmEnDisUnListInfoTest.php b/tests/functional/PmEnDisUnListInfoTest.php index 59094c37b9..3f772a28ca 100644 --- a/tests/functional/PmEnDisUnListInfoTest.php +++ b/tests/functional/PmEnDisUnListInfoTest.php @@ -15,7 +15,6 @@ */ class EnDisUnListInfoTest extends CommandUnishTestCase { - public function testEnDisUnList() { $sites = $this->setUpDrupal(1, true); diff --git a/tests/functional/PmEnLocaleImportTest.php b/tests/functional/PmEnLocaleImportTest.php index 4d17fa15fb..64c9d38e53 100644 --- a/tests/functional/PmEnLocaleImportTest.php +++ b/tests/functional/PmEnLocaleImportTest.php @@ -13,7 +13,6 @@ */ class PmEnLocaleImportTest extends CommandUnishTestCase { - public function testBatchImportTranslations() { $info_yml = Path::join($this->webroot(), 'modules/unish/drush_empty_module/drush_empty_module.info.yml'); diff --git a/tests/functional/RedispatchTest.php b/tests/functional/RedispatchTest.php index 6b2f22572a..e2ff0796ea 100644 --- a/tests/functional/RedispatchTest.php +++ b/tests/functional/RedispatchTest.php @@ -9,7 +9,6 @@ */ class RedispatchTest extends CommandUnishTestCase { - /** * Covers the following origin responsibilities. * - A remote host is recognized in site specification. diff --git a/tests/functional/RsyncTest.php b/tests/functional/RsyncTest.php index a3ebe2e0ba..abdce97945 100644 --- a/tests/functional/RsyncTest.php +++ b/tests/functional/RsyncTest.php @@ -11,7 +11,6 @@ */ class RsyncTest extends CommandUnishTestCase { - public function setup(): void { if ($this->isWindows()) { diff --git a/tests/functional/SiteInstallTest.php b/tests/functional/SiteInstallTest.php index c7b6ed8847..16894fd727 100644 --- a/tests/functional/SiteInstallTest.php +++ b/tests/functional/SiteInstallTest.php @@ -8,7 +8,6 @@ */ class SiteInstallTest extends CommandUnishTestCase { - /** * Test functionality of site set. */ diff --git a/tests/functional/SiteSetTest.php b/tests/functional/SiteSetTest.php index 0e31941557..6a44f1ee3a 100644 --- a/tests/functional/SiteSetTest.php +++ b/tests/functional/SiteSetTest.php @@ -8,7 +8,6 @@ */ class SiteSetTest extends CommandUnishTestCase { - /** * Test functionality of site set. */ diff --git a/tests/functional/SiteSshTest.php b/tests/functional/SiteSshTest.php index 8e16106bc3..89ef906bc6 100644 --- a/tests/functional/SiteSshTest.php +++ b/tests/functional/SiteSshTest.php @@ -10,7 +10,6 @@ */ class SiteSshTest extends CommandUnishTestCase { - /** * Test drush ssh --simulate. No additional bash passed. */ diff --git a/tests/functional/SqlConnectTest.php b/tests/functional/SqlConnectTest.php index e58fe58d59..1f23fc8111 100644 --- a/tests/functional/SqlConnectTest.php +++ b/tests/functional/SqlConnectTest.php @@ -12,7 +12,6 @@ */ class SqlConnectTest extends CommandUnishTestCase { - public function testSqlConnect() { $this->setUpDrupal(1, true); diff --git a/tests/functional/SqlDumpTest.php b/tests/functional/SqlDumpTest.php index 0cfe24b743..475caadda6 100644 --- a/tests/functional/SqlDumpTest.php +++ b/tests/functional/SqlDumpTest.php @@ -13,7 +13,6 @@ */ class SqlDumpTest extends CommandUnishTestCase { - /** * Test that a dump file is created successfully. */ diff --git a/tests/functional/SqlSyncTest.php b/tests/functional/SqlSyncTest.php index c33c4afcdb..6a0ca77aee 100644 --- a/tests/functional/SqlSyncTest.php +++ b/tests/functional/SqlSyncTest.php @@ -1,4 +1,5 @@ isWindows()) { diff --git a/tests/functional/UserTest.php b/tests/functional/UserTest.php index 3871965fe2..8007394211 100644 --- a/tests/functional/UserTest.php +++ b/tests/functional/UserTest.php @@ -10,7 +10,6 @@ */ class UserTest extends CommandUnishTestCase { - const NAME = 'example'; const MAIL = 'example@example.com'; diff --git a/tests/functional/WatchdogTailTest.php b/tests/functional/WatchdogTailTest.php index 3b973f3039..520058c037 100644 --- a/tests/functional/WatchdogTailTest.php +++ b/tests/functional/WatchdogTailTest.php @@ -11,7 +11,6 @@ */ class WatchdogTailTest extends CommandUnishTestCase { - /** * Test that watchdog tail works. */ diff --git a/tests/integration/CacheCommandTest.php b/tests/integration/CacheCommandTest.php index 7bebfd2573..51bf9c772d 100644 --- a/tests/integration/CacheCommandTest.php +++ b/tests/integration/CacheCommandTest.php @@ -39,7 +39,7 @@ public function testCacheSet() // Test cache-set using all arguments and many options. $expected = ['key' => 'value']; - $stdin = json_encode(['data'=> $expected]); + $stdin = json_encode(['data' => $expected]); $bin = 'default'; $this->drush('cache-set', ['my_cache_id', '-', $bin, 'CACHE_PERMANENT'], ['input-format' => 'json', 'cache-get' => true], self::EXIT_SUCCESS, $stdin); diff --git a/tests/integration/CoreTest.php b/tests/integration/CoreTest.php index 9ac99f00d3..184cb81113 100644 --- a/tests/integration/CoreTest.php +++ b/tests/integration/CoreTest.php @@ -71,7 +71,7 @@ public function testRoute() $json = $this->getOutputFromJSON(); $this->assertArrayHasKey('user.login', $json); $this->assertSame('/user/login', $json['user.login']); - $this->drush('route', [], ['path' =>'/user/login', 'format' => 'json']); + $this->drush('route', [], ['path' => '/user/login', 'format' => 'json']); $json = $this->getOutputFromJSON(); $this->assertSame('/user/login', $json['path']); $this->assertSame('user.login', $json['name']); @@ -79,7 +79,7 @@ public function testRoute() $this->assertSame("FALSE", $json['requirements']['_user_is_logged_in']); $this->assertSame('access_check.user.login_status', $json['options']['_access_checks'][0]); - $this->drush('route', [], ['name' =>'user.login', 'format' => 'json']); + $this->drush('route', [], ['name' => 'user.login', 'format' => 'json']); $json = $this->getOutputFromJSON(); $this->assertSame('/user/login', $json['path']); } diff --git a/tests/integration/DeployTest.php b/tests/integration/DeployTest.php index 6e4674a64f..467c6aaa47 100644 --- a/tests/integration/DeployTest.php +++ b/tests/integration/DeployTest.php @@ -7,7 +7,6 @@ */ class DeployTest extends UnishIntegrationTestCase { - /** * A simple test since all the sub-commands are tested elsewhere. */ @@ -15,7 +14,7 @@ public function testDeploy() { // Prep a config directory that will be imported later. $this->drush('config:export'); - + $this->drush('deploy'); $expecteds = ["Database updates start.", 'Config import start.', 'Deploy hook start.', 'Cache rebuild start.']; foreach ($expecteds as $expected) { diff --git a/tests/integration/SecurityUpdatesTest.php b/tests/integration/SecurityUpdatesTest.php index 0897fa69dd..697de3a010 100644 --- a/tests/integration/SecurityUpdatesTest.php +++ b/tests/integration/SecurityUpdatesTest.php @@ -9,7 +9,6 @@ */ class SecurityUpdatesTest extends UnishIntegrationTestCase { - /** * Test that insecure Drupal packages are correctly identified. */ diff --git a/tests/integration/SiteAliasConvertTest.php b/tests/integration/SiteAliasConvertTest.php index 7f989da093..3cb579a269 100644 --- a/tests/integration/SiteAliasConvertTest.php +++ b/tests/integration/SiteAliasConvertTest.php @@ -10,7 +10,6 @@ */ class SiteAliasConvertTest extends UnishIntegrationTestCase { - /** * Test functionality of site:alias-convert. */ diff --git a/tests/integration/SqlCliTest.php b/tests/integration/SqlCliTest.php index a3da378d08..8ac518eda9 100644 --- a/tests/integration/SqlCliTest.php +++ b/tests/integration/SqlCliTest.php @@ -16,7 +16,6 @@ */ class SqlCliTest extends UnishIntegrationTestCase { - public function testSqlCli() { if ($this->isWindows()) { diff --git a/tests/integration/WatchdogTest.php b/tests/integration/WatchdogTest.php index f9a90b3f53..d6751d07ed 100644 --- a/tests/integration/WatchdogTest.php +++ b/tests/integration/WatchdogTest.php @@ -7,7 +7,6 @@ */ class WatchdogTest extends UnishIntegrationTestCase { - public function testWatchdog() { $this->drush('pm-enable', ['dblog']); diff --git a/tests/integration/resources/Commands/ExampleAttributesCommands.php b/tests/integration/resources/Commands/ExampleAttributesCommands.php index 90631b2561..6bd7528fc6 100644 --- a/tests/integration/resources/Commands/ExampleAttributesCommands.php +++ b/tests/integration/resources/Commands/ExampleAttributesCommands.php @@ -1,4 +1,5 @@ $v) { putenv($k . '=' . $v); // Value must be a string. See \Symfony\Component\Process\Process::getDefaultEnv. - $_SERVER[$k]= (string) $v; + $_SERVER[$k] = (string) $v; } } diff --git a/tests/unish/Utils/FSUtils.php b/tests/unish/Utils/FSUtils.php index 4cef991cdd..eac6df48d3 100644 --- a/tests/unish/Utils/FSUtils.php +++ b/tests/unish/Utils/FSUtils.php @@ -1,4 +1,5 @@ database = $database; diff --git a/tests/unit/XhProfTest.php b/tests/unit/XhProfTest.php index 1eee71ce4a..cd4edea2dd 100644 --- a/tests/unit/XhProfTest.php +++ b/tests/unit/XhProfTest.php @@ -13,7 +13,6 @@ */ class XhProfTest extends TestCase { - /** * Test various combinations of XHProf flag options. * From a355f9e73e4bd40585f80ecd3197286d5ee82063 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 9 Jan 2022 11:23:48 -0500 Subject: [PATCH 077/125] Fix CLI history path and startBrowser(). (#5001) --- appveyor.yml | 5 ----- src/Drupal/Commands/core/CliCommands.php | 4 ++-- src/Exec/ExecTrait.php | 2 +- src/Utils/FsUtils.php | 4 ++-- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 06c9d6cf30..d2aecb76d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,11 +20,6 @@ init: # Inspired by https://github.com/Codeception/base/blob/master/appveyor.yml and https://github.com/phpmd/phpmd/blob/master/appveyor.yml install: - ps: Set-Service wuauserv -StartupType Manual -# - ps: appveyor-retry cinst -y curl -# - SET PATH=C:\Program Files\curl;%PATH% - #which is only needed by the test suite. - - cinst --limit-output -y which - - SET PATH=C:\Program Files\which;%PATH% - git clone -q https://github.com/acquia/DevDesktopCommon.git #For tar, cksum, ... - SET PATH=%APPVEYOR_BUILD_FOLDER%/DevDesktopCommon/bintools-win/msys/bin;%PATH% - SET PATH=C:\Program Files\MySql\MySQL Server 5.7\bin\;%PATH% diff --git a/src/Drupal/Commands/core/CliCommands.php b/src/Drupal/Commands/core/CliCommands.php index 1369910c48..5c651f52a0 100644 --- a/src/Drupal/Commands/core/CliCommands.php +++ b/src/Drupal/Commands/core/CliCommands.php @@ -10,9 +10,9 @@ use Drupal\Component\Assertion\Handle; use Drush\Psysh\Shell; use Drush\Runtime\Runtime; +use Drush\Utils\FsUtils; use Psy\Configuration; use Psy\VersionUpdater\Checker; -use Webmozart\PathUtil\Path; class CliCommands extends DrushCommands { @@ -174,7 +174,7 @@ protected function getCasters(): array */ protected function historyPath(array $options): string { - $cli_directory = Path::join($this->getConfig()->cache(), 'cli'); + $cli_directory = FsUtils::getBackupDirParent(); $drupal_major_version = Drush::getMajorVersion(); // If there is no drupal version (and thus no root). Just use the current diff --git a/src/Exec/ExecTrait.php b/src/Exec/ExecTrait.php index 49bc5d67c1..6c298e790b 100644 --- a/src/Exec/ExecTrait.php +++ b/src/Exec/ExecTrait.php @@ -29,7 +29,7 @@ public function startBrowser($uri = null, int $sleep = 0, ?int $port = null, $br if ($browser) { // We can only open a browser if we have a DISPLAY environment variable on // POSIX or are running Windows or OS X. - if (!Drush::simulate() && !getenv('DISPLAY') && !drush_is_windows() && !drush_is_osx()) { + if (!Drush::simulate() && !getenv('DISPLAY') && !in_array(PHP_OS_FAMILY, ['Windows', 'Darwin'])) { $this->logger()->info(dt('No graphical display appears to be available, not starting browser.')); return false; } diff --git a/src/Utils/FsUtils.php b/src/Utils/FsUtils.php index de5d460e7c..c093d49e6d 100644 --- a/src/Utils/FsUtils.php +++ b/src/Utils/FsUtils.php @@ -47,13 +47,13 @@ public static function getBackupDir($subdir = null): string } /** - * Get the base dir where our backup directories will be stored + * Get the base dir where our backup directories will be stored. Also stores CLI history file. * * @return * A path to the backup directory parent * @throws \Exception */ - protected static function getBackupDirParent() + public static function getBackupDirParent() { // Try in order: // 1. The user-specified backup directory from drush.yml config file From 6e5b22b502dad11a39785c00acaa41afb776b463 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 9 Jan 2022 11:29:06 -0500 Subject: [PATCH 078/125] Prep for 11.0.0-rc7 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..33139b0f15 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0-rc7 From 93bf7d7309ed55ad2b7f7f9afbf78d513e3d4dfd Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 9 Jan 2022 11:40:45 -0500 Subject: [PATCH 079/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 33139b0f15..9ad93d53df 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-rc7 +drush_version=11.0.0-dev From 4fa4cbce4bcbd62d0def181865fe1a7892aa41e4 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 9 Jan 2022 13:29:41 -0500 Subject: [PATCH 080/125] Add core:init back as a LegacyCommand (#5002) --- src/Commands/DrushCommands.php | 7 ++----- src/Commands/LegacyCommands.php | 12 ++++++++++++ src/Commands/OptionsCommands.php | 4 ++-- src/Commands/ValidatorsCommands.php | 5 ----- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Commands/DrushCommands.php b/src/Commands/DrushCommands.php index 9bc426d703..35828f78ad 100644 --- a/src/Commands/DrushCommands.php +++ b/src/Commands/DrushCommands.php @@ -42,10 +42,7 @@ abstract class DrushCommands implements IOAwareInterface, LoggerAwareInterface, // Used to signal that the command completed successfully, but we still want to indicate a failure to the caller. const EXIT_FAILURE_WITH_CLARITY = 3; - /** - * @var CommandData - */ - protected $commandData; + protected CommandData $commandData; public function __construct() { @@ -79,7 +76,7 @@ protected function logger(): ?LoggerInterface */ protected function printFile(string $file): void { - if ((substr($file, -4) == ".htm") || (substr($file, -5) == ".html")) { + if (str_ends_with($file, ".htm") || str_ends_with($file, ".html")) { $tmp_file = drush_tempnam(basename($file)); file_put_contents($tmp_file, drush_html_to_text(file_get_contents($file))); $file = $tmp_file; diff --git a/src/Commands/LegacyCommands.php b/src/Commands/LegacyCommands.php index 6815c42378..df7086e896 100644 --- a/src/Commands/LegacyCommands.php +++ b/src/Commands/LegacyCommands.php @@ -4,6 +4,18 @@ class LegacyCommands extends DrushCommands { + /** + * The core:init command was removed. Please edit your .bashrc manually. + * + * @command core:init + * @aliases init + * @hidden + * @obsolete + */ + public function init(): void + { + } + /** * Drupal 8 does not support disabling modules. See pm:uninstall command. * diff --git a/src/Commands/OptionsCommands.php b/src/Commands/OptionsCommands.php index 885658105e..cdd4bd9f5f 100644 --- a/src/Commands/OptionsCommands.php +++ b/src/Commands/OptionsCommands.php @@ -2,11 +2,11 @@ namespace Drush\Commands; +use Symfony\Component\Console\Input\InputOption; + /* * Common options providers. Use them by adding an annotation to your method. */ -use Symfony\Component\Console\Input\InputOption; - class OptionsCommands { const REQ = InputOption::VALUE_REQUIRED; diff --git a/src/Commands/ValidatorsCommands.php b/src/Commands/ValidatorsCommands.php index a7a082f38b..d3e77f0bee 100644 --- a/src/Commands/ValidatorsCommands.php +++ b/src/Commands/ValidatorsCommands.php @@ -18,7 +18,6 @@ class ValidatorsCommands * @see \Drush\Commands\core\ViewsCommands::execute for an example. * * @hook validate @validate-entity-load - * @param CommandData $commandData * @return CommandError|null */ public function validateEntityLoad(CommandData $commandData) @@ -39,7 +38,6 @@ public function validateEntityLoad(CommandData $commandData) * @see \Drush\Commands\core\WatchdogCommands::show for an example. * * @hook post-init @validate-module-enabled - * @return CommandError|null */ public function validateModuleEnabled(Input $input, AnnotationData $annotationData): void { @@ -57,7 +55,6 @@ public function validateModuleEnabled(Input $input, AnnotationData $annotationDa * Annotation value should be the name of the argument containing the path. * * @hook validate @validate-file-exists - * @param CommandData $commandData * @return CommandError|null */ public function validateFileExists(CommandData $commandData) @@ -88,7 +85,6 @@ public function validateFileExists(CommandData $commandData) * Annotation value should be extension name. If multiple, delimit by a comma. * * @hook validate @validate-php-extension - * @param CommandData $commandData * @return CommandError|null */ public function validatePHPExtension(CommandData $commandData) @@ -113,7 +109,6 @@ public function validatePHPExtension(CommandData $commandData) * Annotation value should be the name of the argument/option containing the permission(s). * * @hook validate @validate-permissions - * @param CommandData $commandData * @return CommandError|null */ public function validatePermissions(CommandData $commandData) From b03e4df297312c90ae4e59213e424aa02ca55e45 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 9 Jan 2022 22:08:18 -0500 Subject: [PATCH 081/125] Add SuccessInterface to DrushLogger. (#5003) --- src/Commands/DrushCommands.php | 4 ++-- src/Log/Logger.php | 8 +++++++- src/Log/SuccessInterface.php | 11 +++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/Log/SuccessInterface.php diff --git a/src/Commands/DrushCommands.php b/src/Commands/DrushCommands.php index 35828f78ad..92f1dc74d6 100644 --- a/src/Commands/DrushCommands.php +++ b/src/Commands/DrushCommands.php @@ -2,6 +2,7 @@ namespace Drush\Commands; +use Drush\Log\Logger; use Symfony\Component\Console\Style\SymfonyStyle; use Consolidation\AnnotatedCommand\CommandData; use Drush\Drush; @@ -11,7 +12,6 @@ use GuzzleHttp\Middleware; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; -use Psr\Log\LoggerInterface; use Drush\Config\ConfigAwareTrait; use Drush\Exec\ExecTrait; use Robo\Contract\ConfigAwareInterface; @@ -63,7 +63,7 @@ protected function io(): SymfonyStyle /** * Returns a logger object. */ - protected function logger(): ?LoggerInterface + protected function logger(): ?Logger { return $this->logger; } diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 9078c7598b..3c09938895 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -20,11 +20,12 @@ namespace Drush\Log; +use Consolidation\Log\ConsoleLogLevel; use Drush\Drush; use Robo\Log\RoboLogger; use Symfony\Component\Console\Output\OutputInterface; -class Logger extends RoboLogger +class Logger extends RoboLogger implements SuccessInterface { public function __construct(OutputInterface $output) { @@ -72,4 +73,9 @@ public static function formatSize($size) return str_replace('@size', round($size, 2), $unit); } } + + public function success($message, array $context = array()) + { + $this->log(ConsoleLogLevel::SUCCESS, $message, $context); + } } diff --git a/src/Log/SuccessInterface.php b/src/Log/SuccessInterface.php new file mode 100644 index 0000000000..ed3cab36e4 --- /dev/null +++ b/src/Log/SuccessInterface.php @@ -0,0 +1,11 @@ + Date: Mon, 10 Jan 2022 10:27:20 -0500 Subject: [PATCH 082/125] Update composer conflict to <= drupal/core:9.2 --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 327b423df2..81aae3a713 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,7 @@ "yoast/phpunit-polyfills": "^0.2.0" }, "conflict": { - "drupal/core": "<= 9.1", + "drupal/core": "<= 9.2", "drupal/migrate_run": "*", "drupal/migrate_tools": "<= 5" }, diff --git a/composer.lock b/composer.lock index 4905951065..87de46a6d9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "36d9350ed6ce1833e94b85180c1e26b4", + "content-hash": "298e83ca99695a9fa1c79974c5351bfd", "packages": [ { "name": "chi-teck/drupal-code-generator", From ef02dea21499dc21603f51f9088ba9c09fa0deb4 Mon Sep 17 00:00:00 2001 From: Mikko Rantanen Date: Tue, 11 Jan 2022 14:45:13 +0200 Subject: [PATCH 083/125] Remove reference to label argument (#5007) --- src/Drupal/Commands/config/ConfigImportCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/config/ConfigImportCommands.php b/src/Drupal/Commands/config/ConfigImportCommands.php index 3279d4cb54..3db53e35c7 100644 --- a/src/Drupal/Commands/config/ConfigImportCommands.php +++ b/src/Drupal/Commands/config/ConfigImportCommands.php @@ -199,7 +199,7 @@ public function __construct( * * @return bool|void * @option diff Show preview as a diff. - * @option source An arbitrary directory that holds the configuration files. An alternative to label argument + * @option source An arbitrary directory that holds the configuration files. * @option partial Allows for partial config imports from the source directory. Only updates and new configs will be processed with this flag (missing configs will not be deleted). No config transformation happens. * @aliases cim,config-import * @topics docs:deploy From 78b1f3675cb5c47ea2a38de6e2ea3953ffedb1e9 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 11 Jan 2022 11:35:09 -0500 Subject: [PATCH 084/125] Fix #5004. Handle --editor option. (#5008) --- src/Commands/core/EditCommands.php | 4 ++-- src/Drupal/Commands/config/ConfigCommands.php | 2 +- src/Exec/ExecTrait.php | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Commands/core/EditCommands.php b/src/Commands/core/EditCommands.php index 3c85c1de0f..b827cd4e07 100644 --- a/src/Commands/core/EditCommands.php +++ b/src/Commands/core/EditCommands.php @@ -35,7 +35,7 @@ class EditCommands extends DrushCommands implements SiteAliasManagerAwareInterfa * Edit the second file in the choice list. * @aliases conf,config,core-edit */ - public function edit($filter = null): void + public function edit($filter = null, array $options = []): void { $all = $this->load(); @@ -48,7 +48,7 @@ public function edit($filter = null): void } } - $editor = self::getEditor(); + $editor = self::getEditor($options['editor']); if (count($all) == 1) { $filepath = current($all); } else { diff --git a/src/Drupal/Commands/config/ConfigCommands.php b/src/Drupal/Commands/config/ConfigCommands.php index b2ae4dac07..be25128081 100644 --- a/src/Drupal/Commands/config/ConfigCommands.php +++ b/src/Drupal/Commands/config/ConfigCommands.php @@ -232,7 +232,7 @@ public function edit($config_name, $options = []): void // Note that `getEditor()` returns a string that contains a // %s placeholder for the config file path. - $exec = self::getEditor(); + $exec = self::getEditor($options['editor']); $cmd = sprintf($exec, Escape::shellArg($temp_storage->getFilePath($config_name))); $process = $this->processManager()->shell($cmd); $process->setTty(true); diff --git a/src/Exec/ExecTrait.php b/src/Exec/ExecTrait.php index 6c298e790b..3ce7824bed 100644 --- a/src/Exec/ExecTrait.php +++ b/src/Exec/ExecTrait.php @@ -100,9 +100,9 @@ public static function programExists($program) return $process->isSuccessful(); } - public static function getEditor() + public static function getEditor(?string $editor) { // See http://drupal.org/node/1740294 - return '${VISUAL-${EDITOR-vi}} %s'; + return $editor ? "$editor %s" : '${VISUAL-${EDITOR-vi}} %s'; } } From ed40ba03b6a85059e0799ca39bd1da93b8691a79 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 11 Jan 2022 12:06:30 -0500 Subject: [PATCH 085/125] Prep for 11.0.0 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 9ad93d53df..a456f7a617 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0-dev +drush_version=11.0.0 From 3992c6d2cffef21f48a8b686bb1eae6deaac2e7c Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 11 Jan 2022 12:14:13 -0500 Subject: [PATCH 086/125] Fix error in composer conflict statement. 9.2 is supported for now. --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 81aae3a713..8d98758b23 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,7 @@ "yoast/phpunit-polyfills": "^0.2.0" }, "conflict": { - "drupal/core": "<= 9.2", + "drupal/core": "< 9.2", "drupal/migrate_run": "*", "drupal/migrate_tools": "<= 5" }, diff --git a/composer.lock b/composer.lock index 87de46a6d9..88e2df022b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "298e83ca99695a9fa1c79974c5351bfd", + "content-hash": "ff8221ae494b4436f105199890276615", "packages": [ { "name": "chi-teck/drupal-code-generator", From 95bac55daff28bb3770778d3c694a092934a0c9c Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 11 Jan 2022 13:03:53 -0500 Subject: [PATCH 087/125] Update Drush 10 EOL date --- docs/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install.md b/docs/install.md index 8d77d3c9e2..575875b103 100644 --- a/docs/install.md +++ b/docs/install.md @@ -36,7 +36,7 @@ Drupal Compatibility Drush 10 7.1+ - Nov 2021 + Jan 2022 ✓ From be0718ab9a56ac20ff109c60648017878edf28e2 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 12 Jan 2022 10:27:10 -0500 Subject: [PATCH 088/125] Fix #5010. sql:dump includes path to sqlite3 database file in result-file=auto filename. Also uses in-memory sqlite during CI. (#5012) --- .circleci/config.yml | 2 +- .ddev/config.yaml | 2 ++ src/Commands/core/SiteInstallCommands.php | 2 ++ src/Sql/SqlBase.php | 7 ++++--- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ec7c1167b..c8551df2a7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,7 +73,7 @@ jobs: docker: - image: wodby/php:7.4 environment: - - UNISH_DB_URL=sqlite://sut/sites/dev/files/.ht.sqlite + - "UNISH_DB_URL=sqlite://:memory:" <<: *test74steps test_74_drupal9_postgres: diff --git a/.ddev/config.yaml b/.ddev/config.yaml index d25d9b975a..cd4d76057f 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -17,4 +17,6 @@ composer_version: "" disable_settings_management: true web_environment: - UNISH_DB_URL=mysql://root:root@db +# - "UNISH_DB_URL=sqlite://:memory:" +# - UNISH_DB_URL=pgsql://postgres:@localhost - DRUSH_OPTIONS_URI=$DDEV_PRIMARY_URL diff --git a/src/Commands/core/SiteInstallCommands.php b/src/Commands/core/SiteInstallCommands.php index 68a288c1c2..9f69175dd9 100644 --- a/src/Commands/core/SiteInstallCommands.php +++ b/src/Commands/core/SiteInstallCommands.php @@ -48,6 +48,8 @@ class SiteInstallCommands extends DrushCommands implements SiteAliasManagerAware * Install using the specified DB params. * @usage drush si --db-url=sqlite://sites/example.com/files/.ht.sqlite * Install using SQLite + * @usage drush si --db-url=sqlite://:memory: + * Install using SQLite in-memory database. * @usage drush si --account-pass=mom * Re-install with specified uid1 password. * @usage drush si --existing-config diff --git a/src/Sql/SqlBase.php b/src/Sql/SqlBase.php index 79a9866e4c..36bf02627a 100644 --- a/src/Sql/SqlBase.php +++ b/src/Sql/SqlBase.php @@ -233,13 +233,14 @@ public function dumpCmd($table_selection): string /* * Generate a path to an output file for a SQL dump when needed. * - * @param string|bool @file + * @param string|bool|null @file * If TRUE, generate a path based on usual backup directory and current date. * Otherwise, just return the path that was provided. */ - public function dumpFile($file) + public function dumpFile($file): ?string { - $database = $this->dbSpec['database']; + // basename() is needed for sqlite as $database is a path. Harmless otherwise. + $database = basename($this->dbSpec['database']); // $file is passed in to us usually via --result-file. If the user // has set $options['result-file'] = 'auto', then we From 74a2c4214095d31b07768b6ac588350e977b1db5 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 12 Jan 2022 11:50:32 -0500 Subject: [PATCH 089/125] Add --filter option to migrate:status (#5014) --- src/Drupal/Commands/core/MigrateRunnerCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/core/MigrateRunnerCommands.php b/src/Drupal/Commands/core/MigrateRunnerCommands.php index caabf6050b..8015161ad8 100644 --- a/src/Drupal/Commands/core/MigrateRunnerCommands.php +++ b/src/Drupal/Commands/core/MigrateRunnerCommands.php @@ -107,7 +107,7 @@ public function __construct(DateFormatter $dateFormatter, KeyValueFactoryInterfa * unprocessed: Unprocessed * last_imported: Last Imported * @default-fields id,status,total,imported,unprocessed,last_imported - * + * @filter-default-field status * @return RowsOfFields * Migrations status formatted as table. * @version 10.4 From e86241882dbdc553f4c661983b6c0d7a675cf118 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 14 Jan 2022 07:44:28 -0500 Subject: [PATCH 090/125] Fixes #5015. Nullable string type hint on runserver's parseUri(). (#5017) --- src/Commands/core/RunserverCommands.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/core/RunserverCommands.php b/src/Commands/core/RunserverCommands.php index 362cbebbb1..693f26b5c2 100644 --- a/src/Commands/core/RunserverCommands.php +++ b/src/Commands/core/RunserverCommands.php @@ -119,12 +119,12 @@ public function uri($uri, $options): array /** * Parse a URI or partial URI (including just a port, host IP or path). * - * @param string $uri + * @param $uri * String that can contain partial URI. * * URI array as returned by parse_url. */ - public function parseUri(string $uri): array + public function parseUri(?string $uri): array { if (empty($uri)) { return []; From 77cb2ef52fcc58c6c9ce248c3655a5b4c9f8c06a Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 14 Jan 2022 08:13:14 -0500 Subject: [PATCH 091/125] Use non-interactive for composer in CI (#5018) --- .circleci/config.yml | 36 ++++++++++++++++++------------------ composer.json | 3 +++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c8551df2a7..01996ef953 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,13 +18,13 @@ test_74_steps: &test74steps steps: - checkout - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - - run: composer install -n + - run: composer -n install - run: mkdir -p /tmp/results - - run: composer lint - - run: composer unit -- --log-junit /tmp/results/unit.junit.xml - - run: composer functional -- --log-junit /tmp/results/functional.junit.xml + - run: composer -n lint + - run: composer -n unit -- --log-junit /tmp/results/unit.junit.xml + - run: composer -n functional -- --log-junit /tmp/results/functional.junit.xml # @todo was getting missing key_value table failure when this comes before functional. See https://circleci.com/gh/drush-ops/drush/8828. - - run: composer integration -- --log-junit /tmp/results/integration.junit.xml + - run: composer -n integration -- --log-junit /tmp/results/integration.junit.xml - store_test_results: path: /tmp/results - store_artifacts: @@ -42,8 +42,8 @@ jobs: steps: - checkout - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - - run: composer install -n - - run: composer cs + - run: composer -n install + - run: composer -n cs # Mergeable test: # FAIL if merging test branch with 11.x produces conflicts @@ -101,11 +101,11 @@ jobs: steps: - checkout - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - - run: composer require --dev drupal/core-recommended:9.2.8 --no-update - - run: composer require symfony/polyfill-php80:"1.23 as 1.20" --no-update + - run: composer -n require --dev drupal/core-recommended:9.2.8 --no-update + - run: composer -n require symfony/polyfill-php80:"1.23 as 1.20" --no-update - run: php --version - - run: composer update - - run: composer phpunit -- --testsuite integration --filter=testInsecureDrupalPackage --stop-on-skipped + - run: composer -n update + - run: composer -n phpunit -- --testsuite integration --filter=testInsecureDrupalPackage --stop-on-skipped # PHP 8 test with Drupal tip # Determines whether a newer version of a dependency has broken Drush. @@ -121,14 +121,14 @@ jobs: - checkout - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - run: php --version - - run: composer config platform.php --unset - - run: composer require --dev drupal/core-recommended:9.4.x-dev --no-update - - run: composer update + - run: composer -n config platform.php --unset + - run: composer -n require --dev drupal/core-recommended:9.4.x-dev --no-update + - run: composer -n update - run: mkdir -p /tmp/results - - run: composer lint - - run: composer unit -- --log-junit /tmp/results/unit.junit.xml - - run: composer functional -- --log-junit /tmp/results/functional.junit.xml - - run: composer integration -- --log-junit /tmp/results/integration.junit.xml + - run: composer -n lint + - run: composer -n unit -- --log-junit /tmp/results/unit.junit.xml + - run: composer -n functional -- --log-junit /tmp/results/functional.junit.xml + - run: composer -n integration -- --log-junit /tmp/results/integration.junit.xml - store_test_results: path: /tmp/results - store_artifacts: diff --git a/composer.json b/composer.json index 8d98758b23..200aaa80b6 100644 --- a/composer.json +++ b/composer.json @@ -87,6 +87,9 @@ "files": ["tests/load.environment.php"] }, "config": { + "allow-plugins": { + "composer/installers": true + }, "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true, From 0f566149c917d1f1c38df7d6b0ce14fcd55386fa Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sat, 15 Jan 2022 21:58:02 -0500 Subject: [PATCH 092/125] allow-plugins cweagans/composer-patches --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 200aaa80b6..f3e711bf96 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,8 @@ }, "config": { "allow-plugins": { - "composer/installers": true + "composer/installers": true, + "cweagans/composer-patches": true }, "optimize-autoloader": true, "preferred-install": "dist", From 6ab4edfde21b9b95202ff4ec94a152da75b0861e Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 16 Jan 2022 22:40:48 -0500 Subject: [PATCH 093/125] Enable custom Logger(s). (#5022) --- src/Commands/DrushCommands.php | 3 ++- src/Log/DrushLoggerManager.php | 14 +++++++++++++ src/Log/Logger.php | 8 +------- src/Runtime/DependencyInjection.php | 13 ++++++------ sut/drush/Commands/SimpleSutCommands.php | 25 +++++++++++++++++++++++- tests/integration/CustomLoggerTest.php | 17 ++++++++++++++++ 6 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/Log/DrushLoggerManager.php create mode 100644 tests/integration/CustomLoggerTest.php diff --git a/src/Commands/DrushCommands.php b/src/Commands/DrushCommands.php index 92f1dc74d6..f901645fcc 100644 --- a/src/Commands/DrushCommands.php +++ b/src/Commands/DrushCommands.php @@ -2,6 +2,7 @@ namespace Drush\Commands; +use Drush\Log\DrushLoggerManager; use Drush\Log\Logger; use Symfony\Component\Console\Style\SymfonyStyle; use Consolidation\AnnotatedCommand\CommandData; @@ -63,7 +64,7 @@ protected function io(): SymfonyStyle /** * Returns a logger object. */ - protected function logger(): ?Logger + protected function logger(): ?DrushLoggerManager { return $this->logger; } diff --git a/src/Log/DrushLoggerManager.php b/src/Log/DrushLoggerManager.php new file mode 100644 index 0000000000..bb7a8422de --- /dev/null +++ b/src/Log/DrushLoggerManager.php @@ -0,0 +1,14 @@ +log(ConsoleLogLevel::SUCCESS, $message, $context); + } +} diff --git a/src/Log/Logger.php b/src/Log/Logger.php index 3c09938895..9078c7598b 100644 --- a/src/Log/Logger.php +++ b/src/Log/Logger.php @@ -20,12 +20,11 @@ namespace Drush\Log; -use Consolidation\Log\ConsoleLogLevel; use Drush\Drush; use Robo\Log\RoboLogger; use Symfony\Component\Console\Output\OutputInterface; -class Logger extends RoboLogger implements SuccessInterface +class Logger extends RoboLogger { public function __construct(OutputInterface $output) { @@ -73,9 +72,4 @@ public static function formatSize($size) return str_replace('@size', round($size, 2), $unit); } } - - public function success($message, array $context = array()) - { - $this->log(ConsoleLogLevel::SUCCESS, $message, $context); - } } diff --git a/src/Runtime/DependencyInjection.php b/src/Runtime/DependencyInjection.php index 298a25d300..7d77239f1e 100644 --- a/src/Runtime/DependencyInjection.php +++ b/src/Runtime/DependencyInjection.php @@ -2,6 +2,7 @@ namespace Drush\Runtime; +use Drush\Log\Logger; use League\Container\Container; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Output\ConsoleOutput; @@ -63,7 +64,7 @@ public function initContainer( $container = new Container(); // With league/container 3.x, first call wins, so add Drush services first. - $this->addDrushServices($container, $loader, $drupalFinder, $aliasManager, $config); + $this->addDrushServices($container, $loader, $drupalFinder, $aliasManager, $config, $output); // Robo has the same signature for configureContainer in 1.x, 2.x and 3.x. Robo::configureContainer($container, $application, $config, $input, $output); @@ -93,12 +94,12 @@ public function installHandlers($container): void } // Add Drush Services to league/container 3.x - protected function addDrushServices($container, ClassLoader $loader, DrupalFinder $drupalFinder, SiteAliasManager $aliasManager, DrushConfig $config): void + protected function addDrushServices($container, ClassLoader $loader, DrupalFinder $drupalFinder, SiteAliasManager $aliasManager, DrushConfig $config, OutputInterface $output): void { - // Override Robo's logger with our own - $container->share('logger', 'Drush\Log\Logger') - ->addArgument('output') - ->addMethodCall('setLogOutputStyler', ['logStyler']); + // Override Robo's logger with a LoggerManager that delegates to the Drush logger. + $container->share('logger', '\Drush\Log\DrushLoggerManager') + ->addMethodCall('setLogOutputStyler', ['logStyler']) + ->addMethodCall('add', ['drush', new Logger($output)]); $container->share('loader', $loader); $container->share('site.alias.manager', $aliasManager); diff --git a/sut/drush/Commands/SimpleSutCommands.php b/sut/drush/Commands/SimpleSutCommands.php index 06b6087236..ffccfcbc4a 100644 --- a/sut/drush/Commands/SimpleSutCommands.php +++ b/sut/drush/Commands/SimpleSutCommands.php @@ -5,8 +5,12 @@ use Consolidation\AnnotatedCommand\CommandData; use Consolidation\AnnotatedCommand\Events\CustomEventAwareInterface; use Consolidation\AnnotatedCommand\Events\CustomEventAwareTrait; +use Consolidation\Log\ConsoleLogLevel; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; +use Drush\Drush; +use Drush\Symfony\DrushArgvInput; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Logger\ConsoleLogger; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Drush\Commands\DrushCommands; @@ -21,7 +25,7 @@ class SimpleSutCommands extends DrushCommands { /** - * Show a fabulous picture. + * Show a message. * * @command sut:simple * @hidden @@ -30,4 +34,23 @@ public function example() { $this->logger()->notice(dt("This is an example site-wide command committed to the repository in the SUT inside of the 'drush/Commands' directory.")); } + + /** + * Replace Drush logger with a custom one. + * + * In a real-world implementation, you would likely use `@hook *` instead of `@hook sut:simple`. + * + * @hook init sut:simple + */ + public function customLogger(DrushArgvInput $argv, AnnotationData $annotationData): void + { + $verbosityLevelMap = [ConsoleLogLevel::SUCCESS => OutputInterface::VERBOSITY_NORMAL]; + $formatLevelMap = [ConsoleLogLevel::SUCCESS => \Psr\Log\LogLevel::INFO]; + // One could use Monolog if desired. + // Drush expects custom loggers to always write to stderr, so dont use ConsoleLogger directly, + $newLogger = new ConsoleLogger(Drush::output(), $verbosityLevelMap, $formatLevelMap); + $drushLoggerManager = $this->logger(); + $drushLoggerManager->reset()->add('foo', $newLogger); + } } + diff --git a/tests/integration/CustomLoggerTest.php b/tests/integration/CustomLoggerTest.php new file mode 100644 index 0000000000..98ca6fd0a6 --- /dev/null +++ b/tests/integration/CustomLoggerTest.php @@ -0,0 +1,17 @@ +drush('version', [], ['debug' => true]); + $this->assertStringContainsString('sec', $this->getErrorOutputRaw()); + + // sut:simple has been hooked so that a custom logger is use. It doesn't show timing information during --debug. + $this->drush('sut:simple', [], ['debug' => true, 'simulate' => true]); + $this->assertStringNotContainsString('sec', $this->getOutput()); + } +} From e51895f1854d70e86717eee5ff7995b29e86660e Mon Sep 17 00:00:00 2001 From: mondrake Date: Mon, 17 Jan 2022 04:43:47 +0100 Subject: [PATCH 094/125] drush core:status no longer works in Drush 11 with non-core db drivers --- src/Sql/SqlBase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Sql/SqlBase.php b/src/Sql/SqlBase.php index 36bf02627a..39a03a5536 100644 --- a/src/Sql/SqlBase.php +++ b/src/Sql/SqlBase.php @@ -111,6 +111,7 @@ public static function getInstance($db_spec, $options): ?self $instance->setConfig(Drush::config()); return $instance; } + return null; } /* From 1e71eaed75329969eb8768e8b8a34995eb3d550f Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 16 Jan 2022 22:57:21 -0500 Subject: [PATCH 095/125] Fix docs page title --- src/Commands/core/MkCommands.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Commands/core/MkCommands.php b/src/Commands/core/MkCommands.php index 78974f1438..4f6bc885d5 100644 --- a/src/Commands/core/MkCommands.php +++ b/src/Commands/core/MkCommands.php @@ -46,7 +46,7 @@ public function docs(): void $all = $application->all(); $namespaced = ListCommands::categorize($all); [$nav_commands, $pages_commands] = $this->writeContentFilesAndAddToNav($namespaced, $destination, $dir_root, $destination_path); - $this->writeAllMd($pages_commands, $destination_path); + $this->writeAllMd($pages_commands, $destination_path, 'All commands'); $destination = 'generators'; $destination_path = Path::join($dir_root, 'docs', $destination); @@ -57,7 +57,7 @@ public function docs(): void $all = $this->createAnnotatedCommands($application_generate, Drush::getApplication()); $namespaced = ListCommands::categorize($all); [$nav_generators, $pages_generators] = $this->writeContentFilesAndAddToNav($namespaced, $destination, $dir_root, $destination_path); - $this->writeAllMd($pages_generators, $destination_path); + $this->writeAllMd($pages_generators, $destination_path, 'All generators'); $this->writeYml($nav_commands, $nav_generators, $dir_root); } @@ -225,7 +225,7 @@ protected function writeYml(array $nav_commands, $nav_generators, string $dest): file_put_contents(Path::join($dest, 'mkdocs.yml'), $yaml_nav); } - protected function writeAllMd(array $pages_all, string $destination_path): void + protected function writeAllMd(array $pages_all, string $destination_path, string $title): void { unset($pages_all['all']); foreach ($pages_all as $name => $page) { @@ -233,7 +233,7 @@ protected function writeAllMd(array $pages_all, string $destination_path): void $items[] = "* [$name]($basename)"; } $preamble = << Date: Mon, 17 Jan 2022 11:17:28 -0500 Subject: [PATCH 096/125] Prep for 11.0.1 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index a456f7a617..01de2083f9 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.0 +drush_version=11.0.1 From 5cbd52ea926c65bf7de3da2c8d0cd1ee0a5f481f Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 17 Jan 2022 11:19:19 -0500 Subject: [PATCH 097/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 01de2083f9..43ab35b1e9 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.1 +drush_version=11.1.0-dev From fd0366d51dac3e552bfd398eee5a4ec58d33504a Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 17 Jan 2022 17:52:53 -0500 Subject: [PATCH 098/125] Fixes #5024. Allow Symfony 5.4 and 6 (#5025) --- .circleci/config.yml | 8 ++-- composer.json | 12 +++--- composer.lock | 42 +++++++++---------- .../drush_empty_module.info.yml | 2 +- tests/fixtures/modules/woot/composer.json | 2 +- tests/fixtures/modules/woot/woot.info.yml | 2 +- tests/integration/SecurityUpdatesTest.php | 5 +++ tests/unish/CreateEntityType.php | 9 +++- tests/unish/TestModuleHelperTrait.php | 2 +- 9 files changed, 49 insertions(+), 35 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 01996ef953..1883ccf605 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,7 +109,7 @@ jobs: # PHP 8 test with Drupal tip # Determines whether a newer version of a dependency has broken Drush. - test_81_drupal94_highest: + test_81_drupal10_highest: <<: *defaults docker: - image: wodby/php:latest @@ -122,7 +122,9 @@ jobs: - run: cp .docker/zz-php.ini /usr/local/etc/php/conf.d/ - run: php --version - run: composer -n config platform.php --unset - - run: composer -n require --dev drupal/core-recommended:9.4.x-dev --no-update + - run: composer -n require --dev drupal/core-recommended:10.0.x-dev --no-update + # Bring it back when it is compatible with Drupal 10. + - run: composer -n remove drupal/semver_example --no-update --dev - run: composer -n update - run: mkdir -p /tmp/results - run: composer -n lint @@ -144,7 +146,7 @@ workflows: <<: *requires - test_74_drupal9_mysql: <<: *requires - - test_81_drupal94_highest: + - test_81_drupal10_highest: <<: *requires - test_74_drupal9_sqlite: <<: *requires diff --git a/composer.json b/composer.json index f3e711bf96..0bb50d9571 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "ext-dom": "*", "chi-teck/drupal-code-generator": "^2.3", "composer/semver": "^1.4 || ^3", - "consolidation/annotated-command": "^4.4", + "consolidation/annotated-command": "^4.5", "consolidation/config": "^1.2", "consolidation/filter-via-dot-access-data": "^1", "consolidation/robo": "^3", @@ -46,11 +46,11 @@ "league/container": "^3.4", "psr/log": "~1.0", "psy/psysh": "~0.11", - "symfony/event-dispatcher": "^4.0", - "symfony/finder": "^4.0 || ^5", + "symfony/event-dispatcher": "^4.0 || ^5.0 || ^6.0", + "symfony/finder": "^4.0 || ^5 || ^6", "symfony/polyfill-php80": "^1.23", - "symfony/var-dumper": "^4.0 || ^5.0", - "symfony/yaml": "^4.0", + "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0", + "symfony/yaml": "^4.0 || ^5.0 || ^6.0", "webflo/drupal-finder": "^1.2", "webmozart/path-util": "^2.1.0" }, @@ -58,7 +58,7 @@ "composer/installers": "^1.7", "cweagans/composer-patches": "~1.0", "david-garcia/phpwhois": "4.3.0", - "drupal/core-recommended": "^9", + "drupal/core-recommended": "^9 || ^10", "drupal/semver_example": "2.2.0", "phpunit/phpunit": ">=7.5.20", "rector/rector": "^0.12", diff --git a/composer.lock b/composer.lock index 88e2df022b..209a0e3924 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ff8221ae494b4436f105199890276615", + "content-hash": "8ba272546279a9c366d810659d25c2a2", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -2171,16 +2171,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.23.1", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", "shasum": "" }, "require": { @@ -2232,7 +2232,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" }, "funding": [ { @@ -2248,7 +2248,7 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2021-11-23T21:10:46+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -2503,7 +2503,7 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", @@ -2559,7 +2559,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" }, "funding": [ { @@ -2579,16 +2579,16 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", + "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", "shasum": "" }, "require": { @@ -2638,7 +2638,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" }, "funding": [ { @@ -2654,7 +2654,7 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-06-05T21:20:04+00:00" }, { "name": "symfony/polyfill-php80", @@ -5433,16 +5433,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { @@ -5477,9 +5477,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phpspec/prophecy", diff --git a/sut/modules/unish/drush_empty_module/drush_empty_module.info.yml b/sut/modules/unish/drush_empty_module/drush_empty_module.info.yml index ebac62f70d..c85994ec0b 100644 --- a/sut/modules/unish/drush_empty_module/drush_empty_module.info.yml +++ b/sut/modules/unish/drush_empty_module/drush_empty_module.info.yml @@ -1,7 +1,7 @@ name: Drush empty module description: 'Drush empty module' core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^8 || ^9 || ^10 type: module # Require for the sake of tests - simulate what packaging would do. project: drush_empty_module diff --git a/tests/fixtures/modules/woot/composer.json b/tests/fixtures/modules/woot/composer.json index e2b8325324..a2dceee453 100644 --- a/tests/fixtures/modules/woot/composer.json +++ b/tests/fixtures/modules/woot/composer.json @@ -14,7 +14,7 @@ "extra": { "drush": { "services": { - "drush.services.yml": "^9 || ^10" + "drush.services.yml": "^9 || ^10 || ^11" } } } diff --git a/tests/fixtures/modules/woot/woot.info.yml b/tests/fixtures/modules/woot/woot.info.yml index e1c43e11df..7fe4f3a572 100644 --- a/tests/fixtures/modules/woot/woot.info.yml +++ b/tests/fixtures/modules/woot/woot.info.yml @@ -1,5 +1,5 @@ name: Woot type: module description: Woot Mightily. -core_version_requirement: ^9 +core_version_requirement: ^9 || ^10 package: Other diff --git a/tests/integration/SecurityUpdatesTest.php b/tests/integration/SecurityUpdatesTest.php index 697de3a010..28d0694907 100644 --- a/tests/integration/SecurityUpdatesTest.php +++ b/tests/integration/SecurityUpdatesTest.php @@ -2,6 +2,8 @@ namespace Unish; +use Composer\Semver\Semver; + /** * Tests "pm:security" command. * @group commands @@ -14,6 +16,9 @@ class SecurityUpdatesTest extends UnishIntegrationTestCase */ public function testInsecureDrupalPackage() { + if (Semver::satisfies(\Drupal::VERSION, '^10')) { + $this->markTestSkipped('drupal/semver_example not yet compatible.'); + } list($expected_package, $expected_version) = ['drupal/semver_example', '2.2.0']; $this->drush('pm:security', [], ['format' => 'json'], self::EXIT_ERROR_WITH_CLARITY); $this->assertStringContainsString('One or more of your dependencies has an outstanding security update.', $this->getErrorOutput()); diff --git a/tests/unish/CreateEntityType.php b/tests/unish/CreateEntityType.php index 701e5e229e..7f5ec6b349 100644 --- a/tests/unish/CreateEntityType.php +++ b/tests/unish/CreateEntityType.php @@ -15,10 +15,17 @@ public static function createContentEntity($testCase): void 'name' => 'Unish Article', 'machine_name' => 'unish_article', 'description' => 'A test module', - 'package' => 'unish', + // See https://www.drupal.org/project/drupal/issues/3096609. + 'package' => 'Testing', 'dependencies' => 'drupal:text', ]; $testCase->drush('generate', ['module'], ['verbose' => null, 'answer' => $answers, 'destination' => Path::join($testCase->webroot(), 'modules/contrib')], null, null, $testCase::EXIT_SUCCESS, null, ['SHELL_INTERACTIVE' => 1]); + // Currently needed for Drush 10.x tests. Harmless on other versions. + $path = Path::join($testCase->webroot(), 'modules/contrib/unish_article/unish_article.info.yml'); + $contents = file_get_contents($path); + file_put_contents($path, str_replace('^8 || ^9', '^8 || ^9 || ^10', $contents)); + + // Create a content entity type and enable its module. // Note that only the values below are used. The keys are for documentation. $answers = [ diff --git a/tests/unish/TestModuleHelperTrait.php b/tests/unish/TestModuleHelperTrait.php index edf7e7c4fe..90d8ea343f 100644 --- a/tests/unish/TestModuleHelperTrait.php +++ b/tests/unish/TestModuleHelperTrait.php @@ -33,7 +33,7 @@ public function setupModulesForTests(array $modules, $sourcePath) $info_path = $targetDir . "/$module.info.yml"; $module_info = file_get_contents($info_path); if (strpos($module_info, 'core_version_requirement') === false) { - $module_info = "core_version_requirement: ^8 || ^9\n$module_info"; + $module_info = "core_version_requirement: ^8 || ^9 || ^10\n$module_info"; file_put_contents($info_path, $module_info); } } From e4423edd1342d1ba219f3c3bb2ab0e023f454304 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 18 Jan 2022 07:07:49 -0500 Subject: [PATCH 099/125] Bump chi-teck/drupal-code-generator --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 0bb50d9571..a390d7df53 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "require": { "php": ">=7.4", "ext-dom": "*", - "chi-teck/drupal-code-generator": "^2.3", + "chi-teck/drupal-code-generator": "^2.4", "composer/semver": "^1.4 || ^3", "consolidation/annotated-command": "^4.5", "consolidation/config": "^1.2", diff --git a/composer.lock b/composer.lock index 209a0e3924..e2948952e6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8ba272546279a9c366d810659d25c2a2", + "content-hash": "7278bfee8f4740f6d4197054d6443858", "packages": [ { "name": "chi-teck/drupal-code-generator", - "version": "2.3.1", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/Chi-teck/drupal-code-generator.git", - "reference": "69f7a9cdbf0ef7021f1f960d237d3b224f6864d3" + "reference": "872086aeeee1c933adc403d98c35dc029e26ae7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/69f7a9cdbf0ef7021f1f960d237d3b224f6864d3", - "reference": "69f7a9cdbf0ef7021f1f960d237d3b224f6864d3", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/872086aeeee1c933adc403d98c35dc029e26ae7c", + "reference": "872086aeeee1c933adc403d98c35dc029e26ae7c", "shasum": "" }, "require": { @@ -64,9 +64,9 @@ "description": "Drupal code generator", "support": { "issues": "https://github.com/Chi-teck/drupal-code-generator/issues", - "source": "https://github.com/Chi-teck/drupal-code-generator/tree/2.3.1" + "source": "https://github.com/Chi-teck/drupal-code-generator/tree/2.4.0" }, - "time": "2021-12-09T10:20:43+00:00" + "time": "2022-01-18T04:19:55+00:00" }, { "name": "composer/semver", From 3f495abe97147aa75262669b72359783ca1ad433 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 18 Jan 2022 07:10:28 -0500 Subject: [PATCH 100/125] Remove shim for unish_article.module --- tests/unish/CreateEntityType.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/unish/CreateEntityType.php b/tests/unish/CreateEntityType.php index 7f5ec6b349..1be7265162 100644 --- a/tests/unish/CreateEntityType.php +++ b/tests/unish/CreateEntityType.php @@ -15,16 +15,10 @@ public static function createContentEntity($testCase): void 'name' => 'Unish Article', 'machine_name' => 'unish_article', 'description' => 'A test module', - // See https://www.drupal.org/project/drupal/issues/3096609. - 'package' => 'Testing', + 'package' => 'Unish', 'dependencies' => 'drupal:text', ]; $testCase->drush('generate', ['module'], ['verbose' => null, 'answer' => $answers, 'destination' => Path::join($testCase->webroot(), 'modules/contrib')], null, null, $testCase::EXIT_SUCCESS, null, ['SHELL_INTERACTIVE' => 1]); - // Currently needed for Drush 10.x tests. Harmless on other versions. - $path = Path::join($testCase->webroot(), 'modules/contrib/unish_article/unish_article.info.yml'); - $contents = file_get_contents($path); - file_put_contents($path, str_replace('^8 || ^9', '^8 || ^9 || ^10', $contents)); - // Create a content entity type and enable its module. // Note that only the values below are used. The keys are for documentation. From 29fc8f19ae16d35144b83b02aeeeccb80431e29c Mon Sep 17 00:00:00 2001 From: alexpott Date: Tue, 18 Jan 2022 13:20:01 +0000 Subject: [PATCH 101/125] Remove grasmash/yaml-expander as it is not used (#5028) --- composer.json | 1 - composer.lock | 56 ++------------------------------------------------- 2 files changed, 2 insertions(+), 55 deletions(-) diff --git a/composer.json b/composer.json index a390d7df53..57ed1f22a1 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,6 @@ "consolidation/site-alias": "^3.1.3", "consolidation/site-process": "^4", "enlightn/security-checker": "^1", - "grasmash/yaml-expander": "^1.1.1", "guzzlehttp/guzzle": "^6.3 || ^7.0", "league/container": "^3.4", "psr/log": "~1.0", diff --git a/composer.lock b/composer.lock index e2948952e6..d30c692a3c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7278bfee8f4740f6d4197054d6443858", + "content-hash": "ae1eb0419aef16c09a7f6ec6c34b0051", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -921,58 +921,6 @@ }, "time": "2017-12-21T22:14:55+00:00" }, - { - "name": "grasmash/yaml-expander", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/grasmash/yaml-expander.git", - "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/grasmash/yaml-expander/zipball/3f0f6001ae707a24f4d9733958d77d92bf9693b1", - "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1", - "shasum": "" - }, - "require": { - "dflydev/dot-access-data": "^1.1.0", - "php": ">=5.4", - "symfony/yaml": "^2.8.11|^3|^4" - }, - "require-dev": { - "greg-1-anderson/composer-test-scenarios": "^1", - "phpunit/phpunit": "^4.8|^5.5.4", - "satooshi/php-coveralls": "^1.0.2|dev-master", - "squizlabs/php_codesniffer": "^2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Grasmash\\YamlExpander\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Grasmick" - } - ], - "description": "Expands internal property references in a yaml file.", - "support": { - "issues": "https://github.com/grasmash/yaml-expander/issues", - "source": "https://github.com/grasmash/yaml-expander/tree/master" - }, - "time": "2017-12-16T16:06:03+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "6.5.5", @@ -8771,5 +8719,5 @@ "platform-overrides": { "php": "7.4" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.2.0" } From a1b4bb160dac12533d69b2a8e70f70dc1faa264d Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 18 Jan 2022 10:37:48 -0500 Subject: [PATCH 102/125] Tighten squizlabs/php_codesniffer constraint (#5029) --- composer.json | 2 +- composer.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 57ed1f22a1..11eddebf3b 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "drupal/semver_example": "2.2.0", "phpunit/phpunit": ">=7.5.20", "rector/rector": "^0.12", - "squizlabs/php_codesniffer": "^2.7 || ^3", + "squizlabs/php_codesniffer": "^3.6", "vlucas/phpdotenv": "^2.4", "yoast/phpunit-polyfills": "^0.2.0" }, diff --git a/composer.lock b/composer.lock index d30c692a3c..eeae7ae6b0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ae1eb0419aef16c09a7f6ec6c34b0051", + "content-hash": "101833872d33f2b7c5702a49c06577b8", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -8719,5 +8719,5 @@ "platform-overrides": { "php": "7.4" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.1.0" } From d2d1877b21067d5b524281d0057b66086d79f5ec Mon Sep 17 00:00:00 2001 From: mondrake Date: Tue, 18 Jan 2022 23:08:49 +0100 Subject: [PATCH 103/125] Update SqlBase.php (#5032) --- src/Sql/SqlBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sql/SqlBase.php b/src/Sql/SqlBase.php index 39a03a5536..2915202939 100644 --- a/src/Sql/SqlBase.php +++ b/src/Sql/SqlBase.php @@ -71,7 +71,7 @@ public function setProcess(Process $process): void * @param $options * An options array as handed to a command callback. */ - public static function create(array $options = []): SqlBase + public static function create(array $options = []): ?SqlBase { // Set defaults in the unfortunate event that caller doesn't provide values. $options += [ From 1bc10c9901cb744928cca90aff933111b7630eed Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 18 Jan 2022 17:43:02 -0500 Subject: [PATCH 104/125] Move entity:updates command to LegacyCommands. Its unused in Drupal 9+ (#5033) --- src/Commands/LegacyCommands.php | 12 +++ src/Commands/core/UpdateDBCommands.php | 138 +------------------------ 2 files changed, 14 insertions(+), 136 deletions(-) diff --git a/src/Commands/LegacyCommands.php b/src/Commands/LegacyCommands.php index df7086e896..791d83ab4a 100644 --- a/src/Commands/LegacyCommands.php +++ b/src/Commands/LegacyCommands.php @@ -4,6 +4,18 @@ class LegacyCommands extends DrushCommands { + /** + * Drupal removed its automatic entity-updates API in 8.7. See https://www.drupal.org/node/3034742. + * + * @command entity:updates + * @aliases entup,entity-updates + * @hidden + * @obsolete + */ + public function entityUpdates(): void + { + } + /** * The core:init command was removed. Please edit your .bashrc manually. * diff --git a/src/Commands/core/UpdateDBCommands.php b/src/Commands/core/UpdateDBCommands.php index 0d837c99a8..f6350efc99 100644 --- a/src/Commands/core/UpdateDBCommands.php +++ b/src/Commands/core/UpdateDBCommands.php @@ -10,7 +10,6 @@ use Consolidation\SiteAlias\SiteAliasManagerAwareInterface; use Consolidation\SiteAlias\SiteAliasManagerAwareTrait; use Drupal\Core\Utility\Error; -use Drupal\Core\Entity\EntityStorageException; use Drush\Commands\DrushCommands; use Drush\Drush; use Drush\Exceptions\UserAbortException; @@ -29,25 +28,19 @@ class UpdateDBCommands extends DrushCommands implements SiteAliasManagerAwareInt * * @command updatedb * @option cache-clear Clear caches upon completion. - * @option entity-updates Run automatic entity schema updates at the end of any update hooks. Not supported in Drupal >= 8.7.0. * @option post-updates Run post updates after hook_update_n and entity updates. * @bootstrap full * @topics docs:deploy * @kernel update * @aliases updb */ - public function updatedb($options = ['cache-clear' => true, 'entity-updates' => false, 'post-updates' => true]): int + public function updatedb($options = ['cache-clear' => true, 'post-updates' => true]): int { $this->cache_clear = $options['cache-clear']; require_once DRUPAL_ROOT . '/core/includes/install.inc'; require_once DRUPAL_ROOT . '/core/includes/update.inc'; drupal_load_updates(); - if ($options['entity-updates'] && version_compare(drush_drupal_version(), '8.7.0', '>=')) { - $this->logger()->warning(dt('Drupal removed its automatic entity-updates API in 8.7. See https://www.drupal.org/node/3034742.')); - $options['entity-updates'] = false; - } - // Disables extensions that have a lower Drupal core major version, or too high of a PHP requirement. // Those are rare, and this function does a full rebuild. So commenting it out for now. // update_fix_compatibility(); @@ -60,8 +53,6 @@ public function updatedb($options = ['cache-clear' => true, 'entity-updates' => } $status_options = [ - // @see https://github.com/drush-ops/drush/pull/3855. - 'no-entity-updates' => !$options['entity-updates'], 'no-post-updates' => !$options['post-updates'], 'strict' => 0, ]; @@ -92,46 +83,10 @@ public function updatedb($options = ['cache-clear' => true, 'entity-updates' => return $success ? self::EXIT_SUCCESS : self::EXIT_FAILURE; } - /** - * Apply pending entity schema updates. - * - * @command entity:updates - * @option cache-clear Set to 0 to suppress normal cache clearing; the caller should then clear if needed. - * @bootstrap full - * @kernel update - * @aliases entup,entity-updates - * @usage drush updatedb:status --entity-updates | grep entity-update - * Use updatedb:status to detect pending updates. - * - */ - public function entityUpdates($options = ['cache-clear' => true]): void - { - if ($this->getConfig()->simulate()) { - throw new \Exception(dt('entity-updates command does not support --simulate option.')); - } - - // @todo - Do same check for updatedb as well. - if (version_compare(drush_drupal_version(), '8.7.0', '>=')) { - throw new \Exception(dt('Drupal removed its automatic entity-updates API in 8.7. See https://www.drupal.org/node/3034742.')); - } - - if ($this->entityUpdatesMain() === false) { - throw new \Exception('Entity updates not run.'); - } - - if ($options['cache-clear']) { - $process = $this->processManager()->drush($this->siteAliasManager()->getSelf(), 'cache-rebuild'); - $process->mustrun(); - } - - $this->logger()->success(dt('Finished performing updates.')); - } - /** * List any pending database updates. * * @command updatedb:status - * @option entity-updates Show entity schema updates. * @option post-updates Show post updates. * @bootstrap full * @kernel update @@ -145,7 +100,7 @@ public function entityUpdates($options = ['cache-clear' => true]): void * @filter-default-field type * @return RowsOfFields */ - public function updatedbStatus($options = ['format' => 'table', 'entity-updates' => true, 'post-updates' => true]) + public function updatedbStatus($options = ['format' => 'table', 'post-updates' => true]) { require_once DRUSH_DRUPAL_CORE . '/includes/install.inc'; drupal_load_updates(); @@ -422,16 +377,6 @@ public function updateBatch($options): bool } } - // Perform entity definition updates, which will update storage - // schema if needed. If module update functions need to work with specific - // entity schema they should call the entity update service for the specific - // update themselves. - // @see \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::applyEntityUpdate() - // @see \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::applyFieldUpdate() - if ($options['entity-updates'] && \Drupal::entityDefinitionUpdateManager()->needsUpdates()) { - $operations[] = [[$this, 'updateEntityDefinitions'], []]; - } - // Lastly, apply post update hooks if specified. if ($options['post-updates']) { $post_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateFunctions(); @@ -485,26 +430,6 @@ public static function restoreMaintMode($status): void \Drupal::service('state')->set('system.maintenance_mode', $status); } - /** - * Apply entity schema updates. - */ - public function updateEntityDefinitions(&$context): void - { - try { - \Drupal::entityDefinitionUpdateManager()->applyupdates(); - } catch (EntityStorageException $e) { - watchdog_exception('update', $e); - $variables = Error::decodeException($e); - unset($variables['backtrace']); - // The exception message is run through - // \Drupal\Component\Utility\SafeMarkup::checkPlain() by - // \Drupal\Core\Utility\Error::decodeException(). - $ret['#abort'] = ['success' => false, 'query' => t('%type: !message in %function (line %line of %file).', $variables)]; - $context['results']['core']['update_entity_definitions'] = $ret; - $context['results']['#abort'][] = 'update_entity_definitions'; - } - } - // Copy of protected \Drupal\system\Controller\DbUpdateController::getModuleUpdates. public function getUpdateList(): array { @@ -573,23 +498,6 @@ public function getUpdatedbStatus(array $options): array } } - // Append row(s) for pending entity definition updates. - if ($options['entity-updates']) { - foreach ( - \Drupal::entityDefinitionUpdateManager() - ->getChangeSummary() as $entity_type_id => $changes - ) { - foreach ($changes as $change) { - $return[] = [ - 'module' => dt('@type entity type', ['@type' => $entity_type_id]), - 'update_id' => '', - 'description' => strip_tags($change), - 'type' => 'entity-update' - ]; - } - } - } - // Pending hook_post_update_X() implementations. $post_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateInformation(); if ($options['post-updates']) { @@ -612,48 +520,6 @@ public function getUpdatedbStatus(array $options): array return [$return, $start]; } - /** - * Apply pending entity schema updates. - */ - public function entityUpdatesMain(): void - { - $change_summary = \Drupal::entityDefinitionUpdateManager()->getChangeSummary(); - if (!empty($change_summary)) { - $this->output()->writeln(dt('The following updates are pending:')); - $this->io()->newLine(); - - foreach ($change_summary as $entity_type_id => $changes) { - $this->output()->writeln($entity_type_id . ' entity type : '); - foreach ($changes as $change) { - $this->output()->writeln(strip_tags($change), 2); - } - } - - if (!$this->io()->confirm(dt('Do you wish to run all pending updates?'))) { - throw new UserAbortException(); - } - - $operations[] = [[$this, 'updateEntityDefinitions'], []]; - - - $batch['operations'] = $operations; - $batch += [ - 'title' => 'Updating', - 'init_message' => 'Starting updates', - 'error_message' => 'An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference.', - 'finished' => [$this, 'updateFinished'], - ]; - batch_set($batch); - - // See updateFinished() for the restore of maint mode. - $this->maintenanceModeOriginalState = \Drupal::service('state')->get('system.maintenance_mode'); - \Drupal::service('state')->set('system.maintenance_mode', true); - drush_backend_batch_process(); - } else { - $this->logger()->success(dt("No entity schema updates required")); - } - } - /** * Log messages for any requirements warnings/errors. */ From 41ff51f4d5c5e0e06092828db6f7569d35bf8fe7 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Tue, 18 Jan 2022 19:04:57 -0600 Subject: [PATCH 105/125] Simplify compatiblity matrix now that Drupal 8 is EOL. (#5035) --- docs/install.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/install.md b/docs/install.md index 575875b103..740d87e09c 100644 --- a/docs/install.md +++ b/docs/install.md @@ -23,56 +23,56 @@ Drupal Compatibility End Of Life Drupal versions - 7 -8.3 8.4+ 9 + 7 8 9 Drush 11 7.4+ TBD - + Drush 10 7.1+ Jan 2022 - ✓ + ✓ Drush 9 5.6+ May 2020 - ✓ + ✓ Drush 8 5.4.5+ Nov 2022 - ✅ ✅ ⚠️ + ✅ ⚠️ Drush 7 5.3.0+ Jul 2017 - ✓ + ✓ Drush 6 5.3.0+ Dec 2015 - ✓ + ✓ Drush 5 5.2.0+ May 2015 - ✓ + ✓ From a7e69ec72bf57a625805957a07956457f91df7d9 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 19 Jan 2022 07:49:12 -0500 Subject: [PATCH 106/125] Bump site-process for less verbose exceptions. (#5034) --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 11eddebf3b..bfe3e6f2b7 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "consolidation/filter-via-dot-access-data": "^1", "consolidation/robo": "^3", "consolidation/site-alias": "^3.1.3", - "consolidation/site-process": "^4", + "consolidation/site-process": "^4.1.3", "enlightn/security-checker": "^1", "guzzlehttp/guzzle": "^6.3 || ^7.0", "league/container": "^3.4", diff --git a/composer.lock b/composer.lock index eeae7ae6b0..f0b1e764cd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "101833872d33f2b7c5702a49c06577b8", + "content-hash": "0741387fd6370a7498f593fd139d63e3", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -685,16 +685,16 @@ }, { "name": "consolidation/site-process", - "version": "4.1.0", + "version": "4.1.3", "source": { "type": "git", "url": "https://github.com/consolidation/site-process.git", - "reference": "ef57711d7049f7606ce936ded16ad93f1ad7f02c" + "reference": "ca41dc82b280bccdf1b231d5599c7d506fba5c04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/site-process/zipball/ef57711d7049f7606ce936ded16ad93f1ad7f02c", - "reference": "ef57711d7049f7606ce936ded16ad93f1ad7f02c", + "url": "https://api.github.com/repos/consolidation/site-process/zipball/ca41dc82b280bccdf1b231d5599c7d506fba5c04", + "reference": "ca41dc82b280bccdf1b231d5599c7d506fba5c04", "shasum": "" }, "require": { @@ -702,7 +702,7 @@ "consolidation/site-alias": "^3", "php": ">=7.1.3", "symfony/console": "^2.8.52|^3|^4.4|^5", - "symfony/process": "^4.3.4" + "symfony/process": "^4.3.4|^5" }, "require-dev": { "phpunit/phpunit": "^7.5.20|^8.5.14", @@ -737,9 +737,9 @@ "description": "A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.", "support": { "issues": "https://github.com/consolidation/site-process/issues", - "source": "https://github.com/consolidation/site-process/tree/4.1.0" + "source": "https://github.com/consolidation/site-process/tree/4.1.3" }, - "time": "2021-02-21T02:53:33+00:00" + "time": "2022-01-18T23:04:54+00:00" }, { "name": "dflydev/dot-access-data", From f9faeb6457840fb7e8fd93af9138dcae5326b2fe Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 19 Jan 2022 08:36:18 -0500 Subject: [PATCH 107/125] Remove dead code and re-enbale --partial test. (#5036) * Remove dead code and re-enbale --partial test. * Remove conditional --- src/Commands/core/SiteInstallCommands.php | 35 ---------------------- tests/functional/ConfigTest.php | 19 +++++------- tests/functional/PmEnDisUnListInfoTest.php | 6 ---- 3 files changed, 7 insertions(+), 53 deletions(-) diff --git a/src/Commands/core/SiteInstallCommands.php b/src/Commands/core/SiteInstallCommands.php index 9f69175dd9..fc55e45882 100644 --- a/src/Commands/core/SiteInstallCommands.php +++ b/src/Commands/core/SiteInstallCommands.php @@ -2,7 +2,6 @@ namespace Drush\Commands\core; -use Composer\Semver\Comparator; use Consolidation\AnnotatedCommand\CommandData; use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Core\Database\Database; @@ -173,13 +172,6 @@ public function taskCallback($install_state): void protected function determineProfile($profile, $options, $class_loader) { - // --config-dir fails with Standard profile and any other one that carries content entities. - // Force to minimal install profile only for drupal < 8.6. - if ($options['config-dir'] && Comparator::lessThan(self::getVersion(), '8.6')) { - $this->logger()->info(dt("Using 'minimal' install profile since --config-dir option was provided.")); - $profile = 'minimal'; - } - // Try to get profile from existing config if not provided as an argument. // @todo Arguably Drupal core [$boot->getKernel()->getInstallProfile()] could do this - https://github.com/drupal/drupal/blob/8.6.x/core/lib/Drupal/Core/DrupalKernel.php#L1606 reads from DB storage but not file storage. if (empty($profile) && $options['existing-config']) { @@ -224,27 +216,6 @@ protected function determineProfile($profile, $options, $class_loader) return $profile; } - /** - * Post installation, run the configuration import. - * - * @hook post-command site-install - */ - public function post($result, CommandData $commandData): void - { - if ($config = $commandData->input()->getOption('config-dir') && Comparator::lessThan(self::getVersion(), '8.6')) { - // Set the destination site UUID to match the source UUID, to bypass a core fail-safe. - $source_storage = new FileStorage($config); - $options = array_merge(Drush::redispatchOptions(), ['yes' => true, 'strict' => 0]); - $selfRecord = $this->siteAliasManager()->getSelf(); - - $process = $this->processManager()->drush($selfRecord, 'config-set', ['system.site', 'uuid', $source_storage->read('system.site')['uuid']], $options); - $process->mustRun(); - - $process = $this->processManager()->drush($selfRecord, 'config-import', [], ['source' => $config] + $options); - $process->mustRun($process->showRealtime()); - } - } - /** * Check to see if there are any .yml files in the provided config directory. */ @@ -440,12 +411,6 @@ protected function getSitesSubdirFromUri($root, $uri) return false; } - public static function getVersion(): ?string - { - $drupal_root = Drush::bootstrapManager()->getRoot(); - return Drush::bootstrap()->getVersion($drupal_root); - } - /** * Fake the necessary HTTP headers that the Drupal installer still needs: * @see https://github.com/drupal/drupal/blob/d260101f1ea8a6970df88d2f1899248985c499fc/core/includes/install.core.inc#L287 diff --git a/tests/functional/ConfigTest.php b/tests/functional/ConfigTest.php index 36520171fe..f10c3d9f7d 100644 --- a/tests/functional/ConfigTest.php +++ b/tests/functional/ConfigTest.php @@ -100,20 +100,15 @@ public function testConfigExportImportStatusExistingConfig() // Test the --existing-config option for site:install. $this->drush('core:status', [], ['field' => 'drupal-version']); $drupal_version = $this->getOutputRaw(); - if (Comparator::greaterThanOrEqualTo($drupal_version, '8.6')) { - $contents = file_get_contents($system_site_yml); - $contents = preg_replace('/front: .*/', 'front: unish existing', $contents); - file_put_contents($system_site_yml, $contents); - $this->installDrupal('dev', true, ['existing-config' => true], false); - $this->drush('config-get', ['system.site', 'page'], ['format' => 'json']); - $page = $this->getOutputFromJSON('system.site:page'); - $this->assertStringContainsString('unish existing', $page['front'], 'Existing config was successfully imported during site:install.'); - } + $contents = file_get_contents($system_site_yml); + $contents = preg_replace('/front: .*/', 'front: unish existing', $contents); + file_put_contents($system_site_yml, $contents); + $this->installDrupal('dev', true, ['existing-config' => true], false); + $this->drush('config-get', ['system.site', 'page'], ['format' => 'json']); + $page = $this->getOutputFromJSON('system.site:page'); + $this->assertStringContainsString('unish existing', $page['front'], 'Existing config was successfully imported during site:install.'); // Similar, but this time via --partial option. - if ($this->isDrupalGreaterThanOrEqualTo('8.8.0')) { - $this->markTestSkipped('Partial config import not yet working on 8.8.0'); - } $contents = file_get_contents($system_site_yml); $contents = preg_replace('/front: .*/', 'front: unish partial', $contents); $partial_path = self::getSandbox() . '/partial'; diff --git a/tests/functional/PmEnDisUnListInfoTest.php b/tests/functional/PmEnDisUnListInfoTest.php index 3f772a28ca..1c3adddb51 100644 --- a/tests/functional/PmEnDisUnListInfoTest.php +++ b/tests/functional/PmEnDisUnListInfoTest.php @@ -47,13 +47,7 @@ public function testEnDisUnList() $drupal_version = $this->getOutputRaw(); // Test the testing install profile theme is installed. - // Since Drupal 8.8, stark is the default testing theme. - // https://www.drupal.org/node/3083055. - // TODO: Replace once Drupal 8.7 is no longer supported. $active_theme = 'stark'; - if (Comparator::lessThan($drupal_version, '8.8')) { - $active_theme = 'classy'; - } $this->assertStringContainsString($active_theme, $out, 'Themes are in the pm-list'); // Test cache was cleared after enabling a module. From 3c93b6393d6a463cb1df314dae3db27fbb640cd4 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 19 Jan 2022 08:42:06 -0500 Subject: [PATCH 108/125] Prep for 11.0.2 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 43ab35b1e9..8de41641d0 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.1.0-dev +drush_version=11.0.2 From c585e785fd4a0eebc7a35e998b7a6e03a87b4da3 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Wed, 19 Jan 2022 23:03:55 -0500 Subject: [PATCH 109/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 8de41641d0..43ab35b1e9 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.2 +drush_version=11.1.0-dev From 3d2cea1555f54e85d8f51091e299a7e9b14f264c Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Thu, 20 Jan 2022 13:39:11 -0500 Subject: [PATCH 110/125] Dont define entity-updates (#5038) * Dont define entity-updates * PHPCS --- src/Commands/LegacyCommands.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Commands/LegacyCommands.php b/src/Commands/LegacyCommands.php index 791d83ab4a..df7086e896 100644 --- a/src/Commands/LegacyCommands.php +++ b/src/Commands/LegacyCommands.php @@ -4,18 +4,6 @@ class LegacyCommands extends DrushCommands { - /** - * Drupal removed its automatic entity-updates API in 8.7. See https://www.drupal.org/node/3034742. - * - * @command entity:updates - * @aliases entup,entity-updates - * @hidden - * @obsolete - */ - public function entityUpdates(): void - { - } - /** * The core:init command was removed. Please edit your .bashrc manually. * From d5c63f337f52b059cbe9d39fca2f3090980450dd Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 21 Jan 2022 07:52:10 -0500 Subject: [PATCH 111/125] Prep for 11.0.3 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 43ab35b1e9..2a9161e537 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.1.0-dev +drush_version=11.0.3 From 6a9187f944be0c7d29ae4407e2ea572bda598fe9 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Fri, 21 Jan 2022 07:53:22 -0500 Subject: [PATCH 112/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 2a9161e537..43ab35b1e9 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.3 +drush_version=11.1.0-dev From 25b52ff1121244c26c8dfaf922e0adae30f4ca02 Mon Sep 17 00:00:00 2001 From: Kevin Porras Date: Mon, 24 Jan 2022 16:22:42 -0600 Subject: [PATCH 113/125] Return values instead of keys in discoverCommandsFromConfiguration. (#5039) * Return values instead of keys in discoverCommandsFromConfiguration. * Add testCommandsFromConfiguration test. * Change wording for command not found. * Fix wording one more time and enable commented out tests. --- src/Application.php | 2 +- .../DrushExtensionsCommands.php | 20 ++++++++++++++ tests/fixtures/drush-extensions/drush.yml | 8 ++++++ .../CommandsFromConfigurationTest.php | 27 +++++++++++++++++++ tests/unish/UnishTestCase.php | 1 + 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/drush-extensions/DrushExtensionsCommands.php create mode 100644 tests/fixtures/drush-extensions/drush.yml create mode 100644 tests/integration/CommandsFromConfigurationTest.php diff --git a/src/Application.php b/src/Application.php index c54da5ef30..d5ce79a167 100644 --- a/src/Application.php +++ b/src/Application.php @@ -351,7 +351,7 @@ protected function discoverCommandsFromConfiguration() } } $this->loadCommandClasses($commandList); - return array_keys($commandList); + return array_values($commandList); } /** diff --git a/tests/fixtures/drush-extensions/DrushExtensionsCommands.php b/tests/fixtures/drush-extensions/DrushExtensionsCommands.php new file mode 100644 index 0000000000..2800829b32 --- /dev/null +++ b/tests/fixtures/drush-extensions/DrushExtensionsCommands.php @@ -0,0 +1,20 @@ +io()->text('Hello world!'); + } +} diff --git a/tests/fixtures/drush-extensions/drush.yml b/tests/fixtures/drush-extensions/drush.yml new file mode 100644 index 0000000000..17a3d4c09f --- /dev/null +++ b/tests/fixtures/drush-extensions/drush.yml @@ -0,0 +1,8 @@ +# +# Drush configuration file used to configure the System Unter Test (sut) +# +# Docs at https://github.com/drush-ops/drush/blob/master/examples/example.drush.yml +# +drush: + commands: + '\Drush\Commands\drush_extensions\DrushExtensionsCommands': '${env.FIXTURES_DIR}/drush-extensions/DrushExtensionsCommands.php' \ No newline at end of file diff --git a/tests/integration/CommandsFromConfigurationTest.php b/tests/integration/CommandsFromConfigurationTest.php new file mode 100644 index 0000000000..021c44f8c4 --- /dev/null +++ b/tests/integration/CommandsFromConfigurationTest.php @@ -0,0 +1,27 @@ +drush('drush-extensions-hello', [], ['help' => null], self::EXIT_ERROR); + $this->assertStringContainsString('Command "drush-extensions-hello" is not defined.', $this->getErrorOutput()); + $this->drush('drush-extensions-hello', [], [ + 'help' => null, + 'config' => getenv('FIXTURES_DIR') . '/drush-extensions/drush.yml', + ]); + $this->assertStringContainsString('Command to load from this file using drush config.', $this->getOutput()); + $this->drush('drush-extensions-hello', [], [ + 'config' => getenv('FIXTURES_DIR') . '/drush-extensions/drush.yml', + ]); + $this->assertStringContainsString('Hello world!', $this->getOutput()); + } +} diff --git a/tests/unish/UnishTestCase.php b/tests/unish/UnishTestCase.php index 2ce0861507..48d7e2d6a0 100644 --- a/tests/unish/UnishTestCase.php +++ b/tests/unish/UnishTestCase.php @@ -71,6 +71,7 @@ public function __construct($name = null, array $data = [], $dataName = '') self::setEnv(['ETC_PREFIX' => $unish_sandbox]); self::setEnv(['SHARE_PREFIX' => $unish_sandbox]); self::setEnv(['TEMP' => Path::join($unish_sandbox, 'tmp')]); + self::setEnv(['FIXTURES_DIR' => Path::join(dirname(__DIR__), 'fixtures')]); } /** From 8a1b0ad0b4ffbd9731e8a8c065d36ad81d776b1b Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 24 Jan 2022 20:00:44 -0500 Subject: [PATCH 114/125] Add back semver_example test on highest. (#5031) * Add back semver_example test on highest. * 3.0 * Bring back CI for highest --- .circleci/config.yml | 2 -- composer.json | 2 +- composer.lock | 22 +++++++++++++--------- tests/integration/SecurityUpdatesTest.php | 5 +---- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1883ccf605..3673f29275 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -123,8 +123,6 @@ jobs: - run: php --version - run: composer -n config platform.php --unset - run: composer -n require --dev drupal/core-recommended:10.0.x-dev --no-update - # Bring it back when it is compatible with Drupal 10. - - run: composer -n remove drupal/semver_example --no-update --dev - run: composer -n update - run: mkdir -p /tmp/results - run: composer -n lint diff --git a/composer.json b/composer.json index bfe3e6f2b7..be126d8923 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "cweagans/composer-patches": "~1.0", "david-garcia/phpwhois": "4.3.0", "drupal/core-recommended": "^9 || ^10", - "drupal/semver_example": "2.2.0", + "drupal/semver_example": "2.3.0", "phpunit/phpunit": ">=7.5.20", "rector/rector": "^0.12", "squizlabs/php_codesniffer": "^3.6", diff --git a/composer.lock b/composer.lock index f0b1e764cd..0deb693837 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0741387fd6370a7498f593fd139d63e3", + "content-hash": "7e54876426a30fe150ea012e9d53de25", "packages": [ { "name": "chi-teck/drupal-code-generator", @@ -4284,26 +4284,26 @@ }, { "name": "drupal/semver_example", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/semver_example.git", - "reference": "2.2.0" + "reference": "2.3.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/semver_example-2.2.0.zip", - "reference": "2.2.0", - "shasum": "8cb04baee5ca950a96ef825434b1da3b5bc985a2" + "url": "https://ftp.drupal.org/files/projects/semver_example-2.3.0.zip", + "reference": "2.3.0", + "shasum": "3de7ff51a8ce4bdf71c2f32059631f5bd8d71458" }, "require": { - "drupal/core": "^8 || ^9" + "drupal/core": ">=8" }, "type": "drupal-module", "extra": { "drupal": { - "version": "2.2.0", - "datestamp": "1593188229", + "version": "2.3.0", + "datestamp": "1642787442", "security-coverage": { "status": "not-covered", "message": "Project has not opted into security advisory coverage!" @@ -4323,6 +4323,10 @@ "name": "dww", "homepage": "https://www.drupal.org/user/46549" }, + { + "name": "moshe weitzman", + "homepage": "https://www.drupal.org/user/23" + }, { "name": "tedbow", "homepage": "https://www.drupal.org/user/240860" diff --git a/tests/integration/SecurityUpdatesTest.php b/tests/integration/SecurityUpdatesTest.php index 28d0694907..a38f8f6090 100644 --- a/tests/integration/SecurityUpdatesTest.php +++ b/tests/integration/SecurityUpdatesTest.php @@ -16,10 +16,7 @@ class SecurityUpdatesTest extends UnishIntegrationTestCase */ public function testInsecureDrupalPackage() { - if (Semver::satisfies(\Drupal::VERSION, '^10')) { - $this->markTestSkipped('drupal/semver_example not yet compatible.'); - } - list($expected_package, $expected_version) = ['drupal/semver_example', '2.2.0']; + list($expected_package, $expected_version) = ['drupal/semver_example', '2.3.0']; $this->drush('pm:security', [], ['format' => 'json'], self::EXIT_ERROR_WITH_CLARITY); $this->assertStringContainsString('One or more of your dependencies has an outstanding security update.', $this->getErrorOutput()); $this->assertStringContainsString("$expected_package", $this->getErrorOutput()); From 14d55983120db638889de0ed56f8f386cdddc5ce Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 24 Jan 2022 23:14:31 -0500 Subject: [PATCH 115/125] sql:sync minor cleanup (#5044) --- src/Commands/sql/SqlSyncCommands.php | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/Commands/sql/SqlSyncCommands.php b/src/Commands/sql/SqlSyncCommands.php index a7ec536c7d..1ba1cd0bbf 100644 --- a/src/Commands/sql/SqlSyncCommands.php +++ b/src/Commands/sql/SqlSyncCommands.php @@ -125,16 +125,15 @@ public function databaseName(SiteAlias $record): string } /** - * Perform sql-dump on source unless told otherwise. + * Perform sql-dump on source unless told otherwise. Returns the path to the dump file. * * @param $options * @param $global_options * @param $sourceRecord * - * Path to the source dump file. * @throws \Exception */ - public function dump($options, $global_options, $sourceRecord): string + public function dump(array $options, array $global_options, SiteAlias $sourceRecord): string { $dump_options = $global_options + [ 'gzip' => true, @@ -148,17 +147,8 @@ public function dump($options, $global_options, $sourceRecord): string if ($this->getConfig()->simulate()) { $source_dump_path = '/simulated/path/to/dump.tgz'; } else { - // First try a Drush 9.6+ return format. $json = $process->getOutputAsJson(); - if (!empty($json['path'])) { - $source_dump_path = $json['path']; - } else { - // Next, try 9.5- format. - $return = drush_backend_parse_output($process->getOutput()); - if (!$return['error_status'] || !empty($return['object'])) { - $source_dump_path = $return['object']; - } - } + $source_dump_path = $json['path']; } } else { $source_dump_path = $options['source-dump']; From 58243aa79721cdca5b89110f3da46e1f54112fbf Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 25 Jan 2022 04:31:08 -0500 Subject: [PATCH 116/125] Remove unused global options remote-host and remote-user. (#5045) --- includes/drush.inc | 2 -- src/Application.php | 12 +----------- src/Commands/sql/SqlCommands.php | 6 +----- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/includes/drush.inc b/includes/drush.inc index 5229c0bb83..0ecd13b5a2 100644 --- a/includes/drush.inc +++ b/includes/drush.inc @@ -137,8 +137,6 @@ function drush_get_global_options($brief = FALSE) { $options['confirm-rollback'] = ['description' => 'Wait for confirmation before doing a rollback when something goes wrong.']; $options['php-options'] = ['hidden' => TRUE, 'description' => "Options to pass to `php` when running drush. Only effective when specified in a site alias definition.", 'never-propagate' => TRUE, 'example-value' => '-d error_reporting="E_ALL"']; $options['halt-on-error'] = ['propagate-cli-value' => TRUE, 'description' => "Manage recoverable errors. Values: 1=Execution halted. 0=Execution continues."]; - $options['remote-host'] = ['hidden' => TRUE, 'description' => 'Remote site to execute drush command on. Managed by site alias.', 'example-value' => 'http://example.com']; - $options['remote-user'] = ['hidden' => TRUE, 'description' => 'User account to use with a remote drush command. Managed by site alias.', 'example-value' => 'www-data']; $options['remote-os'] = ['hidden' => TRUE, 'description' => 'The operating system used on the remote host. Managed by site alias.', 'example-value' => 'linux']; $options['strict'] = ['propagate' => TRUE, 'description' => 'Return an error on unrecognized options. --strict=0: Allow unrecognized options.']; $options['command-specific'] = ['hidden' => TRUE, 'merge-associative' => TRUE, 'description' => 'Command-specific options.']; diff --git a/src/Application.php b/src/Application.php index d5ce79a167..88d41741e8 100644 --- a/src/Application.php +++ b/src/Application.php @@ -69,16 +69,6 @@ public function configureGlobalOptions() new InputOption('--no', null, InputOption::VALUE_NONE, 'Cancels at any confirmation prompt.') ); - $this->getDefinition() - ->addOption( - new InputOption('--remote-host', null, InputOption::VALUE_REQUIRED, 'Run on a remote server.') - ); - - $this->getDefinition() - ->addOption( - new InputOption('--remote-user', null, InputOption::VALUE_REQUIRED, 'The user to use in remote execution.') - ); - $this->getDefinition() ->addOption( new InputOption('--root', '-r', InputOption::VALUE_REQUIRED, 'The Drupal root for this site.') @@ -98,7 +88,7 @@ public function configureGlobalOptions() // TODO: Implement handling for 'pipe' $this->getDefinition() ->addOption( - new InputOption('--pipe', null, InputOption::VALUE_NONE, 'Select the canonical script-friendly output format.') + new InputOption('--pipe', null, InputOption::VALUE_NONE, 'Select the canonical script-friendly output format. Deprecated - use --format.') ); $this->getDefinition() diff --git a/src/Commands/sql/SqlCommands.php b/src/Commands/sql/SqlCommands.php index 863d24714f..87912873f4 100644 --- a/src/Commands/sql/SqlCommands.php +++ b/src/Commands/sql/SqlCommands.php @@ -90,12 +90,8 @@ public function create($options = ['db-su' => self::REQ, 'db-su-pw' => self::REQ { $sql = SqlBase::create($options); $db_spec = $sql->getDbSpec(); - // Prompt for confirmation. - - // @todo odd - maybe for sql-sync. - $txt_destination = (isset($db_spec['remote-host']) ? $db_spec['remote-host'] . '/' : '') . $db_spec['database']; - $this->output()->writeln(dt("Creating database !target. Any existing database will be dropped!", ['!target' => $txt_destination])); + $this->output()->writeln(dt("Creating database !target. Any existing database will be dropped!", ['!target' => $db_spec['database']])); if (!$this->getConfig()->simulate() && !$this->io()->confirm(dt('Do you really want to continue?'))) { throw new UserAbortException(); } From 1093fcaeab2892f7f354bee6349fcf9a0020c105 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 25 Jan 2022 08:13:15 -0500 Subject: [PATCH 117/125] Remove drush_get_global_options() (#5046) --- includes/drush.inc | 78 ------------------------------ src/Commands/core/CoreCommands.php | 13 +++-- 2 files changed, 10 insertions(+), 81 deletions(-) diff --git a/includes/drush.inc b/includes/drush.inc index 0ecd13b5a2..f86b8d811d 100644 --- a/includes/drush.inc +++ b/includes/drush.inc @@ -69,84 +69,6 @@ function drush_log($message, $type = LogLevel::INFO, $error = []) { Drush::logger()->log($type, $message, $error); } -/** - * Get the available global options. Used by list/help commands. All other users - * should pull options from $application. - * - * @param boolean $brief - * Return a reduced set of important options. Used by help command. - * - * @return - * An associative array containing the option definition as the key, - * and a descriptive array for each of the available options. The array - * elements for each item are: - * - * - short-form: The shortcut form for specifying the key on the commandline. - * - propagate: backend invoke will use drush_get_option to propagate this - * option, when set, to any other Drush command that is called. - * - context: The drush context where the value of this item is cached. Used - * by backend invoke to propagate values set in code. - * - never-post: If TRUE, backend invoke will never POST this item's value - * on STDIN; it will always be sent as a commandline option. - * - never-propagate: If TRUE, backend invoke will never pass this item on - * to the subcommand being executed. - * - local-context-only: Backend invoke will only pass this value on for local calls. - * - merge: For options such as $options['shell-aliases'] that consist of an array - * of items, make a merged array that contains all of the values specified for - * all of the contexts (config files) where the option is defined. The value is stored in - * the specified 'context', or in a context named after the option itself if the - * context flag is not specified. - * IMPORTANT: When the merge flag is used, the option value must be obtained via - * drush_get_context('option') rather than drush_get_option('option'). - * - merge-pathlist: For options such as --include and --config, make a merged list - * of options from all contexts; works like the 'merge' flag, but also handles string - * values separated by the PATH_SEPARATOR. - * - merge-associative: Like 'merge-pathlist', but key values are preserved. - * - propagate-cli-value: Used to tell backend invoke to include the value for - * this item as specified on the cli. This can either override 'context' - * (e.g., propagate --include from cli value instead of DRUSH_INCLUDE context), - * or for an independent global setting (e.g. --user) - * - description: The help text for this item. displayed by `drush help`. - */ -function drush_get_global_options($brief = FALSE) { - $options['root'] = ['short-form' => 'r', 'short-has-arg' => TRUE, 'never-post' => TRUE, 'description' => "Drupal root directory to use.", 'example-value' => 'path']; - $options['uri'] = ['short-form' => 'l', 'short-has-arg' => TRUE, 'never-post' => TRUE, 'description' => 'URI of the drupal site to use.', 'example-value' => 'http://example.com:8888']; - $options['verbose'] = ['short-form' => 'v', 'context' => 'DRUSH_VERBOSE', 'description' => 'Display extra information about the command.', 'symfony-conflict' => TRUE]; - $options['debug'] = ['short-form' => 'd', 'context' => 'DRUSH_DEBUG', 'description' => 'Display even more information.']; - $options['yes'] = ['short-form' => 'y', 'context' => 'DRUSH_AFFIRMATIVE', 'description' => "Assume 'yes' as answer to all prompts."]; - $options['no'] = ['short-form' => 'n', 'context' => 'DRUSH_NEGATIVE', 'description' => "Assume 'no' as answer to all prompts."]; - $options['help'] = ['short-form' => 'h', 'description' => "This help system."]; - - if (!$brief) { - $options['simulate'] = ['short-form' => 's', 'context' => 'DRUSH_SIMULATE', 'never-propagate' => TRUE, 'description' => "Simulate all relevant actions (don't actually change the system).", 'symfony-conflict' => TRUE]; - $options['pipe'] = ['short-form' => 'p', 'hidden' => TRUE, 'description' => "Emit a compact representation of the command for scripting."]; - $options['php'] = ['description' => "The absolute path to your PHP interpreter, if not 'php' in the path.", 'example-value' => '/path/to/file', 'never-propagate' => TRUE]; - $options['interactive'] = ['short-form' => 'ia', 'description' => "Force interactive mode for commands run on multiple targets (e.g. `drush @site1,@site2 cc --ia`).", 'never-propagate' => TRUE]; - $options['tty'] = ['hidden' => TRUE, 'description' => "Force allocation of tty for remote commands", 'never-propagate' => TRUE]; - $options['quiet'] = ['short-form' => 'q', 'description' => 'Suppress non-error messages.']; - $options['include'] = ['short-form' => 'i', 'short-has-arg' => TRUE, 'context' => 'DRUSH_INCLUDE', 'never-post' => TRUE, 'propagate-cli-value' => TRUE, 'merge-pathlist' => TRUE, 'description' => "A list of additional directory paths to search for Drush commands. Commandfiles should be placed in a subfolder called 'Commands'.", 'example-value' => '/path/dir']; - $options['exclude'] = ['propagate-cli-value' => TRUE, 'never-post' => TRUE, 'merge-pathlist' => TRUE, 'description' => "A list of files and directory paths to exclude from consideration when searching for drush commandfiles.", 'example-value' => '/path/dir']; - $options['config'] = ['short-form' => 'c', 'short-has-arg' => TRUE, 'context' => 'DRUSH_CONFIG', 'never-post' => TRUE, 'propagate-cli-value' => TRUE, 'merge-pathlist' => TRUE, 'description' => "Specify an additional config file to load. See example.drush.yml", 'example-value' => '/path/file']; - $options['choice'] = ['description' => "Provide an answer to a multiple-choice prompt.", 'example-value' => 'number']; - $options['search-depth'] = ['description' => "Control the depth that drush will search for alias files.", 'example-value' => 'number']; - $options['ignored-modules'] = ['description' => "Exclude some modules from consideration when searching for drush command files.", 'example-value' => 'token,views']; - $options['no-label'] = ['description' => "Remove the site label that drush includes in multi-site command output (e.g. `drush @site1,@site2 status`)."]; - $options['label-separator'] = ['description' => "Specify the separator to use in multi-site command output (e.g. `drush @sites pm-list --label-separator=',' --format=csv`).", 'example-value' => ',']; - $options['show-invoke'] = ['description' => "Show all function names which could have been called for the current command. See drush_invoke()."]; - $options['alias-path'] = ['context' => 'ALIAS_PATH', 'local-context-only' => TRUE, 'merge-pathlist' => TRUE, 'propagate-cli-value' => TRUE, 'description' => "Specifies the list of paths where drush will search for alias files.", 'example-value' => '/path/alias1:/path/alias2']; - $options['confirm-rollback'] = ['description' => 'Wait for confirmation before doing a rollback when something goes wrong.']; - $options['php-options'] = ['hidden' => TRUE, 'description' => "Options to pass to `php` when running drush. Only effective when specified in a site alias definition.", 'never-propagate' => TRUE, 'example-value' => '-d error_reporting="E_ALL"']; - $options['halt-on-error'] = ['propagate-cli-value' => TRUE, 'description' => "Manage recoverable errors. Values: 1=Execution halted. 0=Execution continues."]; - $options['remote-os'] = ['hidden' => TRUE, 'description' => 'The operating system used on the remote host. Managed by site alias.', 'example-value' => 'linux']; - $options['strict'] = ['propagate' => TRUE, 'description' => 'Return an error on unrecognized options. --strict=0: Allow unrecognized options.']; - $options['command-specific'] = ['hidden' => TRUE, 'merge-associative' => TRUE, 'description' => 'Command-specific options.']; - $options['path-aliases'] = ['hidden' => TRUE, 'never-propagate' => TRUE, 'description' => 'Path aliases from site alias.']; - $options['ssh-options'] = ['never-propagate' => TRUE, 'description' => 'A string of extra options that will be passed to the ssh command', 'example-value' => '-p 100']; - $options['local'] = ['propagate' => TRUE, 'description' => 'Don\'t look in global locations for commandfiles, config, and site aliases']; - } - return $options; -} - /** * Calls a given function, passing through all arguments unchanged. * diff --git a/src/Commands/core/CoreCommands.php b/src/Commands/core/CoreCommands.php index 244e6e606d..29f84f2682 100644 --- a/src/Commands/core/CoreCommands.php +++ b/src/Commands/core/CoreCommands.php @@ -45,11 +45,18 @@ public function globalOptions($options = ['format' => 'table']): RowsOfFields // Also document the keys that are recognized by PreflightArgs. It would be possible to redundantly declare // those as global options. We don't do that for now, to avoid confusion. - $ancient = drush_get_global_options(); - foreach (['config', 'alias-path', 'include', 'local', 'strict', 'ssh-options'] as $name) { + $ancient = [ + 'config' => 'Specify an additional config file to load. See example.drush.yml. Example: /path/file', + 'alias-path' => 'Specifies additional paths where Drush will search for alias files. Example: /path/alias1:/path/alias2', + 'include' => 'Additional directories to search for Drush commands. Commandfiles should be placed in a subdirectory called Commands. Example: path/dir', + 'local' => 'Don\'t look outside the Composer project for Drush config.', + 'strict' => 'Return an error on unrecognized options. --strict=0 allows unrecognized options.', + 'ssh-options' => 'A string of extra options that will be passed to the ssh command. Example: -p 100', + ]; + foreach ($ancient as $name => $description) { $rows[] = [ 'name' => '--' . $name, - 'description' => $ancient[$name]['description'], + 'description' => $description, ]; } usort($rows, function ($a, $b) { From b7d97acf0ec1acedd2e47f52b0a2139c4c21ce49 Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Tue, 25 Jan 2022 14:54:25 +0100 Subject: [PATCH 118/125] Update SecurityUpdateCommands endpoint (#5043) --- src/Commands/pm/SecurityUpdateCommands.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Commands/pm/SecurityUpdateCommands.php b/src/Commands/pm/SecurityUpdateCommands.php index 4ac6cd3e06..208ffdf0c4 100644 --- a/src/Commands/pm/SecurityUpdateCommands.php +++ b/src/Commands/pm/SecurityUpdateCommands.php @@ -101,9 +101,8 @@ public function suggestComposerCommand($updates): void */ protected function fetchAdvisoryComposerJson() { - // We use the v2 branch for now, as per https://github.com/drupal-composer/drupal-security-advisories/pull/11. $client = new Client(['handler' => $this->getStack()]); - $response = $client->get('https://raw.githubusercontent.com/drupal-composer/drupal-security-advisories/8.x-v2/composer.json'); + $response = $client->get('https://raw.githubusercontent.com/drupal-composer/drupal-security-advisories/9.x/composer.json'); $security_advisories_composer_json = json_decode($response->getBody(), true); return $security_advisories_composer_json; } From 94707767c12dd2282556089f08b599512f4d1050 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 25 Jan 2022 09:02:58 -0500 Subject: [PATCH 119/125] Prep for 11.0.4 --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 43ab35b1e9..20284db6bd 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.1.0-dev +drush_version=11.0.4 From 4700fecd5ec1691c71ea53e81c88c4e05a6e96ce Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Tue, 25 Jan 2022 09:04:05 -0500 Subject: [PATCH 120/125] Back to dev. --- drush.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drush.info b/drush.info index 20284db6bd..43ab35b1e9 100644 --- a/drush.info +++ b/drush.info @@ -1 +1 @@ -drush_version=11.0.4 +drush_version=11.1.0-dev From 45b79898baa99036f06dc825276608184206857a Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 30 Jan 2022 18:29:27 +0500 Subject: [PATCH 121/125] Fix usage example in core:route command (#5053) --- src/Drupal/Commands/core/DrupalCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/core/DrupalCommands.php b/src/Drupal/Commands/core/DrupalCommands.php index d39630cece..286f8c2ce3 100644 --- a/src/Drupal/Commands/core/DrupalCommands.php +++ b/src/Drupal/Commands/core/DrupalCommands.php @@ -143,7 +143,7 @@ public function requirements($options = ['format' => 'table', 'severity' => -1, * View all routes. * @usage drush route --name=update.status * View details about the update.status route. - * @usage drush route --path=user/1 + * @usage drush route --path=/user/1 * View details about the entity.user.canonical route. * @option name A route name. * @option path An internal path. From 8c71d0001f39a336a85ff6dad44447bcce993ef2 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Sun, 30 Jan 2022 22:03:20 -0500 Subject: [PATCH 122/125] Fix tests on Drupal 10 (#5054) --- src/Application.php | 10 ++++++++++ src/Command/RemoteCommandProxy.php | 3 +++ src/Drupal/Commands/core/DeployHookCommands.php | 4 ++-- src/Symfony/BufferedConsoleOutput.php | 7 +++++++ src/TestTraits/CliTestTrait.php | 5 ++--- .../unish/drush_empty_theme/drush_empty_theme.info.yml | 2 +- .../woot/src/EventSubscriber/ConfigSubscriber.php | 2 +- tests/unish/CommandUnishTestCase.php | 5 +++-- 8 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Application.php b/src/Application.php index 88d41741e8..0a224de2cf 100644 --- a/src/Application.php +++ b/src/Application.php @@ -405,4 +405,14 @@ public function renderException(\Exception $e, OutputInterface $output) $this->doRenderException($e, $output); } + + /** + * Renders a caught Throwable. Omits the command docs at end. + */ + public function renderThrowable(\Throwable $e, OutputInterface $output): void + { + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + + $this->doRenderThrowable($e, $output); + } } diff --git a/src/Command/RemoteCommandProxy.php b/src/Command/RemoteCommandProxy.php index ef7256d854..ff83f5c17a 100644 --- a/src/Command/RemoteCommandProxy.php +++ b/src/Command/RemoteCommandProxy.php @@ -40,6 +40,9 @@ public function __construct($name, RedispatchHook $redispatchHook) InputArgument::IS_ARRAY, 'Proxy for command arguments' ); + + // The above should be enough but isn't in Drupal 10. + $this->ignoreValidationErrors(); } protected function execute(InputInterface $input, OutputInterface $output): void diff --git a/src/Drupal/Commands/core/DeployHookCommands.php b/src/Drupal/Commands/core/DeployHookCommands.php index f6477eea2d..9bcbb0a761 100644 --- a/src/Drupal/Commands/core/DeployHookCommands.php +++ b/src/Drupal/Commands/core/DeployHookCommands.php @@ -25,8 +25,8 @@ class DeployHookCommands extends DrushCommands implements SiteAliasManagerAwareI public static function getRegistry(): UpdateRegistry { $registry = new class ( - \Drupal::service('app.root'), - \Drupal::service('site.path'), + \Drupal::getContainer()->getParameter('app.root'), + \Drupal::getContainer()->getParameter('site.path'), array_keys(\Drupal::service('module_handler')->getModuleList()), \Drupal::service('keyvalue')->get('deploy_hook') ) extends UpdateRegistry { diff --git a/src/Symfony/BufferedConsoleOutput.php b/src/Symfony/BufferedConsoleOutput.php index cddabd0f9f..96b8af58ab 100644 --- a/src/Symfony/BufferedConsoleOutput.php +++ b/src/Symfony/BufferedConsoleOutput.php @@ -5,6 +5,7 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; use Symfony\Component\Console\Output\OutputInterface; /** @@ -13,6 +14,7 @@ class BufferedConsoleOutput extends BufferedOutput implements ConsoleOutputInterface { protected $stderr; + private array $consoleSectionOutputs = []; /** * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) @@ -41,4 +43,9 @@ public function setErrorOutput(OutputInterface $error): void { $this->stderr = $error; } + + public function section(): ConsoleSectionOutput + { + // @todo + } } diff --git a/src/TestTraits/CliTestTrait.php b/src/TestTraits/CliTestTrait.php index dc3db23d57..194773d178 100644 --- a/src/TestTraits/CliTestTrait.php +++ b/src/TestTraits/CliTestTrait.php @@ -79,7 +79,7 @@ public function getErrorOutputRaw() /** * Run a command and return the process without waiting for it to finish. * - * @param string $command + * @param string|array $command * The actual command line to run. * @param sting cd * The directory to run the command in. @@ -88,12 +88,11 @@ public function getErrorOutputRaw() * @param string $input * A string representing the STDIN that is piped to the command. */ - public function startExecute(string $command, $cd = null, $env = null, $input = null) + public function startExecute($command, $cd = null, $env = null, $input = null) { try { // Process uses a default timeout of 60 seconds, set it to 0 (none). $this->process = new Process($command, $cd, $env, $input, 0); - $this->process->inheritEnvironmentVariables(true); if ($this->timeout) { $this->process->setTimeout($this->timeout) ->setIdleTimeout($this->idleTimeout); diff --git a/sut/themes/unish/drush_empty_theme/drush_empty_theme.info.yml b/sut/themes/unish/drush_empty_theme/drush_empty_theme.info.yml index b68f22c9b7..ac6a509e08 100644 --- a/sut/themes/unish/drush_empty_theme/drush_empty_theme.info.yml +++ b/sut/themes/unish/drush_empty_theme/drush_empty_theme.info.yml @@ -1,6 +1,6 @@ name: Drush empty theme description: 'Drush empty theme' core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^8 || ^9 || ^10 type: theme base theme: stable diff --git a/tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php b/tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php index f97bc396f2..93d240d878 100644 --- a/tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php +++ b/tests/fixtures/modules/woot/src/EventSubscriber/ConfigSubscriber.php @@ -14,7 +14,7 @@ class ConfigSubscriber extends ConfigImportValidateEventSubscriberBase /** * {@inheritdoc} */ - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { $events = []; diff --git a/tests/unish/CommandUnishTestCase.php b/tests/unish/CommandUnishTestCase.php index 7728367506..4333f464bb 100644 --- a/tests/unish/CommandUnishTestCase.php +++ b/tests/unish/CommandUnishTestCase.php @@ -71,7 +71,7 @@ public function getErrorOutputRaw() public function drushBackground($command, array $args = [], array $options = [], $site_specification = null, $cd = null, $suffix = null, $env = []) { list($cmd, ) = $this->prepareDrushCommand($command, $args, $options, $site_specification, $suffix); - return $this->startExecute($cmd, $cd, $env); + return $this->startExecute(explode(' ', $cmd), $cd, $env); } /** @@ -191,7 +191,8 @@ protected function prepareDrushCommand($command, array $args = [], array $option if ($hide_stderr) { $cmd[] = '2>' . $this->bitBucket(); } - $exec = array_filter($cmd, 'strlen'); // Remove NULLs + // Remove NULLs + $exec = @array_filter($cmd, 'strlen'); $cmd = implode(' ', $exec); return [$cmd, $coverage_file]; } From ff824f41e0c9ef77944a1c9e32be2cfd696b28c7 Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Mon, 31 Jan 2022 13:17:47 +0100 Subject: [PATCH 123/125] Ignore services on invalid reference (#5056) --- src/Drupal/FindCommandsCompilerPass.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Drupal/FindCommandsCompilerPass.php b/src/Drupal/FindCommandsCompilerPass.php index ccfaa354db..598642b709 100644 --- a/src/Drupal/FindCommandsCompilerPass.php +++ b/src/Drupal/FindCommandsCompilerPass.php @@ -5,6 +5,7 @@ use Drush\Drush; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Reference; /** @@ -64,7 +65,7 @@ public function process(ContainerBuilder $container): void Drush::logger()->debug(dt("Found tagged service !id", ['!id' => $id])); $definition->addMethodCall( 'addCommandReference', - [new Reference($id)] + [new Reference($id, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)] ); } } From b775b69346380c501f7adb9592df271e84437657 Mon Sep 17 00:00:00 2001 From: Moshe Weitzman Date: Mon, 31 Jan 2022 14:40:33 -0500 Subject: [PATCH 124/125] Fix #5058. Load/delete entities that are access controlled. (#5059) --- src/Drupal/Commands/core/EntityCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/core/EntityCommands.php b/src/Drupal/Commands/core/EntityCommands.php index f857e82f01..f00ea8b825 100644 --- a/src/Drupal/Commands/core/EntityCommands.php +++ b/src/Drupal/Commands/core/EntityCommands.php @@ -167,7 +167,7 @@ public function doSave(string $entity_type, array $ids): void protected function getQuery(string $entity_type, ?string $ids, array $options): QueryInterface { $storage = $this->entityTypeManager->getStorage($entity_type); - $query = $storage->getQuery(); + $query = $storage->getQuery()->accessCheck(false); if ($ids = StringUtils::csvToArray((string) $ids)) { $idKey = $this->entityTypeManager->getDefinition($entity_type)->getKey('id'); $query = $query->condition($idKey, $ids, 'IN'); From e3a3c2d57109bb24b46a39c6ff7085a9e09d638c Mon Sep 17 00:00:00 2001 From: Dieter Holvoet Date: Tue, 1 Feb 2022 14:35:36 +0100 Subject: [PATCH 125/125] Add a default value for the field widget choice in field:create (#5060) --- src/Drupal/Commands/field/FieldCreateCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Drupal/Commands/field/FieldCreateCommands.php b/src/Drupal/Commands/field/FieldCreateCommands.php index 395b73baad..412100a894 100644 --- a/src/Drupal/Commands/field/FieldCreateCommands.php +++ b/src/Drupal/Commands/field/FieldCreateCommands.php @@ -315,7 +315,7 @@ protected function askFieldWidget(): string $choices[$name] = $label; } - return $this->io()->choice('Field widget', $choices); + return $this->io()->choice('Field widget', $choices, key($choices)); } protected function askRequired(): bool