Issue #3112962 by tedbow, quietone: Core compatibility messages on contrib available updates should consider supported branches

(cherry picked from commit 8405f9a095)
merge-requests/7849/head
Dave Long 2024-04-17 14:55:49 +01:00
parent 7506af29b5
commit 97bb6c83a3
No known key found for this signature in database
GPG Key ID: ED52AE211E142771
7 changed files with 96 additions and 209 deletions

View File

@ -54,15 +54,17 @@ final class ProjectCoreCompatibility {
* update_calculate_project_update_status().
* @param array $core_releases
* The Drupal core available releases.
* @param array $supported_branches
* An array for supported branches as returned by drupal.org update XML.
*
* @see \Drupal\update\UpdateManagerInterface::getProjects()
* @see update_process_project_info()
* @see update_calculate_project_update_status()
*/
public function __construct(array $core_data, array $core_releases) {
public function __construct(array $core_data, array $core_releases, array $supported_branches) {
if (isset($core_data['existing_version'])) {
$this->existingCoreVersion = $core_data['existing_version'];
$this->possibleCoreUpdateVersions = $this->getPossibleCoreUpdateVersions($core_releases);
$this->possibleCoreUpdateVersions = $this->getPossibleCoreUpdateVersions($core_releases, $supported_branches);
}
}
@ -71,19 +73,28 @@ final class ProjectCoreCompatibility {
*
* @param array $core_releases
* The Drupal core available releases.
* @param array $supported_branches
* An array for supported branches as returned by drupal.org update XML.
*
* @return string[]
* The core version numbers that are possible to update the site to.
*/
protected function getPossibleCoreUpdateVersions(array $core_releases) {
protected function getPossibleCoreUpdateVersions(array $core_releases, array $supported_branches) {
if (!isset($core_releases[$this->existingCoreVersion])) {
// If we can't determine the existing version of core then we can't
// calculate the core compatibility of a given release based on core
// versions after the existing version.
return [];
}
$core_release_versions = array_keys($core_releases);
$possible_core_update_versions = Semver::satisfiedBy($core_release_versions, '>= ' . $this->existingCoreVersion);
$supported_versions = array_filter(array_keys($core_releases), function ($version) use ($supported_branches) {
foreach ($supported_branches as $supported_branch) {
if (strpos($version, $supported_branch) === 0) {
return TRUE;
}
}
return FALSE;
});
$possible_core_update_versions = Semver::satisfiedBy($supported_versions, '>= ' . $this->existingCoreVersion);
$possible_core_update_versions = Semver::sort($possible_core_update_versions);
$possible_core_update_versions = array_filter($possible_core_update_versions, function ($version) {
return VersionParser::parseStability($version) === 'stable';

View File

@ -3,13 +3,26 @@
<title>Drupal</title>
<short_name>drupal</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches>8.0.,8.1.</supported_branches>
<supported_branches>8.0.</supported_branches>
<project_status>published</project_status>
<link>http://example.com/project/drupal</link>
<terms>
<term><name>Projects</name><value>Drupal project</value></term>
</terms>
<releases>
<release>
<!-- This release is not in a supported branch; therefore it should not be recommended. -->
<name>Drupal 8.2.0</name>
<version>8.2.0</version>
<status>published</status>
<release_link>http://example.com/drupal-8-2-0-release</release_link>
<download_link>http://example.com/drupal-8-2-0.tar.gz</download_link>
<date>1250425521</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Drupal 8.1.1</name>
<version>8.1.1</version>

View File

@ -1,144 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<project xmlns:dc="http://purl.org/dc/elements/1.1/">
<title>Semver Test</title>
<short_name>semver_test</short_name>
<dc:creator>Drupal</dc:creator>
<supported_branches>8.0.,8.1.</supported_branches>
<project_status>published</project_status>
<link>http://example.com/project/semver_test</link>
<terms>
<term><name>Projects</name><value>Semver Test project</value></term>
</terms>
<releases>
<release>
<name>Semver Test 8.1.1-alpha1</name>
<version>8.1.1-alpha1</version>
<tag>8.1.1-alpha1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-1-1-alpha1-release</release_link>
<download_link>http://example.com/semver_test-8-1-1-alpha1.tar.gz</download_link>
<date>1584195300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.1.0</name>
<version>8.1.0</version>
<tag>8.1.0</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-1-0-release</release_link>
<download_link>http://example.com/semver_test-8-1-0.tar.gz</download_link>
<date>1581603300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.1.0-beta1</name>
<version>8.1.0-beta1</version>
<tag>8.1.0-beta1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-1-0-beta1-release</release_link>
<download_link>http://example.com/semver_test-8-1-0-beta1.tar.gz</download_link>
<date>1579011300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.1.0-alpha1</name>
<version>8.1.0-alpha1</version>
<tag>8.1.0-alpha1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-1-0-alpha1-release</release_link>
<download_link>http://example.com/semver_test-8-1-0-alpha1.tar.gz</download_link>
<date>1576419300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.1</name>
<version>8.0.1</version>
<tag>8.0.1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-1-release</release_link>
<download_link>http://example.com/semver_test-8-0-1.tar.gz</download_link>
<date>1573827300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.1-beta1</name>
<version>8.0.1-beta1</version>
<tag>8.0.1-beta1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-1-beta1-release</release_link>
<download_link>http://example.com/semver_test-8-0-1-beta1.tar.gz</download_link>
<date>1571235300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.1-alpha1</name>
<version>8.0.1-alpha1</version>
<tag>8.0.1-alpha1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-1-alpha1-release</release_link>
<download_link>http://example.com/semver_test-8-0-1-alpha1.tar.gz</download_link>
<date>1568643300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.0</name>
<version>8.0.0</version>
<tag>8.0.0</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-0-release</release_link>
<download_link>http://example.com/semver_test-8-0-0.tar.gz</download_link>
<date>1566051300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.0-beta1</name>
<version>8.0.0-beta1</version>
<tag>8.0.0-beta1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-0-beta1-release</release_link>
<download_link>http://example.com/semver_test-8-0-0-beta1.tar.gz</download_link>
<date>1563459300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
<release>
<name>Semver Test 8.0.0-alpha1</name>
<version>8.0.0-alpha1</version>
<tag>8.0.0-alpha1</tag>
<status>published</status>
<release_link>http://example.com/semver_test-8-0-0-alpha1-release</release_link>
<download_link>http://example.com/semver_test-8-0-0-alpha1.tar.gz</download_link>
<date>1560867300</date>
<terms>
<term><name>Release type</name><value>New features</value></term>
<term><name>Release type</name><value>Bug fixes</value></term>
</terms>
</release>
</releases>
</project>

View File

@ -562,26 +562,25 @@ class UpdateContribTest extends UpdateTestBase {
]);
$this->mockDefaultExtensionsInfo(['version' => '8.0.0']);
// Confirm that messages are displayed for recommended and latest updates.
// @todo In https://www.drupal.org/project/drupal/issues/3112962:
// Change the calls to 'refreshUpdateStatus()' to use:
// - '1.1' instead of '1.1-core_compatibility'.
// - '1.1-alpha1' instead of '1.1-alpha1-core_compatibility'.
// Delete the files:
// - core/modules/update/tests/modules/update_test/drupal.8.1.1-alpha1-core_compatibility.xml
// - core/modules/update/tests/modules/update_test/drupal.8.1.1-core_compatibility.xml
$this->refreshUpdateStatus(['drupal' => '8.1.1-core_compatibility', 'aaa_update_test' => '8.x-1.2']);
$this->refreshUpdateStatus(['drupal' => '8.1.1', 'aaa_update_test' => '8.x-1.2']);
$this->assertCoreCompatibilityMessage('8.x-1.2', '8.0.0 to 8.1.1', 'Recommended version:');
$this->assertCoreCompatibilityMessage('8.x-1.3-beta1', '8.0.0, 8.1.1', 'Latest version:');
// Run the same check as above but with a Drupal core XML test fixture
// without '8.1.' in 'supported_branches'. Confirm that messages do not
// include releases from the '8.1.' branch.
$this->refreshUpdateStatus(['drupal' => '8.1.1-core_compatibility', 'aaa_update_test' => '8.x-1.2']);
$this->assertCoreCompatibilityMessage('8.x-1.2', '8.0.0 to 8.0.1', 'Recommended version:');
$this->assertCoreCompatibilityMessage('8.x-1.3-beta1', '8.0.0', 'Latest version:');
// Change the available core releases and confirm that the messages change.
$this->refreshUpdateStatus(['drupal' => '8.1.1-alpha1-core_compatibility', 'aaa_update_test' => '8.x-1.2']);
$this->refreshUpdateStatus(['drupal' => '8.1.1-alpha1', 'aaa_update_test' => '8.x-1.2']);
$this->assertCoreCompatibilityMessage('8.x-1.2', '8.0.0 to 8.1.0', 'Recommended version:');
$this->assertCoreCompatibilityMessage('8.x-1.3-beta1', '8.0.0', 'Latest version:');
// Confirm that messages are displayed for security and 'Also available'
// updates.
$this->refreshUpdateStatus(['drupal' => '8.1.1-core_compatibility', 'aaa_update_test' => 'core_compatibility.8.x-1.2_8.x-2.2']);
$this->refreshUpdateStatus(['drupal' => '8.1.1', 'aaa_update_test' => 'core_compatibility.8.x-1.2_8.x-2.2']);
$this->assertCoreCompatibilityMessage('8.x-1.2', '8.1.0 to 8.1.1', 'Security update:', FALSE);
$this->assertCoreCompatibilityMessage('8.x-2.2', '8.1.1', 'Also available:', FALSE);
}

View File

@ -82,21 +82,13 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
* <core_compatibility> at all).
* - 8.x-1.2 is available and requires Drupal 8.1.0 and above.
*
* @todo In https://www.drupal.org/project/drupal/issues/3112962:
* Change the 'core_fixture' values here to use:
* - '1.1' instead of '1.1-core_compatibility'.
* - '1.1-alpha1' instead of '1.1-alpha1-core_compatibility'.
* Delete the files:
* - core/modules/update/tests/modules/update_test/drupal.8.1.1-alpha1-core_compatibility.xml
* - core/modules/update/tests/modules/update_test/drupal.8.1.1-core_compatibility.xml
*
* @return array[]
* Test data.
*/
public static function incompatibleUpdatesTableProvider() {
return [
'only one compatible' => [
'core_fixture' => '8.1.1-core_compatibility',
'core_fixture' => '8.1.1',
// aaa_update_test.8.x-1.2.xml has core compatibility set and will test
// the case where $recommended_release['core_compatible'] === TRUE in
// \Drupal\update\Form\UpdateManagerUpdate.
@ -109,7 +101,7 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
'incompatible' => [],
],
'only one incompatible' => [
'core_fixture' => '8.1.1-core_compatibility',
'core_fixture' => '8.1.1',
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
// Use a fixture with only a 8.x-1.0 release so BBB is up to date.
'b_fixture' => '1_0',
@ -122,7 +114,7 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
],
],
'two compatible, no incompatible' => [
'core_fixture' => '8.1.1-core_compatibility',
'core_fixture' => '8.1.1',
'a_fixture' => '8.x-1.2',
// bbb_update_test.1_1.xml does not have core compatibility set and will
// test the case where $recommended_release['core_compatible'] === NULL
@ -135,7 +127,7 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
'incompatible' => [],
],
'two incompatible, no compatible' => [
'core_fixture' => '8.1.1-core_compatibility',
'core_fixture' => '8.1.1',
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
// bbb_update_test.1_2.xml has core compatibility set and will test the
// case where $recommended_release['core_compatible'] === FALSE in
@ -154,7 +146,7 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
],
],
'one compatible, one incompatible' => [
'core_fixture' => '8.1.1-core_compatibility',
'core_fixture' => '8.1.1',
'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
'b_fixture' => '1_1',
'compatible' => [
@ -245,7 +237,7 @@ class UpdateManagerUpdateTest extends UpdateTestBase {
$uninstalled_table_locator = '[data-drupal-selector="edit-uninstalled-projects"]';
$fixtures = [
'drupal' => '8.1.1-core_compatibility',
'drupal' => '8.1.1',
'aaa_update_test' => '8.x-1.2',
// Use a fixture with only a 8.x-1.0 release so BBB is up to date.
'bbb_update_test' => '1_0',

View File

@ -18,8 +18,8 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
* @covers ::setReleaseMessage
* @dataProvider providerSetProjectCoreCompatibilityRanges
*/
public function testSetProjectCoreCompatibilityRanges(array $project_data, $core_data, array $core_releases, array $expected_releases, array $expected_security_updates) {
$project_compatibility = new ProjectCoreCompatibility($core_data, $core_releases);
public function testSetProjectCoreCompatibilityRanges(array $project_data, $core_data, array $supported_branches, array $core_releases, array $expected_releases, array $expected_security_updates) {
$project_compatibility = new ProjectCoreCompatibility($core_data, $core_releases, $supported_branches);
$project_compatibility->setStringTranslation($this->getStringTranslationStub());
$project_compatibility->setReleaseMessage($project_data);
$this->assertSame($expected_releases, $project_data['releases']);
@ -30,7 +30,7 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
* Data provider for testSetProjectCoreCompatibilityRanges().
*/
public static function providerSetProjectCoreCompatibilityRanges() {
$test_cases['no 9 releases'] = [
$test_cases['no 9 releases, no supported branches'] = [
'project_data' => [
'recommended' => '1.0.1',
'latest_version' => '1.2.3',
@ -60,6 +60,7 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
'core_data' => [
'existing_version' => '8.8.0',
],
'supported_branches' => [],
'core_releases' => [
'8.8.0-alpha1' => [],
'8.8.0-beta1' => [],
@ -71,30 +72,40 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
'8.9.1' => [],
'8.9.2' => [],
],
'expected_releases' => [
'1.0.1' => [
'core_compatibility' => '8.x',
'core_compatible' => TRUE,
'core_compatibility_message' => 'Requires Drupal core: 8.8.0 to 8.9.2',
],
'1.2.3' => [
'core_compatibility' => '^8.9 || ^9',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.0 to 8.9.2',
],
'1.2.4' => [
'core_compatibility' => '^8.9.2 || ^9',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.2',
],
'1.2.6' => [],
];
// Confirm that with no core supported branches the releases are not changed.
$test_cases['no 9 releases, no supported branches'] += [
'expected_releases' => $test_cases['no 9 releases, no supported branches']['project_data']['releases'],
'expected_security_updates' => $test_cases['no 9 releases, no supported branches']['project_data']['security updates'],
];
// Confirm that if core has supported branches the releases will updated
// with 'core_compatible' and 'core_compatibility_message'.
$test_cases['no 9 releases'] = $test_cases['no 9 releases, no supported branches'];
$test_cases['no 9 releases']['supported_branches'] = ['8.8.', '8.9.'];
$test_cases['no 9 releases']['expected_releases'] = [
'1.0.1' => [
'core_compatibility' => '8.x',
'core_compatible' => TRUE,
'core_compatibility_message' => 'Requires Drupal core: 8.8.0 to 8.9.2',
],
'expected_security_updates' => [
'1.2.5' => [
'core_compatibility' => '8.9.0 || 8.9.2 || ^9.0.1',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.0, 8.9.2',
],
'1.2.3' => [
'core_compatibility' => '^8.9 || ^9',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.0 to 8.9.2',
],
'1.2.4' => [
'core_compatibility' => '^8.9.2 || ^9',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.2',
],
'1.2.6' => [],
];
$test_cases['no 9 releases']['expected_security_updates'] = [
'1.2.5' => [
'core_compatibility' => '8.9.0 || 8.9.2 || ^9.0.1',
'core_compatible' => FALSE,
'core_compatibility_message' => 'Requires Drupal core: 8.9.0, 8.9.2',
],
];
// Ensure that when only Drupal 9 pre-releases none of the expected ranges
@ -105,15 +116,19 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
'9.0.0-beta1' => [],
'9.0.0-rc1' => [],
];
// Ensure that when the Drupal 9 full release are added the expected ranges
// do change.
$test_cases['with 9 full releases'] = $test_cases['with 9 pre releases'];
$test_cases['with 9 full releases']['core_releases'] += [
// Ensure that when the Drupal 9 full releases are added but they are not
// supported none of the expected ranges change.
$test_cases['with 9 full releases, not supported'] = $test_cases['with 9 pre releases'];
$test_cases['with 9 full releases, not supported']['core_releases'] += [
'9.0.0' => [],
'9.0.1' => [],
'9.0.2' => [],
];
$test_cases['with 9 full releases']['expected_releases'] = [
// Ensure that when the Drupal 9 full releases are supported the expected
// ranges do change.
$test_cases['with 9 full releases, supported'] = $test_cases['with 9 full releases, not supported'];
$test_cases['with 9 full releases, supported']['supported_branches'][] = '9.0.';
$test_cases['with 9 full releases, supported']['expected_releases'] = [
'1.0.1' => [
'core_compatibility' => '8.x',
'core_compatible' => TRUE,
@ -131,7 +146,7 @@ class ProjectCoreCompatibilityTest extends UnitTestCase {
],
'1.2.6' => [],
];
$test_cases['with 9 full releases']['expected_security_updates'] = [
$test_cases['with 9 full releases, supported']['expected_security_updates'] = [
'1.2.5' => [
'core_compatibility' => '8.9.0 || 8.9.2 || ^9.0.1',
'core_compatible' => FALSE,

View File

@ -102,8 +102,9 @@ function update_calculate_project_data($available) {
// \Drupal\update\ProjectCoreCompatibility::setReleaseMessage() is called
// for each module below.
update_calculate_project_update_status($projects['drupal'], $available['drupal']);
if (isset($available['drupal']['releases'])) {
$project_core_compatibility = new ProjectCoreCompatibility($projects['drupal'], $available['drupal']['releases']);
if (isset($available['drupal']['releases']) && !empty($available['drupal']['supported_branches'])) {
$supported_branches = explode(',', $available['drupal']['supported_branches']);
$project_core_compatibility = new ProjectCoreCompatibility($projects['drupal'], $available['drupal']['releases'], $supported_branches);
}
}