diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index e6d01a70d67324466c04c99b79e490ee717f5d78..4850a512fd85e29b4f4e1544ae5c66d5d4e3d6ed 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -6,6 +6,7 @@ services: - '@datetime.time' - '@package_manager.path_locator' - '@event_dispatcher' + - '@automatic_updates.updater' - 24 automatic_updates.updater: class: Drupal\automatic_updates\Updater diff --git a/src/BatchProcessor.php b/src/BatchProcessor.php index d7f046b7e523c3ef4aada1ffdddc9990d62e7ed8..6e0ac4f158ff283516e67270189b9fa419103875 100644 --- a/src/BatchProcessor.php +++ b/src/BatchProcessor.php @@ -39,7 +39,7 @@ class BatchProcessor { ]; if ($error instanceof UpdateException) { - foreach ($error->getValidationResults() as $result) { + foreach ($error->getResults() as $result) { $messages = $result->getMessages(); if (count($messages) > 1) { array_unshift($messages, $result->getSummary()); diff --git a/src/Event/PackagesAwareTrait.php b/src/Event/PackagesAwareTrait.php deleted file mode 100644 index 49ead03861c49f1f7c0877440f94511c6169919f..0000000000000000000000000000000000000000 --- a/src/Event/PackagesAwareTrait.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -namespace Drupal\automatic_updates\Event; - -/** - * Common functionality for events which can carry desired package versions. - */ -trait PackagesAwareTrait { - - /** - * The desired package versions to update to, keyed by package name. - * - * @var string[] - */ - protected $packageVersions; - - /** - * Returns the desired package versions to update to. - * - * @return string[] - * The desired package versions to update to, keyed by package name. - */ - public function getPackageVersions(): array { - return $this->packageVersions; - } - -} diff --git a/src/Event/PreStartEvent.php b/src/Event/PreStartEvent.php deleted file mode 100644 index 02450fe055429507bfce5e80270b78f070db92eb..0000000000000000000000000000000000000000 --- a/src/Event/PreStartEvent.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -namespace Drupal\automatic_updates\Event; - -use Drupal\package_manager\ComposerUtility; -use Drupal\package_manager\Event\ExcludedPathsTrait; - -/** - * Event fired before an update begins. - * - * This event is fired before any files are staged. Validation results added - * by subscribers are not cached. - */ -class PreStartEvent extends UpdateEvent { - - use ExcludedPathsTrait; - use PackagesAwareTrait; - - /** - * Constructs a PreStartEvent object. - * - * @param \Drupal\package_manager\ComposerUtility $active_composer - * A Composer utility object for the active directory. - * @param string[] $package_versions - * (optional) The desired package versions to update to, keyed by package - * name. - */ - public function __construct(ComposerUtility $active_composer, array $package_versions = []) { - parent::__construct($active_composer); - $this->packageVersions = $package_versions; - } - -} diff --git a/src/Event/ReadinessCheckEvent.php b/src/Event/ReadinessCheckEvent.php index 74a9190c6fa223469c9953f487ac3c7306e81871..934a5170026437306a99301d3c07e24cd6acb93e 100644 --- a/src/Event/ReadinessCheckEvent.php +++ b/src/Event/ReadinessCheckEvent.php @@ -2,7 +2,8 @@ namespace Drupal\automatic_updates\Event; -use Drupal\package_manager\ComposerUtility; +use Drupal\automatic_updates\Updater; +use Drupal\package_manager\Event\StageEvent; /** * Event fired when checking if the site could perform an update. @@ -16,22 +17,37 @@ use Drupal\package_manager\ComposerUtility; * * @see \Drupal\automatic_updates\Validation\ReadinessValidationManager */ -class ReadinessCheckEvent extends UpdateEvent { +class ReadinessCheckEvent extends StageEvent { - use PackagesAwareTrait; + /** + * The desired package versions to update to, keyed by package name. + * + * @var string[] + */ + protected $packageVersions; /** * Constructs a ReadinessCheckEvent object. * - * @param \Drupal\package_manager\ComposerUtility $active_composer - * A Composer utility object for the active directory. + * @param \Drupal\automatic_updates\Updater $updater + * The updater service. * @param string[] $package_versions * (optional) The desired package versions to update to, keyed by package * name. */ - public function __construct(ComposerUtility $active_composer, array $package_versions = []) { - parent::__construct($active_composer); + public function __construct(Updater $updater, array $package_versions = []) { + parent::__construct($updater); $this->packageVersions = $package_versions; } + /** + * Returns the desired package versions to update to. + * + * @return string[] + * The desired package versions to update to, keyed by package name. + */ + public function getPackageVersions(): array { + return $this->packageVersions; + } + } diff --git a/src/Event/UpdateEvent.php b/src/Event/UpdateEvent.php deleted file mode 100644 index aef519aabbbc10334adb618f9c9d8f2db36d0800..0000000000000000000000000000000000000000 --- a/src/Event/UpdateEvent.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php - -namespace Drupal\automatic_updates\Event; - -use Drupal\Component\EventDispatcher\Event; -use Drupal\package_manager\ComposerUtility; -use Drupal\package_manager\ValidationResult; - -/** - * Event fired when a site is updating. - * - * These events allow listeners to validate updates at various points in the - * update process. Listeners to these events should add validation results via - * ::addValidationResult() if necessary. Only error level validation results - * will stop an update from continuing. - */ -abstract class UpdateEvent extends Event { - - /** - * The validation results. - * - * @var \Drupal\package_manager\ValidationResult[] - */ - protected $results = []; - - /** - * The Composer utility object for the active directory. - * - * @var \Drupal\package_manager\ComposerUtility - */ - protected $activeComposer; - - /** - * Constructs a new UpdateEvent object. - * - * @param \Drupal\package_manager\ComposerUtility $active_composer - * A Composer utility object for the active directory. - */ - public function __construct(ComposerUtility $active_composer) { - $this->activeComposer = $active_composer; - } - - /** - * Returns a Composer utility object for the active directory. - * - * @return \Drupal\package_manager\ComposerUtility - * The Composer utility object for the active directory. - */ - public function getActiveComposer(): ComposerUtility { - return $this->activeComposer; - } - - /** - * Adds a validation result. - * - * @param \Drupal\package_manager\ValidationResult $validation_result - * The validation result. - */ - public function addValidationResult(ValidationResult $validation_result): void { - $this->results[] = $validation_result; - } - - /** - * Gets the validation results. - * - * @param int|null $severity - * (optional) The severity for the results to return. Should be one of the - * SystemManager::REQUIREMENT_* constants. - * - * @return \Drupal\package_manager\ValidationResult[] - * The validation results. - */ - public function getResults(?int $severity = NULL): array { - if ($severity !== NULL) { - return array_filter($this->results, function ($result) use ($severity) { - return $result->getSeverity() === $severity; - }); - } - return $this->results; - } - -} diff --git a/src/Exception/UpdateException.php b/src/Exception/UpdateException.php index b9b604ebcd5120e8d9f469c9b0b798e20e15bf2d..55b87639578ed46a4290d9bc941477e21c19cf13 100644 --- a/src/Exception/UpdateException.php +++ b/src/Exception/UpdateException.php @@ -2,39 +2,10 @@ namespace Drupal\automatic_updates\Exception; +use Drupal\package_manager\StageException; + /** * Defines a custom exception for a failure during an update. */ -class UpdateException extends \RuntimeException { - - /** - * The validation results for the exception. - * - * @var \Drupal\package_manager\ValidationResult[] - */ - protected $validationResults; - - /** - * Constructs an UpdateException object. - * - * @param \Drupal\package_manager\ValidationResult[] $validation_results - * The validation results. - * @param string $message - * The exception message. - */ - public function __construct(array $validation_results, string $message) { - parent::__construct($message); - $this->validationResults = $validation_results; - } - - /** - * Gets the validation results for the exception. - * - * @return \Drupal\package_manager\ValidationResult[] - * The validation results. - */ - public function getValidationResults(): array { - return $this->validationResults; - } - +class UpdateException extends StageException { } diff --git a/src/Updater.php b/src/Updater.php index 3a18139534d56e8f980d92adcf393f0526b6259f..4df1e6b946c4c0f5c2717fc24e8f4f0900d272fb 100644 --- a/src/Updater.php +++ b/src/Updater.php @@ -2,13 +2,12 @@ namespace Drupal\automatic_updates; -use Drupal\automatic_updates\Event\PreStartEvent; -use Drupal\automatic_updates\Event\UpdateEvent; use Drupal\automatic_updates\Exception\UpdateException; use Drupal\Core\State\StateInterface; use Drupal\package_manager\ComposerUtility; +use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\Stage; -use Drupal\system\SystemManager; +use Drupal\package_manager\StageException; /** * Defines a service to perform updates. @@ -79,17 +78,33 @@ class Updater extends Stage { $packages[$package] = $project_versions['drupal']; } $stage_key = $this->createActiveStage($packages); - $this->dispatchUpdateEvent(new PreStartEvent($composer, $packages)); $this->create(); return $stage_key; } + /** + * Returns the package versions that will be required during the update. + * + * @return string[] + * The package versions, as a set of Composer constraints where the keys are + * the package names, and the values are the version constraints. + */ + public function getPackageVersions(): array { + $metadata = $this->state->get(static::STATE_KEY, []); + return $metadata['package_versions']; + } + /** * Stages the update. */ public function stage(): void { - $current = $this->state->get(static::STATE_KEY); - $this->require($current['package_versions']); + $metadata = $this->state->get(static::STATE_KEY, []); + + $requirements = []; + foreach ($metadata['package_versions'] as $package => $constraint) { + $requirements[] = "$package:$constraint"; + } + $this->require($requirements); } /** @@ -117,41 +132,25 @@ class Updater extends Stage { * The active update ID. */ private function createActiveStage(array $package_versions): string { - $requirements = []; - foreach ($package_versions as $package_name => $version) { - $requirements[] = "$package_name:$version"; - } - $value = static::STATE_KEY . microtime(); - $this->state->set( - static::STATE_KEY, - [ - 'id' => $value, - 'package_versions' => $requirements, - ] - ); + + $this->state->set(static::STATE_KEY, [ + 'id' => $value, + 'package_versions' => $package_versions, + ]); return $value; } /** - * Dispatches an update event. - * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event - * The update event. - * - * @return \Drupal\automatic_updates\Event\UpdateEvent - * The event object. - * - * @throws \Drupal\automatic_updates\Exception\UpdateException - * If any of the event subscribers adds a validation error. + * {@inheritdoc} */ - public function dispatchUpdateEvent(UpdateEvent $event): UpdateEvent { - $this->eventDispatcher->dispatch($event); - if ($checker_results = $event->getResults(SystemManager::REQUIREMENT_ERROR)) { - throw new UpdateException($checker_results, - "Unable to complete the update because of errors."); + protected function dispatch(StageEvent $event): void { + try { + parent::dispatch($event); + } + catch (StageException $e) { + throw new UpdateException($e->getResults(), $e->getMessage() ?: "Unable to complete the update because of errors.", $e->getCode(), $e); } - return $event; } } diff --git a/src/Validation/ReadinessValidationManager.php b/src/Validation/ReadinessValidationManager.php index 2e3fe7345234646e9a467ab16c666a4d93904875..4dac6438656c6a3dbdc094f846a4ef6b3ea11d84 100644 --- a/src/Validation/ReadinessValidationManager.php +++ b/src/Validation/ReadinessValidationManager.php @@ -3,6 +3,7 @@ namespace Drupal\automatic_updates\Validation; use Drupal\automatic_updates\Event\ReadinessCheckEvent; +use Drupal\automatic_updates\Updater; use Drupal\automatic_updates\UpdateRecommender; use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface; @@ -50,6 +51,13 @@ class ReadinessValidationManager { */ protected $pathLocator; + /** + * The updater service. + * + * @var \Drupal\automatic_updates\Updater + */ + protected $updater; + /** * Constructs a ReadinessValidationManager. * @@ -61,14 +69,17 @@ class ReadinessValidationManager { * The path locator service. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher * The event dispatcher service. + * @param \Drupal\automatic_updates\Updater $updater + * The updater service. * @param int $results_time_to_live * The number of hours to store results. */ - public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, TimeInterface $time, PathLocator $path_locator, EventDispatcherInterface $dispatcher, int $results_time_to_live) { + public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, TimeInterface $time, PathLocator $path_locator, EventDispatcherInterface $dispatcher, Updater $updater, int $results_time_to_live) { $this->keyValueExpirable = $key_value_expirable_factory->get('automatic_updates'); $this->time = $time; $this->pathLocator = $path_locator; $this->eventDispatcher = $dispatcher; + $this->updater = $updater; $this->resultsTimeToLive = $results_time_to_live; } @@ -91,7 +102,7 @@ class ReadinessValidationManager { else { $package_versions = []; } - $event = new ReadinessCheckEvent($composer, $package_versions); + $event = new ReadinessCheckEvent($this->updater, $package_versions); $this->eventDispatcher->dispatch($event); $results = $event->getResults(); $this->keyValueExpirable->setWithExpire( diff --git a/src/Validator/ComposerExecutableValidator.php b/src/Validator/ComposerExecutableValidator.php index 0a3c3a1a4d35a6bc7c6b4ae56ffa1c776ba56a80..3b2c337b91345bcb1bde257c92e129c4f89a938b 100644 --- a/src/Validator/ComposerExecutableValidator.php +++ b/src/Validator/ComposerExecutableValidator.php @@ -3,7 +3,6 @@ namespace Drupal\automatic_updates\Validator; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; use Drupal\package_manager\ValidationResult; use Drupal\Core\Extension\ExtensionVersion; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -50,10 +49,10 @@ class ComposerExecutableValidator implements EventSubscriberInterface, ProcessOu /** * Validates that the Composer executable can be found. * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event + * @param \Drupal\automatic_updates\Event\ReadinessCheckEvent $event * The event object. */ - public function checkForComposerExecutable(UpdateEvent $event): void { + public function checkForComposerExecutable(ReadinessCheckEvent $event): void { try { $this->composer->run(['--version'], $this); } diff --git a/src/Validator/CoreComposerValidator.php b/src/Validator/CoreComposerValidator.php index 95b02b39b32bfe687d6d4f42593612cbb93aa556..26084650968cf2bcb78155c2ea42ce247d3510f2 100644 --- a/src/Validator/CoreComposerValidator.php +++ b/src/Validator/CoreComposerValidator.php @@ -25,7 +25,7 @@ class CoreComposerValidator implements EventSubscriberInterface { // If neither is, then core cannot be updated, which we consider an error // condition. $core_requirements = array_intersect( - $event->getActiveComposer()->getCorePackageNames(), + $event->getStage()->getActiveComposer()->getCorePackageNames(), ['drupal/core', 'drupal/core-recommended'] ); if (empty($core_requirements)) { diff --git a/src/Validator/DiskSpaceValidator.php b/src/Validator/DiskSpaceValidator.php index b782d571cf1940ec8b242f978644cb57fd9baf7a..2675a771bdfea788ed5df8685946652048bbc5d8 100644 --- a/src/Validator/DiskSpaceValidator.php +++ b/src/Validator/DiskSpaceValidator.php @@ -3,7 +3,6 @@ namespace Drupal\automatic_updates\Validator; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; use Drupal\package_manager\ValidationResult; use Drupal\Component\FileSystem\FileSystem; use Drupal\Component\Utility\Bytes; @@ -100,10 +99,10 @@ class DiskSpaceValidator implements EventSubscriberInterface { /** * Checks that there is enough free space to perform automatic updates. * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event - * The update event object. + * @param \Drupal\automatic_updates\Event\ReadinessCheckEvent $event + * The event object. */ - public function checkDiskSpace(UpdateEvent $event): void { + public function checkDiskSpace(ReadinessCheckEvent $event): void { $root_path = $this->pathLocator->getProjectRoot(); $vendor_path = $this->pathLocator->getVendorDirectory(); $messages = []; diff --git a/src/Validator/PendingUpdatesValidator.php b/src/Validator/PendingUpdatesValidator.php index bc891529be06549fe479665be14caf093107f02b..f82c2793b0766288028a32e1e4e137b4c5160032 100644 --- a/src/Validator/PendingUpdatesValidator.php +++ b/src/Validator/PendingUpdatesValidator.php @@ -2,9 +2,9 @@ namespace Drupal\automatic_updates\Validator; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\ValidationResult; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -52,10 +52,10 @@ class PendingUpdatesValidator implements EventSubscriberInterface { /** * Validates that there are no pending database updates. * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event - * The update event. + * @param \Drupal\package_manager\Event\StageEvent $event + * The event object. */ - public function checkPendingUpdates(UpdateEvent $event) { + public function checkPendingUpdates(StageEvent $event): void { require_once $this->appRoot . '/core/includes/install.inc'; require_once $this->appRoot . '/core/includes/update.inc'; @@ -77,7 +77,7 @@ class PendingUpdatesValidator implements EventSubscriberInterface { */ public static function getSubscribedEvents() { return [ - PreStartEvent::class => 'checkPendingUpdates', + PreCreateEvent::class => 'checkPendingUpdates', ReadinessCheckEvent::class => 'checkPendingUpdates', ]; } diff --git a/src/Validator/UpdateVersionValidator.php b/src/Validator/UpdateVersionValidator.php index a4b5eddba16bb2eca2046f33b498d755f6cba638..18941bc1bbe598c2704434df2627ea86f3f87c33 100644 --- a/src/Validator/UpdateVersionValidator.php +++ b/src/Validator/UpdateVersionValidator.php @@ -3,9 +3,10 @@ namespace Drupal\automatic_updates\Validator; use Composer\Semver\Semver; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; +use Drupal\automatic_updates\Updater; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\ValidationResult; use Drupal\Core\Extension\ExtensionVersion; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -47,17 +48,37 @@ class UpdateVersionValidator implements EventSubscriberInterface { /** * Validates that core is not being updated to another minor or major version. * - * @param \Drupal\automatic_updates\Event\PreStartEvent|\Drupal\automatic_updates\Event\ReadinessCheckEvent $event + * @param \Drupal\package_manager\Event\StageEvent $event * The event object. */ - public function checkUpdateVersion(UpdateEvent $event): void { + public function checkUpdateVersion(StageEvent $event): void { + $stage = $event->getStage(); + // We only want to do this check if the stage belongs to Automatic Updates. + if (!$stage instanceof Updater) { + return; + } + + if ($event instanceof ReadinessCheckEvent) { + $package_versions = $event->getPackageVersions(); + // During readiness checks, we might not know the desired package + // versions, which means there's nothing to validate. + if (empty($package_versions)) { + return; + } + } + else { + // If the stage has begun its life cycle, we expect it knows the desired + // package versions. + $package_versions = $stage->getPackageVersions(); + } + $from_version_string = $this->getCoreVersion(); $from_version = ExtensionVersion::createFromVersionString($from_version_string); - $core_package_names = $event->getActiveComposer()->getCorePackageNames(); + $core_package_names = $stage->getActiveComposer()->getCorePackageNames(); // All the core packages will be updated to the same version, so it doesn't // matter which specific package we're looking at. $core_package_name = reset($core_package_names); - $to_version_string = $event->getPackageVersions()[$core_package_name]; + $to_version_string = $package_versions[$core_package_name]; $to_version = ExtensionVersion::createFromVersionString($to_version_string); if (Semver::satisfies($to_version_string, "< $from_version_string")) { $messages[] = $this->t('Update version @to_version is lower than @from_version, downgrading is not supported.', [ @@ -91,21 +112,6 @@ class UpdateVersionValidator implements EventSubscriberInterface { $error = ValidationResult::createError($messages); $event->addValidationResult($error); } - - } - - /** - * Validates readiness check event. - * - * @param \Drupal\automatic_updates\Event\ReadinessCheckEvent $event - * The readiness check event object. - */ - public function checkReadinessUpdateVersion(ReadinessCheckEvent $event): void { - // During readiness checks, we might not know the desired package versions, - // which means there's nothing to validate. - if ($event->getPackageVersions()) { - $this->checkUpdateVersion($event); - } } /** @@ -113,8 +119,8 @@ class UpdateVersionValidator implements EventSubscriberInterface { */ public static function getSubscribedEvents() { return [ - PreStartEvent::class => 'checkUpdateVersion', - ReadinessCheckEvent::class => 'checkReadinessUpdateVersion', + PreCreateEvent::class => 'checkUpdateVersion', + ReadinessCheckEvent::class => 'checkUpdateVersion', ]; } diff --git a/src/Validator/WritableFileSystemValidator.php b/src/Validator/WritableFileSystemValidator.php index 6c786dfa9a4fa632b82d4eda997d2d6058bbb8fb..7f2714d7e9583e946fbd36de1a6915f2b0198756 100644 --- a/src/Validator/WritableFileSystemValidator.php +++ b/src/Validator/WritableFileSystemValidator.php @@ -2,9 +2,9 @@ namespace Drupal\automatic_updates\Validator; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\ValidationResult; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -51,7 +51,7 @@ class WritableFileSystemValidator implements EventSubscriberInterface { /** * Checks that the file system is writable. * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event + * @param \Drupal\package_manager\Event\StageEvent $event * The event object. * * @todo It might make sense to use a more sophisticated method of testing @@ -59,7 +59,7 @@ class WritableFileSystemValidator implements EventSubscriberInterface { * false negatives/positives due to things like SELinux, exotic file * systems, and so forth. */ - public function checkPermissions(UpdateEvent $event): void { + public function checkPermissions(StageEvent $event): void { $messages = []; if (!is_writable($this->appRoot)) { @@ -85,7 +85,7 @@ class WritableFileSystemValidator implements EventSubscriberInterface { public static function getSubscribedEvents() { return [ ReadinessCheckEvent::class => 'checkPermissions', - PreStartEvent::class => 'checkPermissions', + PreCreateEvent::class => 'checkPermissions', ]; } diff --git a/tests/modules/automatic_updates_test/src/ReadinessChecker/TestChecker1.php b/tests/modules/automatic_updates_test/src/ReadinessChecker/TestChecker1.php index 3a7efd8032b94b30c4f8d0ad894702de1272ed59..c04f373d6cff934ef2605edaa0be7d4960e0304a 100644 --- a/tests/modules/automatic_updates_test/src/ReadinessChecker/TestChecker1.php +++ b/tests/modules/automatic_updates_test/src/ReadinessChecker/TestChecker1.php @@ -2,11 +2,10 @@ namespace Drupal\automatic_updates_test\ReadinessChecker; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent; -use Drupal\automatic_updates\Event\UpdateEvent; use Drupal\Core\State\StateInterface; use Drupal\package_manager\Event\PreApplyEvent; +use Drupal\package_manager\Event\PreCreateEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -65,11 +64,9 @@ class TestChecker1 implements EventSubscriberInterface { * * @param object $event * The update event. - * @param string $state_key - * The state key. */ - protected function addResults(object $event, string $state_key): void { - $results = $this->state->get($state_key, []); + public function addResults(object $event): void { + $results = $this->state->get(static::STATE_KEY . '.' . get_class($event), []); if ($results instanceof \Throwable) { throw $results; } @@ -78,44 +75,14 @@ class TestChecker1 implements EventSubscriberInterface { } } - /** - * Adds test results for the readiness check event. - * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event - * The update event. - */ - public function runPreChecks(UpdateEvent $event): void { - $this->addResults($event, static::STATE_KEY . "." . ReadinessCheckEvent::class); - } - - /** - * Adds test results for the pre-apply event. - * - * @param \Drupal\package_manager\Event\PreApplyEvent $event - * The update event. - */ - public function runPreApplyChecks(PreApplyEvent $event): void { - $this->addResults($event, static::STATE_KEY . "." . PreApplyEvent::class); - } - - /** - * Adds test results for the pre-start event. - * - * @param \Drupal\automatic_updates\Event\UpdateEvent $event - * The update event. - */ - public function runStartChecks(UpdateEvent $event): void { - $this->addResults($event, static::STATE_KEY . "." . PreStartEvent::class); - } - /** * {@inheritdoc} */ public static function getSubscribedEvents() { $priority = defined('AUTOMATIC_UPDATES_TEST_SET_PRIORITY') ? AUTOMATIC_UPDATES_TEST_SET_PRIORITY : 5; - $events[ReadinessCheckEvent::class][] = ['runPreChecks', $priority]; - $events[PreStartEvent::class][] = ['runStartChecks', $priority]; - $events[PreApplyEvent::class][] = ['runPreApplyChecks', $priority]; + $events[ReadinessCheckEvent::class][] = ['addResults', $priority]; + $events[PreCreateEvent::class][] = ['addResults', $priority]; + $events[PreApplyEvent::class][] = ['addResults', $priority]; return $events; } diff --git a/tests/modules/automatic_updates_test/src/TestController.php b/tests/modules/automatic_updates_test/src/TestController.php index 690edc978630c9c9631164ca9ec67d54a0c6b591..69308a467d37b439fdaaa251f3d7fb120e249417 100644 --- a/tests/modules/automatic_updates_test/src/TestController.php +++ b/tests/modules/automatic_updates_test/src/TestController.php @@ -42,7 +42,7 @@ class TestController extends ControllerBase { } catch (UpdateException $e) { $messages = []; - foreach ($e->getValidationResults() as $result) { + foreach ($e->getResults() as $result) { if ($summary = $result->getSummary()) { $messages[] = $summary; } diff --git a/tests/modules/automatic_updates_test2/src/ReadinessChecker/TestChecker2.php b/tests/modules/automatic_updates_test2/src/ReadinessChecker/TestChecker2.php index dfad950052b9b62f66a6fcd41c92723ee5899686..06b0bd14c0b5826ab60d6a773d45c513bd128fd7 100644 --- a/tests/modules/automatic_updates_test2/src/ReadinessChecker/TestChecker2.php +++ b/tests/modules/automatic_updates_test2/src/ReadinessChecker/TestChecker2.php @@ -2,9 +2,9 @@ namespace Drupal\automatic_updates_test2\ReadinessChecker; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent; use Drupal\automatic_updates_test\ReadinessChecker\TestChecker1; +use Drupal\package_manager\Event\PreCreateEvent; /** * A test readiness checker. @@ -14,8 +14,8 @@ class TestChecker2 extends TestChecker1 { protected const STATE_KEY = 'automatic_updates_test2.checker_results'; public static function getSubscribedEvents() { - $events[ReadinessCheckEvent::class][] = ['runPreChecks', 4]; - $events[PreStartEvent::class][] = ['runStartChecks', 4]; + $events[ReadinessCheckEvent::class][] = ['addResults', 4]; + $events[PreCreateEvent::class][] = ['addResults', 4]; return $events; } diff --git a/tests/src/Functional/UpdaterFormTest.php b/tests/src/Functional/UpdaterFormTest.php index da3166bfe8f63c1dc87b658f8e195d48b62e4eb9..c2cdefcde60ee111f1082b43468ad3d20a974273 100644 --- a/tests/src/Functional/UpdaterFormTest.php +++ b/tests/src/Functional/UpdaterFormTest.php @@ -2,8 +2,8 @@ namespace Drupal\Tests\automatic_updates\Functional; -use Drupal\automatic_updates\Event\PreStartEvent; use Drupal\automatic_updates\Exception\UpdateException; +use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\ValidationResult; use Drupal\automatic_updates_test\ReadinessChecker\TestChecker1; use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait; @@ -177,7 +177,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { // Repackage the validation error as an exception, so we can test what // happens if a validator throws once the update has started. $error = new UpdateException($expected_results, 'The update exploded.'); - TestChecker1::setTestResult($error, PreStartEvent::class); + TestChecker1::setTestResult($error, PreCreateEvent::class); $session->reload(); $assert_session->pageTextNotContains(static::$errorsExplanation); $assert_session->pageTextNotContains(static::$warningsExplanation); @@ -193,7 +193,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { // If a validator flags an error, but doesn't throw, the update should still // be halted. - TestChecker1::setTestResult($expected_results, PreStartEvent::class); + TestChecker1::setTestResult($expected_results, PreCreateEvent::class); $this->deleteStagedUpdate(); $page->pressButton('Update'); $this->checkForMetaRefresh(); @@ -206,7 +206,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { // If a validator flags a warning, but doesn't throw, the update should // continue. $expected_results = $this->testResults['checker_1']['1 warning']; - TestChecker1::setTestResult($expected_results, PreStartEvent::class); + TestChecker1::setTestResult($expected_results, PreCreateEvent::class); $session->reload(); $this->deleteStagedUpdate(); $page->pressButton('Update'); diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdaterTest.php index 6de07f4bbed81ce28a48c2387ed3d8141ddd02d3..d65f5e21db4e5b9cb0b4afa6d5ef3a59e44ce8b9 100644 --- a/tests/src/Kernel/CronUpdaterTest.php +++ b/tests/src/Kernel/CronUpdaterTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\automatic_updates\Kernel; use Drupal\automatic_updates\CronUpdater; use Drupal\Core\Form\FormState; +use Drupal\package_manager\ComposerUtility; use Drupal\update\UpdateSettingsForm; /** @@ -100,6 +101,10 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase { // depending on configuration. $will_update = (int) $will_update; $updater = $this->prophesize('\Drupal\automatic_updates\Updater'); + + $composer = ComposerUtility::createForDirectory(__DIR__ . '/../../fixtures/fake-site'); + $updater->getActiveComposer()->willReturn($composer); + $updater->begin(['drupal' => '9.8.1'])->shouldBeCalledTimes($will_update); $updater->stage()->shouldBeCalledTimes($will_update); $updater->commit()->shouldBeCalledTimes($will_update);