diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index b8aaad354bf61cdc2f31c9a5e0aa334b095462f3..277b385801f40d6cae87afbbff63faaa10477e0a 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -91,8 +91,7 @@ services: - { name: event_subscriber } automatic_updates.validator.version_policy: class: Drupal\automatic_updates\Validator\VersionPolicyValidator - arguments: - - '@class_resolver' + autowire: true tags: - { name: event_subscriber } automatic_updates.config_subscriber: diff --git a/src/Validator/VersionPolicyValidator.php b/src/Validator/VersionPolicyValidator.php index 63b707c7f16dce2b9204df57bca1a125555defe1..bbba0577f78daa9a7dd6730d0e0261d09609903e 100644 --- a/src/Validator/VersionPolicyValidator.php +++ b/src/Validator/VersionPolicyValidator.php @@ -5,7 +5,9 @@ declare(strict_types = 1); namespace Drupal\automatic_updates\Validator; use Drupal\automatic_updates\CronUpdater; +use Drupal\package_manager\ComposerInspector; use Drupal\package_manager\Event\StatusCheckEvent; +use Drupal\package_manager\PathLocator; use Drupal\package_manager\ProjectInfo; use Drupal\automatic_updates\Updater; use Drupal\automatic_updates\Validator\VersionPolicy\ForbidDowngrade; @@ -41,9 +43,16 @@ final class VersionPolicyValidator implements EventSubscriberInterface { * * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $classResolver * The class resolver service. + * @param \Drupal\package_manager\PathLocator $pathLocator + * The path locator service. + * @param \Drupal\package_manager\ComposerInspector $composerInspector + * The Composer inspector service. */ - public function __construct(private ClassResolverInterface $classResolver) { - } + public function __construct( + private ClassResolverInterface $classResolver, + private PathLocator $pathLocator, + private ComposerInspector $composerInspector, + ) {} /** * Validates a target version of Drupal core. @@ -188,8 +197,7 @@ final class VersionPolicyValidator implements EventSubscriberInterface { $unknown_target = new \LogicException('The target version of Drupal core could not be determined.'); if (isset($package_versions)) { - // Get the first non-dev core package. - $core_package_name = key(array_diff_key($updater->getActiveComposer()->getCorePackages(), ['drupal/core-dev' => ''])); + $core_package_name = $this->getCorePackageName(); if ($core_package_name && array_key_exists($core_package_name, $package_versions)) { return $package_versions[$core_package_name]; @@ -255,4 +263,26 @@ final class VersionPolicyValidator implements EventSubscriberInterface { ]; } + /** + * Returns the name of the first known installed core package. + * + * This does NOT include dev packages like `drupal/core-dev` and + * `drupal/core-dev-pinned`. + * + * @return string|bool + * The name of the first known installed core package (most likely + * `drupal/core` or `drupal/core-recommended`), or FALSE if none is found. + */ + private function getCorePackageName(): string|bool { + $project_root = $this->pathLocator->getProjectRoot(); + + $core_packages = $this->composerInspector->getInstalledPackagesList($project_root) + ->getCorePackages() + ->getArrayCopy(); + unset($core_packages['drupal/core-dev']); + unset($core_packages['drupal/core-dev-pinned']); + + return key($core_packages) ?? FALSE; + } + } diff --git a/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php b/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php index f84181b2e8b7655cd658830ac3f4a48a8808b100..8b9e3d23ccce36146bc67ae67e1ee6cca9722489 100644 --- a/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php +++ b/tests/src/Kernel/StatusCheck/VersionPolicyValidatorTest.php @@ -5,6 +5,7 @@ declare(strict_types = 1); namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck; use Drupal\automatic_updates\CronUpdater; +use Drupal\fixture_manipulator\ActiveFixtureManipulator; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Exception\StageEventException; use Drupal\package_manager\Exception\StageException; @@ -377,18 +378,17 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase { * just in case it does, we need to be sure that it's an error condition. */ public function testNoCorePackagesInstalled(): void { - // Clear the list of packages in the active directory's installed.json. $listener = function (PreCreateEvent $event): void { // We should have staged package versions. /** @var \Drupal\automatic_updates\Updater $updater */ $updater = $event->stage; $this->assertNotEmpty($updater->getPackageVersions()); - - $active_dir = $this->container->get('package_manager.path_locator') - ->getProjectRoot(); - $installed = $active_dir . '/vendor/composer/installed.json'; - $this->assertFileIsWritable($installed); - file_put_contents($installed, '{"packages": []}'); + // Remove all core packages in the active directory. + (new ActiveFixtureManipulator()) + ->removePackage('drupal/core-recommended') + ->removePackage('drupal/core') + ->removePackage('drupal/core-dev', TRUE) + ->commitChanges(); }; $this->assertTargetVersionNotDiscoverable($listener); }