diff --git a/composer.json b/composer.json index cc37fe2619..338e28bc92 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "chat": "https://www.drupal.org/node/314178" }, "require": { - "composer/installers": "^1.0.24", + "composer/installers": "^1.9", "drupal/core": "self.version", "drupal/core-project-message": "self.version", "drupal/core-vendor-hardening": "self.version" diff --git a/composer.lock b/composer.lock index 3dc5459a1c..645114adb5 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": "966c0ed90c2996cad45b441c58d01aa2", + "content-hash": "bf3f5b1c0d2f35255e03825589a1ee4f", "packages": [ { "name": "asm89/stack-cors", diff --git a/composer/Plugin/ProjectMessage/MessagePlugin.php b/composer/Plugin/ProjectMessage/MessagePlugin.php index 8a5333d8f1..9e57e6a363 100644 --- a/composer/Plugin/ProjectMessage/MessagePlugin.php +++ b/composer/Plugin/ProjectMessage/MessagePlugin.php @@ -45,6 +45,18 @@ public function activate(Composer $composer, IOInterface $io) { $this->io = $io; } + /** + * {@inheritdoc} + */ + public function deactivate(Composer $composer, IOInterface $io) { + } + + /** + * {@inheritdoc} + */ + public function uninstall(Composer $composer, IOInterface $io) { + } + /** * {@inheritdoc} */ diff --git a/composer/Plugin/ProjectMessage/composer.json b/composer/Plugin/ProjectMessage/composer.json index 96ade5102c..3741b31600 100644 --- a/composer/Plugin/ProjectMessage/composer.json +++ b/composer/Plugin/ProjectMessage/composer.json @@ -15,6 +15,6 @@ }, "require": { "php": ">=7.3.0", - "composer-plugin-api": "^1.1" + "composer-plugin-api": "^1.1 || ^2" } } diff --git a/composer/Plugin/Scaffold/AllowedPackages.php b/composer/Plugin/Scaffold/AllowedPackages.php index 9b28368bbd..481492f009 100644 --- a/composer/Plugin/Scaffold/AllowedPackages.php +++ b/composer/Plugin/Scaffold/AllowedPackages.php @@ -3,6 +3,7 @@ namespace Drupal\Composer\Plugin\Scaffold; use Composer\Composer; +use Composer\DependencyResolver\Operation\OperationInterface; use Composer\Installer\PackageEvent; use Composer\IO\IOInterface; use Composer\Package\PackageInterface; @@ -96,8 +97,12 @@ public function getAllowedPackages() { */ public function event(PackageEvent $event) { $operation = $event->getOperation(); - // Determine the package. - $package = $operation->getJobType() == 'update' ? $operation->getTargetPackage() : $operation->getPackage(); + // Determine the package. Later, in evaluateNewPackages(), we will report + // which of the newly-installed packages have scaffold operations, and + // whether or not they are allowed to scaffold by the allowed-packages + // option in the root-level composer.json file. + $operationType = $this->getOperationType($operation); + $package = $operationType === 'update' ? $operation->getTargetPackage() : $operation->getPackage(); if (ScaffoldOptions::hasOptions($package->getExtra())) { $this->newPackages[$package->getName()] = $package; } @@ -176,6 +181,26 @@ protected function evaluateNewPackages(array $allowed_packages) { return $allowed_packages; } + /** + * Determine the type of the provided operation. + * + * Adjusts API used for Composer 1 or Composer 2. + * + * @param \Composer\DependencyResolver\Operation\OperationInterface $operation + * The operation object. + * + * @return string + * The operation type. + */ + protected function getOperationType(OperationInterface $operation) { + // Use Composer 2 method. + if (method_exists($operation, 'getOperationType')) { + return $operation->getOperationType(); + } + // Fallback to Composer 1 method. + return $operation->getJobType(); + } + /** * Retrieves a package from the current composer process. * diff --git a/composer/Plugin/Scaffold/Plugin.php b/composer/Plugin/Scaffold/Plugin.php index a1252cfac1..9a694ec349 100644 --- a/composer/Plugin/Scaffold/Plugin.php +++ b/composer/Plugin/Scaffold/Plugin.php @@ -60,6 +60,18 @@ public function activate(Composer $composer, IOInterface $io) { $this->requireWasCalled = FALSE; } + /** + * {@inheritdoc} + */ + public function deactivate(Composer $composer, IOInterface $io) { + } + + /** + * {@inheritdoc} + */ + public function uninstall(Composer $composer, IOInterface $io) { + } + /** * {@inheritdoc} */ diff --git a/composer/Plugin/Scaffold/composer.json b/composer/Plugin/Scaffold/composer.json index 5cbb4ad79b..ca9d6d7b48 100644 --- a/composer/Plugin/Scaffold/composer.json +++ b/composer/Plugin/Scaffold/composer.json @@ -6,7 +6,7 @@ "homepage": "https://www.drupal.org/project/drupal", "license": "GPL-2.0-or-later", "require": { - "composer-plugin-api": "^1.0.0", + "composer-plugin-api": "^1 || ^2", "php": ">=7.3.0" }, "conflict": { diff --git a/composer/Plugin/VendorHardening/VendorHardeningPlugin.php b/composer/Plugin/VendorHardening/VendorHardeningPlugin.php index c8e6182e11..2cd7bdec52 100644 --- a/composer/Plugin/VendorHardening/VendorHardeningPlugin.php +++ b/composer/Plugin/VendorHardening/VendorHardeningPlugin.php @@ -65,6 +65,18 @@ public function activate(Composer $composer, IOInterface $io) { $this->config = new Config($this->composer->getPackage()); } + /** + * {@inheritdoc} + */ + public function deactivate(Composer $composer, IOInterface $io) { + } + + /** + * {@inheritdoc} + */ + public function uninstall(Composer $composer, IOInterface $io) { + } + /** * {@inheritdoc} */ diff --git a/composer/Plugin/VendorHardening/composer.json b/composer/Plugin/VendorHardening/composer.json index 4ed1adedd0..5f78bc6abd 100644 --- a/composer/Plugin/VendorHardening/composer.json +++ b/composer/Plugin/VendorHardening/composer.json @@ -15,6 +15,6 @@ }, "require": { "php": ">=7.3.0", - "composer-plugin-api": "^1.1" + "composer-plugin-api": "^1.1 || ^2" } } diff --git a/composer/Template/LegacyProject/composer.json b/composer/Template/LegacyProject/composer.json index c7f532dfe6..9162033006 100644 --- a/composer/Template/LegacyProject/composer.json +++ b/composer/Template/LegacyProject/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "composer/installers": "^1.2", + "composer/installers": "^1.9", "drupal/core-composer-scaffold": "^9", "drupal/core-project-message": "^9", "drupal/core-recommended": "^9", diff --git a/composer/Template/RecommendedProject/composer.json b/composer/Template/RecommendedProject/composer.json index 56aa5cdb2c..9de50df252 100644 --- a/composer/Template/RecommendedProject/composer.json +++ b/composer/Template/RecommendedProject/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "composer/installers": "^1.2", + "composer/installers": "^1.9", "drupal/core-composer-scaffold": "^9", "drupal/core-project-message": "^9", "drupal/core-recommended": "^9" diff --git a/core/drupalci.yml b/core/drupalci.yml index 8cc5f1d488..8fb2b41290 100644 --- a/core/drupalci.yml +++ b/core/drupalci.yml @@ -55,3 +55,9 @@ build: # Run nightwatch testing. # @see https://www.drupal.org/project/drupal/issues/2869825 nightwatchjs: + # Re-run Composer plugin tests after installing Composer 2 + container_command.composer-upgrade: + commands: + - "sudo composer self-update --snapshot" + - "./vendor/bin/phpunit -c core --group VendorHardening,ProjectMessage,Scaffold" + halt-on-fail: true diff --git a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php index e9bf830116..641dba464b 100644 --- a/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php +++ b/core/tests/Drupal/BuildTests/Composer/Template/ComposerProjectTemplatesTest.php @@ -105,6 +105,11 @@ public function testVerifyTemplateTestProviderIsAccurate() { * @dataProvider provideTemplateCreateProject */ public function testTemplateCreateProject($project, $package_dir, $docroot_dir) { + $composerVersionLine = exec('composer --version'); + if (strpos($composerVersionLine, 'Composer version 2') !== FALSE) { + $this->markTestSkipped('We cannot run the template create project test with Composer 2 until we have a stable version of composer/semver 2.x. The create project test installs drupal/core-recommended and the Drupal Composer plugins from Packagist, so these must also be compatible with Composer 2.x in order for this test to work.'); + } + $this->copyCodebase(); // Get the Drupal core version branch. For instance, this should be diff --git a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php index 3f6eeedd45..99eb705b28 100644 --- a/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php +++ b/core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ScaffoldUpgradeTest.php @@ -44,6 +44,10 @@ protected function setUp(): void { * Test upgrading the Composer Scaffold plugin. */ public function testScaffoldUpgrade() { + $composerVersionLine = exec('composer --version'); + if (strpos($composerVersionLine, 'Composer version 2') !== FALSE) { + $this->markTestSkipped('We cannot run the scaffold upgrade test with Composer 2 until we have a stable version of drupal/core-composer-scaffold to start from that we can install with Composer 2.x.'); + } $this->fixturesDir = $this->fixtures->tmpDir($this->getName()); $replacements = ['SYMLINK' => 'false', 'PROJECT_ROOT' => $this->fixtures->projectRoot()]; $this->fixtures->cloneFixtureProjects($this->fixturesDir, $replacements);