Problem/Motivation

Since #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning we have a new key available in info.yml files, core_version_requirments. This allows specifying compatibility via composer semver syntax.

In Drupal 8 we could not remove the core: key altogether because it could cause modules to be uninstalled in a very ugly way without the user being notified.

But in Drupal 9 there would never be a need to have core: 9.x this would be the exact same as core_version_requirement: ^9.

We can't remove support for the core key altogether because some modules will support both Drupal 8 and DRupal 9 at the same time via

core: 8.x
core_version_requirement: ^8 || ^9

Technically when Drupal 9 is released probably on Drupal 8.8 and above only would be supported so those sites would not need the core: key at all. But if we remove support for core: 8.x in Drupal 9 every contrib developer who got there module ready early for Drupal 9 by using the settings above would have to update their module again. We should not make them do this.

Proposed resolution

Throw an exception in \Drupal\Core\Extension\InfoParserDynamic::parse() for any value for core other than 8.x. This is the only value that ever worked in info.yml files.

Remove support for the core: key in Drupal 10. Hypothetically this would still allow a module to be compatible with Drupal 8.8.0 to Drupal 10(though very unlikely)

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Modules, themes and profiles may no longer set core: 9.x in their info.yml files. The correct way to specify core compatibility is with the core_version_requirment key. See the original change record for the core_version_requirement key for allowed values. core: 8.x can still be used for modules that need to specify core compatibility with version before Drupal 8.7.7.

CommentFileSizeAuthor
#46 3105701-46.patch25.53 KBtedbow
#46 interdiff-43-46.txt3.82 KBtedbow
#43 3105701-43.patch25.58 KBtedbow
#43 interdiff-40-43.txt873 bytestedbow
#40 3105701-40.patch25.49 KBtedbow
#40 interdiff-36-40.txt2.02 KBtedbow
#36 3105701-36.patch25.31 KBtedbow
#36 interdiff-32-36.txt5.48 KBtedbow
#32 3105701-32.patch22.86 KBtedbow
#32 interdiff-31-32.txt4.88 KBtedbow
#31 3105701-31.patch22.22 KBtedbow
#31 interdiff-30-31.txt1.99 KBtedbow
#30 3105701-30.patch23.58 KBtedbow
#30 interdiff-24-30.txt6.82 KBtedbow
#24 3105701-24.patch20.5 KBtedbow
#24 interdiff-23-24.txt1.18 KBtedbow
#23 3105701-23.patch20.75 KBtedbow
#23 interdiff-20-23.txt6.17 KBtedbow
#20 3105701-20.patch18.66 KBtedbow
#20 interdiff-14-20.txt4.46 KBtedbow
#14 3105701-14.patch15.83 KBtedbow
#14 interdiff-12-14.txt893 bytestedbow
#12 3105701-12.patch14.96 KBtedbow
#12 3105701-12.patch14.96 KBtedbow
#6 3105701-6.patch5.21 KBtedbow
#4 3105701-4.patch13.55 KBtedbow
#2 3105701-2.patch12.41 KBtedbow
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tedbow created an issue. See original summary.

tedbow’s picture

Status: Active » Needs review
FileSize
12.41 KB

Here is a patch

tedbow’s picture

  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -68,37 +65,44 @@ public function parse($filename) {
    +          $invalid_core_message .= " The 'core' key can be removed because this module does not support any Drupal version prior to " . static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION;
    ...
    +          $invalid_core_message .= " The 'core' key must be set to '8.x' to support Drupal versions prior to " . static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION;
    

    These messages are giving the developer a lot of info but I think it is good to explain as much as we can.

  2. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -131,7 +135,7 @@ public function parse($filename) {
       protected function getRequiredKeys() {
    -    return ['type', 'name'];
    +    return ['type', 'name', 'core_version_requirement'];
       }
    

    core_version_requirement becomes required. I moved the check for the missing keys after we set it for core and testing packages.

tedbow’s picture

Failed all functional tests because there was not exception for test info.yml files. Fixed.

But I don't think this approach is a good one now. In Drupal 8 if you had core: 7.x or core: 4.x it would not cause a parsing error you just couldn't enable the module. If we give a parser error now then any code bases that might have this random values will as soon as the replace core with DRupal 9 start to have this hard error.

I think rather we should just check for core: 9.x and not not 8.x.

Status: Needs review » Needs work

The last submitted patch, 4: 3105701-4.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
5.21 KB

Here is patch that specifically looks for core: 9.x.

Krzysztof Domański’s picture

Status: Needs review » Needs work

If core: 9.x is not allowed in Drupal 9 then the core key no longer makes sense in Drupal 9.

Krzysztof Domański’s picture

Status: Needs work » Needs review

I realized that it's a BC break (see issue summary) so core key can't be removed in Drupal 9. Back to "Needs review".

Krzysztof Domański’s picture

Status: Needs review » Reviewed & tested by the community

Remove support for the core: key in Drupal 10.

It cannot be deprecated in 9.0 due to Issues adding new deprecations (for removal in Drupal 10) should be moved to 9.1.x. Needs follow-up.

--- a/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
+++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
@@ -73,8 +73,11 @@ public function parse($filename) {
           throw new InfoParserException("The 'core' or the 'core_version_requirement' key must be present in " . $filename);
         }
       }
-      if (isset($parsed_info['core']) && !preg_match("/^\d\.x$/", $parsed_info['core'])) {
-        throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename);
+      if (isset($parsed_info['core'])) {
+        @trigger_error("'core' key is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0. Use 'core_version_requirement' instead. See https://www.drupal.org/node/the-change-notice-nid", E_USER_DEPRECATED);
+        if (!preg_match("/^\d\.x$/", $parsed_info['core'])) {
+          throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename);
+        }
       }
Wim Leers’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
@@ -94,6 +91,17 @@ public function parse($filename) {
+        if ($parsed_info['core'] === '9.x') {
+          if (!isset($parsed_info['core_version_requirement'])) {
+            throw new InfoParserException("'core: 9.x' is not supported. Use 'core_version_requirement' to specify core compatibility in " . $filename);
+          }
+          throw new InfoParserException("'core: 9.x' is not supported. 'core_version_requirement' is used to specify core compatibility in " . $filename);
+        }

I think this should be inverted.

It should only allow 8.x. That'd mean that 9.x is not allowed nor 10.x. (The current code in principle allows 10.x.)

Otherwise, it'll still be not guaranteed we can remove this in Drupal 10.

tedbow’s picture

@Wim Leers I tried that. See #4. I think the problem with that approach is that we don't do anything like this is in Drupal 8 so you can have any value in core: and it will not give a you fatal error.

I thought it would be disruptive when upgrading from Drupal 8 to Drupal 9 because that means if you have anything besides core: 8.x you site would have a fatal error that would also effect drush(and drupal console I think). So you couldn't even rebuild cache. Maybe that is unlikely. For contrib projects that packaging on drupal.org will add core: 8.x but only for top level modules. I know when I was working on related issues earlier I found that at least 1 contrib project that had a bad value for core: in submodule. In Drupal 8 that would simply mark the module as incompatible. If throw a parsing error on this level you couldn't do anything.

I will check if there are many of these. If there aren't then maybe that wouldn't be a problem

(The current code in principle allows 10.x.)

Actually the current code

if (!preg_match("/^\d\.x$/", $parsed_info['core'])) {
   throw new InfoParserException("Invalid 'core' value \"{$parsed_info['core']}\" in " . $filename);
}

stop 10.x because it doesn't allow 2 digits. But don't know if that was actually the intention.

But even if we did could do 10.x the module wouldn't be compatible because only core_version_requirement is used to check compatiblity in the any either version of the patch here.

tedbow’s picture

Status: Needs work » Needs review
FileSize
14.96 KB
14.96 KB

My concern in #11 with @Wim Leers' ask in #10

It should only allow 8.x. That'd mean that 9.x is not allowed nor 10.x. (The current code in principle allows 10.x.)

was that this would cause fatal errors in that didn't happen in Drupal 8. The problem is you can anything core: for a module in Drupal 8 it won't throw an exception you just can't enable the module.

I did some searching in contrib and I don't that will be problem. I had an automated script pull tons of contrib modules and only found a couple of cases. I can do the search again if we need more info. Of course with custom code we can't know.

Basically if a site has bad values in core: that they were just ignoring Drupal because they didn't enable the module they will have to either update the values or remove the modules or Drupal 9 will throw a hard exception.

I know think that is unlikely and the parser will give them instructions if that does happen.

Here is patch that only excepts core: 8.x

The last submitted patch, 12: 3105701-12.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tedbow’s picture

This should fix the test fail

xjm’s picture

Issue tags: +beta deadline
xjm’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -56,26 +56,34 @@ public function parse($filename) {
    -        else {
    +        elseif (!isset($parsed_info['core']) || $parsed_info['core'] !== '8.x') {
               // Non-core extensions must specify core compatibility.
    -          throw new InfoParserException("The 'core' or the 'core_version_requirement' key must be present in " . $filename);
    +          throw new InfoParserException("The 'core_version_requirement' key must be present in " . $filename);
    

    Do we have a separate issue to make the core key optional so long as core_version_requirement is present?

    This message is also not right. Say they have a correct core_version_requirement but an invalid/nonsense core key. The exception message here would lead them down the wrong road for debugging.

  2. +++ b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml
    @@ -3,4 +3,4 @@ type: module
     version: VERSION
    -core: 5.x
    +core: 8.x
    
    +++ b/core/modules/system/tests/themes/test_invalid_core/test_invalid_core.info.yml
    @@ -3,4 +3,5 @@ type: theme
    -core: 7.x
    +package: Testing
    +core: 8.x
    

    This looks like we're making incompatible modules compatible. Certainly the name seems wrong now.

xjm’s picture

Changing which exceptions are thrown and under what conditions is a disruption, even if they're edge-case or low usage. I'm wondering if we should restrict the scope of this issue to disallowing seemingly-valid keys for 9.x or higher, and have a followup to use deprecation (rather than a hard exception) for other key formats.

xjm’s picture

Really we should be making the core key optional if a valid constraint is present, so that modules can declare 8.8^ || 9^, remove the core key for forward-compatibility, and work on both branches.

tedbow’s picture

@xjm thanks for the review

re #16

  1. No I got this part wrong.
    This should have still been an else. We want to always throw an error if core_version_requirement is not set.

    but since we introduced the core_version_requirement key core has been invalid in cases such as core_version_requirement: ^8.8 or core_version_requirement: ^8.8 || ^9. In those cases you can't specify core: 8.x or any core value at all because other any version of core before 8.7.7 would still let you enable the module, because it doesn't know about core_version_requirement.

    @see the 9.0.x test \Drupal\Tests\Core\Extension\InfoParserUnitTest::testCoreCoreVersionRequirement88()

  2. No since this is the 9.x branch we are stilling making them incompatible.
    It is just with this issue I am following @Wim Leers suggestion in #10.

    It should only allow 8.x. That'd mean that 9.x is not allowed nor 10.x.

    So we can't leave the test modules with core: 5.x or the parser would throw an exception.

re #18
This is already the case without this patch. The core not just optional you have to remove the core key if you have core_version_requirement: ^8.8 || ^9 see my point 1) above

tedbow’s picture

Status: Needs work » Needs review
FileSize
4.46 KB
18.66 KB
  1. fixes #16.1
  2. Add more test cases to \Drupal\Tests\system\Functional\Form\ModulesListFormWebTest::testModulesListFormWithInvalidInfoFile() which was existing test but only had 1 case for a broken info.yml file. We have InfoParserUnitTest But I thought it would be better to also a more functional test cases.
Gábor Hojtsy’s picture

Status: Needs review » Needs work

Two relatively minor things found:

  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -56,26 +56,34 @@ public function parse($filename) {
    +          // easier for contrib to use test modules. We only do not set
    +          // 'core_version_requirement' to allow testing incompatible moodules.
    

    I don't understand what "we only do not set" meant to explain? Especially right before its actually being set.

  2. +++ b/core/modules/system/tests/themes/test_legacy_stylesheets_remove/test_legacy_stylesheets_remove.info.yml
    @@ -2,8 +2,8 @@ name: 'Theme Legacy Test Stylesheets Remove'
    +package: testing
    

    Package would need to be Testing, not testing. At least there are strict match checks elsewhere to check against that.

jungle’s picture

In addition to #21 2 coding standards messages found from https://www.drupal.org/pift-ci-job/1609335 in #20


/var/lib/drupalci/workspace/jenkins-drupal_patches-36923/source/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php ✗ 1 more
line 110	Functions must not contain multiple empty lines in a row; found 2 empty lines
/var/lib/drupalci/workspace/jenkins-drupal_patches-36923/source/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php ✗ 1 more
292	A comma should follow the last multiline array item. Found: '7.x'
tedbow’s picture

Status: Needs work » Needs review
FileSize
6.17 KB
20.75 KB

Test fails and self review

  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -56,26 +56,34 @@ public function parse($filename) {
    +        if ($is_testing_package) {
    +          // Modules in the testing package are exempt as well. This makes it
    +          // easier for contrib to use test modules. We only do not set
    +          // 'core_version_requirement' to allow testing incompatible moodules.
    +          if (!isset($parsed_info['core'])) {
    +            $parsed_info['core_version_requirement'] = \Drupal::VERSION;
    +          }
    +        }
    

    I moved this check first but didn't delete the other copy further down. deleting.
    Also misspelling "moodules"

  2. \Drupal\Tests\system\Functional\UpdateSystem\UpdateScriptTest::testExtensionCompatibilityChange()
    which I just helped add in #2917600: update_fix_compatibility() puts sites into unrecoverable state failed because it was relying on changing to core: 7.x to produce a message on the update page.

    Since the parser would now throw an exception for anything other than core: 8.x this has to be removed.
    So we can't rely on that change compatibility. I removed the 2 test cases that relied on this.

    I think it is ok to remove this test cases because not longer can make a module be set as core_incompatible with changes to the core key.

  3. SingleVisibleProfileTest failed because it made an info file with
    'core' => \Drupal::CORE_COMPATIBILITY,
    This would need core_version_requirment now.

    I changed to
    'core_version_requirement' => '^8 || ^9 || ^10',
    I could have use
    'core_version_requirement' => '*',
    but I am not sure this good example of what we want tests to use. Some test info files are already using. It has the advantage of never needing to be update. But it also shows a bad example if anyone learning to make modules ever sees this code. I think we need issue to decide what we want to use in these cases.

#21 thanks for the review

  1. I update the comment. The intention was to let test module and test modules only to not have core_version_requirement if the have core set. To allow testing error. I updated the comment

    I don't think this is needed now but not changing this right now so I can have patch where that is the only difference to see what that change alone breaks.

  2. fixed

#22
@jungle thanks for pointing these out. Fixed

tedbow’s picture

Here is patch that removes the section of code mentioned in #21.1

If #23 passes and this doesn't then it is still needed for test modules. I don't think it is. I think this was just put in when we specifically didn't allow 9.x and now we only allow 7.x

xjm’s picture

xjm’s picture

xjm’s picture

Chatted about this with @catch and he has no specific concerns. Let's go ahead with the exception in 9.0.x.

Status: Needs review » Needs work

The last submitted patch, 24: 3105701-24.patch, failed testing. View results

tedbow’s picture

Assigned: Unassigned » tedbow

working on test failures

tedbow’s picture

Assigned: tedbow » Unassigned
Status: Needs work » Needs review
FileSize
6.82 KB
23.58 KB

Hopefully this fixes tests. Will comment on patch to explain fixes.

tedbow’s picture

+++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
@@ -87,7 +85,7 @@ public function parse($filename) {
-        if (!$supports_pre_core_version_requirement_version && isset($parsed_info['core'])) {
+        if (!$is_testing_package && !$supports_pre_core_version_requirement_version && isset($parsed_info['core'])) {

So this makes an exception for the testing package to not throw an error if core should not be set.

So right I am reverting more changes in test modules info.yml files where I removed core

But I am not actually sure we want to exempt test modules in this way. will address that in next patch

tedbow’s picture

tedbow’s picture

Comment for #32

So as an alternative to #31 we could actually just throw an exception for test module like we do for all other modules when core should not be set at all.

This would mean we would have remove the core: 8.x from the 6 test modules that have this.

This is because the test modules will automatically get core_version_requirement: 9.0.0-dev set(current behavior this patch doesn't change) so core: 8.x is not valid.

I think this is better unless other have reasons we should treat testing modules different.

The last submitted patch, 31: 3105701-31.patch, failed testing. View results

tedbow’s picture

Assigned: Unassigned » tedbow
Status: Needs review » Needs work

I think #31 was unrelated JS test fail. Retesting.

Assigning to myself for a self review and probably more test coverage. I already see a couple improvements to make so probably makes sense to wait for someone else to review till my next patch.

tedbow’s picture

Assigned: tedbow » Unassigned
Status: Needs work » Needs review
FileSize
5.48 KB
25.31 KB
  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -56,26 +56,23 @@ public function parse($filename) {
    -      if (!isset($parsed_info['core']) && !isset($parsed_info['core_version_requirement'])) {
    -        if (strpos($filename, 'core/') === 0 || strpos($filename, $this->root . '/core/') === 0) {
    +      if (!isset($parsed_info['core_version_requirement'])) {
    +        if (isset($parsed_info['package']) && $parsed_info['package'] === 'Testing') {
    +          // Modules in the testing package are exempt as well. This makes it
    +          // easier for contrib to use test modules.
    +          $parsed_info['core_version_requirement'] = \Drupal::VERSION;
    +        }
    +        elseif (strpos($filename, 'core/') === 0 || strpos($filename, $this->root . '/core/') === 0) {
    ...
    -        elseif (isset($parsed_info['package']) && $parsed_info['package'] === 'Testing') {
    -          // Modules in the testing package are exempt as well. This makes it
    -          // easier for contrib to use test modules.
    -          $parsed_info['core_version_requirement'] = \Drupal::VERSION;
    -        }
    

    I changed the order of evaluation earlier in the patch. I don't think it is necessary any more. Reverting.

  2. +++ b/core/modules/system/tests/modules/database_statement_monitoring_test/database_statement_monitoring_test.info.yml
    @@ -1,6 +1,5 @@
    -core: 8.x
    

    These changes to test files are because they will cause an error when the parser automatically sets core_version_requirement: 9.0.0-dev which doesn't allow 8.x to be set.

  3. +++ b/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info.yml
    @@ -4,4 +4,4 @@ description: 'Support module for testing system dependencies.'
    -  - drupal:system_incompatible_core_version_test
    +  - drupal:system_core_incompatible_semver_test
    diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml
    
    diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info.yml
    deleted file mode 100644
    

    Deleted this test file and related test cases because we can no longer test a file with core: 8.x and no core_version_requirement set.

    In this patch I am adding explicit unit test coverage for this in \Drupal\Tests\Core\Extension\InfoParserUnitTest::testCoreWithoutCoreVersionRequirement()

    I have also added \Drupal\Tests\Core\Extension\InfoParserUnitTest::testCore8x()

    which tests core: 8.x with various values of core_version_requirement where should be allowed.

  4. +++ b/core/modules/system/tests/src/Functional/System/ThemeTest.php
    @@ -376,7 +376,6 @@ public function testInvalidTheme() {
    -    $this->assertThemeIncompatibleText('Theme test with invalid core version', $incompatible_core_message);
         $this->assertThemeIncompatibleText('Theme test with invalid semver core version', $incompatible_core_message);
    

    Again here a theme with just core: 8.x and no core_version_requirement won't parse. So can't do the functional tests but we can do the unit tests added in this patch.

    Since we are stilling doing the functional test with module with core_version_requirement set to an invalid value we still have function test coverage for a theme having core_incompatible set to TRUE in the parser and it stopping the theme from being enabled.

tedbow’s picture

Issue summary: View changes
Issue tags: -Needs release note

Added release no snippet

tedbow’s picture

Issue tags: -Needs change record

Added the change record https://www.drupal.org/node/3119415

Exactly the same as the release snippet for now. I don't think this needs a long explanation. Both link to the original change record for the core_version_requirement key.

Gábor Hojtsy’s picture

Yay thanks! Looks good now other than this minor thing:

+++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
@@ -99,6 +96,9 @@ public function parse($filename) {
+      if (isset($parsed_info['core']) && $parsed_info['core'] !== '8.x') {
+        throw new InfoParserException("'core: {$parsed_info['core']}' is not supported. Use 'core_version_requirement' to specify core compatibility in " . $filename);
+      }

Let's add a comment here that we allow this for backwards compatibility with modules that are also Drupal 8 compatible, otherwise it looks odd to the uninitiated probably.

tedbow’s picture

@Gábor Hojtsy good idea!
Ok added more info to that exception

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me now, thanks!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 3105701-40.patch, failed testing. View results

tedbow’s picture

Status: Needs work » Needs review
FileSize
873 bytes
25.58 KB

Just forgot to update the expected message in \Drupal\Tests\system\Functional\Form\ModulesListFormWebTest::testModulesListFormWithInvalidInfoFile()

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTB then thanks!

dww’s picture

This basically looks great. Only tiny nits. Leaving at RTBC, but if a re-roll is happening for other means, any/all of these could be addressed.

  1. +++ b/core/lib/Drupal/Core/Extension/InfoParserDynamic.php
    @@ -99,6 +96,9 @@ public function parse($filename) {
    +        throw new InfoParserException("'core: {$parsed_info['core']}' is not supported. Use 'core_version_requirement' to specify core compatibility. Only 'core: 8.x' is supported to provide backwards compatibility for Drupal 8 when needed in " . $filename);
    

    The final string concat isn't needed since it's already a " string. Can just end with ... when needed in $filename");

  2. +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php
    @@ -56,29 +56,66 @@ public function testModuleListForm() {
    +core: 9.x
    +BROKEN,
    +        'expected_error' => "The 'core_version_requirement' key must be present in $file_path",
    

    It's slightly unexpected that the error here is that core_verison_requirement is missing, not that core: 9.x is invalid, but maybe a comment would help?

  3. +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php
    @@ -56,29 +56,66 @@ public function testModuleListForm() {
    +name: Module With Broken Info file
    

    Speaking of comments, since this isn't a dataProvider (YAY!) with comment-esque indexes, can we have a # comment in each of these info files? Or use a different value for name: ?

  4. +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php
    @@ -56,29 +56,66 @@ public function testModuleListForm() {
    +      $this->drupalLogin(
    +        $this->drupalCreateUser(
    +          ['administer modules', 'administer permissions']
    +        )
    +      );
    

    Do we really want to call drupalCreateUser() inside this loop? Why not once outside the loop? drupalLogin() too.

  5. +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php
    @@ -56,29 +56,66 @@ public function testModuleListForm() {
    +      // Confirm that the error message is shown.
    

    Can't believe I'm saying this, but I think this comment isn't needed. ;)

  6. +++ b/core/modules/system/tests/src/Functional/Form/ModulesListFormWebTest.php
    @@ -56,29 +56,66 @@ public function testModuleListForm() {
    +      // Check that the module filter text box is available.
    +      $this->assertSession()->elementExists('xpath', '//input[@name="text"]');
    ...
    +      // Check that the module filter text box is available.
    +      $this->assertSession()->elementExists('xpath', '//input[@name="text"]');
    

    Not sure what this assertion has to do with this test. Why do we care if it's present?

    Twice?

  7. +++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
    @@ -255,25 +258,151 @@ public function testInvalidCore() {
    +      '^8' => [
    +        '^8',
    +        'caret8',
    +      ],
    +      '^9' => [
    +        '^9',
    +        'caret',
    +      ],
    

    why not "caret9" for the 2nd one to match?

  8. +++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
    @@ -255,25 +258,151 @@ public function testInvalidCore() {
    +    $core_without_core_version_requirement = <<<CORE_WITHOUT_CORE_VERSION_REQUIREMENT
    

    There heredoc label doesn't have to be so huge. Could just be <<

  9. +++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
    @@ -255,25 +258,151 @@ public function testInvalidCore() {
    +    $this->expectExceptionMessage("$exception_message-duplicate.info.txt");
    
    

    This is slightly magic and raised an eyebrow. Maybe "{$exception_message}-duplicateinfo.info.txt" would be more obvious. Or perhaps full blown string contact would be clearer:

    exceptExceptionMessage($exception_message . '-duplicate.info.txt');

Thanks!
-Derek

tedbow’s picture

@dww thanks for the review

  1. fixed
  2. This because we fail on the first error. The next test case shows that we check core: 9.x value

    I think it is worth just failing on 1 error at a time not complicating the parser class by checking for all errors and outputing list. These should really only be seen by module developers so they can fix see the next error and fix that. Since it fails hard it will be hard to miss as they develop/port their modules.

    Added a comment to the test.

  3. added unique name to each case
  4. whoops! fixed
  5. yep, I guess the assert explains itself.
  6. The existing test has this when it was only dealing with 1 yaml file. I didn't want to take an existing assert away.

    This confirm in the first case that even though the error is shown the filter text is also shown.
    This is actually pretty weird. Why do you want the filter item to be shown if there aren't any modules list? The test was added as is in #2558645: Malformed module.info.yml prevents install with a confusing error

    For the 2nd time it is called I thought it was better to have the same assert because the only difference on the 2nd time should be that the error is not shown.

    Unless that explanation gives you or someone else an idea as to why it is there I will file a follow-up. I will also read the original issue and see why they added it.

    I don't think we should remove an existing assert even if the test has been refactored a bunch.

  7. fixed
  8. Not clear what you are asking for. it can't be just <<. that throws an error. Or just shorter label than CORE_WITHOUT_CORE_VERSION_REQUIREMENT ?

    Not addressing but as you left as RTBC assuming if this doesn't get addressed its not a big deal.

  9. You maybe correct but there 4 of these in the existing file so I don't think having 1 be different is any clearer.

    But also this is just the way double quoted strings work, right?
    Not changing for now.

dww’s picture

@tedbow Thanks for addressing those points.

#45.6. +1 for a follow-up. Not essential for here, agreed it's weird, but should be untangled elsewhere.

#45.8: Looking closely, ugh, dreditor messed up my comment. :( Yeah, I was asking for:

$core_without_core_version_requirement = <<<CORE

Non-essential.

#46.9: Yup, that's how " strings work. It's just a bit funky that it's relying on specific filename punctuation to make sure it all works. If the filename was ..._duplicate.info.txt the whole thing would break. It's just kinda magic and fragile, that's all. Not worth re-re-rolling, but I was advocating for a slightly more defensive / robust solution.

All that said, interdiff looks great. +1 to leaving this at RTBC.

Thanks again,
-Derek

tedbow’s picture

Re #45.8 an .9

I realized that the way \Drupal\Tests\Core\Extension\InfoParserUnitTest is set up now it make adding test cases for parser exceptions. We should actually need any new test methods each time.

I think it should maybe refactored.
We have a bunch of functions that expect an error based on different info.yml files. I think we could just 1 test method for all these with just have a dataProvider

// Tests that 'core_version_requirement: ^8.8' is invalid with a 'core'
      // key.
      'testCoreCoreVersionRequirement88' => [
        'yml' => <<<YML
package: Core
core: 8.x
core_version_requirement: ^8.8
version: VERSION
type: module
name: Form auto submitter
dependencies:
  - field
YML,
        'expected_exception' => "The 'core_version_requirement' constraint (^8.8) requires the 'core' key not be set in",
      ],

So we could get rid of 8 methods and replace it with 1.

I created this follow-up #3119761: Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider

there is the start of a patch there. It should be much simpler and have the same(actually expanded) test coverage.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

This looks really sound. I guess if there are any 9.x only modules out there they might be affected :) But I think it is okay to ignore that.

Committed 6aee149 and pushed to 9.0.x. Thanks!

  • alexpott committed 6aee149 on 9.0.x
    Issue #3105701 by tedbow, xjm, Gábor Hojtsy, Krzysztof Domański, dww,...
Mixologic’s picture

Random fun fact: There are 4 project on drupal.org that have at least one release that contain modules that have a 9.x in their core key.

The first one just looks like some old placeholder in some submodules, the other three look like "9.0.x-dev is open, make a 9.x module!"

jungle’s picture

+++ b/core/tests/Drupal/Tests/Core/Extension/InfoParserUnitTest.php
@@ -255,25 +258,151 @@ public function testInvalidCore() {
+      'fixtures' => [
+        "core_without_core_version_requirement-$core.info.txt" => $core_without_core_version_requirement,
+        "core_without_core_version_requirement-$core-duplicate.info.txt" => $core_without_core_version_requirement,

Hi, there, just want to know/learn. Is there a special reason to use .info.txt, instead of .info.yml? Other exists tests use the .info.txt extension too. They are fake during unit testing, whatever or even no extension works, but .info.yml makes more sense to me which inlines with the convention of Drupal theme/module definition.

dww’s picture

Re: #51 Fun! ;)

Re: #52: I noticed that, too. The existing tests all did the same, so I didn't want to call it out. Agreed that .yml would be slightly better than .txt. I don't believe there's a specific reason. If you felt inspired to open a follow-up about it, we could change it there. Thanks!

jungle’s picture

Hi @dww, the issue has been created. thanks for replying!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.