From bf697bb97796cfc5c73c05072e454ed4fd402eb6 Mon Sep 17 00:00:00 2001 From: "omkar.podey" <omkar.podey@3685158.no-reply.drupal.org> Date: Mon, 5 Dec 2022 04:10:41 +0000 Subject: [PATCH] Issue #3309602 by omkar.podey, tedbow, Wim Leers, phenaproxima, Idoni, TravisCarden: Error: Composer could not find the config file --- package_manager/package_manager.services.yml | 7 ++ .../Validator/ComposerJsonExistsValidator.php | 73 +++++++++++++++++++ .../ComposerJsonExistsValidatorTest.php | 42 +++++++++++ .../EnvironmentSupportValidatorTest.php | 47 ++++-------- 4 files changed, 136 insertions(+), 33 deletions(-) create mode 100644 package_manager/src/Validator/ComposerJsonExistsValidator.php create mode 100644 package_manager/tests/src/Kernel/ComposerJsonExistsValidatorTest.php diff --git a/package_manager/package_manager.services.yml b/package_manager/package_manager.services.yml index 410e3ccce8..48f9775b9f 100644 --- a/package_manager/package_manager.services.yml +++ b/package_manager/package_manager.services.yml @@ -141,6 +141,13 @@ services: - '@extension.list.theme' tags: - { name: event_subscriber } + package_manager.validator.composer_json_exists: + class: Drupal\package_manager\Validator\ComposerJsonExistsValidator + arguments: + - '@package_manager.path_locator' + - '@string_translation' + tags: + - { name: event_subscriber } package_manager.test_site_excluder: class: Drupal\package_manager\PathExcluder\TestSiteExcluder arguments: diff --git a/package_manager/src/Validator/ComposerJsonExistsValidator.php b/package_manager/src/Validator/ComposerJsonExistsValidator.php new file mode 100644 index 0000000000..9542c70004 --- /dev/null +++ b/package_manager/src/Validator/ComposerJsonExistsValidator.php @@ -0,0 +1,73 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\package_manager\Validator; + +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\PreOperationStageEvent; +use Drupal\package_manager\Event\StatusCheckEvent; +use Drupal\package_manager\PathLocator; + +/** + * Validates that the active composer.json file exists. + * + * @internal + * This is an internal part of Package Manager and may be changed or removed + * at any time without warning. External code should not interact with this + * class. + */ +final class ComposerJsonExistsValidator implements EventSubscriberInterface { + + use StringTranslationTrait; + + /** + * The path locator service. + * + * @var \Drupal\package_manager\PathLocator + */ + protected $pathLocator; + + /** + * Constructs a ComposerJsonExistsValidator object. + * + * @param \Drupal\package_manager\PathLocator $path_locator + * The path locator service. + * @param \Drupal\Core\StringTranslation\TranslationInterface $translation + * The string translation service. + */ + public function __construct(PathLocator $path_locator, TranslationInterface $translation) { + $this->pathLocator = $path_locator; + $this->setStringTranslation($translation); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array { + // Set priority to 190 which puts it just after EnvironmentSupportValidator. + // @see \Drupal\package_manager\Validator\EnvironmentSupportValidator + return [ + PreCreateEvent::class => ['validateComposerJson', 190], + StatusCheckEvent::class => ['validateComposerJson', 190], + ]; + } + + /** + * Validates that the active composer.json file exists. + * + * @param \Drupal\package_manager\Event\PreOperationStageEvent $event + * The event. + */ + public function validateComposerJson(PreOperationStageEvent $event): void { + $project_root = $this->pathLocator->getProjectRoot(); + if (!file_exists($project_root . '/composer.json')) { + $event->addError([$this->t('No composer.json file can be found at @project_root', ['@project_root' => $project_root])]); + $event->stopPropagation(); + } + } + +} diff --git a/package_manager/tests/src/Kernel/ComposerJsonExistsValidatorTest.php b/package_manager/tests/src/Kernel/ComposerJsonExistsValidatorTest.php new file mode 100644 index 0000000000..0bb39c908c --- /dev/null +++ b/package_manager/tests/src/Kernel/ComposerJsonExistsValidatorTest.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\Tests\package_manager\Kernel; + +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\StatusCheckEvent; +use Drupal\package_manager\ValidationResult; + +/** + * @covers \Drupal\package_manager\Validator\ComposerJsonExistsValidator + * @group package_manager + */ +class ComposerJsonExistsValidatorTest extends PackageManagerKernelTestBase { + + /** + * Tests validation when the active composer.json is not present. + */ + public function testComposerRequirement(): void { + unlink($this->container->get('package_manager.path_locator') + ->getProjectRoot() . '/composer.json'); + $result = ValidationResult::createError([ + 'No composer.json file can be found at vfs://root/active', + ]); + foreach ([PreCreateEvent::class, StatusCheckEvent::class] as $event_class) { + $this->container->get('event_dispatcher')->addListener( + $event_class, + function () use ($event_class): void { + $this->fail('Event propagation should have been stopped during ' . $event_class . '.'); + }, + // Execute this listener immediately after the tested validator, which + // uses priority 190. This ensures informative test failures. + // @see \Drupal\package_manager\Validator\ComposerJsonExistsValidator::getSubscribedEvents() + 189 + ); + } + $this->assertStatusCheckResults([$result]); + $this->assertResults([$result], PreCreateEvent::class); + } + +} diff --git a/package_manager/tests/src/Kernel/EnvironmentSupportValidatorTest.php b/package_manager/tests/src/Kernel/EnvironmentSupportValidatorTest.php index 9ad3aecf5a..7ebb78ab26 100644 --- a/package_manager/tests/src/Kernel/EnvironmentSupportValidatorTest.php +++ b/package_manager/tests/src/Kernel/EnvironmentSupportValidatorTest.php @@ -3,47 +3,16 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\package_manager\Event\PreCreateEvent; -use Drupal\package_manager\Event\PreOperationStageEvent; +use Drupal\package_manager\Event\StatusCheckEvent; use Drupal\package_manager\ValidationResult; use Drupal\package_manager\Validator\EnvironmentSupportValidator; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * @covers \Drupal\package_manager\Validator\EnvironmentSupportValidator * @group package_manager * @internal */ -class EnvironmentSupportValidatorTest extends PackageManagerKernelTestBase implements EventSubscriberInterface { - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - parent::setUp(); - $this->container->get('event_dispatcher')->addSubscriber($this); - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents(): array { - $map = function (): string { - return 'assertValidationStopped'; - }; - return array_map($map, EnvironmentSupportValidator::getSubscribedEvents()); - } - - /** - * Ensures that the validator stops any further validation. - * - * @param \Drupal\package_manager\Event\PreOperationStageEvent $event - * The event object. - */ - public function assertValidationStopped(PreOperationStageEvent $event): void { - if ($event->getResults()) { - $this->assertTrue($event->isPropagationStopped()); - } - } +class EnvironmentSupportValidatorTest extends PackageManagerKernelTestBase { /** * Tests handling of an invalid URL in the environment support variable. @@ -54,6 +23,18 @@ class EnvironmentSupportValidatorTest extends PackageManagerKernelTestBase imple $result = ValidationResult::createError([ 'Package Manager is not supported by your environment.', ]); + foreach ([PreCreateEvent::class, StatusCheckEvent::class] as $event_class) { + $this->container->get('event_dispatcher')->addListener( + $event_class, + function () use ($event_class): void { + $this->fail('Event propagation should have been stopped during ' . $event_class . '.'); + }, + // Execute this listener immediately after the tested validator, which + // uses priority 200. This ensures informative test failures. + // @see \Drupal\package_manager\Validator\EnvironmentSupportValidator::getSubscribedEvents() + 199 + ); + } $this->assertStatusCheckResults([$result]); $this->assertResults([$result], PreCreateEvent::class); } -- GitLab