-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initialize deprecators before config/initializers run #46550
Initialize deprecators before config/initializers run #46550
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running before config/initializers is a bit arbitrary, and we may want to actually have the deprecators registered before. I tried by changing to
:load_environment_config
, and all the deprecators are then accessible in the environment file, but still not in application, and I think havingconfig/application.rb
andconfig/environments/development.rb
so different isn't wanted....
- We could not use an initializer at all and use a
before_initialize
(to run before all the railties initializers, including config/initializers files) or evenbefore_configuration
(for the deprecators to be available as soon as the application is created inconfig/application.rb
).
Another possibility would be before: "active_support.deprecation_behavior"
, but I think before_configuration
makes sense for the reasons you stated.
Note, though, that whatever we choose here will likely be imitated by library authors. So I would not depend on deprecators
only containing Rails deprecator instances at any point in the boot process.
I currently check the
gem_name
in the deprecation behavior
I think that is more reliable. Also, that currently works with config.active_support.deprecation
, yes?
After this PR, another possibility would be using deprecators.each
and checking the gem_name
:
Rails.application.deprecators.each do |deprecator|
if deprecator.gem_name == "Rails"
deprecator.behavior = ...
end
end
When I added the framework deprecators, I debated whether to set a specific gem name for each deprecator. In the end, I left them as "Rails"
because I felt that's what most people expect to see in warning messages. This seems like another reason to keep them that way.
I'm not sure applications/libraries should have access to the Rails deprecators outside of the |
57072f6
to
8593131
Compare
I just pushed a commit, using
I'm not sure I understand, I'm talking about accessing the Rails railties deprecators via the |
Got it. Tests are broken now. Can you take a look? |
8593131
to
9e89302
Compare
The test failures were legit, the So I moved it back to be an initializer, running before It's an improvement over main because now all deprecators have their |
Ah, that is a good catch. I had intentionally omitted |
Fixing this in #46583. But making all framework deprecators available via Though I did not realize that
Perhaps the difference is okay though? It's likely that different environments need different deprecator configurations. For example, in the default generated environments files: |
9e89302
to
c540cd9
Compare
Doing so moves the deprecator initializers at the very beginning of all the initializers, but I don't think there's any drawback to that. I pushed a commit with that change. I'll rebase for CI. |
Since engine initializers run later in the process, we need to run this initializer earlier than the default. This ensures they're all registered before the environments are loaded.
c540cd9
to
3d6a7b2
Compare
Motivation / Background
In config/initializers, I have some code that sets up an additional deprecator behavior (by taking the current behavior, which is an Array, prepending to it a new behavior, and setting the array as the new behavior). I want to do that only to Rails frameworks initializers since I only care about Rails deprecations in my situation.
When I updated my code to work with the new
deprecators
introduced in #46049 and later, I discovered that only 8 out of the total 13 frameworks have deprecators at this point in the boot process. That's because 5 of the frameworks are engines, and their own initializers by default run after all the engines initializers, which includes:load_config_initializers
.You can see an example app here https://github.com/etiennebarrie/rails-app/tree/deprecators:
[Alternatively, I'd like a better way to configure all the Rails frameworks deprecators, without configuring any of the deprecators that gem engines may add to the application. Setting values on Rails.application.deprecators apply to all existing and later added deprecators, which isn't quite what I'm looking for. Plus I can only set a behavior, not query the existing one and add another one, but I understand that this makes sense for a deprecators collection. Very often people will want the same behavior to apply to all deprecators, in my specific case I only care about the Rails ones. I currently check the
gem_name
in the deprecation behavior, but given we have now multiple deprecators, I thought I might as well configure them separately.]Detail
This pull request configures all the deprecator initializers to run before config/initializers.
Additional information
cc @jonathanhefner since you've been implementing all the deprecators.
Running before config/initializers is a bit arbitrary, and we may want to actually have the deprecators registered before. I tried by changing to
:load_environment_config
, and all the deprecators are then accessible in the environment file, but still not in application, and I think havingconfig/application.rb
andconfig/environments/development.rb
so different isn't wanted.There are two other ways I can see to fix this:
before_initialize
(to run before all the railties initializers, including config/initializers files) or evenbefore_configuration
(for the deprecators to be available as soon as the application is created inconfig/application.rb
).Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]