Skip to content
Snippets Groups Projects
Commit 2a8779fe authored by Ted Bowman's avatar Ted Bowman
Browse files

Issue #3230249 by tedbow: Set the project versions to be updated in begin() instead of stage()

parent dced6f5e
No related branches found
No related tags found
1 merge request!21Issue #3230249: Set the project versions to be updated in begin() instead
...@@ -57,14 +57,16 @@ class BatchProcessor { ...@@ -57,14 +57,16 @@ class BatchProcessor {
/** /**
* Calls the updater's begin() method. * Calls the updater's begin() method.
* *
* @param string[] $project_versions
* The project versions to be staged in the update, keyed by package name.
* @param array $context * @param array $context
* The current context of the batch job. * The current context of the batch job.
* *
* @see \Drupal\automatic_updates\Updater::begin() * @see \Drupal\automatic_updates\Updater::begin()
*/ */
public static function begin(array &$context): void { public static function begin(array $project_versions, array &$context): void {
try { try {
static::getUpdater()->begin(); static::getUpdater()->begin($project_versions);
} }
catch (\Throwable $e) { catch (\Throwable $e) {
static::handleException($e, $context); static::handleException($e, $context);
...@@ -74,16 +76,14 @@ class BatchProcessor { ...@@ -74,16 +76,14 @@ class BatchProcessor {
/** /**
* Calls the updater's stageVersions() method. * Calls the updater's stageVersions() method.
* *
* @param string[] $project_versions
* The project versions to be staged in the update, keyed by package name.
* @param array $context * @param array $context
* The current context of the batch job. * The current context of the batch job.
* *
* @see \Drupal\automatic_updates\Updater::stageVersions() * @see \Drupal\automatic_updates\Updater::stage()
*/ */
public static function stageProjectVersions(array $project_versions, array &$context): void { public static function stage(array &$context): void {
try { try {
static::getUpdater()->stageVersions($project_versions); static::getUpdater()->stage();
} }
catch (\Throwable $e) { catch (\Throwable $e) {
static::handleException($e, $context); static::handleException($e, $context);
......
...@@ -235,10 +235,11 @@ class UpdaterForm extends FormBase { ...@@ -235,10 +235,11 @@ class UpdaterForm extends FormBase {
$batch = (new BatchBuilder()) $batch = (new BatchBuilder())
->setTitle($this->t('Downloading updates')) ->setTitle($this->t('Downloading updates'))
->setInitMessage($this->t('Preparing to download updates')) ->setInitMessage($this->t('Preparing to download updates'))
->addOperation([BatchProcessor::class, 'begin']) ->addOperation(
->addOperation([BatchProcessor::class, 'stageProjectVersions'], [ [BatchProcessor::class, 'begin'],
$form_state->getValue('update_version'), [$form_state->getValue('update_version')]
]) )
->addOperation([BatchProcessor::class, 'stage'])
->setFinishCallback([BatchProcessor::class, 'finishStage']) ->setFinishCallback([BatchProcessor::class, 'finishStage'])
->toArray(); ->toArray();
......
...@@ -163,11 +163,21 @@ class Updater { ...@@ -163,11 +163,21 @@ class Updater {
/** /**
* Begins the update. * Begins the update.
* *
* @param string[] $project_versions
* The versions of the packages to update to, keyed by package name.
*
* @return string * @return string
* A key for this stage update process. * A key for this stage update process.
*
* @throws \InvalidArgumentException
* Thrown if no project version for Drupal core is provided.
*/ */
public function begin(): string { public function begin(array $project_versions): string {
$stage_key = $this->createActiveStage(); if (count($project_versions) !== 1 || !array_key_exists('drupal', $project_versions)) {
throw new \InvalidArgumentException("Currently only updates to Drupal core are supported.");
}
$packages[] = 'drupal/core:' . $project_versions['drupal'];
$stage_key = $this->createActiveStage($packages);
$event = $this->dispatchUpdateEvent(AutomaticUpdatesEvents::PRE_START); $event = $this->dispatchUpdateEvent(AutomaticUpdatesEvents::PRE_START);
$this->beginner->begin(static::getActiveDirectory(), static::getStageDirectory(), $this->getExclusions($event)); $this->beginner->begin(static::getActiveDirectory(), static::getStageDirectory(), $this->getExclusions($event));
return $stage_key; return $stage_key;
...@@ -190,24 +200,11 @@ class Updater { ...@@ -190,24 +200,11 @@ class Updater {
} }
/** /**
* Adds specific project versions to the staging area. * Stages the update.
*
* @param string[] $project_versions
* The project versions to add to the staging area, keyed by package name.
*/ */
public function stageVersions(array $project_versions): void { public function stage(): void {
$packages = []; $current = $this->state->get(static::STATE_KEY);
foreach ($project_versions as $project => $project_version) { $this->stagePackages($current['package_versions']);
if ($project === 'drupal') {
// @todo Determine when to use drupal/core-recommended and when to use
// drupal/core
$packages[] = "drupal/core:$project_version";
}
else {
$packages[] = "drupal/$project:$project_version";
}
}
$this->stagePackages($packages);
} }
/** /**
...@@ -220,11 +217,6 @@ class Updater { ...@@ -220,11 +217,6 @@ class Updater {
$command = array_merge(['require'], $packages); $command = array_merge(['require'], $packages);
$command[] = '--update-with-all-dependencies'; $command[] = '--update-with-all-dependencies';
$this->stageCommand($command); $this->stageCommand($command);
// Store the expected packages to confirm no other Drupal packages were
// updated.
$current = $this->state->get(static::STATE_KEY);
$current['packages'] = $packages;
$this->state->set(self::STATE_KEY, $current);
} }
/** /**
...@@ -265,12 +257,21 @@ class Updater { ...@@ -265,12 +257,21 @@ class Updater {
/** /**
* Initializes an active update and returns its ID. * Initializes an active update and returns its ID.
* *
* @param string[] $package_versions
* The versions of the packages to stage, keyed by package name.
*
* @return string * @return string
* The active update ID. * The active update ID.
*/ */
private function createActiveStage(): string { private function createActiveStage(array $package_versions): string {
$value = static::STATE_KEY . microtime(); $value = static::STATE_KEY . microtime();
$this->state->set(static::STATE_KEY, ['id' => $value]); $this->state->set(
static::STATE_KEY,
[
'id' => $value,
'package_versions' => $package_versions,
]
);
return $value; return $value;
} }
......
...@@ -40,7 +40,7 @@ class ExclusionsTest extends BrowserTestBase { ...@@ -40,7 +40,7 @@ class ExclusionsTest extends BrowserTestBase {
$settings['file_private_path'] = 'files/private'; $settings['file_private_path'] = 'files/private';
new Settings($settings); new Settings($settings);
$updater->begin(); $updater->begin(['drupal' => '9.8.1']);
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.php"); $this->assertFileDoesNotExist("$stage_dir/sites/default/settings.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/settings.local.php"); $this->assertFileDoesNotExist("$stage_dir/sites/default/settings.local.php");
$this->assertFileDoesNotExist("$stage_dir/sites/default/services.yml"); $this->assertFileDoesNotExist("$stage_dir/sites/default/services.yml");
......
<?php
namespace Drupal\Tests\automatic_updates\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Prophecy\Argument;
/**
* @coversDefaultClass \Drupal\automatic_updates\Updater
*
* @group automatic_updates
*/
class UpdaterTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'automatic_updates',
'update',
'composer_stager_bypass',
];
/**
* Tests that correct versions are staged after calling ::begin().
*/
public function testCorrectVersionsStaged() {
$this->container->get('automatic_updates.updater')->begin([
'drupal' => '9.8.1',
]);
// Rebuild the container to ensure the project versions are kept in state.
/** @var \Drupal\Core\DrupalKernel $kernel */
$kernel = $this->container->get('kernel');
$kernel->rebuildContainer();
$this->container = $kernel->getContainer();
$stager = $this->prophesize('\PhpTuf\ComposerStager\Domain\StagerInterface');
$command = [
'require',
'drupal/core:9.8.1',
'--update-with-all-dependencies',
];
$stager->stage($command, Argument::cetera())->shouldBeCalled();
$this->container->set('automatic_updates.stager', $stager->reveal());
$this->container->get('automatic_updates.updater')->stage();
}
/**
* @covers ::begin
*
* @dataProvider providerInvalidProjectVersions
*/
public function testInvalidProjectVersions(array $project_versions): void {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Currently only updates to Drupal core are supported.');
$this->container->get('automatic_updates.updater')->begin($project_versions);
}
/**
* Data provider for testInvalidProjectVersions().
*
* @return array
* The test cases for testInvalidProjectVersions().
*/
public function providerInvalidProjectVersions(): array {
return [
'only not drupal' => [['not_drupal' => '1.1.3']],
'not drupal and drupal' => [['drupal' => '9.8.0', 'not_drupal' => '1.2.3']],
'empty' => [[]],
];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment