Now we're in code freeze, we have a situation where there's a lot of one-line procedural wrappers around calls to \Drupal::something, for example https://api.drupal.org/api/drupal/core%21includes%21common.inc/function/...
Some of these are already marked deprecated, some aren't.
Either way, removing them now is an API change, and having the one-line wrappers (as long as they really are one-line wrappers) doesn't do a great deal of harm.
Assuming we don't/can't remove all of them, it'd still be nice to make it as explicit as possible that they're deprecated, so I started to think about deprecated module. Talking to fubhy in irc he suggested a $module.deprecated.inc that holds the functions. The following is a combination of the two:
We'd add a new module to core, 'deprecated', if you rely on deprecated functions, you have to do
dependencies:
- deprecated
in $module.info.yml
Deprecated module then loads $module.deprecated.php for any module you have install that has that file, so the functions become available.
Comments
Comment #1
fubhy commentedI think we can do even better and just load the *.deprecated.inc file of all modules that the given module depends on.
Comment #2
dawehnerMh, this would require you to either recursive go through the dependency graph or potentially specify each submodule. For example someone would use some methods of comment, and comment still uses node related methods internally.
Comment #3
catchIf every module that relies on deprecated functions adds that to .info.yml then dependencies shouldn't matter I think?
Whether we load all or try to be clever we can decide later though, I'm not sure how good an idea this is in general yet so would be good to get feedback on that bit.
Comment #4
yched commentedI was thinking of putting stuff in field.deprecated.inc as well.
Having a deprecated.module that loads all *.deprecated.inc in all enabled modules sounds good enough functionally. Being smarter seems like it could add unneeded complexity.
That's still like 50 if (file_exists()) on each request though. Other possibilities:
- add deprecated_load($module) in common.inc (or in \Drupal ?) that does if module_exists('deprecated') {require $module.deprecated.inc)}, and let each module call it at the top of its .module file
- be even simpler and let each module do the test in its own module file.
At this point, there's no code in deprecated.module, and maybe we could use a simple setting for the killswitch instead of an empty module ?
Comment #5
yched commentedAlso, is this about functions we intend to remove before 8.0, or functions that are here to stay ?
Comment #6
webchickHm. While I like the simplicity of dependencies: deprecated as a solution, I'm not sure for Drupal 8.
My reading of http://buytaert.net/drupal-8-api-freeze is that we want to vastly minimize API changes that would affect module developers, so they can start to port their stuff with some degree of confidence. And if module developers are suddenly getting fatal errors about undefined functions until they do something (either add the info line or include the deprecated.inc file manually), what's the point in doing @deprecated at all? And this "all of a sudden fatal errors" thing would happen to developers randomly throughout the rest of the release cycle as we commit more and more patches that convert away from procedural wrappers which then get moved around. The end result is APIs would never be truly frozen, because you'd never know from git pull to git pull when something was going to bite you. :\
Comment #7
webchickAlso, FWIW, I actually love that we're keeping the one-liner wrappers around for a release. I see it as a bit of an olive branch to module developers who now have to grapple really tough new concepts like namespaces and "use" statements, convoluted directory structures, plugins, controllers, services, dependency injection, etc. etc. in order to write even basic modules. At least something can look familiar for awhile. ;)
Comment #8
yched commentedMy goal for a *.deprecated.inc file is mostly to move old, crusty code that is only here because we got too late to the point where we could actually remove it, out of the way of the "real D8 code" of the module.
You can look at a module, discarding its .deprecated file, and get a clear grasp of how you're "supposed" to use it in D8, uncluttered with stuff that's only here for legacy / BC.
It also really helps as a maintainer of said module. Keep BC clearly separated from your .module file.
For all I care, I could go with a pure convention approach, where each impacted module manually and unconditionally included its own [module].deprecated.inc file at the top of its own .module (like field.module currently does for field.form.inc, field.crud.inc...).
Comment #9
damien tournoud commentedI thought we had an agreement on removing all the @deprecated before Drupal 8.0 ships?
Comment #10
catch@Damien we're still deprecating stuff and likely will be right through to beta if not RC and post-release. At a certain point we can no longer remove functions, but that shouldn't stop us deprecating stuff that's redundant so it's clear that things have changed.
Anything deprecated that's more than a single line wrapper needs to be removed asap - that's extra code that needs to be maintained/two ways of doing things.
I'm not as worried about removing @deprecated one-line wrappers, those are only minimal code debt, i.e. how much point is there removing t() before 9.x? Or node_load()? And we still have #2018411: Figure out a nice DX when working with injected translation so it's not viable to use the replacement everywhere yet.
Comment #11
damien tournoud commentedObviously it doesn't make sense to deprecate something if we don't have a valid replacement, or haven't even started thinking about a replacement (as we started doing, for example, in #788900: Deprecate and remove usages of arg()).
Comment #12
catchSay #788900: Deprecate and remove usages of arg() actually got fixed properly with viable replacements in three months, we might want to deprecate arg() then. Agreed that issue makes no sense at the moment and it's not the only one that's been trying to remove stuff without actually fixing things.
t() is a bit different - the function is empty, it's more an issue of how ugly it is when used injected, had that issue been raised before the patch that marked it @deprecated it'd be clearer. Another example would be drupal_add_css()/drupal_add_js() where we know they're horrible, there's a valid alternative, but there's been slow progress in actually removing usage around core. In some cases it's being used more like @discouraged, or @sorry_we_know_this_is_horrible.
There's also deprecated functions in core that aren't marked as such, like variable_*() which has been walking dead for over a year.
Comment #13
yched commentedSide note: #2067127: Reorganize the contents of field.* files does the move for field.module @deprecated functions, and introduces field.deprecated.inc - unconditionally loaded for now (as in current HEAD), but doing this sooner rather than later helps us have a clearer vision of the stuff in field.module
Comment #14
gábor hojtsyWhat about deprecated early bootstrap level functions (which also exist AFAIR)? While some deprecated functions may be moved to the module level, some are not.
Comment #15
ianthomas_ukAn alternative solution to the same problem is being discussed in #2158871: [Policy, no patch] Clearly denote when @deprecated code is slated to be removed
Comment #16
catchdeprecated early bootstrap level functions aren't available to code in .module.
They'll be available to code in classes that modules provide that might run in early bootstrap. For those I'd just nuke them, or we'll have to leave the deprecated wrappers in situ.
Comment #17
sunComment #18
andypostIs not it a time to move deprecated code to sandbox deprecated module? see related ajax issue in #2187735-3: Add removal information to docblock of all @deprecated functions
Comment #19
Crell commentedBack in the day, Drupal 4.6 had a "legacy" module for old versions of functions and such. I would not be adverse to such a module being revived, provided it was not enabled by default (meaning core doesn't use it). :-)
Comment #20
thedavidmeister commented+1 to this idea. It would make D8 that little bit leaner if you didn't need/want the procedural stuff. @webchick's concerns in #6 are pretty valid, but are solved by simply setting deprecated as a dependency of the module you're porting to D8 until you're sure that you've removed all the procedural bits from what your module is doing (as per the issue summary).
Is it too late to get this in?
Comment #21
thedavidmeister commentedFWIW, there is a high profile example of a framework successfully doing this recently in the jQuery Migrate plugin between versions 1.8 and 1.9, where multiple previously deprecated functions (that I'm sure were still in high rotation) were removed such as browser(), live() and die().
Comment #22
catchI don't think it's too late to get this in - technically it could go into 8.1.x even if it doesn't make it into 8.0.x
The question is what deprecated functions will actually go in it - so far the focus has mainly been on removing things, not sure we've taken an explicit decision to leave something in yet.
Comment #23
thedavidmeister commented@catch - If you have a look at #2093143: [meta] Remove calls to @deprecated and "backwards compatibility" procedural functions from core, I'd suggest flagging a function to be moved to the deprecated module (or in a deprecated .inc file) the moment Core no longer calls it internally. This way, there's no chance a future patch commit will accidentally re-introduce functions that we're trying to clean up (we had this problem a lot when trying to remove theme() and ended up renaming the function), and you can draw a nice, easy line in the sand over there and even schedule a date ahead of time.
Comment #24
thedavidmeister commentedComment #25
andypostonly starting from 8.1 we can ship the module
Comment #26
webchickHm I don't think so. If we do this, it would probably be ideal for it to be in 8.0.x so modules that don't plan to chase HEAD could depend on it right out of the gate.
Comment #27
andypost@webchick I suppose there's no functions in 8.x that are deprecated in 8.1 and later everything was moved to 9.x for removal, so maybe we need another issue about moving some deprecated in 8.x to the module and change policy
Comment #28
webchickRight, this issue is about "Add the module" and not "Move things into it."
Comment #30
andypostit could be used for jQuery 3.0 "migrate" library to keep compatibility with 2.0 - related #2533498: Update jQuery to version 3
Comment #36
volegerAs we have https://www.drupal.org/core/deprecation deprecation policy, is this issue is outdated?
Comment #37
borisson_I think so, yeah. This can probably be closed.
Comment #38
tim.plunkett