railties 7.1.3.4 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +177 -742
  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 +5 -6
  7. data/lib/rails/application/configuration.rb +73 -38
  8. data/lib/rails/application/dummy_config.rb +2 -2
  9. data/lib/rails/application/finisher.rb +7 -0
  10. data/lib/rails/application.rb +15 -86
  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 +93 -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 +137 -0
  18. data/lib/rails/commands/credentials/credentials_command.rb +2 -2
  19. data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
  20. data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
  21. data/lib/rails/commands/rake/rake_command.rb +1 -1
  22. data/lib/rails/commands/runner/runner_command.rb +14 -3
  23. data/lib/rails/commands/server/server_command.rb +5 -3
  24. data/lib/rails/commands/test/test_command.rb +2 -0
  25. data/lib/rails/configuration.rb +10 -1
  26. data/lib/rails/console/app.rb +5 -32
  27. data/lib/rails/console/helpers.rb +5 -16
  28. data/lib/rails/console/methods.rb +23 -0
  29. data/lib/rails/engine.rb +5 -5
  30. data/lib/rails/gem_version.rb +3 -3
  31. data/lib/rails/generators/app_base.rb +70 -49
  32. data/lib/rails/generators/base.rb +5 -1
  33. data/lib/rails/generators/database.rb +227 -69
  34. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  35. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  36. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  37. data/lib/rails/generators/generated_attribute.rb +26 -1
  38. data/lib/rails/generators/migration.rb +3 -3
  39. data/lib/rails/generators/rails/app/app_generator.rb +53 -24
  40. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
  41. data/lib/rails/generators/rails/app/templates/Gemfile.tt +16 -16
  42. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  43. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  44. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  45. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  46. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  47. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  48. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  49. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  50. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  51. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  52. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  53. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  54. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  55. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +5 -0
  56. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
  57. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  58. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  59. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +24 -26
  60. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -0
  61. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
  62. data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
  63. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  64. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  65. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  67. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  68. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  69. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  70. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  71. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  72. data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
  73. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  74. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
  75. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
  76. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
  77. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  78. data/lib/rails/generators/rails/plugin/plugin_generator.rb +38 -7
  79. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  80. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
  81. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
  82. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  83. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  84. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  85. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  86. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  87. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  88. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  89. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  90. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  91. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  93. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  94. data/lib/rails/generators/testing/assertions.rb +20 -0
  95. data/lib/rails/generators/testing/behavior.rb +7 -6
  96. data/lib/rails/generators.rb +1 -1
  97. data/lib/rails/health_controller.rb +1 -1
  98. data/lib/rails/info.rb +2 -2
  99. data/lib/rails/mailers_controller.rb +14 -1
  100. data/lib/rails/paths.rb +2 -2
  101. data/lib/rails/pwa_controller.rb +15 -0
  102. data/lib/rails/rack/logger.rb +15 -7
  103. data/lib/rails/railtie/configurable.rb +2 -2
  104. data/lib/rails/railtie.rb +2 -3
  105. data/lib/rails/tasks/framework.rake +0 -26
  106. data/lib/rails/tasks/tmp.rake +1 -1
  107. data/lib/rails/templates/layouts/application.html.erb +1 -1
  108. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  109. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  110. data/lib/rails/test_help.rb +2 -4
  111. data/lib/rails/test_unit/reporter.rb +8 -2
  112. data/lib/rails/test_unit/runner.rb +26 -2
  113. data/lib/rails/test_unit/test_parser.rb +45 -0
  114. data/lib/rails.rb +7 -4
  115. metadata +42 -32
  116. data/lib/rails/app_updater.rb +0 -40
  117. data/lib/rails/commands/secrets/USAGE +0 -61
  118. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  119. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  120. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  121. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  122. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  123. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  124. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  125. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -284
  126. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  127. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  128. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  129. data/lib/rails/ruby_version_check.rb +0 -17
  130. 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
@@ -65,8 +64,12 @@ module Rails
65
64
  broadcast_logger.formatter = Rails.logger.formatter
66
65
  Rails.logger = broadcast_logger
67
66
  end
67
+ end
68
68
 
69
- 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
70
73
  Rails.error.logger = Rails.logger
71
74
  end
72
75
  end
@@ -110,10 +113,6 @@ module Rails
110
113
  initializer :bootstrap_hook, group: :all do |app|
111
114
  ActiveSupport.run_load_hooks(:before_initialize, app)
112
115
  end
113
-
114
- initializer :set_secrets_root, group: :all do
115
- Rails::Secrets.root = root
116
- end
117
116
  end
118
117
  end
119
118
  end
@@ -15,15 +15,15 @@ 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, :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
28
  attr_reader :encoding, :api_only, :loaded_config_version, :log_level
29
29
 
@@ -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)
@@ -384,9 +382,7 @@ module Rails
384
382
  @broadcast_log_level = level
385
383
  end
386
384
 
387
- def broadcast_log_level # :nodoc:
388
- defined?(@broadcast_log_level) ? @broadcast_log_level : nil
389
- end
385
+ attr_reader :broadcast_log_level # :nodoc:
390
386
 
391
387
  def debug_exception_response_format
392
388
  @debug_exception_response_format || :default
@@ -398,7 +394,6 @@ module Rails
398
394
  @paths ||= begin
399
395
  paths = super
400
396
  paths.add "config/database", with: "config/database.yml"
401
- paths.add "config/secrets", with: "config", glob: "secrets.yml{,.enc}"
402
397
  paths.add "config/environment", with: "config/environment.rb"
403
398
  paths.add "lib/templates"
404
399
  paths.add "log", with: "log/#{Rails.env}.log"
@@ -503,6 +498,28 @@ module Rails
503
498
  generators.colorize_logging = val
504
499
  end
505
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
+
506
523
  # Specifies what class to use to store the session. Possible values
507
524
  # are +:cache_store+, +:cookie_store+, +:mem_cache_store+, a custom
508
525
  # store, or +:disabled+. +:disabled+ tells \Rails not to deal with
@@ -584,14 +601,16 @@ module Rails
584
601
  def method_missing(method, *args)
585
602
  if method.end_with?("=")
586
603
  @configurations[:"#{method[0..-2]}"] = args.first
587
- else
604
+ elsif args.empty?
588
605
  @configurations.fetch(method) {
589
606
  @configurations[method] = ActiveSupport::OrderedOptions.new
590
607
  }
608
+ else
609
+ raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0) when reading configuration `#{method}`"
591
610
  end
592
611
  end
593
612
 
594
- def respond_to_missing?(symbol, *)
613
+ def respond_to_missing?(symbol, _)
595
614
  true
596
615
  end
597
616
  end
@@ -606,6 +625,22 @@ module Rails
606
625
 
607
626
  { content_path: content_path, key_path: key_path }
608
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
609
644
  end
610
645
  end
611
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?
@@ -226,6 +227,12 @@ module Rails
226
227
  ActiveSupport::DescendantsTracker.disable_clear!
227
228
  end
228
229
  end
230
+
231
+ initializer :enable_yjit do
232
+ if config.yjit && defined?(RubyVM::YJIT.enable)
233
+ RubyVM::YJIT.enable
234
+ end
235
+ end
229
236
  end
230
237
  end
231
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()
@@ -208,17 +207,20 @@ module Rails
208
207
  # It is recommended not to use the same verifier for different things, so you can get different
209
208
  # verifiers passing the +verifier_name+ argument.
210
209
  #
210
+ # For instance, +ActiveStorage::Blob.signed_id_verifier+ is implemented using this feature, which assures that
211
+ # the IDs strings haven't been tampered with and are safe to use in a finder.
212
+ #
213
+ # See the ActiveSupport::MessageVerifier documentation for more information.
214
+ #
211
215
  # ==== Parameters
212
216
  #
213
217
  # * +verifier_name+ - the name of the message verifier.
214
218
  #
215
219
  # ==== Examples
216
220
  #
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.
221
+ # message = Rails.application.message_verifier('my_purpose').generate('data to sign against tampering')
222
+ # Rails.application.message_verifier('my_purpose').verify(message)
223
+ # # => 'data to sign against tampering'
222
224
  def message_verifier(verifier_name)
223
225
  message_verifiers[verifier_name]
224
226
  end
@@ -412,8 +414,8 @@ module Rails
412
414
  def watchable_args # :nodoc:
413
415
  files, dirs = config.watchable_files.dup, config.watchable_dirs.dup
414
416
 
415
- ActiveSupport::Dependencies.autoload_paths.each do |path|
416
- File.file?(path) ? files << path.to_s : dirs[path.to_s] = [:rb]
417
+ Rails.autoloaders.main.dirs.each do |path|
418
+ dirs[path] = [:rb]
417
419
  end
418
420
 
419
421
  [files, dirs]
@@ -439,25 +441,7 @@ module Rails
439
441
  end
440
442
 
441
443
  attr_writer :config
442
-
443
- def secrets
444
- Rails.deprecator.warn(<<~MSG.squish)
445
- `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2.
446
- MSG
447
- @secrets ||= begin
448
- secrets = ActiveSupport::OrderedOptions.new
449
- files = config.paths["config/secrets"].existent
450
- files = files.reject { |path| path.end_with?(".enc") } unless config.read_encrypted_secrets
451
- secrets.merge! Rails::Secrets.parse(files, env: Rails.env)
452
-
453
- # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
454
- secrets.secret_key_base ||= config.secret_key_base
455
-
456
- secrets
457
- end
458
- end
459
-
460
- attr_writer :secrets, :credentials
444
+ attr_writer :credentials
461
445
 
462
446
  # The secret_key_base is used as the input secret to the application's key generator, which in turn
463
447
  # is used to create all ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor instances,
@@ -473,30 +457,10 @@ module Rails
473
457
  # Dockerfile example: <tt>RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile</tt>.
474
458
  #
475
459
  # In all other environments, we look for it first in <tt>ENV["SECRET_KEY_BASE"]</tt>,
476
- # then +credentials.secret_key_base+, and finally +secrets.secret_key_base+. For most applications,
477
- # the correct place to store it is in the encrypted credentials file.
460
+ # then +credentials.secret_key_base+. For most applications, the correct place to store it is in the
461
+ # encrypted credentials file.
478
462
  def secret_key_base
479
- if Rails.env.local? || ENV["SECRET_KEY_BASE_DUMMY"]
480
- config.secret_key_base ||= generate_local_secret
481
- else
482
- validate_secret_key_base(
483
- ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || begin
484
- secret_skb = secrets_secret_key_base
485
-
486
- if secret_skb.equal?(config.secret_key_base)
487
- config.secret_key_base
488
- else
489
- Rails.deprecator.warn(<<~MSG.squish)
490
- Your `secret_key_base` is configured in `Rails.application.secrets`,
491
- which is deprecated in favor of `Rails.application.credentials` and
492
- will be removed in Rails 7.2.
493
- MSG
494
-
495
- secret_skb
496
- end
497
- end
498
- )
499
- end
463
+ config.secret_key_base
500
464
  end
501
465
 
502
466
  # Returns an ActiveSupport::EncryptedConfiguration instance for the
@@ -649,47 +613,12 @@ module Rails
649
613
  default_stack.build_stack
650
614
  end
651
615
 
652
- def validate_secret_key_base(secret_key_base)
653
- if secret_key_base.is_a?(String) && secret_key_base.present?
654
- secret_key_base
655
- elsif secret_key_base
656
- raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
657
- else
658
- raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
659
- end
660
- end
661
-
662
616
  def ensure_generator_templates_added
663
617
  configured_paths = config.generators.templates
664
618
  configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths))
665
619
  end
666
620
 
667
621
  private
668
- def generate_local_secret
669
- if config.secret_key_base.nil?
670
- key_file = Rails.root.join("tmp/local_secret.txt")
671
-
672
- if File.exist?(key_file)
673
- config.secret_key_base = File.binread(key_file)
674
- elsif secrets_secret_key_base
675
- config.secret_key_base = secrets_secret_key_base
676
- else
677
- random_key = SecureRandom.hex(64)
678
- FileUtils.mkdir_p(key_file.dirname)
679
- File.binwrite(key_file, random_key)
680
- config.secret_key_base = File.binread(key_file)
681
- end
682
- end
683
-
684
- config.secret_key_base
685
- end
686
-
687
- def secrets_secret_key_base
688
- Rails.deprecator.silence do
689
- secrets.secret_key_base
690
- end
691
- end
692
-
693
622
  def build_request(env)
694
623
  req = super
695
624
  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
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/rails/app/app_generator"
5
+
6
+ module Rails
7
+ module Command
8
+ module App
9
+ class UpdateCommand < Base # :nodoc:
10
+ include Thor::Actions
11
+ add_runtime_options!
12
+
13
+ desc "update", "Update configs and some other initially generated files (or use just update:configs or update:bin)"
14
+ def perform
15
+ configs
16
+ bin
17
+ public_directory
18
+ active_storage
19
+ display_upgrade_guide_info
20
+ end
21
+
22
+ desc "configs", "Update config files in the application config/ directory", hide: true
23
+ def configs
24
+ require_application!
25
+ app_generator.create_boot_file
26
+ app_generator.update_config_files
27
+ end
28
+
29
+ desc "bin", "Add or update executables in the application bin/ directory", hide: true
30
+ def bin
31
+ require_application!
32
+ app_generator.update_bin_files
33
+ end
34
+
35
+ desc "public_directory", "Add or update files in the application public/ directory", hide: true
36
+ def public_directory
37
+ require_application!
38
+ app_generator.create_public_files
39
+ end
40
+
41
+ desc "active_storage", "Run the active_storage:update command", hide: true
42
+ def active_storage
43
+ require_application!
44
+ app_generator.update_active_storage
45
+ end
46
+
47
+ private
48
+ def display_upgrade_guide_info
49
+ say "\nAfter this, check Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app."
50
+ end
51
+
52
+ def app_generator
53
+ @app_generator ||= begin
54
+ gen = Rails::Generators::AppGenerator.new(["rails"], generator_options, destination_root: Rails.root)
55
+ gen.send(:valid_const?) unless File.exist?(Rails.root.join("config", "application.rb"))
56
+ gen
57
+ end
58
+ end
59
+
60
+ def generator_options
61
+ {
62
+ api: !!Rails.application.config.api_only,
63
+ update: true,
64
+ name: Rails.application.class.name.chomp("::Application").underscore,
65
+ skip_active_job: !defined?(ActiveJob::Railtie),
66
+ skip_active_record: !defined?(ActiveRecord::Railtie),
67
+ skip_active_storage: !defined?(ActiveStorage::Engine),
68
+ skip_action_mailer: !defined?(ActionMailer::Railtie),
69
+ skip_action_mailbox: !defined?(ActionMailbox::Engine),
70
+ skip_action_text: !defined?(ActionText::Engine),
71
+ skip_action_cable: !defined?(ActionCable::Engine),
72
+ skip_test: !defined?(Rails::TestUnitRailtie),
73
+ skip_system_test: Rails.application.config.generators.system_tests.nil?,
74
+ asset_pipeline: asset_pipeline,
75
+ skip_asset_pipeline: asset_pipeline.nil?,
76
+ skip_bootsnap: !defined?(Bootsnap),
77
+ }.merge(options)
78
+ end
79
+
80
+ def asset_pipeline
81
+ case
82
+ when defined?(Sprockets::Railtie)
83
+ "sprockets"
84
+ when defined?(Propshaft::Railtie)
85
+ "propshaft"
86
+ else
87
+ nil
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/command/environment_argument"
4
+
5
+ module Rails
6
+ module Command
7
+ class BootCommand < Base # :nodoc:
8
+ include EnvironmentArgument
9
+
10
+ desc "boot", "Boot the application and exit"
11
+ def perform(*) = boot_application!
12
+ end
13
+ end
14
+ end