railties 7.0.8.7 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +210 -272
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.md +99 -0
  5. data/README.rdoc +4 -4
  6. data/lib/minitest/rails_plugin.rb +67 -1
  7. data/lib/rails/all.rb +1 -3
  8. data/lib/rails/api/task.rb +39 -6
  9. data/lib/rails/application/bootstrap.rb +28 -10
  10. data/lib/rails/application/configuration.rb +228 -72
  11. data/lib/rails/application/default_middleware_stack.rb +8 -2
  12. data/lib/rails/application/dummy_config.rb +19 -0
  13. data/lib/rails/application/finisher.rb +50 -33
  14. data/lib/rails/application.rb +117 -76
  15. data/lib/rails/backtrace_cleaner.rb +19 -4
  16. data/lib/rails/cli.rb +5 -3
  17. data/lib/rails/command/actions.rb +10 -12
  18. data/lib/rails/command/base.rb +55 -53
  19. data/lib/rails/command/environment_argument.rb +32 -16
  20. data/lib/rails/command/helpers/editor.rb +17 -12
  21. data/lib/rails/command.rb +84 -33
  22. data/lib/rails/commands/about/about_command.rb +14 -0
  23. data/lib/rails/commands/app/update_command.rb +102 -0
  24. data/lib/rails/commands/application/application_command.rb +2 -0
  25. data/lib/rails/commands/boot/boot_command.rb +14 -0
  26. data/lib/rails/commands/console/console_command.rb +11 -30
  27. data/lib/rails/commands/console/irb_console.rb +146 -0
  28. data/lib/rails/commands/credentials/USAGE +53 -55
  29. data/lib/rails/commands/credentials/credentials_command/diffing.rb +5 -3
  30. data/lib/rails/commands/credentials/credentials_command.rb +64 -70
  31. data/lib/rails/commands/db/system/change/change_command.rb +2 -1
  32. data/lib/rails/commands/dbconsole/dbconsole_command.rb +32 -131
  33. data/lib/rails/commands/destroy/destroy_command.rb +3 -2
  34. data/lib/rails/commands/dev/dev_command.rb +1 -6
  35. data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
  36. data/lib/rails/commands/encrypted/USAGE +15 -20
  37. data/lib/rails/commands/encrypted/encrypted_command.rb +46 -35
  38. data/lib/rails/commands/gem_help/USAGE +16 -0
  39. data/lib/rails/commands/gem_help/gem_help_command.rb +13 -0
  40. data/lib/rails/commands/generate/generate_command.rb +2 -2
  41. data/lib/rails/commands/help/USAGE +13 -13
  42. data/lib/rails/commands/help/help_command.rb +21 -2
  43. data/lib/rails/commands/initializers/initializers_command.rb +1 -4
  44. data/lib/rails/commands/middleware/middleware_command.rb +17 -0
  45. data/lib/rails/commands/new/new_command.rb +2 -0
  46. data/lib/rails/commands/notes/notes_command.rb +2 -1
  47. data/lib/rails/commands/plugin/plugin_command.rb +2 -0
  48. data/lib/rails/commands/rake/rake_command.rb +25 -22
  49. data/lib/rails/commands/restart/restart_command.rb +14 -0
  50. data/lib/rails/commands/routes/routes_command.rb +13 -1
  51. data/lib/rails/commands/runner/USAGE +14 -12
  52. data/lib/rails/commands/runner/runner_command.rb +42 -19
  53. data/lib/rails/commands/secret/secret_command.rb +13 -0
  54. data/lib/rails/commands/server/server_command.rb +37 -34
  55. data/lib/rails/commands/test/USAGE +14 -0
  56. data/lib/rails/commands/test/test_command.rb +58 -14
  57. data/lib/rails/commands/unused_routes/unused_routes_command.rb +75 -0
  58. data/lib/rails/commands/version/version_command.rb +1 -0
  59. data/lib/rails/configuration.rb +15 -6
  60. data/lib/rails/console/app.rb +5 -35
  61. data/lib/rails/console/helpers.rb +5 -16
  62. data/lib/rails/console/methods.rb +23 -0
  63. data/lib/rails/deprecator.rb +7 -0
  64. data/lib/rails/engine/configuration.rb +50 -6
  65. data/lib/rails/engine.rb +53 -25
  66. data/lib/rails/gem_version.rb +4 -4
  67. data/lib/rails/generators/actions.rb +6 -15
  68. data/lib/rails/generators/active_model.rb +28 -14
  69. data/lib/rails/generators/app_base.rb +382 -88
  70. data/lib/rails/generators/app_name.rb +3 -14
  71. data/lib/rails/generators/base.rb +21 -9
  72. data/lib/rails/generators/database.rb +231 -35
  73. data/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt +1 -1
  74. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  75. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  76. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  77. data/lib/rails/generators/generated_attribute.rb +38 -1
  78. data/lib/rails/generators/migration.rb +4 -5
  79. data/lib/rails/generators/model_helpers.rb +2 -1
  80. data/lib/rails/generators/rails/app/USAGE +22 -6
  81. data/lib/rails/generators/rails/app/app_generator.rb +135 -86
  82. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +110 -0
  83. data/lib/rails/generators/rails/app/templates/Gemfile.tt +19 -21
  84. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  85. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  86. data/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt +1 -1
  87. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  88. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  89. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  90. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  91. data/lib/rails/generators/rails/app/templates/bin/setup.tt +15 -2
  92. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +6 -17
  93. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  94. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +11 -6
  95. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +10 -3
  96. data/lib/rails/generators/rails/app/templates/config/databases/{jdbcmysql.yml.tt → trilogy.yml.tt} +12 -7
  97. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +25 -8
  98. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +40 -28
  99. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +20 -13
  100. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +3 -1
  101. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +2 -2
  102. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +1 -1
  103. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +4 -4
  104. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  105. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -9
  106. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +11 -13
  107. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +25 -34
  108. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +11 -1
  109. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +6 -4
  110. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +15 -0
  111. data/lib/rails/generators/rails/app/templates/dockerignore.tt +56 -0
  112. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  113. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  114. data/lib/rails/generators/rails/app/templates/gitignore.tt +7 -11
  115. data/lib/rails/generators/rails/app/templates/node-version.tt +1 -0
  116. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  117. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  118. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  119. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  120. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  121. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +10 -8
  122. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -7
  123. data/lib/rails/generators/rails/application_record/application_record_generator.rb +4 -0
  124. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +2 -1
  125. data/lib/rails/generators/rails/controller/USAGE +12 -4
  126. data/lib/rails/generators/rails/controller/controller_generator.rb +6 -1
  127. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +1 -1
  128. data/lib/rails/generators/rails/credentials/credentials_generator.rb +29 -24
  129. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +8 -0
  130. data/lib/rails/generators/rails/db/system/change/change_generator.rb +146 -5
  131. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  132. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
  133. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
  134. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
  135. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -2
  136. data/lib/rails/generators/rails/migration/USAGE +21 -11
  137. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  138. data/lib/rails/generators/rails/model/model_generator.rb +4 -0
  139. data/lib/rails/generators/rails/plugin/USAGE +17 -6
  140. data/lib/rails/generators/rails/plugin/plugin_generator.rb +45 -22
  141. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  142. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +7 -3
  143. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +1 -1
  144. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
  145. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -17
  146. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  147. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  148. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  149. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -2
  150. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  151. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  152. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +5 -5
  153. data/lib/rails/generators/rails/resource/resource_generator.rb +6 -0
  154. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -1
  155. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +1 -1
  156. data/lib/rails/generators/test_case.rb +2 -2
  157. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  158. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  159. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +16 -2
  160. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  161. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  162. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  163. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  164. data/lib/rails/generators/testing/assertions.rb +20 -0
  165. data/lib/rails/generators/testing/{behaviour.rb → behavior.rb} +8 -4
  166. data/lib/rails/generators.rb +12 -16
  167. data/lib/rails/health_controller.rb +55 -0
  168. data/lib/rails/info.rb +3 -3
  169. data/lib/rails/info_controller.rb +33 -11
  170. data/lib/rails/mailers_controller.rb +29 -6
  171. data/lib/rails/paths.rb +15 -12
  172. data/lib/rails/pwa_controller.rb +15 -0
  173. data/lib/rails/rack/logger.rb +27 -16
  174. data/lib/rails/rackup/server.rb +15 -0
  175. data/lib/rails/railtie/configurable.rb +2 -2
  176. data/lib/rails/railtie/configuration.rb +14 -1
  177. data/lib/rails/railtie.rb +33 -34
  178. data/lib/rails/source_annotation_extractor.rb +67 -18
  179. data/lib/rails/tasks/engine.rake +8 -8
  180. data/lib/rails/tasks/framework.rake +2 -34
  181. data/lib/rails/tasks/log.rake +1 -1
  182. data/lib/rails/tasks/misc.rake +3 -14
  183. data/lib/rails/tasks/statistics.rake +5 -4
  184. data/lib/rails/tasks/tmp.rake +6 -6
  185. data/lib/rails/tasks/zeitwerk.rake +15 -35
  186. data/lib/rails/tasks.rb +0 -2
  187. data/lib/rails/templates/layouts/application.html.erb +1 -1
  188. data/lib/rails/templates/rails/mailers/email.html.erb +44 -8
  189. data/lib/rails/templates/rails/mailers/index.html.erb +14 -7
  190. data/lib/rails/templates/rails/mailers/mailer.html.erb +11 -5
  191. data/lib/rails/templates/rails/welcome/index.html.erb +5 -2
  192. data/lib/rails/test_help.rb +11 -18
  193. data/lib/rails/test_unit/line_filtering.rb +1 -1
  194. data/lib/rails/test_unit/reporter.rb +14 -4
  195. data/lib/rails/test_unit/runner.rb +62 -20
  196. data/lib/rails/test_unit/test_parser.rb +133 -0
  197. data/lib/rails/test_unit/testing.rake +13 -33
  198. data/lib/rails/testing/maintain_test_schema.rb +16 -0
  199. data/lib/rails/version.rb +1 -1
  200. data/lib/rails/zeitwerk_checker.rb +15 -0
  201. data/lib/rails.rb +20 -17
  202. metadata +87 -40
  203. data/RDOC_MAIN.rdoc +0 -97
  204. data/lib/rails/app_updater.rb +0 -40
  205. data/lib/rails/application/dummy_erb_compiler.rb +0 -18
  206. data/lib/rails/commands/secrets/USAGE +0 -66
  207. data/lib/rails/commands/secrets/secrets_command.rb +0 -65
  208. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  209. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  210. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  211. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  212. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  213. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +0 -143
  214. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  215. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  216. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  217. data/lib/rails/generators/rails/model/USAGE +0 -113
  218. data/lib/rails/ruby_version_check.rb +0 -15
  219. data/lib/rails/secrets.rb +0 -110
  220. data/lib/rails/tasks/middleware.rake +0 -9
  221. data/lib/rails/tasks/restart.rake +0 -9
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
3
4
  require "active_support/core_ext/string/inflections"
4
5
  require "active_support/core_ext/array/conversions"
5
6
  require "active_support/descendants_tracker"
@@ -11,22 +12,27 @@ module Rails
11
12
  include Initializable
12
13
 
13
14
  initializer :add_generator_templates do
14
- config.generators.templates.unshift(*paths["lib/templates"].existent)
15
+ ensure_generator_templates_added
15
16
  end
16
17
 
17
18
  initializer :setup_main_autoloader do
18
19
  autoloader = Rails.autoloaders.main
19
20
 
21
+ # Normally empty, but if the user already defined some, we won't
22
+ # override them. Important if there are custom namespaces associated.
23
+ already_configured_dirs = Set.new(autoloader.dirs)
24
+
20
25
  ActiveSupport::Dependencies.autoload_paths.freeze
21
26
  ActiveSupport::Dependencies.autoload_paths.uniq.each do |path|
22
27
  # Zeitwerk only accepts existing directories in `push_dir`.
23
28
  next unless File.directory?(path)
29
+ next if already_configured_dirs.member?(path.to_s)
24
30
 
25
31
  autoloader.push_dir(path)
26
32
  autoloader.do_not_eager_load(path) unless ActiveSupport::Dependencies.eager_load?(path)
27
33
  end
28
34
 
29
- unless config.cache_classes
35
+ if config.reloading_enabled?
30
36
  autoloader.enable_reloading
31
37
  ActiveSupport::Dependencies.autoloader = autoloader
32
38
 
@@ -72,9 +78,10 @@ module Rails
72
78
  if config.eager_load
73
79
  ActiveSupport.run_load_hooks(:before_eager_load, self)
74
80
  Zeitwerk::Loader.eager_load_all
81
+ Rails.eager_load!
75
82
  config.eager_load_namespaces.each(&:eager_load!)
76
83
 
77
- unless config.cache_classes
84
+ if config.reloading_enabled?
78
85
  app.reloader.after_class_unload do
79
86
  Rails.autoloaders.main.eager_load
80
87
  end
@@ -125,10 +132,7 @@ module Rails
125
132
  else
126
133
  # Default concurrency setting: enabled, but safe
127
134
 
128
- unless config.cache_classes && config.eager_load
129
- # Without cache_classes + eager_load, the load interlock
130
- # is required for proper operation
131
-
135
+ if config.reloading_enabled?
132
136
  app.executor.register_hook(InterlockHook, outer: true)
133
137
  end
134
138
  end
@@ -157,6 +161,7 @@ module Rails
157
161
  reloader.eager_load = app.config.eager_load
158
162
  reloader.execute
159
163
  reloaders << reloader
164
+
160
165
  app.reloader.to_run do
161
166
  # We configure #execute rather than #execute_if_updated because if
162
167
  # autoloaded constants are cleared we need to reload routes also in
@@ -169,7 +174,10 @@ module Rails
169
174
  # some sort of reloaders dependency support, to be added.
170
175
  require_unload_lock!
171
176
  reloader.execute
177
+ ActiveSupport.run_load_hooks(:after_routes_loaded, self)
172
178
  end
179
+
180
+ ActiveSupport.run_load_hooks(:after_routes_loaded, self)
173
181
  end
174
182
 
175
183
  # Set clearing dependencies after the finisher hook to ensure paths
@@ -181,39 +189,48 @@ module Rails
181
189
  ActiveSupport::Dependencies.clear
182
190
  end
183
191
 
184
- if config.cache_classes
185
- app.reloader.check = lambda { false }
186
- elsif config.reload_classes_only_on_change
187
- app.reloader.check = lambda do
188
- app.reloaders.map(&:updated?).any?
192
+ if config.reloading_enabled?
193
+ if config.reload_classes_only_on_change
194
+ app.reloader.check = lambda do
195
+ app.reloaders.map(&:updated?).any?
196
+ end
197
+ else
198
+ app.reloader.check = lambda { true }
189
199
  end
190
200
  else
191
- app.reloader.check = lambda { true }
201
+ app.reloader.check = lambda { false }
192
202
  end
193
203
 
194
- if config.cache_classes
195
- # No reloader
196
- ActiveSupport::DescendantsTracker.disable_clear!
197
- elsif config.reload_classes_only_on_change
198
- reloader = config.file_watcher.new(*watchable_args, &callback)
199
- reloaders << reloader
200
-
201
- # Prepend this callback to have autoloaded constants cleared before
202
- # any other possible reloading, in case they need to autoload fresh
203
- # constants.
204
- app.reloader.to_run(prepend: true) do
205
- # In addition to changes detected by the file watcher, if routes
206
- # or i18n have been updated we also need to clear constants,
207
- # that's why we run #execute rather than #execute_if_updated, this
208
- # callback has to clear autoloaded constants after any update.
209
- class_unload! do
210
- reloader.execute
204
+ if config.reloading_enabled?
205
+ if config.reload_classes_only_on_change
206
+ reloader = config.file_watcher.new(*watchable_args, &callback)
207
+ reloaders << reloader
208
+
209
+ # Prepend this callback to have autoloaded constants cleared before
210
+ # any other possible reloading, in case they need to autoload fresh
211
+ # constants.
212
+ app.reloader.to_run(prepend: true) do
213
+ # In addition to changes detected by the file watcher, if routes
214
+ # or i18n have been updated we also need to clear constants,
215
+ # that's why we run #execute rather than #execute_if_updated, this
216
+ # callback has to clear autoloaded constants after any update.
217
+ class_unload! do
218
+ reloader.execute
219
+ end
220
+ end
221
+ else
222
+ app.reloader.to_complete do
223
+ class_unload!(&callback)
211
224
  end
212
225
  end
213
226
  else
214
- app.reloader.to_complete do
215
- class_unload!(&callback)
216
- end
227
+ ActiveSupport::DescendantsTracker.disable_clear!
228
+ end
229
+ end
230
+
231
+ initializer :enable_yjit do
232
+ if config.yjit && defined?(RubyVM::YJIT.enable)
233
+ RubyVM::YJIT.enable
217
234
  end
218
235
  end
219
236
  end
@@ -4,12 +4,12 @@ require "yaml"
4
4
  require "active_support/core_ext/hash/keys"
5
5
  require "active_support/core_ext/object/blank"
6
6
  require "active_support/key_generator"
7
- require "active_support/message_verifier"
7
+ require "active_support/message_verifiers"
8
+ require "active_support/deprecation"
8
9
  require "active_support/encrypted_configuration"
9
10
  require "active_support/hash_with_indifferent_access"
10
11
  require "active_support/configuration_file"
11
12
  require "rails/engine"
12
- require "rails/secrets"
13
13
  require "rails/autoloaders"
14
14
 
15
15
  module Rails
@@ -26,7 +26,7 @@ module Rails
26
26
  #
27
27
  # Besides providing the same configuration as Rails::Engine and Rails::Railtie,
28
28
  # the application object has several specific configurations, for example
29
- # +cache_classes+, +consider_all_requests_local+, +filter_parameters+,
29
+ # +enable_reloading+, +consider_all_requests_local+, +filter_parameters+,
30
30
  # +logger+, and so forth.
31
31
  #
32
32
  # Check Rails::Application::Configuration to see them all.
@@ -70,6 +70,8 @@ module Rails
70
70
  def inherited(base)
71
71
  super
72
72
  Rails.app_class = base
73
+ # lib has to be added to $LOAD_PATH unconditionally, even if it's in the
74
+ # autoload paths and config.add_autoload_paths_to_load_path is false.
73
75
  add_lib_to_load_path!(find_root(base.called_from))
74
76
  ActiveSupport.run_load_hooks(:before_configuration, base)
75
77
  end
@@ -101,7 +103,7 @@ module Rails
101
103
  delegate :default_url_options, :default_url_options=, to: :routes
102
104
 
103
105
  INITIAL_VARIABLES = [:config, :railties, :routes_reloader, :reloaders,
104
- :routes, :helpers, :app_env_config, :secrets] # :nodoc:
106
+ :routes, :helpers, :app_env_config] # :nodoc:
105
107
 
106
108
  def initialize(initial_variable_values = {}, &block)
107
109
  super()
@@ -111,7 +113,9 @@ module Rails
111
113
  @app_env_config = nil
112
114
  @ordered_railties = nil
113
115
  @railties = nil
114
- @message_verifiers = {}
116
+ @key_generators = {}
117
+ @message_verifiers = nil
118
+ @deprecators = nil
115
119
  @ran_load_hooks = false
116
120
 
117
121
  @executor = Class.new(ActiveSupport::Executor)
@@ -130,6 +134,13 @@ module Rails
130
134
  @initialized
131
135
  end
132
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
+
133
144
  def run_load_hooks! # :nodoc:
134
145
  return self if @ran_load_hooks
135
146
  @ran_load_hooks = true
@@ -149,15 +160,53 @@ module Rails
149
160
  routes_reloader.reload!
150
161
  end
151
162
 
152
- # Returns the application's KeyGenerator
153
- def key_generator
163
+ # Returns a key generator (ActiveSupport::CachingKeyGenerator) for a
164
+ # specified +secret_key_base+. The return value is memoized, so additional
165
+ # calls with the same +secret_key_base+ will return the same key generator
166
+ # instance.
167
+ def key_generator(secret_key_base = self.secret_key_base)
154
168
  # number of iterations selected based on consultation with the google security
155
169
  # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
156
- @caching_key_generator ||= ActiveSupport::CachingKeyGenerator.new(
170
+ @key_generators[secret_key_base] ||= ActiveSupport::CachingKeyGenerator.new(
157
171
  ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
158
172
  )
159
173
  end
160
174
 
175
+ # Returns a message verifier factory (ActiveSupport::MessageVerifiers). This
176
+ # factory can be used as a central point to configure and create message
177
+ # verifiers (ActiveSupport::MessageVerifier) for your application.
178
+ #
179
+ # By default, message verifiers created by this factory will generate
180
+ # messages using the default ActiveSupport::MessageVerifier options. You can
181
+ # override these options with a combination of
182
+ # ActiveSupport::MessageVerifiers#clear_rotations and
183
+ # ActiveSupport::MessageVerifiers#rotate. However, this must be done prior
184
+ # to building any message verifier instances. For example, in a
185
+ # +before_initialize+ block:
186
+ #
187
+ # # Use `url_safe: true` when generating messages
188
+ # config.before_initialize do |app|
189
+ # app.message_verifiers.clear_rotations
190
+ # app.message_verifiers.rotate(url_safe: true)
191
+ # end
192
+ #
193
+ # Message verifiers created by this factory will always use a secret derived
194
+ # from #secret_key_base when generating messages. +clear_rotations+ will not
195
+ # affect this behavior. However, older +secret_key_base+ values can be
196
+ # rotated for verifying messages:
197
+ #
198
+ # # Fall back to old `secret_key_base` when verifying messages
199
+ # config.before_initialize do |app|
200
+ # app.message_verifiers.rotate(secret_key_base: "old secret_key_base")
201
+ # end
202
+ #
203
+ def message_verifiers
204
+ @message_verifiers ||=
205
+ ActiveSupport::MessageVerifiers.new do |salt, secret_key_base: self.secret_key_base|
206
+ key_generator(secret_key_base).generate_key(salt)
207
+ end.rotate_defaults
208
+ end
209
+
161
210
  # Returns a message verifier object.
162
211
  #
163
212
  # This verifier can be used to generate and verify signed messages in the application.
@@ -165,27 +214,36 @@ module Rails
165
214
  # It is recommended not to use the same verifier for different things, so you can get different
166
215
  # verifiers passing the +verifier_name+ argument.
167
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
+ #
168
222
  # ==== Parameters
169
223
  #
170
224
  # * +verifier_name+ - the name of the message verifier.
171
225
  #
172
226
  # ==== Examples
173
227
  #
174
- # message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
175
- # Rails.application.message_verifier('sensitive_data').verify(message)
176
- # # => 'my sensible data'
177
- #
178
- # 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'
179
231
  def message_verifier(verifier_name)
180
- @message_verifiers[verifier_name] ||= begin
181
- secret = key_generator.generate_key(verifier_name.to_s)
182
- ActiveSupport::MessageVerifier.new(secret)
232
+ message_verifiers[verifier_name]
233
+ end
234
+
235
+ # A managed collection of deprecators (ActiveSupport::Deprecation::Deprecators).
236
+ # The collection's configuration methods affect all deprecators in the
237
+ # collection. Additionally, the collection's +silence+ method silences all
238
+ # deprecators in the collection for the duration of a given block.
239
+ def deprecators
240
+ @deprecators ||= ActiveSupport::Deprecation::Deprecators.new.tap do |deprecators|
241
+ deprecators[:railties] = Rails.deprecator
183
242
  end
184
243
  end
185
244
 
186
- # Convenience for loading config/foo.yml for the current Rails env.
187
- #
188
- # Examples:
245
+ # Convenience for loading config/foo.yml for the current \Rails env.
246
+ # Example:
189
247
  #
190
248
  # # config/exception_notification.yml:
191
249
  # production:
@@ -196,13 +254,15 @@ module Rails
196
254
  # url: http://localhost:3001
197
255
  # namespace: my_app_development
198
256
  #
257
+ # <code></code>
258
+ #
199
259
  # # config/environments/production.rb
200
260
  # Rails.application.configure do
201
261
  # config.middleware.use ExceptionNotifier, config_for(:exception_notification)
202
262
  # end
203
263
  #
204
- # # You can also store configurations in a shared section which will be
205
- # # merged with the environment configuration
264
+ # You can also store configurations in a shared section which will be merged
265
+ # with the environment configuration
206
266
  #
207
267
  # # config/example.yml
208
268
  # shared:
@@ -215,6 +275,8 @@ module Rails
215
275
  # bar:
216
276
  # qux: 2
217
277
  #
278
+ # <code></code>
279
+ #
218
280
  # # development environment
219
281
  # Rails.application.config_for(:example)[:foo][:bar]
220
282
  # # => { baz: 1, qux: 2 }
@@ -245,16 +307,17 @@ module Rails
245
307
  end
246
308
  end
247
309
 
248
- # Stores some of the Rails initial environment parameters which
310
+ # Stores some of the \Rails initial environment parameters which
249
311
  # will be used by middlewares and engines to configure themselves.
250
312
  def env_config
251
313
  @app_env_config ||= super.merge(
252
- "action_dispatch.parameter_filter" => config.filter_parameters,
314
+ "action_dispatch.parameter_filter" => filter_parameters,
253
315
  "action_dispatch.redirect_filter" => config.filter_redirect,
254
316
  "action_dispatch.secret_key_base" => secret_key_base,
255
317
  "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
256
318
  "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
257
319
  "action_dispatch.log_rescued_responses" => config.action_dispatch.log_rescued_responses,
320
+ "action_dispatch.debug_exception_log_level" => ActiveSupport::Logger.const_get(config.action_dispatch.debug_exception_log_level.to_s.upcase),
258
321
  "action_dispatch.logger" => Rails.logger,
259
322
  "action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner,
260
323
  "action_dispatch.key_generator" => key_generator,
@@ -337,7 +400,7 @@ module Rails
337
400
  # Rails application, you will need to add lib to $LOAD_PATH on your own in case
338
401
  # you need to load files in lib/ during the application configuration as well.
339
402
  def self.add_lib_to_load_path!(root) # :nodoc:
340
- path = File.join root, "lib"
403
+ path = File.join(root, "lib")
341
404
  if File.exist?(path) && !$LOAD_PATH.include?(path)
342
405
  $LOAD_PATH.unshift(path)
343
406
  end
@@ -358,8 +421,8 @@ module Rails
358
421
  def watchable_args # :nodoc:
359
422
  files, dirs = config.watchable_files.dup, config.watchable_dirs.dup
360
423
 
361
- ActiveSupport::Dependencies.autoload_paths.each do |path|
362
- File.file?(path) ? files << path.to_s : dirs[path.to_s] = [:rb]
424
+ Rails.autoloaders.main.dirs.each do |path|
425
+ dirs[path] = [:rb]
363
426
  end
364
427
 
365
428
  [files, dirs]
@@ -385,41 +448,26 @@ module Rails
385
448
  end
386
449
 
387
450
  attr_writer :config
388
-
389
- def secrets
390
- @secrets ||= begin
391
- secrets = ActiveSupport::OrderedOptions.new
392
- files = config.paths["config/secrets"].existent
393
- files = files.reject { |path| path.end_with?(".enc") } unless config.read_encrypted_secrets
394
- secrets.merge! Rails::Secrets.parse(files, env: Rails.env)
395
-
396
- # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
397
- secrets.secret_key_base ||= config.secret_key_base
398
-
399
- secrets
400
- end
401
- end
402
-
403
- attr_writer :secrets, :credentials
451
+ attr_writer :credentials
404
452
 
405
453
  # The secret_key_base is used as the input secret to the application's key generator, which in turn
406
454
  # is used to create all ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor instances,
407
455
  # including the ones that sign and encrypt cookies.
408
456
  #
409
457
  # In development and test, this is randomly generated and stored in a
410
- # temporary file in <tt>tmp/development_secret.txt</tt>.
458
+ # temporary file in <tt>tmp/local_secret.txt</tt>.
459
+ #
460
+ # You can also set <tt>ENV["SECRET_KEY_BASE_DUMMY"]</tt> to trigger the use of a randomly generated
461
+ # secret_key_base that's stored in a temporary file. This is useful when precompiling assets for
462
+ # production as part of a build step that otherwise does not need access to the production secrets.
463
+ #
464
+ # Dockerfile example: <tt>RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile</tt>.
411
465
  #
412
466
  # In all other environments, we look for it first in <tt>ENV["SECRET_KEY_BASE"]</tt>,
413
- # then +credentials.secret_key_base+, and finally +secrets.secret_key_base+. For most applications,
414
- # 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.
415
469
  def secret_key_base
416
- if Rails.env.development? || Rails.env.test?
417
- secrets.secret_key_base ||= generate_development_secret
418
- else
419
- validate_secret_key_base(
420
- ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
421
- )
422
- end
470
+ config.secret_key_base
423
471
  end
424
472
 
425
473
  # Returns an ActiveSupport::EncryptedConfiguration instance for the
@@ -488,6 +536,11 @@ module Rails
488
536
  ordered_railties.flatten - [self]
489
537
  end
490
538
 
539
+ def load_generators(app = self) # :nodoc:
540
+ app.ensure_generator_templates_added
541
+ super
542
+ end
543
+
491
544
  # Eager loads the application code.
492
545
  def eager_load!
493
546
  Rails.autoloaders.each(&:eager_load)
@@ -567,33 +620,12 @@ module Rails
567
620
  default_stack.build_stack
568
621
  end
569
622
 
570
- def validate_secret_key_base(secret_key_base)
571
- if secret_key_base.is_a?(String) && secret_key_base.present?
572
- secret_key_base
573
- elsif secret_key_base
574
- raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
575
- else
576
- raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
577
- end
623
+ def ensure_generator_templates_added
624
+ configured_paths = config.generators.templates
625
+ configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths))
578
626
  end
579
627
 
580
628
  private
581
- def generate_development_secret
582
- if secrets.secret_key_base.nil?
583
- key_file = Rails.root.join("tmp/development_secret.txt")
584
-
585
- if !File.exist?(key_file)
586
- random_key = SecureRandom.hex(64)
587
- FileUtils.mkdir_p(key_file.dirname)
588
- File.binwrite(key_file, random_key)
589
- end
590
-
591
- secrets.secret_key_base = File.binread(key_file)
592
- end
593
-
594
- secrets.secret_key_base
595
- end
596
-
597
629
  def build_request(env)
598
630
  req = super
599
631
  env["ORIGINAL_FULLPATH"] = req.fullpath
@@ -608,5 +640,14 @@ module Rails
608
640
  def coerce_same_site_protection(protection)
609
641
  protection.respond_to?(:call) ? protection : proc { protection }
610
642
  end
643
+
644
+ def filter_parameters
645
+ if config.precompile_filter_parameters
646
+ config.filter_parameters.replace(
647
+ ActiveSupport::ParameterFilter.precompile_filters(config.filter_parameters)
648
+ )
649
+ end
650
+ config.filter_parameters
651
+ end
611
652
  end
612
653
  end
@@ -4,15 +4,17 @@ require "active_support/backtrace_cleaner"
4
4
  require "active_support/core_ext/string/access"
5
5
 
6
6
  module Rails
7
- class BacktraceCleaner < ActiveSupport::BacktraceCleaner
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,12 +6,14 @@ 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"
13
-
14
- if ARGV.first == "plugin"
12
+ case ARGV.first
13
+ when Rails::Command::HELP_MAPPINGS, "help", nil
14
+ ARGV.shift
15
+ Rails::Command.invoke :gem_help, ARGV
16
+ when "plugin"
15
17
  ARGV.shift
16
18
  Rails::Command.invoke :plugin, ARGV
17
19
  else
@@ -10,23 +10,21 @@ module Rails
10
10
  Dir.chdir(File.expand_path("../..", APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
11
11
  end
12
12
 
13
- def require_application_and_environment!
14
- require_application!
15
- require_environment!
16
- end
17
-
18
13
  def require_application!
19
14
  require ENGINE_PATH if defined?(ENGINE_PATH)
15
+ require APP_PATH if defined?(APP_PATH)
16
+ end
20
17
 
21
- if defined?(APP_PATH)
22
- require APP_PATH
23
- end
18
+ def boot_application!
19
+ require_application!
20
+ Rails.application.require_environment! if defined?(APP_PATH)
24
21
  end
25
22
 
26
- def require_environment!
27
- if defined?(APP_PATH)
28
- Rails.application.require_environment!
29
- end
23
+ def load_environment_config!
24
+ require_application!
25
+ # Only run initializers that are in the :all group, which includes the
26
+ # :load_environment_config initializer.
27
+ Rails.application.initialize!(:_) if defined?(APP_PATH)
30
28
  end
31
29
 
32
30
  if defined?(ENGINE_PATH)