Until now, Rails only droped compatibility with older
rubies on new majors, but I propose to change this policy
because it causes us to either keep compatibility with long
EOLed rubies or to bump the Rails major more often, and to
drop multiple Ruby versions at once when we bump the major.
In my opinion it's a bad alignments of incentives. And we'd
be much better to just drop support in new minors whenever they
go EOL (so 3 years).
Also Ruby being an upstream dependency, it's not even
a semver violation AFAICT.
Since Rails 7.2 isn't planned before a few months, we
can already drop Ruby 3.0 as it will be EOL in March.
This commit addresses the Rails CI using Ruby master branch failure
because Rails CI enables `RAILS_STRICT_WARNINGS` to raise RuntimeError for warnings.
https://buildkite.com/rails/rails/builds/102621#018c49df-e3de-4c2f-aeb7-6d8f08997da9/1102-1107
```ruby
/rails/activesupport/lib/active_support/core_ext/big_decimal/conversions.rb:4: warning: bigdecimal/util is found in bigdecimal, which will no longer be part of the default gems since Ruby 3.4.0. Add bigdecimal to your Gemfile or gemspec. (RuntimeError)
```
According to https://bugs.ruby-lang.org/issues/20058 ,
This failure has been triggered since cc9826503d
and it will be addressed once the bigdecimal 3.1.5 is available at rubygems.org .
In the meantime, we can workaround this issue by logking `bigdecimal` version to 3.1.4 or lower.
This commit should be reverted when the `bigdecimal` 3.1.5 is available at rubygems.org .
On the first call it can be a bit slow because it needs to load
a bunch of data. It's also better to do it as part of boot
so that some of that data is shared via Copy-on-Write
It used to be stdlib but is being extracted in modern rubies.
Overall its usefulness is dubious. In all cases it is included in
Rails, it's only for the `synchronize` method, but end up exposing
a dozen other useless methods.
In the end just using a Mutex is clearer and simpler.
In some cases we can even get away with a single mutex in a constant.
## Motivation / Background
Follow up 1c93288f8b.
This PR adds bigdecimal to runtime dependency of Active Support to suppress the following Ruby 3.3.0dev's warning.
> /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/bundler/gems/rails-a8871e6829e5/activesupport/lib/
> active_support/core_ext/object/json.rb:5: warning: bigdecimal will be not part of the default gems since Ruby 3.4.0.
> Add bigdecimal to your Gemfile. Also contact author of to add bigdecimal into its gemspec.
The grep yields the following results:
```console
$ git grep 'require.*bigdecimal'
activejob/lib/active_job/arguments.rb:3:require "bigdecimal"
activejob/lib/active_job/serializers/big_decimal_serializer.rb:3:require "bigdecimal"
activejob/test/cases/argument_serialization_test.rb:3:require "bigdecimal"
activemodel/lib/active_model/type/decimal.rb:3:require "bigdecimal/util"
activemodel/lib/active_model/validations/numericality.rb:5:require "bigdecimal/util"
activemodel/test/cases/validations/numericality_validation_test.rb:8:require "bigdecimal"
activerecord/test/cases/adapters/sqlite3/quoting_test.rb:4:require "bigdecimal"
activerecord/test/cases/arel/visitors/to_sql_test.rb:4:require "bigdecimal"
activerecord/test/cases/migration_test.rb:5:require "bigdecimal/util"
activesupport/lib/active_support/core_ext/big_decimal/conversions.rb:3:require "bigdecimal"
activesupport/lib/active_support/core_ext/big_decimal/conversions.rb:4:require "bigdecimal/util"
activesupport/lib/active_support/core_ext/object/json.rb:5:require "bigdecimal"
activesupport/lib/active_support/message_pack/extensions.rb:3:require "bigdecimal"
activesupport/lib/active_support/xml_mini.rb:5:require "bigdecimal"
activesupport/lib/active_support/xml_mini.rb:6:require "bigdecimal/util"
activesupport/test/core_ext/hash_ext_test.rb:4:require "bigdecimal"
activesupport/test/core_ext/object/duplicable_test.rb:4:require "bigdecimal"
activesupport/test/hash_with_indifferent_access_test.rb:4:require "bigdecimal"
activesupport/test/json/encoding_test_cases.rb:3:require "bigdecimal"
```
By adding only to Active Support as a dependency, it should resolve the issue due to the dependency.
## Detail
The warning is confirmed in the following step:
```ruby
$ cat generic_main.rb
# frozen_string_literal: true
require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
end
require 'active_support'
require 'minitest/autorun'
# These gems will be bundled gems in Ruby 3.4
require 'bigdecimal'
```
Run generic_main.rb with Ruby 3.3.0dev below.
```console
$ ruby -v
ruby 3.3.0dev (2023-08-25T17:47:04Z master 7d32011399) [x86_64-darwin22]
$ ruby generic_main.rb
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
/Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/bundler/gems/rails-a8871e6829e5/activesupport/lib/
active_support/core_ext/object/json.rb:5: warning: bigdecimal will be not part of the default gems since Ruby 3.4.0.
Add bigdecimal to your Gemfile. Also contact author of to add bigdecimal into its gemspec.
Run options: --seed 39015
# Running:
Finished in 0.001313s, 0.0000 runs/s, 0.0000 assertions/s.
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
```
## Additional information
It is essentially the same as https://github.com/rails/rails/pull/48907.
This commit adds `drb`, `mutex_m` and `base64` to `activesupport/activesupport.gemspec`
because 3.3.0dev shows warnings if bundled gem candidates are required
like `mutex_m will be not part of the default gems since Ruby 3.4.0. Add it to your Gemfile.`
- Example
```
$ ruby -v ; ruby generic_main.rb
ruby 3.3.0dev (2023-08-07T23:09:02Z master 0e5da05a32) [x86_64-linux]
Fetching https://github.com/rails/rails.git
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/.......
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/bundler/gems/rails-2942958827f1/activesupport/lib/active_support/notifications/fanout.rb:3: warning: mutex_m will be not part of the default gems since Ruby 3.4.0. Add it to your Gemfile.
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/bundler/gems/rails-2942958827f1/activesupport/lib/active_support/message_encryptor.rb:4: warning: base64 will be not part of the default gems since Ruby 3.4.0. Add it to your Gemfile.
generic_main.rb:16: warning: drb will be not part of the default gems since Ruby 3.4.0. Add it to your inline Gemfile.
$
```
- generic_main.rb
```
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
end
require "active_support"
require "minitest/autorun"
require "drb"
require "base64"
require "mutex_m"
```
These gems are chosen as follows.
- Bundled gems candidates for Ruby 3.4
```ruby
$ ruby -v ; ruby -e 'pp Gem::BUNDLED_GEMS::SINCE.select { |k,v| v == "3.4.0" }'
ruby 3.3.0dev (2023-08-07T23:09:02Z master 0e5da05a32) [x86_64-linux]
{"abbrev"=>"3.4.0",
"observer"=>"3.4.0",
"getoptlong"=>"3.4.0",
"resolv-replace"=>"3.4.0",
"rinda"=>"3.4.0",
"nkf"=>"3.4.0",
"syslog"=>"3.4.0",
"drb"=>"3.4.0",
"mutex_m"=>"3.4.0",
"csv"=>"3.4.0",
"base64"=>"3.4.0"}
$
```
- `drb`, `mutex_m` and `base64` are required by Rails
- "drb"
```ruby
$ git grep 'require "drb"'
activesupport/lib/active_support/testing/parallelization.rb:require "drb"
activesupport/lib/active_support/testing/parallelization/server.rb:require "drb"
```
- "mutex_m"
```ruby
$ git grep 'require "mutex_m"'
actionpack/lib/action_controller/metal/params_wrapper.rb: require "mutex_m"
activerecord/lib/active_record/attribute_methods.rb:require "mutex_m"
activerecord/lib/active_record/relation/delegation.rb:require "mutex_m"
activesupport/lib/active_support/notifications/fanout.rb:require "mutex_m"
```
- "base64" usage
```ruby
$ git grep 'require "base64"'
actioncable/Rakefile:require "base64"
actionmailer/lib/action_mailer/inline_preview_interceptor.rb:require "base64"
actionpack/lib/action_controller/metal/http_authentication.rb:require "base64"
actionview/Rakefile:require "base64"
activerecord/lib/active_record/encryption/message_serializer.rb:require "base64"
activerecord/lib/active_record/fixture_set/render_context.rb:require "base64"
activerecord/test/cases/encryption/message_serializer_test.rb:require "base64"
activesupport/lib/active_support/message_encryptor.rb:require "base64"
activesupport/lib/active_support/message_verifier.rb:require "base64"
activesupport/lib/active_support/xml_mini.rb:require "base64"
railties/test/application/mailer_previews_test.rb:require "base64"
```
- Dependency between Rails related modules
- "drb" is only required by Active Support
- "mutex_m" is required by Action Pack, Active Record and Active Support
Action Pack and Active Record depend on Active Support. Therefore, adding dependency to Active Support is fine.
2942958827/actionpack/actionpack.gemspec (L36)2942958827/activerecord/activerecord.gemspec (L38)
- "base64" is required by Action Cable, Action Mailer, Action Pack, Action View,
Active Record, Active Support and Raillties.
Action Cable, Action Mailer, Action Pack, Action View and Active Record and Railties depend
on Active Support. Therefore, adding dependency to Active Support is fine.
2942958827/actioncable/actioncable.gemspec (L35)2942958827/actionmailer/actionmailer.gemspec (L36)2942958827/actionpack/actionpack.gemspec (L36)2942958827/actionview/actionview.gemspec (L36)2942958827/actionpack/actionpack.gemspec (L36)2942958827/railties/railties.gemspec (L40)
Refer to:
https://bugs.ruby-lang.org/issues/19776https://github.com/ruby/ruby/pull/8126https://github.com/rubygems/rubygems/pull/6840
rexml is only used in the xml_mini backend and it should be the users
choice if they want to use that feature or not. If they do we will warn
them that installing rexml is needed like we do with all backends.
Let's bump Zeitwerk in preparation for Rails 6.1.
With Zeitwerk 2.3, applications can enable reloading and eager loading
at the same time. As of this writing, Rails does not implement that
logic, but if we do we know the dependency is in place to support it.
Zeitwerk minor releases are backwards compatible, should be a seamlessly
upgrade.
Fix: https://github.com/rails/rails/issues/37650
The classic autoloader used to totally unregister any constant that
failed midway. Which mean `"SomeConst".constantize` was idempotent.
However Zeitwerk rely on normal `Kernel#require` behavior, which mean
that if an exception is raised during a class/module definition,
it will be left incompletely defined. For instance:
```ruby
class FooController
::DoesNotExist
def index
end
end
```
Will leave `FooController` defined, but without its `index` method.
Because of this, when silencing a NameError, it's important
to make sure the missing constant is really the one we were trying
to load.
This commit more or less undoes 9b5401f, restores autoloaded? not to
touch the descendants tracker, and autoloaded_constants because it is
documented in the guide.
The original message from Zeitwerk is "can't reload, please call
loader.enable_reloading before setup (Zeitwerk::Error)", which is not
very informative for Rails programmers.
Rails should err with a message worded in terms of its interface.
Rails.autoloader and Rails.once_autoloader was just tentative API good
enough for a first patch. Rails.autoloader is singular and does not
convey in its name that there is another autoloader. That might be
confusing, for example if you set a logger and miss traces. On the other
hand, the name `once_autoloader` is very close to being horrible.
Rails.autoloaders.main and Rails.autoloaders.once read better for my
taste, and have a nice symmetry. Also, both "main" and "once" are four
letters long, short and same length.
They are tagged as "rails.main" and "rails.once", respectively.
References #35235.
We had a discussion on the Core team and we don't want to expose this information
as a JSON endpoint and not by default.
It doesn't make sense to expose this JSON locally and this controller is only
accessible in dev, so the proposed access from a production app seems off.
This reverts commit 8eaffe7e89719ac62ff29c2e4208cfbeb1cd1c38, reversing
changes made to b6e4305c3bca4c673996d0af9db0f4cfbf50215e.
Generally followed the pattern for https://github.com/rails/rails/pull/32034
* Removes needless CI configs for 2.4
* Targets 2.5 in rubocop
* Updates existing CHANGELOG entries for fewer merge conflicts
* Removes Hash#slice extension as that's inlined on Ruby 2.5.
* Removes the need for send on define_method in MethodCallAssertions.