Closed (fixed)
Project:
Drupal core
Version:
8.8.x-dev
Component:
base system
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
24 Nov 2017 at 15:34 UTC
Updated:
17 Jun 2019 at 11:54 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
ioana apetri commentedHere is my patch, I rerolled the parent of this issue, for not getting conflicts.
See, and review it, Thanks!
Comment #3
almaudoh commented@yo30: You should wait until the parent issue is committed, then you can make these changes.
If you do want to continue with this issue, then you have to find all usages of
system_rebuild_module_data()and replace them with\Drupal::service('extension.list.module')->reset()or\Drupal::service('extension.list.module')->reset()->list()depending on if the return value is assigned to another variable or not. See the changelog at https://drupal.org/node/2709919.You shouldn't reattach patch from the parent issue here.
Comment #4
dawehnerTo be honest we should also think about, whether there are places which don't need to reset the list.
Comment #5
alexpottComment #7
jibranThis seems duplicate of #2873051: Replace usages of system_rebuild_module_data with the extension.list.module service
Comment #8
dawehnerJust doing the reset() thing is IMHO not the right idea. There should be not many places which should actually do that.
Comment #9
mile23Maybe limit scope to just performing the deprecation part and not the removal and trigger error part?
Comment #10
dawehnerThat sounds like a good idea.
Comment #11
larowlanHappy with a two stage process - lets just make sure we have a follow up for the second half
Comment #12
alexpottI think it is important that marking the code deprecated and using
@trigger_error()happen in same issue. This is because marking the code without triggering the error is just a hopeful deprecation and does not solve the problem of technical debt. I suggest that part 1 is trying to replace all the usages in core without do that.Comment #13
almaudoh commentedLet's start with replacement of
system_rebuild_module_data()withModuleExtensionList::getList(). Trying on a best effort to::reset()only where necessary (based on code context and comments)Comment #15
alexpottNo $this here. Before uploading a patch it might be worth trying a test or an install as you would have caught this.
Comment #16
almaudoh commentedFixed that now - copy and paste error. I was actually very sleepy and reaching for the bed at the point I uploaded that patch.
Comment #18
dawehnerGiven this is part of the installer it might need the reset.
I would have guessed this one wouldn't need it
Should we inject the service?
+1 for not resetting this here. We have not changed the overall state of the system
Do we still need the system_list_reset() call?
Comment #19
oleksiyUpdated according to comment #18.
Comment #21
almaudoh commentedReverted the
->reset()in #19. Also did constructor injection for some of the classes.One thing to decide is constructor injection for all the service classes, whether those would be a BC break.
Comment #23
dawehnerOne really nice thing would be to document why we need a
->reset()in all the cases.Comment #24
almaudoh commentedFixed all the test fails.
For this I just added an optional parameter with a getter that can initialize the value with \Drupal::service('extension.list.module') if it wasn't injected. This way the service constructor can stay backward compatible. The only exception is the
RequiredModuleUninstallValidatorwhere the constructor a non-optional constructor argument is added - this class is part of the extension system.Done this too. As a matter of fact, we only needed to call
->reset()in five places.Comment #25
alexpottI think for BC it'd be nice if the argument here was optional. This class is not a service and things like Drush will have to change and it'll be complicated to support both Drupal 8.5.x and 8.6.x. Therefore I recommend making it optional and triggering a deprecation notice when its NULL.
Let's inject this. As an event subscriber it's internal and constructed via the container.
Let's add a comment as to why reset().
yay
If this is optional needs
(optional)and|null. Not sure why this is optional because UpdateManager should be constructed via the service container. So also why is update.services.yml not changing.yay
Should we still be looking to remove these calls?
There is likely to be a few other KernelTests where this is the case. Let's file a followup to review all tests where system is the only dependency. There are 52 tests where this is the case. For example the same code can be removed from \Drupal\Tests\field\Kernel\FieldDefinitionIntegrityTest but not from \Drupal\KernelTests\Core\Theme\ThemeInstallerTest - so working through that in a follow-up makes sense to me.
Comment #26
almaudoh commentedThanks for the review:
1. Done
2. Injected
3. Since I couldn't see a good reason, I removed the
->reset()and the test still passed. Great! So I went a step further and checked all the other tests that had reset() and found that it wasn't needed in many more places. Removed all of them. Tests still pass. I guess this is primarily becauseModuleHandler::install()already does a reset and that is why most of these calls were made. +1 for better structured code.4. \o/
5. Fixed. No more optional.
6. \o/
7. Removed all of them and more of the same.
8. Created #2943436: Review all tests where system module is the only dependency
Comment #27
almaudoh commentedThis may be overreaching, but a couple more
->reset()s inModuleInstallerthat I don't think are needed. Tested locally and passed. Let's see what testbot says.Comment #29
alexpott@almaudoh yeah those are unlikely to be able to be removed... it's the ModuleInstaller after all :) Can you re-upload the last green patch so the latest patch is the one to review? Thanks.
Comment #30
alexpottWe should test if it is NULL and if so trigger a deprecation error as per https://www.drupal.org/core/deprecation
Comment #31
almaudoh commentedReverted #27 and added a
@trigger_errorfor #30Also retitling to reflect actual scope per #12. I will open a follow-up to actually deprecate and @trigger_error for
system_rebuild_module_data()Comment #32
alexpott@almaudoh why wouldn't we deprecate it in this issue? This issue removes all the usages and without triggering the deprecation error we can't be sure that another issue won't sneak a usage back in.
Comment #33
alexpottI think #8 to #12 has been made irrelevant by your excellent work. The patch is not that big or hard so multiple issue seems unnecessary.
Comment #34
almaudoh commentedGood point @alexpott :) Thanks. TBH, I was hoping you would say "let's just deprecate it in this issue". So done.
Comment #35
almaudoh commentedSorry, I mixed up the url in the deprecation message. Fixed it now to point to the change record.
Comment #36
alexpottNearly there... one minor thing re the deprecation in ConfigImporter.
It's not optional - the optionality is deprecated. The param description should mention this.
We should point to a change record. I think we're going to need a new one for this issue. Very simple one that just says ConfigImporter will have a new required parameter in Drupal 9 and for now it is optional.
Comment #37
almaudoh commented#36 done. Change record is at https://www.drupal.org/node/2943918
#36.1: Since the optional usage is not recommended, I have removed
(optional)and instead explained it in the @param description. I hope that is ok.Comment #38
alexpott@almaudoh +1 on removing optional from the param description since the correct usage is not optional.
This unfortunately is a BC break even though it is unused. Its usage was removed in #2281989: Add a fast and simple way to get module name from the module handler which was committed before 8.0.0 so we should have removed it then and as much as overriding the PermissionHandler is unlikely it possible so something might extend it and rely on this method. So we should not remove it. We should leave it in and deprecate and do
return \Drupal::service('extension.list.module')->reset()->getList();and yep I think we should do a reset because we have no idea of the usage.Comment #39
berdirThe common approach is to initialize "optional" dependencies directly in the constructor, the we can avoid the lazy-loading protected method.
Comment #40
almaudoh commentedDid #38 and #39.
Comment #41
alexpottNo need to the two ifs... normally this is done like this:
Comment #42
almaudoh commentedAh, well. Didn't really think that mattered that much...
Comment #43
mile23Is there a follow-up against D9 to make this change? We should make one and add a @todo. Also link the follow-up from the change record.
Comment #44
almaudoh commentedCreated follow up #2947083: Make ModuleExtensionList argument required in \Drupal\Core\Config\ConfigImporter and added @todo and to change record.
Comment #45
almaudoh commentedComment #47
almaudoh commentedReroll
Comment #49
almaudoh commentedA new usage of
ConfigImporterwas added using the signature this patch has deprecated.Comment #50
andypostline length overflows 80 chars
Two \\
Comment #52
volegerRerolled.
Addressed #50.2 Replaced \\ => \
#50.1 - outdated.
Comment #54
volegerRerolled again.
Comment #55
volegerComment #56
alexpottThis can be removed from the patch.
Comment #58
volegerSure
Comment #59
volegerMissed use core/modules/system/src/Form/ModulesListForm.php
Comment #61
andypostIt looks like parts with cache cleaning needs more detailed review but here's a quick skim
update to 8.7.0 needed
Could use to check that module exists instead of exception
now clear why removed
looks wrong change
8.7.0 and looks could be removed
Comment #62
andypostFix install tests and address comments #61
Comment #64
andypostFix installer
Comment #65
almaudoh commentedFrom interdiff at #62
I don't think we need the
->reset()here.How are we handling the exception now?
Comment #66
andypostI agree that uninstall should not rebuild list - patch does it
#65.2
the
exists()cares about itComment #67
alexpottThe code formatting here does not look quite right. The closing
);should not be indented.We have no legacy test of this. I think that is okay because there is no logic inside this.
I wonder if we should note about resetting the list as this method has normally done that so telling people to do
\Drupal::service('extension.list.module')->getList()will not always work for them if areset()was required.Comment #68
andypostFixed 2 and added note for 3.
Comment #69
berdirA few minor nitpicks, setting to needs work for that, otherwise mostly just some more or less random thoughts...
our deprecation messages for constructor arguments are pretty inconsistent but yay for having one.
I suppose we expect that nobody is extending this, which is probably fair, but adding arguments first is still a bit uncommon although I suppose it makes sense for being the more important one?
there seems to be one subclass of this in contrib, but it doesn't override the constructor.
Finding 2-3 subclasses, one in config_distro even overrides create() but they do it in a way that's compatible with changes
I'll never understand understand why everyone is using $this->container in tests...
double semicolon nitpick
another one
missing "."
Somewhat interesting that ModuleExtensionList doesn't have an interface and even has an explicit @internal and documentation about how it's not yet stable, considering that we're adding a ton of injections and type hints on it now...
merging this all in one statement makes it tricky to review, especially due to the $modules change, which seems to be fine. The newline *before* the anonymous function call is a bit unusual though?
interestingly, this test for example uses the (preferred by me) Drupal::service(), looks like quite a few people worked on the patch over time, resulting in some inconsistencies like this, injection order and so on.
we sure have a lot of new ConfigImporter(...) in all these tests, might be worth to have a helper trait or base class for these config tests?
Comment #70
almaudoh commentedI have had this dilemma myself. So, question - what is the recommended option to use in tests (since I see an equal number of both
\Drupal::service('xyz')and$this->container->get('xyz')This would help in other patches as well.
Comment #71
andypostUsage of services in tests is neverending story #2066993: Use magic methods to sync container property to \Drupal::getContainer in functional tests and #2644256: Replace \Drupal:: with $this->container->get() in test classes of simpletest module
Comment #72
berdirTrue, but I didn't set it to needs work because of that but to fix those nitpicks.
Comment #73
andypostRe-roll and address #69 5-9
IIRC service() vs container was supposed to use
containerin kernel tests andservice()in other onesI changed usage to notion used in each specific file to be consistent - so it will be easy to replace when there will be conclusion in one of issues from #71
Comment #74
andypostFixed failed test
@Berdir it really needs kind of trait for config importer in #3017360: Replace theme handler with theme installer in ConfigImporter
Comment #75
dawehnerMay I ask why we sometimes use extension_list_module and sometimes moduleExtensionList. Is there any reason to not have more symmetry?
May I ask whether someone did some benchmarking? I could imagine that this helps a bit with installing an install profile.
Nice!
Comment #77
andypostReroll, #75.1 because argument following service name but variable following class name
Comment #78
andypostClean-up constructor argument (should be last)
Comment #79
volegerWe could simplify it now to be able to remove only 4 lines instead of removing 4 lines and modifying of 3 lines in Drupal 9 depreciation cleanup.
Let's keep 'if' construction without 'else'.
Comment #80
YurkinPark commentedPatch rerolled and fixes are implemented
Comment #81
alexpottWe need to update this to 8.8.0 now.
Comment #82
andypostChanged version and added test
Comment #83
andypostand comment
Comment #84
andypostAnd fix typo
Comment #85
volegerAll comments were addressed. Looks good.
Comment #86
alexpottNot a huge fan of unit testing this.
Here's why this code is now included for all tests after this has run if you multiple phpunit tests. Doesn't happen for run-tests.sh because of how we run them. Imo a kernel test that installs system and calls the function is safer.
Comment #87
alexpottWe need to update these to make them as per the standard. See #3024461: Adopt consistent deprecation format for core and contrib deprecation messagesApparently we're not using the new format yet so let's wait on this.
Comment #88
claudiu.cristeaFixed #86. Regarding #87, I don't think we should wait for the policy issue as that waits for a coding standards rule. For actual deprecations we should go with the current deprecation policy and this patch fulfills that policy. When a new policy will be in place we, probably, will bulk update all the existing deprecations to use it.
Comment #90
claudiu.cristeaNew occurrence in HEAD.
Comment #91
almaudoh commentedRe-RTBC since committer comment in #86 has been addressed and test is passing.
Comment #93
jibranRandom fails.
Comment #95
andypostFailure caused by unrelated #3055648: Frequent random fail in \Drupal\Tests\media_library\FunctionalJavascript\MediaLibraryTest
Comment #96
andypostreroll for 2 hunks
Comment #97
alexpottNeeds another reroll.
Comment #98
alexpottThe new argument here needs to be optional. Whislt I agree that event and form constructor don;t need to do the optional service dance I think things like the service should. Thanks @Berdir for checking the state of contrib.
Comment #99
andypostreroll
Comment #100
andypost@alexpott do you mean to use private getter here?
Comment #101
alexpottNope I mean we need to make the new argument in UpdateManager optional like we are doing for ConfigImporter
Comment #102
andypostHere it is
Comment #103
claudiu.cristeaThis issues has been once RTBCed, in #91. I'm reviewing and RTBCing for changes requested in #98.
Comment #104
alexpottCommitted 23fad5b and pushed to 8.8.x. Thanks!