railties 5.2.4 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +284 -130
- data/MIT-LICENSE +1 -1
- data/RDOC_MAIN.rdoc +38 -31
- data/README.rdoc +2 -2
- data/lib/minitest/rails_plugin.rb +7 -11
- data/lib/rails.rb +5 -0
- data/lib/rails/all.rb +4 -0
- data/lib/rails/api/generator.rb +2 -1
- data/lib/rails/api/task.rb +16 -0
- data/lib/rails/app_loader.rb +2 -2
- data/lib/rails/app_updater.rb +3 -1
- data/lib/rails/application.rb +71 -29
- data/lib/rails/application/bootstrap.rb +2 -10
- data/lib/rails/application/configuration.rb +113 -13
- data/lib/rails/application/default_middleware_stack.rb +3 -0
- data/lib/rails/application/dummy_erb_compiler.rb +18 -0
- data/lib/rails/application/finisher.rb +54 -0
- data/lib/rails/autoloaders.rb +48 -0
- data/lib/rails/backtrace_cleaner.rb +5 -17
- data/lib/rails/code_statistics.rb +3 -3
- data/lib/rails/command.rb +11 -10
- data/lib/rails/command/base.rb +12 -8
- data/lib/rails/command/behavior.rb +7 -48
- data/lib/rails/command/environment_argument.rb +8 -15
- data/lib/rails/command/spellchecker.rb +58 -0
- data/lib/rails/commands/console/console_command.rb +6 -0
- data/lib/rails/commands/credentials/USAGE +19 -1
- data/lib/rails/commands/credentials/credentials_command.rb +52 -19
- data/lib/rails/commands/db/system/change/change_command.rb +20 -0
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +20 -8
- data/lib/rails/commands/dev/dev_command.rb +19 -0
- data/lib/rails/commands/encrypted/USAGE +1 -1
- data/lib/rails/commands/encrypted/encrypted_command.rb +2 -2
- data/lib/rails/commands/help/help_command.rb +1 -1
- data/lib/rails/commands/initializers/initializers_command.rb +23 -0
- data/lib/rails/commands/new/new_command.rb +2 -2
- data/lib/rails/commands/notes/notes_command.rb +39 -0
- data/lib/rails/commands/plugin/plugin_command.rb +1 -1
- data/lib/rails/commands/routes/routes_command.rb +37 -0
- data/lib/rails/commands/runner/runner_command.rb +13 -9
- data/lib/rails/commands/secrets/USAGE +3 -3
- data/lib/rails/commands/secrets/secrets_command.rb +3 -3
- data/lib/rails/commands/server/server_command.rb +113 -50
- data/lib/rails/configuration.rb +1 -7
- data/lib/rails/engine.rb +24 -16
- data/lib/rails/engine/configuration.rb +5 -2
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators.rb +11 -10
- data/lib/rails/generators/actions.rb +52 -39
- data/lib/rails/generators/app_base.rb +52 -92
- data/lib/rails/generators/app_name.rb +50 -0
- data/lib/rails/generators/base.rb +0 -4
- data/lib/rails/generators/database.rb +58 -0
- data/lib/rails/generators/erb/mailer/mailer_generator.rb +1 -1
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +6 -3
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +1 -1
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +9 -1
- data/lib/rails/generators/generated_attribute.rb +53 -27
- data/lib/rails/generators/migration.rb +1 -2
- data/lib/rails/generators/model_helpers.rb +8 -1
- data/lib/rails/generators/named_base.rb +1 -5
- data/lib/rails/generators/rails/app/app_generator.rb +37 -72
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +7 -10
- data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -3
- data/lib/rails/generators/rails/app/templates/app/{assets/javascripts/cable.js.tt → javascript/channels/consumer.js} +2 -9
- data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +5 -0
- data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +23 -0
- data/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt +5 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +7 -7
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +2 -0
- data/lib/rails/generators/rails/app/templates/config/cable.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +4 -4
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +6 -6
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +5 -2
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +28 -12
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +13 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +7 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt +45 -0
- data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +4 -3
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +6 -6
- data/lib/rails/generators/rails/app/templates/gitignore.tt +2 -7
- data/lib/rails/generators/rails/app/templates/package.json.tt +7 -1
- data/lib/rails/generators/rails/app/templates/public/robots.txt +1 -1
- data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +11 -0
- data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +7 -0
- data/lib/rails/generators/rails/assets/USAGE +1 -4
- data/lib/rails/generators/rails/assets/assets_generator.rb +0 -1
- data/lib/rails/generators/rails/controller/controller_generator.rb +11 -1
- data/lib/rails/generators/rails/credentials/credentials_generator.rb +7 -8
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +65 -0
- data/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb +4 -5
- data/lib/rails/generators/rails/helper/helper_generator.rb +5 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +9 -33
- data/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/gitignore.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +1 -2
- data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +14 -0
- data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -1
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +1 -1
- data/lib/rails/generators/resource_helpers.rb +1 -6
- data/lib/rails/generators/test_unit/integration/integration_generator.rb +6 -0
- data/lib/rails/generators/test_unit/job/job_generator.rb +5 -0
- data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +1 -1
- data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +8 -3
- data/lib/rails/generators/test_unit/system/system_generator.rb +5 -0
- data/lib/rails/generators/testing/behaviour.rb +3 -0
- data/lib/rails/info.rb +2 -2
- data/lib/rails/info_controller.rb +1 -1
- data/lib/rails/mailers_controller.rb +7 -4
- data/lib/rails/paths.rb +19 -9
- data/lib/rails/railtie.rb +1 -1
- data/lib/rails/ruby_version_check.rb +3 -3
- data/lib/rails/secrets.rb +0 -1
- data/lib/rails/source_annotation_extractor.rb +138 -117
- data/lib/rails/tasks.rb +1 -0
- data/lib/rails/tasks/annotations.rake +9 -9
- data/lib/rails/tasks/dev.rake +5 -4
- data/lib/rails/tasks/framework.rake +5 -1
- data/lib/rails/tasks/initializers.rake +5 -4
- data/lib/rails/tasks/log.rake +0 -1
- data/lib/rails/tasks/routes.rake +4 -26
- data/lib/rails/tasks/statistics.rake +4 -0
- data/lib/rails/tasks/yarn.rake +1 -1
- data/lib/rails/tasks/zeitwerk.rake +66 -0
- data/lib/rails/templates/rails/welcome/index.html.erb +2 -2
- data/lib/rails/test_help.rb +11 -9
- data/lib/rails/test_unit/reporter.rb +1 -1
- data/lib/rails/test_unit/runner.rb +5 -5
- data/lib/rails/test_unit/testing.rake +1 -1
- metadata +32 -23
- data/lib/rails/generators/js/assets/assets_generator.rb +0 -15
- data/lib/rails/generators/js/assets/templates/javascript.js +0 -2
- data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +0 -22
- data/lib/rails/generators/rails/app/templates/bin/bundle.tt +0 -2
- data/lib/rails/generators/rails/app/templates/bin/update.tt +0 -34
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt +0 -38
- data/lib/rails/generators/rails/assets/templates/javascript.js +0 -2
@@ -34,20 +34,12 @@ INFO
|
|
34
34
|
# Initialize the logger early in the stack in case we need to log some deprecation.
|
35
35
|
initializer :initialize_logger, group: :all do
|
36
36
|
Rails.logger ||= config.logger || begin
|
37
|
-
|
38
|
-
unless File.exist? File.dirname path
|
39
|
-
FileUtils.mkdir_p File.dirname path
|
40
|
-
end
|
41
|
-
|
42
|
-
f = File.open path, "a"
|
43
|
-
f.binmode
|
44
|
-
f.sync = config.autoflush_log # if true make sure every write flushes
|
45
|
-
|
46
|
-
logger = ActiveSupport::Logger.new f
|
37
|
+
logger = ActiveSupport::Logger.new(config.default_log_file)
|
47
38
|
logger.formatter = config.log_formatter
|
48
39
|
logger = ActiveSupport::TaggedLogging.new(logger)
|
49
40
|
logger
|
50
41
|
rescue StandardError
|
42
|
+
path = config.paths["log"].first
|
51
43
|
logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDERR))
|
52
44
|
logger.level = ActiveSupport::Logger::WARN
|
53
45
|
logger.warn(
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "ipaddr"
|
3
4
|
require "active_support/core_ext/kernel/reporting"
|
4
5
|
require "active_support/file_update_checker"
|
5
6
|
require "rails/engine/configuration"
|
@@ -11,15 +12,16 @@ module Rails
|
|
11
12
|
attr_accessor :allow_concurrency, :asset_host, :autoflush_log,
|
12
13
|
:cache_classes, :cache_store, :consider_all_requests_local, :console,
|
13
14
|
:eager_load, :exceptions_app, :file_watcher, :filter_parameters,
|
14
|
-
:force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags,
|
15
|
-
:railties_order, :relative_url_root, :secret_key_base,
|
15
|
+
:force_ssl, :helpers_paths, :hosts, :logger, :log_formatter, :log_tags,
|
16
|
+
:railties_order, :relative_url_root, :secret_key_base,
|
16
17
|
:ssl_options, :public_file_server,
|
17
18
|
:session_options, :time_zone, :reload_classes_only_on_change,
|
18
19
|
:beginning_of_week, :filter_redirect, :x, :enable_dependency_loading,
|
19
20
|
:read_encrypted_secrets, :log_level, :content_security_policy_report_only,
|
20
|
-
:content_security_policy_nonce_generator, :
|
21
|
+
:content_security_policy_nonce_generator, :content_security_policy_nonce_directives,
|
22
|
+
:require_master_key, :credentials, :disable_sandbox, :add_autoload_paths_to_load_path
|
21
23
|
|
22
|
-
attr_reader :encoding, :api_only, :loaded_config_version
|
24
|
+
attr_reader :encoding, :api_only, :loaded_config_version, :autoloader
|
23
25
|
|
24
26
|
def initialize(*)
|
25
27
|
super
|
@@ -29,6 +31,7 @@ module Rails
|
|
29
31
|
@filter_parameters = []
|
30
32
|
@filter_redirect = []
|
31
33
|
@helpers_paths = []
|
34
|
+
@hosts = Array(([IPAddr.new("0.0.0.0/0"), IPAddr.new("::/0"), ".localhost"] if Rails.env.development?))
|
32
35
|
@public_file_server = ActiveSupport::OrderedOptions.new
|
33
36
|
@public_file_server.enabled = true
|
34
37
|
@public_file_server.index_name = "index"
|
@@ -48,7 +51,6 @@ module Rails
|
|
48
51
|
@autoflush_log = true
|
49
52
|
@log_formatter = ActiveSupport::Logger::SimpleFormatter.new
|
50
53
|
@eager_load = nil
|
51
|
-
@secret_token = nil
|
52
54
|
@secret_key_base = nil
|
53
55
|
@api_only = false
|
54
56
|
@debug_exception_response_format = nil
|
@@ -58,8 +60,15 @@ module Rails
|
|
58
60
|
@content_security_policy = nil
|
59
61
|
@content_security_policy_report_only = false
|
60
62
|
@content_security_policy_nonce_generator = nil
|
63
|
+
@content_security_policy_nonce_directives = nil
|
61
64
|
@require_master_key = false
|
62
65
|
@loaded_config_version = nil
|
66
|
+
@credentials = ActiveSupport::OrderedOptions.new
|
67
|
+
@credentials.content_path = default_credentials_content_path
|
68
|
+
@credentials.key_path = default_credentials_key_path
|
69
|
+
@autoloader = :classic
|
70
|
+
@disable_sandbox = false
|
71
|
+
@add_autoload_paths_to_load_path = true
|
63
72
|
end
|
64
73
|
|
65
74
|
def load_defaults(target_version)
|
@@ -92,10 +101,6 @@ module Rails
|
|
92
101
|
|
93
102
|
if respond_to?(:active_record)
|
94
103
|
active_record.cache_versioning = true
|
95
|
-
# Remove the temporary load hook from SQLite3Adapter when this is removed
|
96
|
-
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
97
|
-
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = true
|
98
|
-
end
|
99
104
|
end
|
100
105
|
|
101
106
|
if respond_to?(:action_dispatch)
|
@@ -114,6 +119,38 @@ module Rails
|
|
114
119
|
if respond_to?(:action_view)
|
115
120
|
action_view.form_with_generates_ids = true
|
116
121
|
end
|
122
|
+
when "6.0"
|
123
|
+
load_defaults "5.2"
|
124
|
+
|
125
|
+
self.autoloader = :zeitwerk if RUBY_ENGINE == "ruby"
|
126
|
+
|
127
|
+
if respond_to?(:action_view)
|
128
|
+
action_view.default_enforce_utf8 = false
|
129
|
+
end
|
130
|
+
|
131
|
+
if respond_to?(:action_dispatch)
|
132
|
+
action_dispatch.use_cookies_with_metadata = true
|
133
|
+
action_dispatch.return_only_media_type_on_content_type = false
|
134
|
+
end
|
135
|
+
|
136
|
+
if respond_to?(:action_mailer)
|
137
|
+
action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"
|
138
|
+
end
|
139
|
+
|
140
|
+
if respond_to?(:active_job)
|
141
|
+
active_job.return_false_on_aborted_enqueue = true
|
142
|
+
end
|
143
|
+
|
144
|
+
if respond_to?(:active_storage)
|
145
|
+
active_storage.queues.analysis = :active_storage_analysis
|
146
|
+
active_storage.queues.purge = :active_storage_purge
|
147
|
+
|
148
|
+
active_storage.replace_on_assign_to_many = true
|
149
|
+
end
|
150
|
+
|
151
|
+
if respond_to?(:active_record)
|
152
|
+
active_record.collection_cache_versioning = true
|
153
|
+
end
|
117
154
|
else
|
118
155
|
raise "Unknown version #{target_version.to_s.inspect}"
|
119
156
|
end
|
@@ -140,9 +177,7 @@ module Rails
|
|
140
177
|
@debug_exception_response_format || :default
|
141
178
|
end
|
142
179
|
|
143
|
-
|
144
|
-
@debug_exception_response_format = value
|
145
|
-
end
|
180
|
+
attr_writer :debug_exception_response_format
|
146
181
|
|
147
182
|
def paths
|
148
183
|
@paths ||= begin
|
@@ -160,6 +195,26 @@ module Rails
|
|
160
195
|
end
|
161
196
|
end
|
162
197
|
|
198
|
+
# Load the database YAML without evaluating ERB. This allows us to
|
199
|
+
# create the rake tasks for multiple databases without filling in the
|
200
|
+
# configuration values or loading the environment. Do not use this
|
201
|
+
# method.
|
202
|
+
#
|
203
|
+
# This uses a DummyERB custom compiler so YAML can ignore the ERB
|
204
|
+
# tags and load the database.yml for the rake tasks.
|
205
|
+
def load_database_yaml # :nodoc:
|
206
|
+
if path = paths["config/database"].existent.first
|
207
|
+
require "rails/application/dummy_erb_compiler"
|
208
|
+
|
209
|
+
yaml = Pathname.new(path)
|
210
|
+
erb = DummyERB.new(yaml.read)
|
211
|
+
|
212
|
+
YAML.load(erb.result) || {}
|
213
|
+
else
|
214
|
+
{}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
163
218
|
# Loads and returns the entire raw configuration of database from
|
164
219
|
# values stored in <tt>config/database.yml</tt>.
|
165
220
|
def database_configuration
|
@@ -235,7 +290,7 @@ module Rails
|
|
235
290
|
end
|
236
291
|
|
237
292
|
def annotations
|
238
|
-
SourceAnnotationExtractor::Annotation
|
293
|
+
Rails::SourceAnnotationExtractor::Annotation
|
239
294
|
end
|
240
295
|
|
241
296
|
def content_security_policy(&block)
|
@@ -246,6 +301,30 @@ module Rails
|
|
246
301
|
end
|
247
302
|
end
|
248
303
|
|
304
|
+
def autoloader=(autoloader)
|
305
|
+
case autoloader
|
306
|
+
when :classic
|
307
|
+
@autoloader = autoloader
|
308
|
+
when :zeitwerk
|
309
|
+
require "zeitwerk"
|
310
|
+
@autoloader = autoloader
|
311
|
+
else
|
312
|
+
raise ArgumentError, "config.autoloader may be :classic or :zeitwerk, got #{autoloader.inspect} instead"
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def default_log_file
|
317
|
+
path = paths["log"].first
|
318
|
+
unless File.exist? File.dirname path
|
319
|
+
FileUtils.mkdir_p File.dirname path
|
320
|
+
end
|
321
|
+
|
322
|
+
f = File.open path, "a"
|
323
|
+
f.binmode
|
324
|
+
f.sync = autoflush_log # if true make sure every write flushes
|
325
|
+
f
|
326
|
+
end
|
327
|
+
|
249
328
|
class Custom #:nodoc:
|
250
329
|
def initialize
|
251
330
|
@configurations = Hash.new
|
@@ -265,6 +344,27 @@ module Rails
|
|
265
344
|
true
|
266
345
|
end
|
267
346
|
end
|
347
|
+
|
348
|
+
private
|
349
|
+
def default_credentials_content_path
|
350
|
+
if credentials_available_for_current_env?
|
351
|
+
root.join("config", "credentials", "#{Rails.env}.yml.enc")
|
352
|
+
else
|
353
|
+
root.join("config", "credentials.yml.enc")
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def default_credentials_key_path
|
358
|
+
if credentials_available_for_current_env?
|
359
|
+
root.join("config", "credentials", "#{Rails.env}.key")
|
360
|
+
else
|
361
|
+
root.join("config", "master.key")
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def credentials_available_for_current_env?
|
366
|
+
File.exist?(root.join("config", "credentials", "#{Rails.env}.yml.enc"))
|
367
|
+
end
|
268
368
|
end
|
269
369
|
end
|
270
370
|
end
|
@@ -13,6 +13,8 @@ module Rails
|
|
13
13
|
|
14
14
|
def build_stack
|
15
15
|
ActionDispatch::MiddlewareStack.new do |middleware|
|
16
|
+
middleware.use ::ActionDispatch::HostAuthorization, config.hosts, config.action_dispatch.hosts_response_app
|
17
|
+
|
16
18
|
if config.force_ssl
|
17
19
|
middleware.use ::ActionDispatch::SSL, config.ssl_options
|
18
20
|
end
|
@@ -47,6 +49,7 @@ module Rails
|
|
47
49
|
middleware.use ::Rails::Rack::Logger, config.log_tags
|
48
50
|
middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
|
49
51
|
middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format
|
52
|
+
middleware.use ::ActionDispatch::ActionableExceptions
|
50
53
|
|
51
54
|
unless config.cache_classes
|
52
55
|
middleware.use ::ActionDispatch::Reloader, app.reloader
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# These classes are used to strip out the ERB configuration
|
4
|
+
# values so we can evaluate the database.yml without evaluating
|
5
|
+
# the ERB values.
|
6
|
+
class DummyERB < ERB # :nodoc:
|
7
|
+
def make_compiler(trim_mode)
|
8
|
+
DummyCompiler.new trim_mode
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class DummyCompiler < ERB::Compiler # :nodoc:
|
13
|
+
def compile_content(stag, out)
|
14
|
+
if stag == "<%="
|
15
|
+
out.push "_erbout << ''"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/string/inflections"
|
4
|
+
require "active_support/core_ext/array/conversions"
|
5
|
+
|
3
6
|
module Rails
|
4
7
|
class Application
|
5
8
|
module Finisher
|
@@ -21,6 +24,53 @@ module Rails
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
27
|
+
# This will become an error if/when we remove classic mode. The plan is
|
28
|
+
# autoloaders won't be configured up to this point in the finisher, so
|
29
|
+
# constants just won't be found, raising regular NameError exceptions.
|
30
|
+
initializer :warn_if_autoloaded, before: :let_zeitwerk_take_over do
|
31
|
+
next if config.cache_classes
|
32
|
+
next if ActiveSupport::Dependencies.autoloaded_constants.empty?
|
33
|
+
|
34
|
+
autoloaded = ActiveSupport::Dependencies.autoloaded_constants
|
35
|
+
constants = "constant".pluralize(autoloaded.size)
|
36
|
+
enum = autoloaded.to_sentence
|
37
|
+
have = autoloaded.size == 1 ? "has" : "have"
|
38
|
+
these = autoloaded.size == 1 ? "This" : "These"
|
39
|
+
example = autoloaded.first
|
40
|
+
example_klass = example.constantize.class
|
41
|
+
|
42
|
+
if config.autoloader == :zeitwerk
|
43
|
+
ActiveSupport::DescendantsTracker.clear
|
44
|
+
ActiveSupport::Dependencies.clear
|
45
|
+
|
46
|
+
unload_message = "#{these} autoloaded #{constants} #{have} been unloaded."
|
47
|
+
else
|
48
|
+
unload_message = "`config.autoloader` is set to `#{config.autoloader}`. #{these} autoloaded #{constants} would have been unloaded if `config.autoloader` had been set to `:zeitwerk`."
|
49
|
+
end
|
50
|
+
|
51
|
+
ActiveSupport::Deprecation.warn(<<~WARNING)
|
52
|
+
Initialization autoloaded the #{constants} #{enum}.
|
53
|
+
|
54
|
+
Being able to do this is deprecated. Autoloading during initialization is going
|
55
|
+
to be an error condition in future versions of Rails.
|
56
|
+
|
57
|
+
Reloading does not reboot the application, and therefore code executed during
|
58
|
+
initialization does not run again. So, if you reload #{example}, for example,
|
59
|
+
the expected changes won't be reflected in that stale #{example_klass} object.
|
60
|
+
|
61
|
+
#{unload_message}
|
62
|
+
|
63
|
+
Please, check the "Autoloading and Reloading Constants" guide for solutions.
|
64
|
+
WARNING
|
65
|
+
end
|
66
|
+
|
67
|
+
initializer :let_zeitwerk_take_over do
|
68
|
+
if config.autoloader == :zeitwerk
|
69
|
+
require "active_support/dependencies/zeitwerk_integration"
|
70
|
+
ActiveSupport::Dependencies::ZeitwerkIntegration.take_over(enable_reloading: !config.cache_classes)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
24
74
|
initializer :add_builtin_route do |app|
|
25
75
|
if Rails.env.development?
|
26
76
|
app.routes.prepend do
|
@@ -66,6 +116,10 @@ module Rails
|
|
66
116
|
initializer :eager_load! do
|
67
117
|
if config.eager_load
|
68
118
|
ActiveSupport.run_load_hooks(:before_eager_load, self)
|
119
|
+
# Checks defined?(Zeitwerk) instead of zeitwerk_enabled? because we
|
120
|
+
# want to eager load any dependency managed by Zeitwerk regardless of
|
121
|
+
# the autoloading mode of the application.
|
122
|
+
Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk)
|
69
123
|
config.eager_load_namespaces.each(&:eager_load!)
|
70
124
|
end
|
71
125
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/dependencies/zeitwerk_integration"
|
4
|
+
|
5
|
+
module Rails
|
6
|
+
module Autoloaders # :nodoc:
|
7
|
+
class << self
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def main
|
11
|
+
if zeitwerk_enabled?
|
12
|
+
@main ||= Zeitwerk::Loader.new.tap do |loader|
|
13
|
+
loader.tag = "rails.main"
|
14
|
+
loader.inflector = ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def once
|
20
|
+
if zeitwerk_enabled?
|
21
|
+
@once ||= Zeitwerk::Loader.new.tap do |loader|
|
22
|
+
loader.tag = "rails.once"
|
23
|
+
loader.inflector = ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def each
|
29
|
+
if zeitwerk_enabled?
|
30
|
+
yield main
|
31
|
+
yield once
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def logger=(logger)
|
36
|
+
each { |loader| loader.logger = logger }
|
37
|
+
end
|
38
|
+
|
39
|
+
def log!
|
40
|
+
each(&:log!)
|
41
|
+
end
|
42
|
+
|
43
|
+
def zeitwerk_enabled?
|
44
|
+
Rails.configuration.autoloader == :zeitwerk
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -5,30 +5,18 @@ require "active_support/backtrace_cleaner"
|
|
5
5
|
module Rails
|
6
6
|
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
|
7
7
|
APP_DIRS_PATTERN = /^\/?(app|config|lib|test|\(\w*\))/
|
8
|
-
RENDER_TEMPLATE_PATTERN = /:in
|
9
|
-
EMPTY_STRING = ""
|
10
|
-
SLASH = "/"
|
11
|
-
DOT_SLASH = "./"
|
8
|
+
RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/
|
9
|
+
EMPTY_STRING = ""
|
10
|
+
SLASH = "/"
|
11
|
+
DOT_SLASH = "./"
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
super
|
15
|
-
@root = "#{Rails.root}/"
|
15
|
+
@root = "#{Rails.root}/"
|
16
16
|
add_filter { |line| line.sub(@root, EMPTY_STRING) }
|
17
17
|
add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, EMPTY_STRING) }
|
18
18
|
add_filter { |line| line.sub(DOT_SLASH, SLASH) } # for tests
|
19
|
-
|
20
|
-
add_gem_filters
|
21
19
|
add_silencer { |line| !APP_DIRS_PATTERN.match?(line) }
|
22
20
|
end
|
23
|
-
|
24
|
-
private
|
25
|
-
def add_gem_filters
|
26
|
-
gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
|
27
|
-
return if gems_paths.empty?
|
28
|
-
|
29
|
-
gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
|
30
|
-
gems_result = '\2 (\3) \4'.freeze
|
31
|
-
add_filter { |line| line.sub(gems_regexp, gems_result) }
|
32
|
-
end
|
33
21
|
end
|
34
22
|
end
|
@@ -46,7 +46,7 @@ class CodeStatistics #:nodoc:
|
|
46
46
|
|
47
47
|
if File.directory?(path) && (/^\./ !~ file_name)
|
48
48
|
stats.add(calculate_directory_statistics(path, pattern))
|
49
|
-
elsif file_name
|
49
|
+
elsif file_name&.match?(pattern)
|
50
50
|
stats.add_by_file_path(path)
|
51
51
|
end
|
52
52
|
end
|
@@ -95,8 +95,8 @@ class CodeStatistics #:nodoc:
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def print_line(name, statistics)
|
98
|
-
m_over_c = (statistics.methods / statistics.classes) rescue
|
99
|
-
loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue
|
98
|
+
m_over_c = (statistics.methods / statistics.classes) rescue 0
|
99
|
+
loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue 0
|
100
100
|
|
101
101
|
print "| #{name.ljust(20)} "
|
102
102
|
HEADERS.each_key do |k|
|