railties 7.1.0 → 7.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +203 -650
  3. data/lib/minitest/rails_plugin.rb +5 -2
  4. data/lib/rails/all.rb +1 -3
  5. data/lib/rails/api/task.rb +6 -4
  6. data/lib/rails/application/bootstrap.rb +11 -8
  7. data/lib/rails/application/configuration.rb +80 -36
  8. data/lib/rails/application/dummy_config.rb +2 -2
  9. data/lib/rails/application/finisher.rb +10 -0
  10. data/lib/rails/application.rb +29 -76
  11. data/lib/rails/backtrace_cleaner.rb +18 -3
  12. data/lib/rails/cli.rb +0 -1
  13. data/lib/rails/command.rb +1 -1
  14. data/lib/rails/commands/app/update_command.rb +102 -0
  15. data/lib/rails/commands/boot/boot_command.rb +14 -0
  16. data/lib/rails/commands/console/console_command.rb +2 -21
  17. data/lib/rails/commands/console/irb_console.rb +146 -0
  18. data/lib/rails/commands/credentials/USAGE +1 -1
  19. data/lib/rails/commands/credentials/credentials_command.rb +2 -2
  20. data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
  21. data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
  22. data/lib/rails/commands/rake/rake_command.rb +1 -1
  23. data/lib/rails/commands/runner/runner_command.rb +14 -3
  24. data/lib/rails/commands/server/server_command.rb +5 -3
  25. data/lib/rails/commands/test/test_command.rb +2 -0
  26. data/lib/rails/configuration.rb +10 -1
  27. data/lib/rails/console/app.rb +5 -32
  28. data/lib/rails/console/helpers.rb +5 -16
  29. data/lib/rails/console/methods.rb +23 -0
  30. data/lib/rails/engine/configuration.rb +45 -6
  31. data/lib/rails/engine.rb +24 -17
  32. data/lib/rails/gem_version.rb +3 -3
  33. data/lib/rails/generators/active_model.rb +26 -12
  34. data/lib/rails/generators/app_base.rb +80 -61
  35. data/lib/rails/generators/base.rb +9 -5
  36. data/lib/rails/generators/database.rb +227 -69
  37. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  38. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  39. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  40. data/lib/rails/generators/generated_attribute.rb +26 -1
  41. data/lib/rails/generators/migration.rb +3 -3
  42. data/lib/rails/generators/rails/app/app_generator.rb +57 -32
  43. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +23 -16
  44. data/lib/rails/generators/rails/app/templates/Gemfile.tt +17 -17
  45. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  46. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  47. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  48. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  49. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  50. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  51. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  52. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  53. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  54. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +11 -4
  55. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  56. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  57. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  58. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -6
  59. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +10 -7
  60. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
  61. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -3
  62. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  63. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +25 -26
  64. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +6 -0
  65. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
  66. data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
  67. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  68. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  69. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
  70. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  71. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  72. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  73. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  74. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  75. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  76. data/lib/rails/generators/rails/db/system/change/change_generator.rb +134 -20
  77. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  78. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
  79. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
  80. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
  81. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  82. data/lib/rails/generators/rails/plugin/plugin_generator.rb +40 -7
  83. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  84. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
  85. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
  86. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  87. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  88. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  89. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  90. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  91. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  93. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  94. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  95. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  96. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  97. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  98. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  99. data/lib/rails/generators/testing/assertions.rb +20 -0
  100. data/lib/rails/generators/testing/behavior.rb +7 -6
  101. data/lib/rails/generators.rb +7 -3
  102. data/lib/rails/health_controller.rb +2 -2
  103. data/lib/rails/info.rb +2 -2
  104. data/lib/rails/info_controller.rb +4 -2
  105. data/lib/rails/mailers_controller.rb +14 -1
  106. data/lib/rails/paths.rb +2 -2
  107. data/lib/rails/pwa_controller.rb +15 -0
  108. data/lib/rails/rack/logger.rb +15 -7
  109. data/lib/rails/railtie/configurable.rb +2 -2
  110. data/lib/rails/railtie.rb +15 -16
  111. data/lib/rails/tasks/framework.rake +0 -26
  112. data/lib/rails/tasks/tmp.rake +1 -1
  113. data/lib/rails/tasks/zeitwerk.rake +14 -34
  114. data/lib/rails/templates/layouts/application.html.erb +1 -1
  115. data/lib/rails/templates/rails/mailers/email.html.erb +20 -9
  116. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  117. data/lib/rails/test_help.rb +2 -4
  118. data/lib/rails/test_unit/reporter.rb +8 -2
  119. data/lib/rails/test_unit/runner.rb +26 -2
  120. data/lib/rails/test_unit/test_parser.rb +45 -0
  121. data/lib/rails/testing/maintain_test_schema.rb +1 -1
  122. data/lib/rails/zeitwerk_checker.rb +15 -0
  123. data/lib/rails.rb +7 -4
  124. metadata +46 -35
  125. data/lib/rails/app_updater.rb +0 -40
  126. data/lib/rails/commands/secrets/USAGE +0 -61
  127. data/lib/rails/commands/secrets/secrets_command.rb +0 -46
  128. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  129. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  130. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  131. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  132. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  133. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  134. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -223
  135. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  136. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  137. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  138. data/lib/rails/ruby_version_check.rb +0 -17
  139. data/lib/rails/secrets.rb +0 -110
@@ -94,7 +94,7 @@ module Minitest
94
94
  if count.nil?
95
95
  warn("Non integer specified as profile count, separate " \
96
96
  "your path from options with -- e.g. " \
97
- "`bin/test --profile -- #{value}`")
97
+ "`#{::Rails::TestUnitReporter.executable} --profile -- #{value}`")
98
98
  count = default_count
99
99
  end
100
100
  end
@@ -109,7 +109,10 @@ module Minitest
109
109
  # Owes great inspiration to test runner trailblazers like RSpec,
110
110
  # minitest-reporters, maxitest, and others.
111
111
  def self.plugin_rails_init(options)
112
- unless options[:full_backtrace] || ENV["BACKTRACE"]
112
+ # Don't mess with Minitest unless RAILS_ENV is set
113
+ return unless ENV["RAILS_ENV"]
114
+
115
+ unless options[:full_backtrace]
113
116
  # Plugin can run without Rails loaded, check before filtering.
114
117
  if ::Rails.respond_to?(:backtrace_cleaner)
115
118
  Minitest.backtrace_filter = BacktraceFilterWithFallback.new(::Rails.backtrace_cleaner, Minitest.backtrace_filter)
data/lib/rails/all.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/RedundantBegin
4
-
5
3
  require "rails"
6
4
 
7
5
  %w(
@@ -16,7 +14,7 @@ require "rails"
16
14
  action_text/engine
17
15
  rails/test_unit/railtie
18
16
  ).each do |railtie|
19
- begin
17
+ begin # rubocop:disable Style/RedundantBegin
20
18
  require railtie
21
19
  rescue LoadError
22
20
  end
@@ -146,8 +146,6 @@ module Rails
146
146
  end
147
147
 
148
148
  def configure_rdoc_files
149
- rdoc_files.include(api_main)
150
-
151
149
  RDOC_FILES.each do |component, cfg|
152
150
  cdr = component_root_dir(component)
153
151
 
@@ -162,8 +160,9 @@ module Rails
162
160
 
163
161
  # Only generate documentation for files that have been
164
162
  # changed since the API was generated.
165
- if Dir.exist?(api_dir) && !ENV["ALL"]
166
- last_generation = DateTime.rfc2822(File.open("#{api_dir}/created.rid", &:readline))
163
+ timestamp_path = "#{api_dir}/created.rid"
164
+ if File.exist?(timestamp_path) && !File.zero?(timestamp_path) && !ENV["ALL"]
165
+ last_generation = DateTime.rfc2822(File.open(timestamp_path, &:readline))
167
166
 
168
167
  rdoc_files.keep_if do |file|
169
168
  File.mtime(file).to_datetime > last_generation
@@ -172,6 +171,9 @@ module Rails
172
171
  # Nothing to do
173
172
  exit(0) if rdoc_files.empty?
174
173
  end
174
+
175
+ # This must come after the mtime comparison to ensure the main page is not excluded.
176
+ rdoc_files.include(api_main)
175
177
  end
176
178
 
177
179
  # These variables are used by the sdoc template
@@ -5,7 +5,6 @@ require "set"
5
5
  require "active_support/notifications"
6
6
  require "active_support/dependencies"
7
7
  require "active_support/descendants_tracker"
8
- require "rails/secrets"
9
8
 
10
9
  module Rails
11
10
  class Application
@@ -54,15 +53,23 @@ module Rails
54
53
  )
55
54
  logger
56
55
  end
57
- Rails.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase)
58
56
 
59
- unless Rails.logger.is_a?(ActiveSupport::BroadcastLogger)
57
+ if Rails.logger.is_a?(ActiveSupport::BroadcastLogger)
58
+ if config.broadcast_log_level
59
+ Rails.logger.level = ActiveSupport::Logger.const_get(config.broadcast_log_level.to_s.upcase)
60
+ end
61
+ else
62
+ Rails.logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase)
60
63
  broadcast_logger = ActiveSupport::BroadcastLogger.new(Rails.logger)
61
64
  broadcast_logger.formatter = Rails.logger.formatter
62
65
  Rails.logger = broadcast_logger
63
66
  end
67
+ end
64
68
 
65
- unless config.consider_all_requests_local
69
+ initializer :initialize_error_reporter, group: :all do
70
+ if config.consider_all_requests_local
71
+ Rails.error.debug_mode = true
72
+ else
66
73
  Rails.error.logger = Rails.logger
67
74
  end
68
75
  end
@@ -106,10 +113,6 @@ module Rails
106
113
  initializer :bootstrap_hook, group: :all do |app|
107
114
  ActiveSupport.run_load_hooks(:before_initialize, app)
108
115
  end
109
-
110
- initializer :set_secrets_root, group: :all do
111
- Rails::Secrets.root = root
112
- end
113
116
  end
114
117
  end
115
118
  end
@@ -15,17 +15,17 @@ module Rails
15
15
  :cache_classes, :cache_store, :consider_all_requests_local, :console,
16
16
  :eager_load, :exceptions_app, :file_watcher, :filter_parameters, :precompile_filter_parameters,
17
17
  :force_ssl, :helpers_paths, :hosts, :host_authorization, :logger, :log_formatter,
18
- :log_tags, :railties_order, :relative_url_root, :secret_key_base,
18
+ :log_tags, :railties_order, :relative_url_root,
19
19
  :ssl_options, :public_file_server,
20
20
  :session_options, :time_zone, :reload_classes_only_on_change,
21
21
  :beginning_of_week, :filter_redirect, :x,
22
- :read_encrypted_secrets, :log_level, :content_security_policy_report_only,
22
+ :content_security_policy_report_only,
23
23
  :content_security_policy_nonce_generator, :content_security_policy_nonce_directives,
24
24
  :require_master_key, :credentials, :disable_sandbox, :sandbox_by_default,
25
25
  :add_autoload_paths_to_load_path, :rake_eager_load, :server_timing, :log_file_size,
26
- :dom_testing_default_html_version
26
+ :dom_testing_default_html_version, :yjit
27
27
 
28
- attr_reader :encoding, :api_only, :loaded_config_version
28
+ attr_reader :encoding, :api_only, :loaded_config_version, :log_level
29
29
 
30
30
  def initialize(*)
31
31
  super
@@ -67,8 +67,6 @@ module Rails
67
67
  @api_only = false
68
68
  @debug_exception_response_format = nil
69
69
  @x = Custom.new
70
- @enable_dependency_loading = false
71
- @read_encrypted_secrets = false
72
70
  @content_security_policy = nil
73
71
  @content_security_policy_report_only = false
74
72
  @content_security_policy_nonce_generator = nil
@@ -83,6 +81,7 @@ module Rails
83
81
  @rake_eager_load = false
84
82
  @server_timing = false
85
83
  @dom_testing_default_html_version = :html4
84
+ @yjit = false
86
85
  end
87
86
 
88
87
  # Loads default configuration values for a target version. This includes
@@ -279,8 +278,6 @@ module Rails
279
278
 
280
279
  if respond_to?(:active_record)
281
280
  active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
282
- active_record.commit_transaction_on_non_local_return = true
283
- active_record.allow_deprecated_singular_associations_name = false
284
281
  active_record.sqlite3_adapter_strict_strings_by_default = true
285
282
  active_record.query_log_tags_format = :sqlcommenter
286
283
  active_record.raise_on_assign_to_attr_readonly = true
@@ -305,10 +302,6 @@ module Rails
305
302
  action_dispatch.debug_exception_log_level = :error
306
303
  end
307
304
 
308
- if respond_to?(:active_job)
309
- active_job.use_big_decimal_serializer = true
310
- end
311
-
312
305
  if respond_to?(:active_support)
313
306
  active_support.cache_format_version = 7.1
314
307
  active_support.message_serializer = :json_allow_marshal
@@ -316,18 +309,31 @@ module Rails
316
309
  active_support.raise_on_invalid_cache_expiration_time = true
317
310
  end
318
311
 
319
- if respond_to?(:action_controller)
320
- action_controller.allow_deprecated_parameters_hash_equality = false
312
+ if respond_to?(:action_view)
313
+ require "action_view/helpers"
314
+ action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
321
315
  end
322
316
 
323
- if defined?(Rails::HTML::Sanitizer) # nested ifs to avoid linter errors
324
- if respond_to?(:action_view)
325
- action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
326
- end
317
+ if respond_to?(:action_text)
318
+ require "action_view/helpers"
319
+ action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
320
+ end
321
+ when "7.2"
322
+ load_defaults "7.1"
327
323
 
328
- if respond_to?(:action_text)
329
- action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
330
- end
324
+ self.yjit = true
325
+
326
+ if respond_to?(:active_job)
327
+ active_job.enqueue_after_transaction_commit = :default
328
+ end
329
+
330
+ if respond_to?(:active_storage)
331
+ active_storage.web_image_content_types = %w( image/png image/jpeg image/gif image/webp )
332
+ end
333
+
334
+ if respond_to?(:active_record)
335
+ active_record.postgresql_adapter_decode_dates = true
336
+ active_record.validate_migration_timestamps = true
331
337
  end
332
338
  else
333
339
  raise "Unknown version #{target_version.to_s.inspect}"
@@ -348,20 +354,12 @@ module Rails
348
354
  self.cache_classes = !value
349
355
  end
350
356
 
351
- ENABLE_DEPENDENCY_LOADING_WARNING = <<~MSG
352
- This flag addressed a limitation of the `classic` autoloader and has no effect nowadays.
353
- To fix this deprecation, please just delete the reference.
354
- MSG
355
- private_constant :ENABLE_DEPENDENCY_LOADING_WARNING
356
-
357
- def enable_dependency_loading
358
- Rails.deprecator.warn(ENABLE_DEPENDENCY_LOADING_WARNING)
359
- @enable_dependency_loading
357
+ def read_encrypted_secrets
358
+ Rails.deprecator.warn("'config.read_encrypted_secrets' is deprecated and will be removed in Rails 8.0.")
360
359
  end
361
360
 
362
- def enable_dependency_loading=(value)
363
- Rails.deprecator.warn(ENABLE_DEPENDENCY_LOADING_WARNING)
364
- @enable_dependency_loading = value
361
+ def read_encrypted_secrets=(value)
362
+ Rails.deprecator.warn("'config.read_encrypted_secrets=' is deprecated and will be removed in Rails 8.0.")
365
363
  end
366
364
 
367
365
  def encoding=(value)
@@ -379,6 +377,13 @@ module Rails
379
377
  @debug_exception_response_format ||= :api
380
378
  end
381
379
 
380
+ def log_level=(level)
381
+ @log_level = level
382
+ @broadcast_log_level = level
383
+ end
384
+
385
+ attr_reader :broadcast_log_level # :nodoc:
386
+
382
387
  def debug_exception_response_format
383
388
  @debug_exception_response_format || :default
384
389
  end
@@ -389,7 +394,6 @@ module Rails
389
394
  @paths ||= begin
390
395
  paths = super
391
396
  paths.add "config/database", with: "config/database.yml"
392
- paths.add "config/secrets", with: "config", glob: "secrets.yml{,.enc}"
393
397
  paths.add "config/environment", with: "config/environment.rb"
394
398
  paths.add "lib/templates"
395
399
  paths.add "log", with: "log/#{Rails.env}.log"
@@ -494,6 +498,28 @@ module Rails
494
498
  generators.colorize_logging = val
495
499
  end
496
500
 
501
+ def secret_key_base
502
+ @secret_key_base || begin
503
+ self.secret_key_base = if generate_local_secret?
504
+ generate_local_secret
505
+ else
506
+ ENV["SECRET_KEY_BASE"] || Rails.application.credentials.secret_key_base
507
+ end
508
+ end
509
+ end
510
+
511
+ def secret_key_base=(new_secret_key_base)
512
+ if new_secret_key_base.nil? && generate_local_secret?
513
+ @secret_key_base = generate_local_secret
514
+ elsif new_secret_key_base.is_a?(String) && new_secret_key_base.present?
515
+ @secret_key_base = new_secret_key_base
516
+ elsif new_secret_key_base
517
+ raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
518
+ else
519
+ raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
520
+ end
521
+ end
522
+
497
523
  # Specifies what class to use to store the session. Possible values
498
524
  # are +:cache_store+, +:cookie_store+, +:mem_cache_store+, a custom
499
525
  # store, or +:disabled+. +:disabled+ tells \Rails not to deal with
@@ -575,14 +601,16 @@ module Rails
575
601
  def method_missing(method, *args)
576
602
  if method.end_with?("=")
577
603
  @configurations[:"#{method[0..-2]}"] = args.first
578
- else
604
+ elsif args.empty?
579
605
  @configurations.fetch(method) {
580
606
  @configurations[method] = ActiveSupport::OrderedOptions.new
581
607
  }
608
+ else
609
+ raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0) when reading configuration `#{method}`"
582
610
  end
583
611
  end
584
612
 
585
- def respond_to_missing?(symbol, *)
613
+ def respond_to_missing?(symbol, _)
586
614
  true
587
615
  end
588
616
  end
@@ -597,6 +625,22 @@ module Rails
597
625
 
598
626
  { content_path: content_path, key_path: key_path }
599
627
  end
628
+
629
+ def generate_local_secret
630
+ key_file = root.join("tmp/local_secret.txt")
631
+
632
+ unless File.exist?(key_file)
633
+ random_key = SecureRandom.hex(64)
634
+ FileUtils.mkdir_p(key_file.dirname)
635
+ File.binwrite(key_file, random_key)
636
+ end
637
+
638
+ File.binread(key_file)
639
+ end
640
+
641
+ def generate_local_secret?
642
+ Rails.env.local? || ENV["SECRET_KEY_BASE_DUMMY"]
643
+ end
600
644
  end
601
645
  end
602
646
  end
@@ -9,9 +9,9 @@ class DummyConfig # :nodoc:
9
9
  "DummyConfig"
10
10
  end
11
11
 
12
- def method_missing(selector, *args, &blk)
12
+ def method_missing(selector, ...)
13
13
  if @config.respond_to?(selector)
14
- @config.send(selector, *args, &blk)
14
+ @config.send(selector, ...)
15
15
  else
16
16
  self
17
17
  end
@@ -78,6 +78,7 @@ module Rails
78
78
  if config.eager_load
79
79
  ActiveSupport.run_load_hooks(:before_eager_load, self)
80
80
  Zeitwerk::Loader.eager_load_all
81
+ Rails.eager_load!
81
82
  config.eager_load_namespaces.each(&:eager_load!)
82
83
 
83
84
  if config.reloading_enabled?
@@ -160,6 +161,7 @@ module Rails
160
161
  reloader.eager_load = app.config.eager_load
161
162
  reloader.execute
162
163
  reloaders << reloader
164
+
163
165
  app.reloader.to_run do
164
166
  # We configure #execute rather than #execute_if_updated because if
165
167
  # autoloaded constants are cleared we need to reload routes also in
@@ -174,6 +176,8 @@ module Rails
174
176
  reloader.execute
175
177
  ActiveSupport.run_load_hooks(:after_routes_loaded, self)
176
178
  end
179
+
180
+ ActiveSupport.run_load_hooks(:after_routes_loaded, self)
177
181
  end
178
182
 
179
183
  # Set clearing dependencies after the finisher hook to ensure paths
@@ -223,6 +227,12 @@ module Rails
223
227
  ActiveSupport::DescendantsTracker.disable_clear!
224
228
  end
225
229
  end
230
+
231
+ initializer :enable_yjit do
232
+ if config.yjit && defined?(RubyVM::YJIT.enable)
233
+ RubyVM::YJIT.enable
234
+ end
235
+ end
226
236
  end
227
237
  end
228
238
  end
@@ -10,7 +10,6 @@ require "active_support/encrypted_configuration"
10
10
  require "active_support/hash_with_indifferent_access"
11
11
  require "active_support/configuration_file"
12
12
  require "rails/engine"
13
- require "rails/secrets"
14
13
  require "rails/autoloaders"
15
14
 
16
15
  module Rails
@@ -104,7 +103,7 @@ module Rails
104
103
  delegate :default_url_options, :default_url_options=, to: :routes
105
104
 
106
105
  INITIAL_VARIABLES = [:config, :railties, :routes_reloader, :reloaders,
107
- :routes, :helpers, :app_env_config, :secrets] # :nodoc:
106
+ :routes, :helpers, :app_env_config] # :nodoc:
108
107
 
109
108
  def initialize(initial_variable_values = {}, &block)
110
109
  super()
@@ -135,6 +134,13 @@ module Rails
135
134
  @initialized
136
135
  end
137
136
 
137
+ # Returns the dasherized application name.
138
+ #
139
+ # MyApp::Application.new.name => "my-app"
140
+ def name
141
+ self.class.name.underscore.dasherize.delete_suffix("/application")
142
+ end
143
+
138
144
  def run_load_hooks! # :nodoc:
139
145
  return self if @ran_load_hooks
140
146
  @ran_load_hooks = true
@@ -208,17 +214,20 @@ module Rails
208
214
  # It is recommended not to use the same verifier for different things, so you can get different
209
215
  # verifiers passing the +verifier_name+ argument.
210
216
  #
217
+ # For instance, +ActiveStorage::Blob.signed_id_verifier+ is implemented using this feature, which assures that
218
+ # the IDs strings haven't been tampered with and are safe to use in a finder.
219
+ #
220
+ # See the ActiveSupport::MessageVerifier documentation for more information.
221
+ #
211
222
  # ==== Parameters
212
223
  #
213
224
  # * +verifier_name+ - the name of the message verifier.
214
225
  #
215
226
  # ==== Examples
216
227
  #
217
- # message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
218
- # Rails.application.message_verifier('sensitive_data').verify(message)
219
- # # => 'my sensible data'
220
- #
221
- # See the ActiveSupport::MessageVerifier documentation for more information.
228
+ # message = Rails.application.message_verifier('my_purpose').generate('data to sign against tampering')
229
+ # Rails.application.message_verifier('my_purpose').verify(message)
230
+ # # => 'data to sign against tampering'
222
231
  def message_verifier(verifier_name)
223
232
  message_verifiers[verifier_name]
224
233
  end
@@ -234,8 +243,7 @@ module Rails
234
243
  end
235
244
 
236
245
  # Convenience for loading config/foo.yml for the current \Rails env.
237
- #
238
- # Examples:
246
+ # Example:
239
247
  #
240
248
  # # config/exception_notification.yml:
241
249
  # production:
@@ -246,13 +254,15 @@ module Rails
246
254
  # url: http://localhost:3001
247
255
  # namespace: my_app_development
248
256
  #
257
+ # <code></code>
258
+ #
249
259
  # # config/environments/production.rb
250
260
  # Rails.application.configure do
251
261
  # config.middleware.use ExceptionNotifier, config_for(:exception_notification)
252
262
  # end
253
263
  #
254
- # # You can also store configurations in a shared section which will be
255
- # # merged with the environment configuration
264
+ # You can also store configurations in a shared section which will be merged
265
+ # with the environment configuration
256
266
  #
257
267
  # # config/example.yml
258
268
  # shared:
@@ -265,6 +275,8 @@ module Rails
265
275
  # bar:
266
276
  # qux: 2
267
277
  #
278
+ # <code></code>
279
+ #
268
280
  # # development environment
269
281
  # Rails.application.config_for(:example)[:foo][:bar]
270
282
  # # => { baz: 1, qux: 2 }
@@ -409,8 +421,8 @@ module Rails
409
421
  def watchable_args # :nodoc:
410
422
  files, dirs = config.watchable_files.dup, config.watchable_dirs.dup
411
423
 
412
- ActiveSupport::Dependencies.autoload_paths.each do |path|
413
- File.file?(path) ? files << path.to_s : dirs[path.to_s] = [:rb]
424
+ Rails.autoloaders.main.dirs.each do |path|
425
+ dirs[path] = [:rb]
414
426
  end
415
427
 
416
428
  [files, dirs]
@@ -436,25 +448,7 @@ module Rails
436
448
  end
437
449
 
438
450
  attr_writer :config
439
-
440
- def secrets
441
- Rails.deprecator.warn(<<~MSG.squish)
442
- `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2.
443
- MSG
444
- @secrets ||= begin
445
- secrets = ActiveSupport::OrderedOptions.new
446
- files = config.paths["config/secrets"].existent
447
- files = files.reject { |path| path.end_with?(".enc") } unless config.read_encrypted_secrets
448
- secrets.merge! Rails::Secrets.parse(files, env: Rails.env)
449
-
450
- # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
451
- secrets.secret_key_base ||= config.secret_key_base
452
-
453
- secrets
454
- end
455
- end
456
-
457
- attr_writer :secrets, :credentials
451
+ attr_writer :credentials
458
452
 
459
453
  # The secret_key_base is used as the input secret to the application's key generator, which in turn
460
454
  # is used to create all ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor instances,
@@ -470,16 +464,10 @@ module Rails
470
464
  # Dockerfile example: <tt>RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile</tt>.
471
465
  #
472
466
  # In all other environments, we look for it first in <tt>ENV["SECRET_KEY_BASE"]</tt>,
473
- # then +credentials.secret_key_base+, and finally +secrets.secret_key_base+. For most applications,
474
- # the correct place to store it is in the encrypted credentials file.
467
+ # then +credentials.secret_key_base+. For most applications, the correct place to store it is in the
468
+ # encrypted credentials file.
475
469
  def secret_key_base
476
- if Rails.env.local? || ENV["SECRET_KEY_BASE_DUMMY"]
477
- config.secret_key_base ||= generate_local_secret
478
- else
479
- validate_secret_key_base(
480
- ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
481
- )
482
- end
470
+ config.secret_key_base
483
471
  end
484
472
 
485
473
  # Returns an ActiveSupport::EncryptedConfiguration instance for the
@@ -632,47 +620,12 @@ module Rails
632
620
  default_stack.build_stack
633
621
  end
634
622
 
635
- def validate_secret_key_base(secret_key_base)
636
- if secret_key_base.is_a?(String) && secret_key_base.present?
637
- secret_key_base
638
- elsif secret_key_base
639
- raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
640
- else
641
- raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
642
- end
643
- end
644
-
645
623
  def ensure_generator_templates_added
646
624
  configured_paths = config.generators.templates
647
625
  configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths))
648
626
  end
649
627
 
650
628
  private
651
- def generate_local_secret
652
- if config.secret_key_base.nil?
653
- key_file = Rails.root.join("tmp/local_secret.txt")
654
-
655
- if File.exist?(key_file)
656
- config.secret_key_base = File.binread(key_file)
657
- elsif secrets_secret_key_base
658
- config.secret_key_base = secrets_secret_key_base
659
- else
660
- random_key = SecureRandom.hex(64)
661
- FileUtils.mkdir_p(key_file.dirname)
662
- File.binwrite(key_file, random_key)
663
- config.secret_key_base = File.binread(key_file)
664
- end
665
- end
666
-
667
- config.secret_key_base
668
- end
669
-
670
- def secrets_secret_key_base
671
- Rails.deprecator.silence do
672
- secrets.secret_key_base
673
- end
674
- end
675
-
676
629
  def build_request(env)
677
630
  req = super
678
631
  env["ORIGINAL_FULLPATH"] = req.fullpath
@@ -6,13 +6,15 @@ require "active_support/core_ext/string/access"
6
6
  module Rails
7
7
  class BacktraceCleaner < ActiveSupport::BacktraceCleaner # :nodoc:
8
8
  APP_DIRS_PATTERN = /\A(?:\.\/)?(?:app|config|lib|test|\(\w*\))/
9
- RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/
9
+ RENDER_TEMPLATE_PATTERN = /:in [`'].*_\w+_{2,3}\d+_\d+'/
10
10
 
11
11
  def initialize
12
12
  super
13
- @root = "#{Rails.root}/"
14
13
  add_filter do |line|
15
- line.start_with?(@root) ? line.from(@root.size) : line
14
+ # We may be called before Rails.root is assigned.
15
+ # When that happens we fallback to not truncating.
16
+ @root ||= Rails.root && "#{Rails.root}/"
17
+ @root && line.start_with?(@root) ? line.from(@root.size) : line
16
18
  end
17
19
  add_filter do |line|
18
20
  if RENDER_TEMPLATE_PATTERN.match?(line)
@@ -23,5 +25,18 @@ module Rails
23
25
  end
24
26
  add_silencer { |line| !APP_DIRS_PATTERN.match?(line) }
25
27
  end
28
+
29
+ def clean(backtrace, kind = :silent)
30
+ kind = nil if ENV["BACKTRACE"]
31
+
32
+ super(backtrace, kind)
33
+ end
34
+ alias_method :filter, :clean
35
+
36
+ def clean_frame(frame, kind = :silent)
37
+ kind = nil if ENV["BACKTRACE"]
38
+
39
+ super(frame, kind)
40
+ end
26
41
  end
27
42
  end
data/lib/rails/cli.rb CHANGED
@@ -6,7 +6,6 @@ require "rails/app_loader"
6
6
  # the rest of this script is not run.
7
7
  Rails::AppLoader.exec_app
8
8
 
9
- require "rails/ruby_version_check"
10
9
  Signal.trap("INT") { puts; exit(1) }
11
10
 
12
11
  require "rails/command"
data/lib/rails/command.rb CHANGED
@@ -23,7 +23,7 @@ module Rails
23
23
  super(message)
24
24
  end
25
25
 
26
- if !Exception.method_defined?(:detailed_message)
26
+ if !Exception.method_defined?(:detailed_message) # Ruby 3.2+
27
27
  def detailed_message(...)
28
28
  message
29
29
  end