Problem/Motivation
When a deprecated module or theme is enabled, we could trigger a deprecation notice. This would help to notify contrib modules depending on a deprecated module, and also ensure that core test coverage is cleaned up when something is deprecated - we often have to remove modules from tests before removing the module.
Per #3124762: Add 'lifecycle' key to .info.yml files there's an exception when you try to install an obsolete module, so that's already covered.
Steps to reproduce
Proposed resolution
Deprecation message, "The module 'foo' is deprecated." or "The theme 'foo' is deprecated."
Remaining tasks
Review
User interface changes
API changes
Data model changes
Release notes snippet
A deprecation warning is issued when an deprecated module or deprecated theme is installed.
| Comment | File | Size | Author |
|---|---|---|---|
| #83 | 3257127-83-d10.patch | 30.99 KB | spokje |
| #83 | interdiff_d10_75-83.txt | 3.19 KB | spokje |
| #83 | 3257127-83-d9.patch | 30.97 KB | spokje |
| #83 | interdiff_d9_75-83.txt | 3.19 KB | spokje |
Issue fork drupal-3257127
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
murilohp commentedHey @catch,maybe this patch can help you with that.
Comment #4
quietone commentedFor the failing tests I've adding checks to exclude deprecate modules from the test so that the deprecation message is not generated. Otherwise, all those tests would have to be '@legacy'. For readability the longer if statements that were on one line are now multi-line.
Comment #5
murilohp commentedThanks for the patch @quietone! This issue was on my queue for a while, and I think, filtering the deprecated modules is the best approach for the tests. I also like the if statement changed to be multi-line, definitely improves the readability. For me it is almost ready for RTBC.
Just one question, do you think we should have a change record explaining the deprecation message?
Comment #6
catchI think we could re-title https://www.drupal.org/node/3236434 and include all these related changes under it.
Comment #7
murilohp commentedI think it's a good idea @catch, I updated the https://www.drupal.org/node/3236434, now I'm +1 for RTBC.
Comment #8
gábor hojtsy@murilohp: Thanks for looking into this! I rolled back your edits on https://www.drupal.org/node/3236434 until this issue lands, since that is a published change record, so documenting this issue as if it happened is misleading. I think its fine to update it again once this issue lands, but not before.
Comment #9
murilohp commentedThanks for rolling back the edits and for the explanation @Gábor Hojtsy! Once this lands, I'll update the change record.
Comment #10
gábor hojtsyThis looks like a wonderful patch!
I would use
$moduleand$themedirectly in the error. I believe that is the machine name. This error is triggered for tests to fail, so the machine name would be more accurate for that scenario to figure out why things fail IMHO.Comment #11
quietone commented#10. the error messages are now using the module or theme machine name. I also added the lifecycle_link to the message.
Comment #13
murilohp commentedSince
Drupal\Tests\system\Functional\Module\NonStableModulesTestandDrupal\Tests\system\Functional\System\StatusTestnow install deprecated modules and themes, and both deprecated modules and themes trigger a deprecation message, maybe we should add a@group legacyinto the tests, I tried here, let's see if it pass now.Comment #14
quietone commentedThis is testing the install of experimental and should not have to be legacy. This is needed because the file is using $modules with a deprecated module. I think that declaration needs to be removed and all the tests reviewed to find out where it needs to be installed.
I'll have a look.
Comment #15
quietone commentedThis removed the installation of 'deprecated_module_test' during the setup.
Doing that results in failures in testDeprecatedConfirmForm which I tracked down to the fact that the test module, 'deprecated_module_contrib' is considered to be a core module not a contrib module. Then I found that module 'deprecated_module_test' had deprecated_module_test_system_info_alter with a comment indicating that it should be in 'deprecated_module_contrib'. So I moved that but then found that the hook is not called in the test. If it was then the module would be seen as contrib, which it should be. I don't know why the hook is not called. Anyone?
Comment #16
quietone commentedComment #17
daffie commentedThe patch looks good and is almost ready for RTBC.
I have just 1 remark:
Why do we add this line. It looks like it is out of scope for this issue. If not, then please explain.
Comment #18
quietone commented@daffie, thanks. Just wish I could figure out why deprecated_module_contrib_system_info_alter is not executed in the failing test.
The explanation for the additional checking in seeming unrelated tests is in comment #4.
Comment #19
quietone commentedA bit of empirical testing and I found that the hook is only executed when the lifecyle is 'stable'. That needs to be fixed.
Comment #20
gábor hojtsy@quietone: good find! that sounds like would be its own issue?
Comment #21
quietone commented@Gábor Hojtsy, thanks, but fortunately I was wrong. More on that in a bit.
First, this needs a reroll.
Comment #23
quietone commentedThere is no problem with the hooks running. My mistake was thinking the test was installing the module, when, in fact, it was just getting the confirm form.
Previously, testDeprecatedConfirmForm was working because a hook in deprecated_module_test, which is installed in the test, modifies the info for deprecated_module_contrib. There were no comments in the test to explain this behavior so when I moved the hook I broke it. Perhaps others more familiar with hook_system_info_alter would have realized that. But I think it would be better for the test to be explicit about the location of a module that should be considered contrib. Therefor, I added a few lines to move deprecated_module_contrib from the test directory to the modules/contrib in the test.
Comment #25
quietone commentedWell, I didn't think that through did I?
This restores the hook and adds a comment explaining why 'deprecated_module' must be installed.
Comment #27
quietone commentedDarn, the test passed locally because I wasn't working on a clean environment.
This updates the comments and Installs the correct module to get the hook to run.
Comment #29
quietone commentedAnd lets fix the last failing test.
Comment #30
murilohp commentedThanks for the patch @quietone, it looks good to me, I just noticed some minor stuff.
There's two spaces between "core" and "module" words
I think you maybe missed a quote here on 'core
Comment #31
elberComment #33
elberComment #34
murilohp commentedThanks for the patch @elber! However, I really don't know what happened, your patch removed a lot of stuff. I made this new one addressing my previous comment(#30).
Comment #35
daffie commentedGreat that we add this kind of testing, only I cannot find anything about it in the IS or anywhere else for that matter. Could somebody explain this?
Comment #36
daffie commentedComment #37
gábor hojtsy@daffie: what do you think is missing from the issue summary? Explain the internals of the test? We usually don't do that?
Comment #38
xjmI agree with #37 -- I think the test coverage comment is self-explanatory and consistent with existing patterns in core. Leaving the IS tag on in case anyone has ideas for improvements, but moving back to NR. This is quite important for the Drupal 10 requirements.
Comment #39
xjm(Removing credit for broken patch.)
Comment #40
gábor hojtsy@daffie: https://api.drupal.org/api/drupal/core%21modules%21system%21tests%21modu... is the code for making deprecated_module_test appear like it is not a core module.
There could be multiple techniques for this, however this is a pre-existing test :) Upgrade status uses the
projectkey in the info.yml file, however that module itself only uses that to decide whether something is contrib or not.I think the patch looks good on another review, thanks all!
Comment #41
xjmNeeds CR and release note please. :)
Also, I was expecting runtime to also be included in the scope of this. I'd be okay with that as a followup. If there are reasons runtime is not included, please document them. Thanks!
Comment #42
quietone commentedStarted a change record.
Comment #43
xjmA few more review points:
This is a bit of a jumble, grammatically. We could instead use the text from the JSON:API test in the next hunk:
We could also reuse that same comment here:
"Test uninstalling modules. Filter out..."
"There should be a confirmation form with a deprecated warning for a 'project' not 'core'" does not make sense. Maybe it should be:
(If that is what is meant?)
Also, I assume warnings for a deprecated module that is part of core are tested elsewhere already? Or if not, why not?
hook_system_info_alter()should have parens.Should it also test that the module was installed successfully despite being deprecated?
Should it also test that the theme was installed successfully?
I'm quite glad this issue is happening! :D
Comment #44
quietone commentedThis patch is fixing the items in #43
1. Fixed
2. Fixed
3. Reworked the comments for this new section. Hopefully easier to understand.
There are existing tests for core deprecated modules. The addition is this issue is adding tests for deprecated modules that do not have
origin: core.4. Fixed
5. Added
6. Added
Comment #45
quietone commentedFollow up made, #3262417: Trigger a deprecation message when a deprecated module or theme is used at runtime
Comment #46
dwwI reviewed the CR. Mostly looked good, but I gave it a little cleanup. Removing that tag.
Also, the summary now has a reasonable release note draft, removing that tag, too.
Confirming that the interdiff in #44 addresses all the review points in #43. Almost there! A few other possible concerns / nits:
While this works, it's a little jarring to have one line reading from
$this->containerand the very next one using\Drupal::service(). I know there's an open, unresolved debate about this, but my understanding is that the convention / recommendation is to use\Drupal::service()in tests, not$this->container, to avoid weird hard to track down bugs with when the container is rebuilt in tests. Regardless of how you feel about that debate, doing both approaches in the same test seems a bit weird. Can we use\Drupal::service()consistently for all this?We see this big identical if() multiple times in this patch. Rule of Three(tm)? Can we share this somewhere reasonable? E.g. somewhere in
Drupal\Core\Extension? Or is that scope creep for the task at hand?That's all I can find. Everything else looks great. Perhaps this is already RTBC and these points can be ignored. But I think at least 1 would be an improvement, even if #2 is better as a follow-up. Thanks much!
Comment #47
quietone commented46.1 Fixed. I didn't even notice that.
46.2 There are actually two versions of the big 'if' statement; most exclude Deprecated but one does not. Since there are in tests I don't see the need to create a helper somewhere to share the code. Like you I don't know where it would go either. It may be long but it is easy to read.
Comment #48
dww1. Thanks.
2. Yeah, agree. There’s really no good spot, and it’s kinda scope creepy.
Everything looks good. No further concerns. RTBC!
Thanks again,
-Derek
Comment #49
bbralaWell, you could have a BaseTest for those which would deduplicate a lot. But since you RTBC'd, i'll guess ill keep the patch on my machine ;)
Comment #50
catchGiven there's two versions of the big if statement and it's only ever going to be used in tests, I think it's OK to have the duplication here. If the duplication annoys someone when they're working on another change to the extension system, we could add a helper then. It's very unlikely this logic will ever be replicated outside core.
However, needs a re-roll against 10.0.x
Comment #51
catchComment #52
bbralaOk, since it needs a reroll i'll post the optimized version. First the 9.4.x version, and ill get to work on the reroll right now.
Comment #53
bbralaThe reroll for 10.0.x, seems there was something weird applying one of the files. The resulting patch is pretty much the same though.
Comment #54
bbralaThe Base test class should not be run as a test. Changed to abstract as that is how jsonapi also does it.
Comment #55
catchThis should be StableLibraryOverrideTestBase.
Comment #56
bbralaUpdated class name as suggested.
Comment #57
bbralaAnd the patch as applied to the 10.0.x branch. But it seems to be the same... The interdiff is the same.
Comment #58
catchCan this also use the base class?
Comment #59
catchAnd also can this?
Comment #60
bbralaThe duplication cost of that method is pretty minor. And other than that the duplication in the
TemplateOverrideTestis pretty minimal. Notice that theTemplateOverrideTestdoesnt extend the testbase, the code that was deduplicated was mostly in theStableLibraryOverrideTest.So i think introducing a new class for only those 2 lines is overkill imo.
Comment #61
catchThat makes sense, thanks for explaining.
Comment #62
andypostIt could use follow-up to display top-3 deprecation warnings from code
Comment #63
xjmOops, one point above didn't quite get fixed:
Looks like this copied the jumbled comment instead of the un-jumbled one. It should be:
This makes sense, thanks!
BTW, there are actually three hunks where we filter out certain kinds of modules, not just two. We could add an
ExtensionListTestTrait::filter()or something. But that could be a followup.Comment #64
bbralaThanks @xjm.
63.1: Ok fair enough, let me prepare a new patch.
63.2: Follow-up would be better i think for now imo.
Added d9 and d10 patch.
Comment #65
bbralaComment #66
quietone commentedI took a look at the optimizations.
This title is not correct. The method filters our experimental modules, which can and are core modules, for example, ckeditor5, field_layout, help_topics, workspaces. It also filters out hidden, and migrate_drupal_multilingual is a core module and hidden.
'and so on' is vague. At least, I do not know what that means.
And again
This method filters out the installed modules and then adds just these three. Why just these three modules?
These do not fit with the title of the method. The should go into the setup().
Comment #67
quietone commentedForgot to set to NW.
Comment #68
bbralaenableAllCoreModules=>enableVisibleAndStableCoreModules.name, and so on.=>name, then by asset type.name, and so on.=>name, then by asset type.Added the 9.4 patch, 10.x will follow soon.
Comment #69
bbralaComment #70
bbralaI missed an return type in the d9 patch that triggers an error in d10. I'd rather keep the patches as close to eachother as possible so uploading a new one for d9.
Comment #74
bbralaYeah i was afraid this would happen. The modules of those services are not loaded yet. There are 2 options. Duplicate the initialization to the setUp methods of the tests, or move them back to the new method.
Since the initilization of the services is not really something that makes sense in the context of the method, i'll opt for adding it to the setUp's of the 2 tests.
Comment #75
bbralaThe patches, also removed the setUp method from the testbase since that is no longer needed.
Comment #76
catchIt's a shame there's no way to differentiate between a test of deprecated code, and a test of our own deprecation API support. I think we should add an explanatory comment that this is a test of the deprecation API and should not be removed - will help to stop anyone trying to do so.
And also here.
And here.
Same here.
And here.
Comment #77
catchComment #78
catchFollowing discussion on #3263109: Use PHPStan for deprecation checking, I think we actually don't need to do anything here with comments at all.
If we mark 'tests testing deprecated code' as @deprecated, that's an easy way to distinguish them from 'tests testing deprecation APIs', since the latter won't have the tag.
Comment #79
daffie commentedAll code changes look good to me.
The added trigger_errors() has testing.
For me it is RTBC.
The stuff with adding
@group legacyis a bit strange as those test method would normally be removed in a new major version. @catch Said that it is going to be changed in #3263109: Use PHPStan for deprecation checking.This can we fixed on commit.
Why is this on a single line? For both patches.
Comment #80
catchComment #81
xjmIdeally, let's not "fix on commit" (for #79). This puts certain changes outside our review process and puts pressure on the committer to context-switch between reviewing/committing and editiing files. So that can be addressed on top of the reroll. Thanks!
Comment #82
spokjeI'll reroll and fix-before-fixing-on-commit...
Comment #83
spokjeComment #84
spokjeComment #85
daffie commentedBack to RTBC.
Comment #88
catchCommitted 1ad1a2d and pushed to 10.0.x and the respective patch to 9.4.x. Thanks!
Comment #89
heddnI've opened #3264811: Add FileSystemModuleDiscoveryDataProviderTrait::coreStableModuleListDataProvider as a follow-up. Either calling
FileSystemModuleDiscoveryDataProviderTrait::coreModuleListDataProvidershould filter out deprecated modules or something. Calling and enabling all the modules provided by it in a functional test (in contrib) causes test failures. Core only uses it in Kernel tests.Comment #91
catchOpened #3270499: Add a deprecated module version of ResolvedLibraryDefinitionsFilesMatchTest to add back some test coverage we lost here.