From ad0162361d4241b75555b7cf637a52b34d9c47e7 Mon Sep 17 00:00:00 2001 From: Ted Bowman <41201-tedbow@users.noreply.drupalcode.org> Date: Mon, 6 Feb 2023 20:46:06 +0000 Subject: [PATCH] Issue #3335908 by tedbow, Wim Leers: The 'fake_site' fixture cannot be using with `composer show` because the packages are not installed --- composer.json | 8 +- .../tests/fixtures/fake_site/composer.json | 37 +++++++- .../tests/fixtures/fake_site/composer.lock | 77 ++++++++++++++- .../fake_site/vendor/composer/installed.json | 95 ++++++++++++++----- .../fake_site/vendor/composer/installed.php | 52 +++++++--- .../vendor/drupal/core-dev/composer.json | 1 + .../drupal/core-recommended/composer.json | 1 + .../vendor/drupal/core/composer.json | 19 ++++ .../path_repos/drupal--core-dev/composer.json | 1 + .../drupal--core-recommended/composer.json | 1 + .../path_repos/drupal--core/composer.json | 19 ++++ .../src/FixtureManipulator.php | 7 ++ .../tests/src/Kernel/FakeSiteFixtureTest.php | 16 ++++ .../src/Kernel/FixtureManipulatorTest.php | 61 +++++++----- scripts/src/ComposerFixtureCreator.php | 89 +++++++++++++++++ scripts/src/Converter.php | 2 +- src/Validator/VersionPolicyValidator.php | 3 +- 17 files changed, 424 insertions(+), 65 deletions(-) create mode 100644 package_manager/tests/fixtures/fake_site/vendor/drupal/core-dev/composer.json create mode 100644 package_manager/tests/fixtures/fake_site/vendor/drupal/core-recommended/composer.json create mode 100644 package_manager/tests/fixtures/fake_site/vendor/drupal/core/composer.json create mode 100644 package_manager/tests/fixtures/path_repos/drupal--core-dev/composer.json create mode 100644 package_manager/tests/fixtures/path_repos/drupal--core-recommended/composer.json create mode 100644 package_manager/tests/fixtures/path_repos/drupal--core/composer.json create mode 100644 scripts/src/ComposerFixtureCreator.php diff --git a/composer.json b/composer.json index 981d23d640..7e1ac02772 100644 --- a/composer.json +++ b/composer.json @@ -32,20 +32,22 @@ "Composer\\Config::disableProcessTimeout", "scripts/phpunit.sh" ], - "core-convert": "Drupal\\automatic_updates\\CoreCovert\\Converter::doConvert" + "core-convert": "Drupal\\automatic_updates\\Development\\Converter::doConvert", + "create-site-fixture": "\\Drupal\\automatic_updates\\Development\\ComposerFixtureCreator::createFixture" }, "scripts-descriptions": { "phpcbf": "Automatically fixes standards violations where possible.", "phpcs": "Checks code for standards compliance.", "test": "Runs PHPUnit tests.", - "core-convert": "Converts this module to a core merge request. Excepts 2 arguments. 1) The core clone directory. 2) The core merge request branch." + "core-convert": "Converts this module to a core merge request. Excepts 2 arguments. 1) The core clone directory. 2) The core merge request branch.", + "create-site-fixture": "Recreates the 'fake_site' fixture needed for testing" }, "require-dev": { "colinodell/psr-testlogger": "^1" }, "autoload": { "psr-4": { - "Drupal\\automatic_updates\\CoreCovert\\": "scripts/src" + "Drupal\\automatic_updates\\Development\\": "scripts/src" } } } diff --git a/package_manager/tests/fixtures/fake_site/composer.json b/package_manager/tests/fixtures/fake_site/composer.json index 300c62e8d5..17e40a3ec4 100644 --- a/package_manager/tests/fixtures/fake_site/composer.json +++ b/package_manager/tests/fixtures/fake_site/composer.json @@ -1,6 +1,8 @@ { + "version": "1.2.4", "require": { - "drupal/core-recommended": "9.8.0" + "drupal/core-recommended": "9.8.0", + "drupal/core": "9.8.0" }, "require-dev": { "drupal/core-dev": "^9" @@ -16,5 +18,38 @@ "bar": 134, "foo-bar": null } + }, + "repositories": { + "packagist.org": false, + "drupal/core-recommended": { + "type": "path", + "version": "9.8.0", + "url": "../path_repos/drupal--core-recommended", + "options": { + "symlink": false + } + }, + "drupal/core-dev": { + "type": "path", + "version": "9.8.0", + "url": "../path_repos/drupal--core-dev", + "options": { + "symlink": false + } + }, + "drupal/core": { + "type": "path", + "version": "9.8.0", + "url": "../path_repos/drupal--core", + "options": { + "symlink": false + } + } + }, + "minimum-stability": "stable", + "config": { + "allow-plugins": { + "drupal/core-composer-scaffold": false + } } } diff --git a/package_manager/tests/fixtures/fake_site/composer.lock b/package_manager/tests/fixtures/fake_site/composer.lock index 0967ef424b..06c5112224 100644 --- a/package_manager/tests/fixtures/fake_site/composer.lock +++ b/package_manager/tests/fixtures/fake_site/composer.lock @@ -1 +1,76 @@ -{} +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "e9b347834f96b988de85d370a723d3bf", + "packages": [ + { + "name": "drupal/core", + "version": "9.8.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core", + "reference": "5aeab06c3087477e20e617328f2fa9f3ed18373d" + }, + "type": "drupal-core", + "extra": { + "_readme": [ + "The 'drupal-scaffold' section below is needed because 'Drupal\\automatic_updates\\Validator\\ScaffoldFilePermissionsValidator'", + "uses this section to determine which files to check. The actual composer.json file for drupal/core will have more files listed", + "but this limited list is used in '\\Drupal\\Tests\\automatic_updates\\Kernel\\StatusCheck\\ScaffoldFilePermissionsValidatorTest'", + "to ensure the section is source of the file list." + ], + "drupal-scaffold": { + "file-mapping": { + "[web-root]/sites/default/default.settings.php": "", + "[web-root]/sites/default/default.services.yml": "" + } + } + }, + "transport-options": { + "symlink": false, + "relative": true + } + }, + { + "name": "drupal/core-recommended", + "version": "9.8.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core-recommended", + "reference": "c9babad9851edc2b7b4b43c778bc30db09f14946" + }, + "type": "project", + "transport-options": { + "symlink": false, + "relative": true + } + } + ], + "packages-dev": [ + { + "name": "drupal/core-dev", + "version": "9.8.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core-dev", + "reference": "6a8d7df3a5650a5d3bce6e478114064b176f7104" + }, + "type": "package", + "transport-options": { + "symlink": false, + "relative": true + } + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json index 59e05ee10a..74ac9f6922 100644 --- a/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json +++ b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json @@ -1,28 +1,73 @@ { - "packages": [ - { - "name": "drupal/core", - "version": "9.8.0", - "type": "drupal-core", - "extra": { - "drupal-scaffold": { - "file-mapping": { - "[web-root]/sites/default/default.settings.php": "", - "[web-root]/sites/default/default.services.yml": "" - } + "packages": [ + { + "name": "drupal/core", + "version": "9.8.0", + "version_normalized": "9.8.0.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core", + "reference": "5aeab06c3087477e20e617328f2fa9f3ed18373d" + }, + "type": "drupal-core", + "extra": { + "_readme": [ + "The 'drupal-scaffold' section below is needed because 'Drupal\\automatic_updates\\Validator\\ScaffoldFilePermissionsValidator'", + "uses this section to determine which files to check. The actual composer.json file for drupal/core will have more files listed", + "but this limited list is used in '\\Drupal\\Tests\\automatic_updates\\Kernel\\StatusCheck\\ScaffoldFilePermissionsValidatorTest'", + "to ensure the section is source of the file list." + ], + "drupal-scaffold": { + "file-mapping": { + "[web-root]/sites/default/default.settings.php": "", + "[web-root]/sites/default/default.services.yml": "" + } + } + }, + "installation-source": "dist", + "transport-options": { + "symlink": false, + "relative": true + }, + "install-path": "../drupal/core" + }, + { + "name": "drupal/core-dev", + "version": "9.8.0", + "version_normalized": "9.8.0.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core-dev", + "reference": "6a8d7df3a5650a5d3bce6e478114064b176f7104" + }, + "type": "package", + "installation-source": "dist", + "transport-options": { + "symlink": false, + "relative": true + }, + "install-path": "../drupal/core-dev" + }, + { + "name": "drupal/core-recommended", + "version": "9.8.0", + "version_normalized": "9.8.0.0", + "dist": { + "type": "path", + "url": "../path_repos/drupal--core-recommended", + "reference": "c9babad9851edc2b7b4b43c778bc30db09f14946" + }, + "type": "project", + "installation-source": "dist", + "transport-options": { + "symlink": false, + "relative": true + }, + "install-path": "../drupal/core-recommended" } - } - }, - { - "name": "drupal/core-recommended", - "version": "9.8.0", - "type": "drupal-core" - }, - { - "name": "drupal/core-dev", - "version": "9.8.0", - "type": "drupal-core" - } - ], - "dev-package-names": [] + ], + "dev": true, + "dev-package-names": [ + "drupal/core-dev" + ] } diff --git a/package_manager/tests/fixtures/fake_site/vendor/composer/installed.php b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.php index bd4f9d5cc1..cb52f9d591 100644 --- a/package_manager/tests/fixtures/fake_site/vendor/composer/installed.php +++ b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.php @@ -4,23 +4,53 @@ * @file */ -// Composer Utility needs the versions key to be present. return [ + 'root' => [ + 'name' => '__root__', + 'pretty_version' => '1.2.4', + 'version' => '1.2.4.0', + 'reference' => NULL, + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => [], + 'dev' => TRUE, + ], 'versions' => [ - 'drupal/core' => [ - 'name' => 'drupal/core', - 'version' => '9.8.0', - 'type' => 'drupal-core', + '__root__' => [ + 'pretty_version' => '1.2.4', + 'version' => '1.2.4.0', + 'reference' => NULL, + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => [], + 'dev_requirement' => FALSE, ], - 'drupal/core-recommended' => [ - 'name' => 'drupal/core-recommended', - 'version' => '9.8.0', + 'drupal/core' => [ + 'pretty_version' => '9.8.0', + 'version' => '9.8.0.0', + 'reference' => '5aeab06c3087477e20e617328f2fa9f3ed18373d', 'type' => 'drupal-core', + 'install_path' => __DIR__ . '/../drupal/core', + 'aliases' => [], + 'dev_requirement' => FALSE, ], 'drupal/core-dev' => [ - 'name' => 'drupal/core-dev', - 'version' => '9.8.0', - 'type' => 'drupal-core', + 'pretty_version' => '9.8.0', + 'version' => '9.8.0.0', + 'reference' => '6a8d7df3a5650a5d3bce6e478114064b176f7104', + 'type' => 'package', + 'install_path' => __DIR__ . '/../drupal/core-dev', + 'aliases' => [], + 'dev_requirement' => TRUE, + ], + 'drupal/core-recommended' => [ + 'pretty_version' => '9.8.0', + 'version' => '9.8.0.0', + 'reference' => 'c9babad9851edc2b7b4b43c778bc30db09f14946', + 'type' => 'project', + 'install_path' => __DIR__ . '/../drupal/core-recommended', + 'aliases' => [], + 'dev_requirement' => FALSE, ], ], ]; diff --git a/package_manager/tests/fixtures/fake_site/vendor/drupal/core-dev/composer.json b/package_manager/tests/fixtures/fake_site/vendor/drupal/core-dev/composer.json new file mode 100644 index 0000000000..e7cb4fc29d --- /dev/null +++ b/package_manager/tests/fixtures/fake_site/vendor/drupal/core-dev/composer.json @@ -0,0 +1 @@ +{"name":"drupal\/core-dev","type":"package","version":"9.8.0"} \ No newline at end of file diff --git a/package_manager/tests/fixtures/fake_site/vendor/drupal/core-recommended/composer.json b/package_manager/tests/fixtures/fake_site/vendor/drupal/core-recommended/composer.json new file mode 100644 index 0000000000..0117405708 --- /dev/null +++ b/package_manager/tests/fixtures/fake_site/vendor/drupal/core-recommended/composer.json @@ -0,0 +1 @@ +{"name":"drupal/core-recommended","type":"project","version":"9.8.0"} diff --git a/package_manager/tests/fixtures/fake_site/vendor/drupal/core/composer.json b/package_manager/tests/fixtures/fake_site/vendor/drupal/core/composer.json new file mode 100644 index 0000000000..47e44a3c2f --- /dev/null +++ b/package_manager/tests/fixtures/fake_site/vendor/drupal/core/composer.json @@ -0,0 +1,19 @@ +{ + "name":"drupal/core", + "type":"drupal-core", + "version":"9.8.0", + "extra": { + "_readme": [ + "The 'drupal-scaffold' section below is needed because 'Drupal\\automatic_updates\\Validator\\ScaffoldFilePermissionsValidator'", + "uses this section to determine which files to check. The actual composer.json file for drupal/core will have more files listed", + "but this limited list is used in '\\Drupal\\Tests\\automatic_updates\\Kernel\\StatusCheck\\ScaffoldFilePermissionsValidatorTest'", + "to ensure the section is source of the file list." + ], + "drupal-scaffold": { + "file-mapping": { + "[web-root]/sites/default/default.settings.php": "", + "[web-root]/sites/default/default.services.yml": "" + } + } + } +} diff --git a/package_manager/tests/fixtures/path_repos/drupal--core-dev/composer.json b/package_manager/tests/fixtures/path_repos/drupal--core-dev/composer.json new file mode 100644 index 0000000000..e7cb4fc29d --- /dev/null +++ b/package_manager/tests/fixtures/path_repos/drupal--core-dev/composer.json @@ -0,0 +1 @@ +{"name":"drupal\/core-dev","type":"package","version":"9.8.0"} \ No newline at end of file diff --git a/package_manager/tests/fixtures/path_repos/drupal--core-recommended/composer.json b/package_manager/tests/fixtures/path_repos/drupal--core-recommended/composer.json new file mode 100644 index 0000000000..0117405708 --- /dev/null +++ b/package_manager/tests/fixtures/path_repos/drupal--core-recommended/composer.json @@ -0,0 +1 @@ +{"name":"drupal/core-recommended","type":"project","version":"9.8.0"} diff --git a/package_manager/tests/fixtures/path_repos/drupal--core/composer.json b/package_manager/tests/fixtures/path_repos/drupal--core/composer.json new file mode 100644 index 0000000000..6ded695485 --- /dev/null +++ b/package_manager/tests/fixtures/path_repos/drupal--core/composer.json @@ -0,0 +1,19 @@ +{ + "name":"drupal/core", + "type":"drupal-core", + "version":"9.8.0", + "extra": { + "_readme": [ + "The 'drupal-scaffold' section below is needed because 'Drupal\\automatic_updates\\Validator\\ScaffoldFilePermissionsValidator'", + "uses this section to determine which files to check. The actual composer.json file for drupal/core will have more files listed", + "but this limited list is used in '\\Drupal\\Tests\\automatic_updates\\Kernel\\StatusCheck\\ScaffoldFilePermissionsValidatorTest'", + "to ensure this section determines the file list." + ], + "drupal-scaffold": { + "file-mapping": { + "[web-root]/sites/default/default.settings.php": "", + "[web-root]/sites/default/default.services.yml": "" + } + } + } +} diff --git a/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php b/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php index d79016f6dd..5392844db2 100644 --- a/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php +++ b/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php @@ -2,6 +2,7 @@ namespace Drupal\fixture_manipulator; +use Composer\Semver\VersionParser; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Serialization\Yaml; use Symfony\Component\Filesystem\Filesystem; @@ -190,6 +191,12 @@ class FixtureManipulator { if ($package) { $package = ['name' => $pretty_name] + $package; $install_json_package = array_diff_key($package, array_flip(['install_path'])); + // Composer will use 'version_normalized', if present, to determine the + // version number. + if (isset($install_json_package['version']) && !isset($install_json_package['version_normalized'])) { + $parser = new VersionParser(); + $install_json_package['version_normalized'] = $parser->normalize($install_json_package['version']); + } } if (isset($position)) { diff --git a/package_manager/tests/src/Kernel/FakeSiteFixtureTest.php b/package_manager/tests/src/Kernel/FakeSiteFixtureTest.php index 61dd008d5b..a986c9f47d 100644 --- a/package_manager/tests/src/Kernel/FakeSiteFixtureTest.php +++ b/package_manager/tests/src/Kernel/FakeSiteFixtureTest.php @@ -6,6 +6,7 @@ namespace Drupal\Tests\package_manager\Kernel; use Drupal\fixture_manipulator\ActiveFixtureManipulator; use Drupal\package_manager\ComposerUtility; +use Symfony\Component\Process\Process; /** * Test that the 'fake-site' fixture is a valid starting point. @@ -113,4 +114,19 @@ class FakeSiteFixtureTest extends PackageManagerKernelTestBase { return $packages; } + /** + * Tests that Composer show command can be used on the fixture. + */ + public function testComposerShow(): void { + $process = new Process(['composer', 'show', '--format=json'], $this->container->get('package_manager.path_locator')->getProjectRoot()); + $process->run(); + if ($error = $process->getErrorOutput()) { + $this->fail('Process error: ' . $error); + } + $output = json_decode($process->getOutput(), TRUE); + $package_names = array_map(fn (array $package) => $package['name'], $output['installed']); + $this->assertTrue(asort($package_names)); + $this->assertSame(['drupal/core', 'drupal/core-dev', 'drupal/core-recommended'], $package_names); + } + } diff --git a/package_manager/tests/src/Kernel/FixtureManipulatorTest.php b/package_manager/tests/src/Kernel/FixtureManipulatorTest.php index 5e5549f06b..b8928fa03c 100644 --- a/package_manager/tests/src/Kernel/FixtureManipulatorTest.php +++ b/package_manager/tests/src/Kernel/FixtureManipulatorTest.php @@ -30,27 +30,23 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { private \Exception $expectedTearDownException; /** - * The existing packages in the fixture. + * The original 'installed.php' data before any manipulation. * - * @var \string[][] + * @var array */ - private array $existingCorePackages = [ - 'drupal/core' => [ - 'name' => 'drupal/core', - 'version' => '9.8.0', - 'type' => 'drupal-core', - ], - 'drupal/core-recommended' => [ - 'name' => 'drupal/core-recommended', - 'version' => '9.8.0', - 'type' => 'drupal-core', - ], - 'drupal/core-dev' => [ - 'name' => 'drupal/core-dev', - 'version' => '9.8.0', - 'type' => 'drupal-core', - ], - ]; + private array $originalInstalledPhp; + + /** + * Ensures the original fixture packages in 'installed.php' are unchanged. + * + * @param array $installed_php + * The current 'installed.php' data. + */ + private function assertOriginalFixturePackagesUnchanged(array $installed_php): void { + $original_package_names = array_keys($this->originalInstalledPhp); + $installed_php_core_packages = array_intersect_key($installed_php, array_flip($original_package_names)); + $this->assertSame($this->originalInstalledPhp, $installed_php_core_packages); + } /** * {@inheritdoc} @@ -61,6 +57,8 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { $this->dir = $this->container->get('package_manager.path_locator') ->getProjectRoot(); + [, $this->originalInstalledPhp] = $this->getData(); + $manipulator = new ActiveFixtureManipulator(); $manipulator ->addPackage([ @@ -157,9 +155,13 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { 'name' => 'my/dev-package', 'version' => '2.1.0', 'type' => 'library', + 'version_normalized' => '2.1.0.0', ], ]; $installed_php_expected_packages = $installed_json_expected_packages; + // Composer stores `version_normalized`in 'installed.json' but not + // 'installed.php'. + unset($installed_php_expected_packages['my/dev-package']['version_normalized']); [$installed_json, $installed_php] = $this->getData(); $installed_json['packages'] = array_intersect_key($installed_json['packages'], $installed_json_expected_packages); $this->assertSame($installed_json_expected_packages, $installed_json['packages']); @@ -169,7 +171,13 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { // have been prefixed with the __DIR__ constant, which should be interpreted // when installed.php is loaded by the PHP runtime. $installed_php_expected_packages['my/dev-package']['install_path'] = "$this->dir/vendor/composer/../relative/path"; - $installed_php_expected_packages = $this->existingCorePackages + $installed_php_expected_packages; + + // None of the operations should have changed the original packages. + $this->assertOriginalFixturePackagesUnchanged($installed_php); + + // Remove the original packages since we have confirmed that they have not + // changed. + $installed_php = array_diff_key($installed_php, $this->originalInstalledPhp); $this->assertSame($installed_php_expected_packages, $installed_php); } @@ -241,6 +249,7 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { 'my/dev-package' => [ 'name' => 'my/dev-package', 'version' => '3.2.1', + 'version_normalized' => '3.2.1.0', 'type' => 'library', ], 'my/other-package' => [ @@ -249,6 +258,9 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { ], ]; $installed_php_expected_packages = $install_json_expected_packages; + // Composer stores `version_normalized`in 'installed.json' but not + // 'installed.php'. + unset($installed_php_expected_packages['my/dev-package']['version_normalized']); $installed_php_expected_packages['my/dev-package']['install_path'] = "$this->dir/vendor/composer/../relative/path"; [$installed_json, $installed_php] = $this->getData(); $installed_json['packages'] = array_intersect_key($installed_json['packages'], $install_json_expected_packages); @@ -256,8 +268,13 @@ class FixtureManipulatorTest extends PackageManagerKernelTestBase { $this->assertContains('my/dev-package', $installed_json['dev-package-names']); $this->assertNotContains('my/other-package', $installed_json['dev-package-names']); $this->assertNotContains('my/package', $installed_json['dev-package-names']); - $installed_php_expected_packages = $this->existingCorePackages + $installed_php_expected_packages; - // @see ::testAddPackage() + + // None of the operations should have changed the original packages. + $this->assertOriginalFixturePackagesUnchanged($installed_php); + + // Remove the original packages since we have confirmed that they have not + // changed. + $installed_php = array_diff_key($installed_php, $this->originalInstalledPhp); $this->assertSame($installed_php_expected_packages, $installed_php); } diff --git a/scripts/src/ComposerFixtureCreator.php b/scripts/src/ComposerFixtureCreator.php new file mode 100644 index 0000000000..b42de3eff4 --- /dev/null +++ b/scripts/src/ComposerFixtureCreator.php @@ -0,0 +1,89 @@ +<?php + +declare(strict_types = 1); + +namespace Drupal\automatic_updates\Development; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Process\Exception\ProcessFailedException; +use Symfony\Component\Process\Process; + +/** + * Creates the test fixture at 'package_manager/tests/fixtures/fake_site'. + */ +final class ComposerFixtureCreator { + + const FIXTURE_PATH = __DIR__ . '/../../package_manager/tests/fixtures/fake_site'; + + /** + * Creates the fixture. + */ + public static function createFixture(): void { + $fs = new Filesystem(); + $fs->remove(static::FIXTURE_PATH . "/composer.lock"); + // Remove all the vendor folders but leave our 2 test files. + // @see \Drupal\Tests\package_manager\Kernel\PathExcluder\VendorHardeningExcluderTest + self::removeAllExcept(self::FIXTURE_PATH . "/vendor", ['.htaccess', 'web.config']); + + static::doComposerInstall(); + static::removeAllExcept(static::FIXTURE_PATH . '/vendor/composer', ['installed.json', 'installed.php']); + $fs->remove(static::FIXTURE_PATH . '/vendor/autoload.php'); + + $process = new Process(['composer', 'phpcbf'], __DIR__ . '/../..'); + $process->run(); + print "\nFixture created 🎉."; + } + + /** + * Runs a Composer command at the fixture root. + * + * @param array $command + * The command to run as passed to + * \Symfony\Component\Process\Process::__construct. + * + * @return string + * The Composer command output. + */ + protected static function runComposerCommand(array $command): string { + array_unshift($command, 'composer'); + $command[] = "--working-dir=" . static::FIXTURE_PATH; + $process = new Process($command); + $process->run(); + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + return $process->getOutput(); + } + + /** + * Removes all files in a directory except the ones specified. + * + * @param string $directory + * The directory path. + * @param string[] $files_to_keep + * The files to not delete. + */ + protected static function removeAllExcept(string $directory, array $files_to_keep): void { + if (!is_dir($directory)) { + throw new \LogicException("Expected directory $directory"); + } + $paths_to_remove = glob("$directory/*"); + $fs = new Filesystem(); + foreach ($paths_to_remove as $path_to_remove) { + $base_name = basename($path_to_remove); + if (!in_array($base_name, $files_to_keep, TRUE)) { + $fs->remove($path_to_remove); + } + } + } + + /** + * Runs `composer install`. + */ + protected static function doComposerInstall(): void { + // Disable Packagist entirely so that we don't test the Internet. + static::runComposerCommand(['config', 'repo.packagist.org', 'false']); + static::runComposerCommand(['install']); + } + +} diff --git a/scripts/src/Converter.php b/scripts/src/Converter.php index 617a71a19f..0bdb88655a 100644 --- a/scripts/src/Converter.php +++ b/scripts/src/Converter.php @@ -2,7 +2,7 @@ declare(strict_types = 1); -namespace Drupal\automatic_updates\CoreCovert; +namespace Drupal\automatic_updates\Development; use Composer\Script\Event; use Symfony\Component\Filesystem\Filesystem; diff --git a/src/Validator/VersionPolicyValidator.php b/src/Validator/VersionPolicyValidator.php index dd55485cea..79ff6e15ac 100644 --- a/src/Validator/VersionPolicyValidator.php +++ b/src/Validator/VersionPolicyValidator.php @@ -196,7 +196,8 @@ final class VersionPolicyValidator implements EventSubscriberInterface { $unknown_target = new \LogicException('The target version of Drupal core could not be determined.'); if (isset($package_versions)) { - $core_package_name = key($updater->getActiveComposer()->getCorePackages()); + // Get the first non-dev core package. + $core_package_name = key(array_diff_key($updater->getActiveComposer()->getCorePackages(), ['drupal/core-dev' => ''])); if ($core_package_name && array_key_exists($core_package_name, $package_versions)) { return $package_versions[$core_package_name]; -- GitLab