aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELEASING_RAILS.md2
-rw-r--r--actionview/app/assets/javascripts/README.md2
-rw-r--r--activerecord/CHANGELOG.md2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb4
-rw-r--r--activerecord/lib/active_record/transactions.rb4
-rw-r--r--guides/source/5_1_release_notes.md4
-rw-r--r--guides/source/6_0_release_notes.md2
-rw-r--r--guides/source/upgrading_ruby_on_rails.md36
-rw-r--r--railties/lib/rails/tasks/zeitwerk.rake73
11 files changed, 98 insertions, 35 deletions
diff --git a/RELEASING_RAILS.md b/RELEASING_RAILS.md
index d2d7a771bc..bc39e2313d 100644
--- a/RELEASING_RAILS.md
+++ b/RELEASING_RAILS.md
@@ -125,7 +125,7 @@ guide. You can generate keys with the GPG suite from here: https://gpgtools.org.
Run `rake changelog:header` to put a header with the new version in every
CHANGELOG. Don't commit this, the release task handles it.
-Run `rake release`. This will populate the gemspecs and NPM package.json with
+Run `rake release`. This will populate the gemspecs and npm package.json with
the current RAILS_VERSION, commit the changes, tag it, and push the gems to
rubygems.org.
diff --git a/actionview/app/assets/javascripts/README.md b/actionview/app/assets/javascripts/README.md
index aa167004b6..c9282ba76f 100644
--- a/actionview/app/assets/javascripts/README.md
+++ b/actionview/app/assets/javascripts/README.md
@@ -15,7 +15,7 @@ Note that the `data` attributes this library adds are a feature of HTML5. If you
## Installation
-### NPM
+### npm
npm install @rails/ujs --save
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index a787e6dca7..8c5342edb2 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,4 +1,4 @@
-* Allow generated create_table migrations to include or skip timestamps
+* Allow generated `create_table` migrations to include or skip timestamps.
*Michael Duchemin*
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index ef19538447..044272ea51 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -205,8 +205,6 @@ module ActiveRecord
# In order to get around this problem, #transaction will emulate the effect
# of nested transactions, by using savepoints:
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
- # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
- # supports savepoints.
#
# It is safe to call this method if a database transaction is already open,
# i.e. if #transaction is called within another #transaction block. In case
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 2b64e96450..f97842b3f5 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -735,7 +735,7 @@ module ActiveRecord
#
# CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
#
- # Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+.
+ # Note: Partial indexes are only supported for PostgreSQL and SQLite.
#
# ====== Creating an index with a specific method
#
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index f5f5827d04..41b35d9fc6 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -48,8 +48,8 @@ module ActiveRecord
end
module ConnectionAdapters #:nodoc:
- # The SQLite3 adapter works SQLite 3.6.16 or newer
- # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
+ # The SQLite3 adapter works with the sqlite3-ruby drivers
+ # (available as gem from https://rubygems.org/gems/sqlite3).
#
# Options:
#
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 148bc0550c..cbb970ac98 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -164,12 +164,12 @@ module ActiveRecord
# end
# end
#
- # only "Kotori" is created. This works on MySQL and PostgreSQL. SQLite3 version >= '3.6.8' also supports it.
+ # only "Kotori" is created.
#
# Most databases don't support true nested transactions. At the time of
# writing, the only database that we're aware of that supports true nested
# transactions, is MS-SQL. Because of this, Active Record emulates nested
- # transactions by using savepoints on MySQL and PostgreSQL. See
+ # transactions by using savepoints. See
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
# for more information about savepoints.
#
diff --git a/guides/source/5_1_release_notes.md b/guides/source/5_1_release_notes.md
index e885b1e42e..f870c4c47c 100644
--- a/guides/source/5_1_release_notes.md
+++ b/guides/source/5_1_release_notes.md
@@ -41,8 +41,8 @@ Major Features
[Pull Request](https://github.com/rails/rails/pull/26836)
Rails 5.1 allows managing JavaScript dependencies
-from NPM via Yarn. This will make it easy to use libraries like React, VueJS
-or any other library from NPM world. The Yarn support is integrated with
+from npm via Yarn. This will make it easy to use libraries like React, VueJS
+or any other library from npm world. The Yarn support is integrated with
the asset pipeline so that all dependencies will work seamlessly with the
Rails 5.1 app.
diff --git a/guides/source/6_0_release_notes.md b/guides/source/6_0_release_notes.md
index 1b37bf50e1..fa45e7240d 100644
--- a/guides/source/6_0_release_notes.md
+++ b/guides/source/6_0_release_notes.md
@@ -245,7 +245,7 @@ Please refer to the [Changelog][action-pack] for detailed changes.
* Expose `ActionController::Parameters#each_key`.
([Pull Request](https://github.com/rails/rails/pull/33758))
-* Add purpose metadata to signed/encrypted cookies to prevent copying the value of
+* Add purpose and expiry metadata inside signed/encrypted cookies to prevent copying the value of
cookies into one another.
([Pull Request](https://github.com/rails/rails/pull/32937))
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 76ee5c0c48..10a9f24c9a 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -85,13 +85,14 @@ Rails 6.1. You are encouraged to enable `config.force_ssl` to enforce HTTPS
connections throughout your application. If you need to exempt certain endpoints
from redirection, you can use `config.ssl_options` to configure that behavior.
-### Purpose in signed or encrypted cookie is now embedded within cookies
+### Purpose and expiry metadata is now embedded inside signed and encrypted cookies for increased security
+
+To improve security, Rails embeds the purpose and expiry metadata inside encrypted or signed cookies value.
-To improve security, Rails embeds the purpose information in encrypted or signed cookies value.
Rails can then thwart attacks that attempt to copy the signed/encrypted value
of a cookie and use it as the value of another cookie.
-This new embed information make those cookies incompatible with versions of Rails older than 6.0.
+This new embed metadata make those cookies incompatible with versions of Rails older than 6.0.
If you require your cookies to be read by Rails 5.2 and older, or you are still validating your 6.0 deploy and want
to be able to rollback set
@@ -281,6 +282,35 @@ won't work, child objects like `Hotel::Pricing` won't be found.
This restriction only applies to explicit namespaces. Classes and modules not defining a namespace can be defined using those idioms.
+#### One file, one constant (at the same top-level)
+
+In `classic` mode you could technically define several constants at the same top-level and have them all reloaded. For example, given
+
+```ruby
+# app/models/foo.rb
+
+class Foo
+end
+
+class Bar
+end
+```
+
+while `Bar` could not be autoloaded, autoloading `Foo` would mark `Bar` as autoloaded too. This is not the case in `zeitwerk` mode, you need to move `Bar` to its own file `bar.rb`. One file, one constant.
+
+This affects only to constants at the same top-level as in the example above. Inner classes and modules are fine. For example, consider
+
+```ruby
+# app/models/foo.rb
+
+class Foo
+ class InnerClass
+ end
+end
+```
+
+If the application reloads `Foo`, it will reload `Foo::InnerClass` too.
+
#### Spring and the `test` Environment
Spring reloads the application code if something changes. In the `test` environment you need to enable reloading for that to work:
diff --git a/railties/lib/rails/tasks/zeitwerk.rake b/railties/lib/rails/tasks/zeitwerk.rake
index b7f5cd154b..e748a479a7 100644
--- a/railties/lib/rails/tasks/zeitwerk.rake
+++ b/railties/lib/rails/tasks/zeitwerk.rake
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+indent = " " * 2
+
ensure_classic_mode = ->() do
if Rails.autoloaders.zeitwerk_enabled?
abort <<~EOS
@@ -17,8 +19,7 @@ eager_load = ->() do
Rails.configuration.eager_load_namespaces.each(&:eager_load!)
end
-mismatches = []
-check_directory = ->(directory, parent) do
+check_directory = ->(directory, parent, mismatches) do
# test/mailers/previews might not exist.
return unless File.exist?(directory)
@@ -33,7 +34,7 @@ check_directory = ->(directory, parent) do
cname = File.basename(abspath, ".rb").camelize.to_sym
if parent.const_defined?(cname, false)
if File.directory?(abspath)
- check_directory[abspath, parent.const_get(cname)]
+ check_directory[abspath, parent.const_get(cname), mismatches]
end
else
mismatches << [abspath, parent, cname]
@@ -42,22 +43,47 @@ check_directory = ->(directory, parent) do
end
end
-report = ->() do
+report_mismatches = ->(mismatches) do
+ puts
+ rails_root_prefix_re = %r{\A#{Regexp.escape(Rails.root.to_path)}/}
+ mismatches.each do |abspath, parent, cname|
+ relpath = abspath.sub(rails_root_prefix_re, "")
+ cpath = parent == Object ? cname : "#{parent.name}::#{cname}"
+ puts indent + "Mismatch: Expected #{relpath} to define #{cpath}"
+ end
+ puts
+
+ puts <<~EOS
+ Please revise the reported mismatches. You can normally fix them by adding
+ acronyms to config/initializers/inflections.rb or renaming the constants.
+ EOS
+end
+
+report_not_checked = ->(not_checked) do
+ puts
+ puts <<~EOS
+ WARNING: The files in these directories cannot be checked because they
+ are not eager loaded:
+ EOS
+ puts
+
+ not_checked.each { |dir| puts indent + dir }
puts
- if mismatches.empty?
+
+ puts <<~EOS
+ You may verify them manually, or add them to config.eager_load_paths
+ in config/application.rb and run zeitwerk:check again.
+ EOS
+end
+
+report = ->(mismatches, not_checked) do
+ puts
+ if mismatches.empty? && not_checked.empty?
puts "All is good!"
puts "Please, remember to delete `config.autoloader = :classic` from config/application.rb."
else
- mismatches.each do |abspath, parent, cname|
- relpath = abspath.sub(%r{\A#{Regexp.escape(Rails.root.to_path)}/}, "")
- cpath = parent == Object ? cname : "#{parent.name}::#{cname}"
- puts "expected #{relpath} to define #{cpath}"
- end
- puts
- puts <<~EOS
- Please revise the reported mismatches. You can normally fix them by adding
- acronyms to config/initializers/inflections.rb or renaming the constants.
- EOS
+ report_mismatches[mismatches] if mismatches.any?
+ report_not_checked[not_checked] if not_checked.any?
end
end
@@ -67,12 +93,21 @@ namespace :zeitwerk do
ensure_classic_mode[]
eager_load[]
+ eager_load_paths = Rails.configuration.eager_load_namespaces.map do |eln|
+ eln.config.eager_load_paths if eln.respond_to?(:config)
+ end.compact.flatten
+
+ mismatches = []
+
$stdout.sync = true
- ActiveSupport::Dependencies.autoload_paths.each do |autoload_path|
- check_directory[autoload_path, Object]
+ eager_load_paths.each do |eager_load_path|
+ check_directory[eager_load_path, Object, mismatches]
end
- puts
- report[]
+ not_checked = ActiveSupport::Dependencies.autoload_paths - eager_load_paths
+ not_checked.select! { |dir| Dir.exist?(dir) }
+ not_checked.reject! { |dir| Dir.empty?(dir) }
+
+ report[mismatches, not_checked]
end
end