diff --git a/core/modules/update/src/ProjectCoreCompatibility.php b/core/modules/update/src/ProjectCoreCompatibility.php index 42f5a061b55f900edf9733dcdd09f79831e53311..66c37d03bdafeed6c9ebbe200bc96ecc193f8b18 100644 --- a/core/modules/update/src/ProjectCoreCompatibility.php +++ b/core/modules/update/src/ProjectCoreCompatibility.php @@ -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 @@ public function __construct(array $core_data, array $core_releases) { * * @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'; diff --git a/core/modules/update/tests/fixtures/release-history/drupal.8.1.1-core_compatibility.xml b/core/modules/update/tests/fixtures/release-history/drupal.8.1.1-core_compatibility.xml index ef19bc2786fbfd383d4ae5e75bf81f7bb699fa71..8a6146c8b7e31393e7334e25cd04b980f99a8a8a 100644 --- a/core/modules/update/tests/fixtures/release-history/drupal.8.1.1-core_compatibility.xml +++ b/core/modules/update/tests/fixtures/release-history/drupal.8.1.1-core_compatibility.xml @@ -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> diff --git a/core/modules/update/tests/fixtures/release-history/semver_test.1.1-alpha1-core_compatibility.xml b/core/modules/update/tests/fixtures/release-history/semver_test.1.1-alpha1-core_compatibility.xml deleted file mode 100644 index 18352e9dafde41c8c352fcb564a44d7ea5b13c87..0000000000000000000000000000000000000000 --- a/core/modules/update/tests/fixtures/release-history/semver_test.1.1-alpha1-core_compatibility.xml +++ /dev/null @@ -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> diff --git a/core/modules/update/tests/src/Functional/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php index 196aac2d0b750c7798a746b45975460ea7b95abf..97932acade8414cdc286923172d73f7285c322ef 100644 --- a/core/modules/update/tests/src/Functional/UpdateContribTest.php +++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php @@ -562,26 +562,25 @@ public function testCoreCompatibilityMessage() { ]); $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); } diff --git a/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php b/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php index 778d08a14cf0115245ec826020fba932dab56c25..3f1a55126596e0a83b78b769f8be85c4203f96ce 100644 --- a/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php +++ b/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php @@ -82,21 +82,13 @@ protected function setUp(): void { * <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 @@ public static function incompatibleUpdatesTableProvider() { '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 @@ public static function incompatibleUpdatesTableProvider() { ], ], '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 @@ public static function incompatibleUpdatesTableProvider() { '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 @@ public static function incompatibleUpdatesTableProvider() { ], ], '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 @@ public function testUninstalledUpdatesTable() { $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', diff --git a/core/modules/update/tests/src/Unit/ProjectCoreCompatibilityTest.php b/core/modules/update/tests/src/Unit/ProjectCoreCompatibilityTest.php index 661d2742e23d9f8db321465326fc9046ee23cdf9..15b407c6092532d59012bee7faf4988d73aa4c95 100644 --- a/core/modules/update/tests/src/Unit/ProjectCoreCompatibilityTest.php +++ b/core/modules/update/tests/src/Unit/ProjectCoreCompatibilityTest.php @@ -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 @@ public function testSetProjectCoreCompatibilityRanges(array $project_data, $core * 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 @@ public static function providerSetProjectCoreCompatibilityRanges() { 'core_data' => [ 'existing_version' => '8.8.0', ], + 'supported_branches' => [], 'core_releases' => [ '8.8.0-alpha1' => [], '8.8.0-beta1' => [], @@ -71,30 +72,40 @@ public static function providerSetProjectCoreCompatibilityRanges() { '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 @@ public static function providerSetProjectCoreCompatibilityRanges() { '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 @@ public static function providerSetProjectCoreCompatibilityRanges() { ], '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, diff --git a/core/modules/update/update.compare.inc b/core/modules/update/update.compare.inc index c9d1877c19228d4afe091b6be03ab661bde1c32a..465446beec60e3ae309502a688f821d8243d6888 100644 --- a/core/modules/update/update.compare.inc +++ b/core/modules/update/update.compare.inc @@ -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); } }