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.
Comment | File | Size | Author |
---|---|---|---|
#46 | 3105701-46.patch | 25.53 KB | tedbow |
#46 | interdiff-43-46.txt | 3.82 KB | tedbow |
#43 | 3105701-43.patch | 25.58 KB | tedbow |
#43 | interdiff-40-43.txt | 873 bytes | tedbow |
#40 | 3105701-40.patch | 25.49 KB | tedbow |
Comments
Comment #2
tedbowHere is a patch
Comment #3
tedbowThese messages are giving the developer a lot of info but I think it is good to explain as much as we can.
core_version_requirement
becomes required. I moved the check for the missing keys after we set it for core and testing packages.Comment #4
tedbowFailed 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
orcore: 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.Comment #6
tedbowHere is patch that specifically looks for
core: 9.x
.Comment #7
Krzysztof DomańskiIfcore: 9.x
is not allowed in Drupal 9 then thecore
key no longer makes sense in Drupal 9.Comment #8
Krzysztof DomańskiI realized that it's a BC break (see issue summary) so core key can't be removed in Drupal 9. Back to "Needs review".
Comment #9
Krzysztof DomańskiIt 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.
Comment #10
Wim LeersI think this should be inverted.
It should only allow
8.x
. That'd mean that9.x
is not allowed nor10.x
. (The current code in principle allows10.x
.)Otherwise, it'll still be not guaranteed we can remove this in Drupal 10.
Comment #11
tedbow@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 addcore: 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 forcore:
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
Actually the current code
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.Comment #12
tedbowMy concern in #11 with @Wim Leers' ask in #10
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
Comment #14
tedbowThis should fix the test fail
Comment #15
xjmComment #16
xjmDo 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/nonsensecore
key. The exception message here would lead them down the wrong road for debugging.This looks like we're making incompatible modules compatible. Certainly the name seems wrong now.
Comment #17
xjmChanging 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.
Comment #18
xjmReally 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.Comment #19
tedbow@xjm thanks for the review
re #16
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 ascore_version_requirement: ^8.8
orcore_version_requirement: ^8.8 || ^9
. In those cases you can't specifycore: 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 aboutcore_version_requirement
.@see the 9.0.x test \Drupal\Tests\Core\Extension\InfoParserUnitTest::testCoreCoreVersionRequirement88()
It is just with this issue I am following @Wim Leers suggestion in #10.
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) aboveComment #20
tedbow\Drupal\Tests\system\Functional\Form\ModulesListFormWebTest::testModulesListFormWithInvalidInfoFile()
which was existing test but only had 1 case for a broken info.yml file. We haveInfoParserUnitTest
But I thought it would be better to also a more functional test cases.Comment #21
Gábor HojtsyTwo relatively minor things found:
I don't understand what "we only do not set" meant to explain? Especially right before its actually being set.
Package would need to be Testing, not testing. At least there are strict match checks elsewhere to check against that.
Comment #22
jungleIn addition to #21 2 coding standards messages found from https://www.drupal.org/pift-ci-job/1609335 in #20
Comment #23
tedbowTest fails and self review
I moved this check first but didn't delete the other copy further down. deleting.
Also misspelling "moodules"
\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 thecore
key.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
core_version_requirement
if the havecore
set. To allow testing error. I updated the commentI 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.
#22
@jungle thanks for pointing these out. Fixed
Comment #24
tedbowHere 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 allow7.x
Comment #25
xjmComment #26
xjmComment #27
xjmChatted about this with @catch and he has no specific concerns. Let's go ahead with the exception in 9.0.x.
Comment #29
tedbowworking on test failures
Comment #30
tedbowHopefully this fixes tests. Will comment on patch to explain fixes.
Comment #31
tedbowSo 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
Comment #32
tedbowComment #33
tedbowComment 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) socore: 8.x
is not valid.I think this is better unless other have reasons we should treat testing modules different.
Comment #35
tedbowI 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.
Comment #36
tedbowI changed the order of evaluation earlier in the patch. I don't think it is necessary any more. Reverting.
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.Deleted this test file and related test cases because we can no longer test a file with
core: 8.x
and nocore_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 ofcore_version_requirement
where should be allowed.Again here a theme with just
core: 8.x
and nocore_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 havingcore_incompatible
set to TRUE in the parser and it stopping the theme from being enabled.Comment #37
tedbowAdded release no snippet
Comment #38
tedbowAdded 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.Comment #39
Gábor HojtsyYay thanks! Looks good now other than this minor thing:
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.
Comment #40
tedbow@Gábor Hojtsy good idea!
Ok added more info to that exception
Comment #41
Gábor HojtsyLooks good to me now, thanks!
Comment #43
tedbowJust forgot to update the expected message in
\Drupal\Tests\system\Functional\Form\ModulesListFormWebTest::testModulesListFormWithInvalidInfoFile()
Comment #44
Gábor HojtsyBack to RTB then thanks!
Comment #45
dwwThis 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.
The final string concat isn't needed since it's already a " string. Can just end with
... when needed in $filename");
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?
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 forname:
?Do we really want to call
drupalCreateUser()
inside this loop? Why not once outside the loop?drupalLogin()
too.Can't believe I'm saying this, but I think this comment isn't needed. ;)
Not sure what this assertion has to do with this test. Why do we care if it's present?
Twice?
why not "caret9" for the 2nd one to match?
There heredoc label doesn't have to be so huge. Could just be <<
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
Comment #46
tedbow@dww thanks for the review
core: 9.x
valueI 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.
name
to each caseThis 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.
<<
. that throws an error. Or just shorter label thanCORE_WITHOUT_CORE_VERSION_REQUIREMENT
?Not addressing but as you left as RTBC assuming if this doesn't get addressed its not a big deal.
But also this is just the way double quoted strings work, right?
Not changing for now.
Comment #47
dww@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
Comment #48
tedbowRe #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
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.
Comment #49
alexpottThis 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!
Comment #51
MixologicRandom 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!"
Comment #52
jungleHi, 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.
Comment #53
dwwRe: #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!
Comment #54
jungleHi @dww, the issue has been created. thanks for replying!