Loading src/ComposerInstaller/Installer.php +0 −64 Original line number Diff line number Diff line Loading @@ -18,70 +18,6 @@ use Drupal\project_browser\Exception\InstallException; */ final class Installer extends Stage { /** * Begins the install operation. * * @param string[] $package_versions * The versions of the package versions to install, keyed by package name. * @param int|null $timeout * (optional) How long to allow the file copying operation to run before * timing out, in seconds, or NULL to never time out. Defaults to 300 * seconds. * * @return string * The unique ID of the stage. * * @throws \InvalidArgumentException * Thrown if no package versions are provided. */ public function begin(array $package_versions, ?int $timeout = 300): string { if (empty($package_versions)) { throw new \InvalidArgumentException("No packages to begin the install"); } // Ensure that package versions are available to pre-create event // subscribers. We can't use ::setMetadata() here because it requires the // stage to be claimed, but that only happens during ::create(). $this->tempStore->set(static::TEMPSTORE_METADATA_KEY, [ 'packages' => [ 'production' => $package_versions, 'dev' => [], ], ]); return $this->create($timeout); } /** * Returns the package versions that will be required during the install. * * @return string[][] * An array with two sub-arrays: 'production' and 'dev'. Each is a set of * package versions, where the keys are package names and the values are * version constraints understood by Composer. */ public function getPackageVersions(): array { return $this->getMetadata('packages'); } /** * Stages the install. */ public function stage(): void { $this->checkOwnership(); // Convert an associative array of package versions, keyed by name, to // command-line arguments in the form `vendor/name:version`. $map = function (array $versions): array { $requirements = []; foreach ($versions as $package => $version) { $requirements[] = "$package:$version"; } return $requirements; }; $versions = array_map($map, $this->getPackageVersions()); $this->require($versions['production']); } /** * {@inheritdoc} */ Loading tests/src/Kernel/InstallerTest.php +6 −83 Original line number Diff line number Diff line Loading @@ -45,81 +45,6 @@ class InstallerTest extends PackageManagerKernelTestBase { } /** * Tests that correct versions are staged after calling ::begin(). */ public function testCorrectVersionsStaged(): void { // Create a user who will own the stage even after the container is rebuilt. $user = $this->createUser([], NULL, TRUE, ['uid' => 2]); $this->setCurrentUser($user); $id = $this->container->get('project_browser.installer')->begin([ 'drupal/my_module' => '9.8.1', 'other/my_package' => '1.2.3', ]); // Rebuild the container to ensure the package versions are persisted. /** @var \Drupal\Core\DrupalKernel $kernel */ $kernel = $this->container->get('kernel'); $kernel->rebuildContainer(); $this->container = $kernel->getContainer(); $this->setCurrentUser($user); $installer = $this->container->get('project_browser.installer'); // Ensure that the target package versions are what we expect. $expected_versions = [ 'production' => [ 'drupal/my_module' => '9.8.1', 'other/my_package' => '1.2.3', ], 'dev' => [], ]; $this->assertSame($expected_versions, $installer->claim($id)->getPackageVersions()); // When we call Installer::stage(), the stored project versions // should be read from state and passed to Composer Stager's Stager service, // in the form of a Composer command. This is done using // package_manager_bypass's invocation recorder, rather than a regular mock, // in order to test that the invocation recorder itself works. The // production requirements are changed first, followed by the dev // requirements. Then the installed packages are updated. This is tested // functionally in Package Manager. // @see \Drupal\Tests\package_manager\Build\StagedUpdateTest $expected_arguments = [ [ 'require', '--no-update', 'drupal/my_module:9.8.1', 'other/my_package:1.2.3', ], [ 'update', '--with-all-dependencies', 'drupal/my_module:9.8.1', 'other/my_package:1.2.3', ], ]; $installer->stage(); $actual_arguments = $this->container->get('package_manager.stager') ->getInvocationArguments(); $this->assertSame(count($expected_arguments), count($actual_arguments)); foreach ($actual_arguments as $i => [$arguments]) { $this->assertSame($expected_arguments[$i], $arguments); } } /** * Tests that an exception is thrown when calling begin() with no projects. */ public function testNoProjectsInBegin(): void { $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('No packages to begin the install'); $this->container->get('project_browser.installer')->begin([]); } /** * Data provider for testCommitException(). * Loading Loading @@ -154,11 +79,10 @@ class InstallerTest extends PackageManagerKernelTestBase { * @dataProvider providerCommitException */ public function testCommitException(string $thrown_class, string $expected_class = NULL): void { /** @var \Drupal\project_browser\ComposerInstaller\Installer $installer */ $installer = $this->container->get('project_browser.installer'); $installer->begin([ 'drupal/my_module' => '9.8.1', ]); $installer->stage(); $installer->create(); $installer->require(['org/package-name']); $thrown_message = 'A very bad thing happened'; Committer::setException(new $thrown_class($thrown_message, 123)); $this->expectException($expected_class); Loading @@ -176,11 +100,10 @@ class InstallerTest extends PackageManagerKernelTestBase { * @covers ::dispatch */ public function testInstallException() { /** @var \Drupal\project_browser\ComposerInstaller\Installer $installer */ $installer = $this->container->get('project_browser.installer'); $installer->begin([ 'drupal/my_module' => '9.8.1', ]); $installer->stage(); $installer->create(); $installer->require(['org/package-name']); $results = [ ValidationResult::createError([t('These are not the projects you are looking for.')]), ]; Loading Loading
src/ComposerInstaller/Installer.php +0 −64 Original line number Diff line number Diff line Loading @@ -18,70 +18,6 @@ use Drupal\project_browser\Exception\InstallException; */ final class Installer extends Stage { /** * Begins the install operation. * * @param string[] $package_versions * The versions of the package versions to install, keyed by package name. * @param int|null $timeout * (optional) How long to allow the file copying operation to run before * timing out, in seconds, or NULL to never time out. Defaults to 300 * seconds. * * @return string * The unique ID of the stage. * * @throws \InvalidArgumentException * Thrown if no package versions are provided. */ public function begin(array $package_versions, ?int $timeout = 300): string { if (empty($package_versions)) { throw new \InvalidArgumentException("No packages to begin the install"); } // Ensure that package versions are available to pre-create event // subscribers. We can't use ::setMetadata() here because it requires the // stage to be claimed, but that only happens during ::create(). $this->tempStore->set(static::TEMPSTORE_METADATA_KEY, [ 'packages' => [ 'production' => $package_versions, 'dev' => [], ], ]); return $this->create($timeout); } /** * Returns the package versions that will be required during the install. * * @return string[][] * An array with two sub-arrays: 'production' and 'dev'. Each is a set of * package versions, where the keys are package names and the values are * version constraints understood by Composer. */ public function getPackageVersions(): array { return $this->getMetadata('packages'); } /** * Stages the install. */ public function stage(): void { $this->checkOwnership(); // Convert an associative array of package versions, keyed by name, to // command-line arguments in the form `vendor/name:version`. $map = function (array $versions): array { $requirements = []; foreach ($versions as $package => $version) { $requirements[] = "$package:$version"; } return $requirements; }; $versions = array_map($map, $this->getPackageVersions()); $this->require($versions['production']); } /** * {@inheritdoc} */ Loading
tests/src/Kernel/InstallerTest.php +6 −83 Original line number Diff line number Diff line Loading @@ -45,81 +45,6 @@ class InstallerTest extends PackageManagerKernelTestBase { } /** * Tests that correct versions are staged after calling ::begin(). */ public function testCorrectVersionsStaged(): void { // Create a user who will own the stage even after the container is rebuilt. $user = $this->createUser([], NULL, TRUE, ['uid' => 2]); $this->setCurrentUser($user); $id = $this->container->get('project_browser.installer')->begin([ 'drupal/my_module' => '9.8.1', 'other/my_package' => '1.2.3', ]); // Rebuild the container to ensure the package versions are persisted. /** @var \Drupal\Core\DrupalKernel $kernel */ $kernel = $this->container->get('kernel'); $kernel->rebuildContainer(); $this->container = $kernel->getContainer(); $this->setCurrentUser($user); $installer = $this->container->get('project_browser.installer'); // Ensure that the target package versions are what we expect. $expected_versions = [ 'production' => [ 'drupal/my_module' => '9.8.1', 'other/my_package' => '1.2.3', ], 'dev' => [], ]; $this->assertSame($expected_versions, $installer->claim($id)->getPackageVersions()); // When we call Installer::stage(), the stored project versions // should be read from state and passed to Composer Stager's Stager service, // in the form of a Composer command. This is done using // package_manager_bypass's invocation recorder, rather than a regular mock, // in order to test that the invocation recorder itself works. The // production requirements are changed first, followed by the dev // requirements. Then the installed packages are updated. This is tested // functionally in Package Manager. // @see \Drupal\Tests\package_manager\Build\StagedUpdateTest $expected_arguments = [ [ 'require', '--no-update', 'drupal/my_module:9.8.1', 'other/my_package:1.2.3', ], [ 'update', '--with-all-dependencies', 'drupal/my_module:9.8.1', 'other/my_package:1.2.3', ], ]; $installer->stage(); $actual_arguments = $this->container->get('package_manager.stager') ->getInvocationArguments(); $this->assertSame(count($expected_arguments), count($actual_arguments)); foreach ($actual_arguments as $i => [$arguments]) { $this->assertSame($expected_arguments[$i], $arguments); } } /** * Tests that an exception is thrown when calling begin() with no projects. */ public function testNoProjectsInBegin(): void { $this->expectException('InvalidArgumentException'); $this->expectExceptionMessage('No packages to begin the install'); $this->container->get('project_browser.installer')->begin([]); } /** * Data provider for testCommitException(). * Loading Loading @@ -154,11 +79,10 @@ class InstallerTest extends PackageManagerKernelTestBase { * @dataProvider providerCommitException */ public function testCommitException(string $thrown_class, string $expected_class = NULL): void { /** @var \Drupal\project_browser\ComposerInstaller\Installer $installer */ $installer = $this->container->get('project_browser.installer'); $installer->begin([ 'drupal/my_module' => '9.8.1', ]); $installer->stage(); $installer->create(); $installer->require(['org/package-name']); $thrown_message = 'A very bad thing happened'; Committer::setException(new $thrown_class($thrown_message, 123)); $this->expectException($expected_class); Loading @@ -176,11 +100,10 @@ class InstallerTest extends PackageManagerKernelTestBase { * @covers ::dispatch */ public function testInstallException() { /** @var \Drupal\project_browser\ComposerInstaller\Installer $installer */ $installer = $this->container->get('project_browser.installer'); $installer->begin([ 'drupal/my_module' => '9.8.1', ]); $installer->stage(); $installer->create(); $installer->require(['org/package-name']); $results = [ ValidationResult::createError([t('These are not the projects you are looking for.')]), ]; Loading