diff --git a/core/lib/Drupal/Core/Extension/ExtensionList.php b/core/lib/Drupal/Core/Extension/ExtensionList.php index 4a479a479e..e5f7a2fee9 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionList.php +++ b/core/lib/Drupal/Core/Extension/ExtensionList.php @@ -317,10 +317,6 @@ protected function doList() { // Invoke hook_system_info_alter() to give installed modules a chance to // modify the data in the .info.yml files if necessary. $this->moduleHandler->alter('system_info', $extension->info, $extension, $this->type); - - // Determine if the extension is compatible with the current version of - // Drupal core. - $extension->info['core_incompatible'] = !DrupalSemver::satisfies(\Drupal::VERSION, $extension->info['core_dependency']); } return $extensions; diff --git a/core/lib/Drupal/Core/Extension/InfoParserDynamic.php b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php index 806966f9c5..e34215f420 100644 --- a/core/lib/Drupal/Core/Extension/InfoParserDynamic.php +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php @@ -57,6 +57,11 @@ public function parse($filename) { else { $parsed_info['core_dependency'] = $parsed_info['core']; } + + // Determine if the extension is compatible with the current version of + // Drupal core. + $parsed_info['core_incompatible'] = !DrupalSemver::satisfies(\Drupal::VERSION, $parsed_info['core_dependency']); + if (isset($parsed_info['version']) && $parsed_info['version'] === 'VERSION') { $parsed_info['version'] = \Drupal::VERSION; } diff --git a/core/modules/system/tests/modules/system_core_incompatible_semver_test/system_core_incompatible_semver_test.info.yml b/core/modules/system/tests/modules/system_core_incompatible_semver_test/system_core_incompatible_semver_test.info.yml new file mode 100644 index 0000000000..850c9344e0 --- /dev/null +++ b/core/modules/system/tests/modules/system_core_incompatible_semver_test/system_core_incompatible_semver_test.info.yml @@ -0,0 +1,6 @@ +name: 'System core incompatible semver test' +type: module +description: 'Support module for testing core incompatible semver.' +package: Testing +version: 1.0.0 +core_dependency: ^7 diff --git a/core/modules/system/tests/src/Functional/Module/DependencyTest.php b/core/modules/system/tests/src/Functional/Module/DependencyTest.php index cb57205740..e7ee2abfc6 100644 --- a/core/modules/system/tests/src/Functional/Module/DependencyTest.php +++ b/core/modules/system/tests/src/Functional/Module/DependencyTest.php @@ -105,36 +105,15 @@ public function testIncompatiblePhpVersionDependency() { /** * Tests enabling modules with different core version specifications. */ - public function testCoreVersionDependency() { + public function testCoreCompatibility() { $assert_session = $this->assertSession(); - list($major, $minor) = explode('.', \Drupal::VERSION); - $next_minor = $minor + 1; - $next_major = $major + 1; - - // Test the next minor release. - \Drupal::state()->set('dependency_test.core_version_requirement', "~$major.$next_minor"); + // Test incompatible 'core_dependency'. $this->drupalGet('admin/modules'); $assert_session->fieldDisabled('modules[system_incompatible_core_version_test_1x][enable]'); - $assert_session->fieldDisabled('modules[common_test][enable]'); - - // Test either current major or the next one. - \Drupal::state()->set('dependency_test.core_version_requirement', "^$major || ^$next_major"); - $this->drupalGet('admin/modules'); - $assert_session->fieldEnabled('modules[common_test][enable]'); - - // Test either a previous major or the next one. - \Drupal::state()->set('dependency_test.core_version_requirement', "^1 || ^$next_major"); - $this->drupalGet('admin/modules'); - $assert_session->fieldDisabled('modules[common_test][enable]'); - - // Test an invalid major. - \Drupal::state()->set('dependency_test.core_version_requirement', 'this-string-is-invalid'); - $this->drupalGet('admin/modules'); - $assert_session->fieldDisabled('modules[common_test][enable]'); + $assert_session->fieldDisabled('modules[system_core_incompatible_semver_test][enable]'); - // Test the current minor. - \Drupal::state()->set('dependency_test.core_version_requirement', "~$major.$minor"); + // Test compatible 'core_dependency' and compatible 'core'. $this->drupalGet('admin/modules'); $assert_session->fieldEnabled('modules[common_test][enable]'); $assert_session->fieldEnabled('modules[system_core_semver_test][enable]'); diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php index a0bd2c9002..e0955a1c3a 100644 --- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php @@ -92,12 +92,37 @@ public function testKernelRebuildDuringHookInstall() { * @dataProvider providerTestInvalidCoreInstall * @covers ::install */ - public function testInvalidCoreInstall($install_dependencies) { + public function testInvalidCoreInstall($module_name, $install_dependencies) { $this->expectException(MissingDependencyException::class); - $this->expectExceptionMessage("Unable to install modules: module 'system_incompatible_core_version_test_1x' is incompatible with this version of Drupal core."); - $this->container->get('module_installer')->install(['system_incompatible_core_version_test_1x'], $install_dependencies); + $this->expectExceptionMessage("Unable to install modules: module '$module_name' is incompatible with this version of Drupal core."); + $this->container->get('module_installer')->install([$module_name], $install_dependencies); } + /** + * Dataprovider for testInvalidCoreInstall(). + */ + public function providerTestInvalidCoreInstall() { + return [ + 'no dependencies system_incompatible_core_version_test_1x' => [ + 'system_incompatible_core_version_test_1x', + FALSE, + ], + 'install_dependencies system_incompatible_core_version_test_1x' => [ + 'system_incompatible_core_version_test_1x', + TRUE, + ], + 'no dependencies system_core_incompatible_semver_test' => [ + 'system_core_incompatible_semver_test', + FALSE, + ], + 'install_dependencies system_core_incompatible_semver_test' => [ + 'system_core_incompatible_semver_test', + TRUE, + ], + ]; + } + + /** * Tests install with a dependency with an invalid core version constraint. * @@ -118,11 +143,4 @@ public function testDependencyInvalidCoreInstallNoDependencies() { $this->assertTrue($this->container->get('module_installer')->install(['system_incompatible_core_version_dependencies_test'], FALSE)); } - public function providerTestInvalidCoreInstall() { - return [ - 'no dependencies' => [FALSE], - 'install_dependencies' => [TRUE], - ]; - } - } diff --git a/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php index 19746f1da6..31f7461637 100644 --- a/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php @@ -307,4 +307,69 @@ public function testInfoParserCommonInfo() { $this->assertEquals($info_values['double_colon'], 'dummyClassName::method', 'Value containing double-colon was parsed correctly.'); } + /** + * @covers ::parse + * + * @dataProvider providerCoreIncompatibility + */ + public function testCoreIncompatibility($file_name, $constraint, $expected) { + $file_name = "core_incompatible_$file_name"; + + $core_incompatibility = << [ + "$file_name.info.txt" => $core_incompatibility, + ], + ]); + $info_values = $this->infoParser->parse(vfsStream::url("modules/fixtures/$file_name.info.txt")); + $this->assertSame($expected, $info_values['core_incompatible']); + } + + /** + * Dataprovider for testCoreIncompatibility() + */ + public function providerCoreIncompatibility() { + list($major, $minor) = explode('.', \Drupal::VERSION); + + $next_minor = $minor + 1; + $next_major = $major + 1; + return [ + 'next_minor' => [ + 'next_minor', + "^$major.$next_minor", + TRUE, + ], + 'current_major_next_major' => [ + 'current_major_next_major', + "^$major || ^$next_major", + FALSE, + ], + 'previous_major_next_major' => [ + 'previous_major_next_major', + "^1 || ^$next_major", + TRUE, + ], + 'invalid' => [ + 'invalid', + 'this-string-is-invalid', + TRUE, + ], + 'current_minor' => [ + 'current_minor', + "~$major.$minor", + FALSE, + ], + ]; + } + }