railties 5.2.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +293 -89
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +39 -33
  5. data/README.rdoc +3 -3
  6. data/lib/minitest/rails_plugin.rb +24 -13
  7. data/lib/rails/all.rb +4 -0
  8. data/lib/rails/api/generator.rb +2 -1
  9. data/lib/rails/api/task.rb +17 -0
  10. data/lib/rails/app_loader.rb +2 -2
  11. data/lib/rails/app_updater.rb +4 -1
  12. data/lib/rails/application/bootstrap.rb +9 -17
  13. data/lib/rails/application/configuration.rb +177 -27
  14. data/lib/rails/application/default_middleware_stack.rb +7 -3
  15. data/lib/rails/application/dummy_erb_compiler.rb +18 -0
  16. data/lib/rails/application/finisher.rb +69 -2
  17. data/lib/rails/application/routes_reloader.rb +9 -19
  18. data/lib/rails/application.rb +96 -66
  19. data/lib/rails/application_controller.rb +0 -1
  20. data/lib/rails/autoloaders.rb +48 -0
  21. data/lib/rails/backtrace_cleaner.rb +14 -21
  22. data/lib/rails/code_statistics.rb +8 -6
  23. data/lib/rails/code_statistics_calculator.rb +6 -6
  24. data/lib/rails/command/actions.rb +10 -0
  25. data/lib/rails/command/base.rb +17 -5
  26. data/lib/rails/command/behavior.rb +8 -49
  27. data/lib/rails/command/environment_argument.rb +9 -16
  28. data/lib/rails/command/spellchecker.rb +57 -0
  29. data/lib/rails/command.rb +18 -11
  30. data/lib/rails/commands/console/console_command.rb +6 -0
  31. data/lib/rails/commands/credentials/USAGE +33 -0
  32. data/lib/rails/commands/credentials/credentials_command/diffing.rb +41 -0
  33. data/lib/rails/commands/credentials/credentials_command.rb +78 -21
  34. data/lib/rails/commands/db/system/change/change_command.rb +25 -0
  35. data/lib/rails/commands/dbconsole/dbconsole_command.rb +66 -51
  36. data/lib/rails/commands/dev/dev_command.rb +19 -0
  37. data/lib/rails/commands/encrypted/USAGE +28 -0
  38. data/lib/rails/commands/encrypted/encrypted_command.rb +5 -4
  39. data/lib/rails/commands/generate/generate_command.rb +1 -1
  40. data/lib/rails/commands/help/help_command.rb +1 -1
  41. data/lib/rails/commands/initializers/initializers_command.rb +23 -0
  42. data/lib/rails/commands/new/new_command.rb +2 -2
  43. data/lib/rails/commands/notes/notes_command.rb +29 -0
  44. data/lib/rails/commands/plugin/plugin_command.rb +1 -1
  45. data/lib/rails/commands/rake/rake_command.rb +9 -8
  46. data/lib/rails/commands/routes/routes_command.rb +37 -0
  47. data/lib/rails/commands/runner/runner_command.rb +13 -9
  48. data/lib/rails/commands/secrets/USAGE +6 -0
  49. data/lib/rails/commands/secrets/secrets_command.rb +3 -3
  50. data/lib/rails/commands/server/server_command.rb +92 -56
  51. data/lib/rails/commands/test/test_command.rb +2 -2
  52. data/lib/rails/configuration.rb +48 -19
  53. data/lib/rails/engine/configuration.rb +6 -2
  54. data/lib/rails/engine/updater.rb +1 -1
  55. data/lib/rails/engine.rb +63 -35
  56. data/lib/rails/gem_version.rb +2 -2
  57. data/lib/rails/generators/actions/create_migration.rb +5 -1
  58. data/lib/rails/generators/actions.rb +89 -56
  59. data/lib/rails/generators/app_base.rb +80 -108
  60. data/lib/rails/generators/app_name.rb +50 -0
  61. data/lib/rails/generators/base.rb +19 -12
  62. data/lib/rails/generators/database.rb +57 -0
  63. data/lib/rails/generators/erb/mailer/mailer_generator.rb +1 -2
  64. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +0 -1
  65. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +7 -4
  66. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +1 -1
  67. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +9 -1
  68. data/lib/rails/generators/erb.rb +0 -1
  69. data/lib/rails/generators/generated_attribute.rb +50 -31
  70. data/lib/rails/generators/migration.rb +3 -3
  71. data/lib/rails/generators/model_helpers.rb +33 -2
  72. data/lib/rails/generators/named_base.rb +3 -7
  73. data/lib/rails/generators/rails/app/USAGE +2 -1
  74. data/lib/rails/generators/rails/app/app_generator.rb +127 -84
  75. data/lib/rails/generators/rails/app/templates/Gemfile.tt +18 -21
  76. data/lib/rails/generators/rails/app/templates/Rakefile.tt +1 -1
  77. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -3
  78. data/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js +6 -0
  79. data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +5 -0
  80. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +23 -0
  81. data/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt +5 -0
  82. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +6 -5
  83. data/lib/rails/generators/rails/app/templates/bin/rails.tt +5 -2
  84. data/lib/rails/generators/rails/app/templates/bin/rake.tt +5 -2
  85. data/lib/rails/generators/rails/app/templates/bin/setup.tt +9 -9
  86. data/lib/rails/generators/rails/app/templates/bin/spring.tt +9 -0
  87. data/lib/rails/generators/rails/app/templates/bin/yarn.tt +11 -3
  88. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +16 -7
  89. data/lib/rails/generators/rails/app/templates/config/boot.rb.tt +2 -2
  90. data/lib/rails/generators/rails/app/templates/config/cable.yml.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +4 -5
  92. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +12 -11
  93. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +13 -12
  94. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +1 -1
  95. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +13 -12
  96. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +12 -11
  97. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +16 -15
  98. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  99. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +11 -10
  100. data/lib/rails/generators/rails/app/templates/config/environment.rb.tt +1 -1
  101. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +22 -5
  102. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +43 -17
  103. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +26 -7
  104. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
  105. data/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt +4 -3
  106. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +7 -0
  107. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -1
  108. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_1.rb.tt +63 -0
  109. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -0
  110. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
  111. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +13 -4
  112. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +1 -1
  113. data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +6 -6
  114. data/lib/rails/generators/rails/app/templates/config.ru.tt +2 -1
  115. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +1 -1
  116. data/lib/rails/generators/rails/app/templates/gitattributes.tt +14 -0
  117. data/lib/rails/generators/rails/app/templates/gitignore.tt +10 -7
  118. data/lib/rails/generators/rails/app/templates/package.json.tt +8 -2
  119. data/lib/rails/generators/rails/app/templates/public/robots.txt +1 -1
  120. data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
  121. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +11 -0
  122. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -2
  123. data/lib/rails/generators/rails/assets/USAGE +3 -7
  124. data/lib/rails/generators/rails/assets/assets_generator.rb +0 -1
  125. data/lib/rails/generators/rails/benchmark/USAGE +19 -0
  126. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +29 -0
  127. data/lib/rails/generators/rails/benchmark/templates/benchmark.rb.tt +15 -0
  128. data/lib/rails/generators/rails/controller/USAGE +2 -2
  129. data/lib/rails/generators/rails/controller/controller_generator.rb +10 -39
  130. data/lib/rails/generators/rails/credentials/credentials_generator.rb +6 -7
  131. data/lib/rails/generators/rails/db/system/change/change_generator.rb +65 -0
  132. data/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb +10 -7
  133. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -0
  134. data/lib/rails/generators/rails/generator/USAGE +2 -2
  135. data/lib/rails/generators/rails/generator/generator_generator.rb +0 -1
  136. data/lib/rails/generators/rails/generator/templates/USAGE.tt +1 -1
  137. data/lib/rails/generators/rails/helper/USAGE +2 -3
  138. data/lib/rails/generators/rails/helper/helper_generator.rb +5 -0
  139. data/lib/rails/generators/rails/integration_test/USAGE +2 -2
  140. data/lib/rails/generators/rails/migration/USAGE +4 -4
  141. data/lib/rails/generators/rails/model/USAGE +15 -16
  142. data/lib/rails/generators/rails/plugin/plugin_generator.rb +32 -56
  143. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +18 -18
  144. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +3 -10
  145. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -18
  146. data/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +1 -2
  147. data/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt +1 -1
  148. data/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt +1 -1
  149. data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +1 -1
  150. data/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +1 -1
  151. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +3 -3
  152. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +14 -11
  153. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +1 -1
  154. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt +1 -1
  155. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb.tt +1 -0
  156. data/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt +1 -1
  157. data/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb.tt +4 -4
  158. data/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb.tt +1 -1
  159. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +0 -4
  160. data/lib/rails/generators/rails/resource/USAGE +4 -4
  161. data/lib/rails/generators/rails/resource_route/resource_route_generator.rb +2 -27
  162. data/lib/rails/generators/rails/scaffold/USAGE +5 -5
  163. data/lib/rails/generators/rails/scaffold_controller/USAGE +2 -2
  164. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +19 -0
  165. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
  166. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +2 -2
  167. data/lib/rails/generators/rails/system_test/USAGE +2 -2
  168. data/lib/rails/generators/rails/task/USAGE +3 -3
  169. data/lib/rails/generators/resource_helpers.rb +1 -6
  170. data/lib/rails/generators/test_case.rb +1 -1
  171. data/lib/rails/generators/test_unit/controller/controller_generator.rb +2 -0
  172. data/lib/rails/generators/test_unit/controller/templates/functional_test.rb.tt +3 -3
  173. data/lib/rails/generators/test_unit/generator/generator_generator.rb +0 -1
  174. data/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt +2 -2
  175. data/lib/rails/generators/test_unit/integration/integration_generator.rb +5 -0
  176. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb.tt +1 -1
  177. data/lib/rails/generators/test_unit/job/job_generator.rb +5 -0
  178. data/lib/rails/generators/test_unit/job/templates/unit_test.rb.tt +1 -1
  179. data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +1 -1
  180. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +1 -1
  181. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +3 -3
  182. data/lib/rails/generators/test_unit/model/templates/unit_test.rb.tt +1 -1
  183. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +1 -1
  184. data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +2 -2
  185. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +12 -3
  186. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +1 -1
  187. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +1 -1
  188. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +10 -2
  189. data/lib/rails/generators/test_unit/system/system_generator.rb +5 -0
  190. data/lib/rails/generators/testing/assertions.rb +2 -2
  191. data/lib/rails/generators/testing/behaviour.rb +4 -2
  192. data/lib/rails/generators.rb +38 -24
  193. data/lib/rails/info.rb +4 -4
  194. data/lib/rails/info_controller.rb +2 -3
  195. data/lib/rails/mailers_controller.rb +10 -4
  196. data/lib/rails/paths.rb +26 -10
  197. data/lib/rails/rack/logger.rb +5 -6
  198. data/lib/rails/railtie/configurable.rb +0 -1
  199. data/lib/rails/railtie/configuration.rb +3 -3
  200. data/lib/rails/railtie.rb +33 -13
  201. data/lib/rails/ruby_version_check.rb +3 -3
  202. data/lib/rails/secrets.rb +0 -1
  203. data/lib/rails/source_annotation_extractor.rb +124 -117
  204. data/lib/rails/tasks/engine.rake +1 -4
  205. data/lib/rails/tasks/framework.rake +13 -3
  206. data/lib/rails/tasks/log.rake +0 -1
  207. data/lib/rails/tasks/misc.rake +1 -1
  208. data/lib/rails/tasks/statistics.rake +5 -1
  209. data/lib/rails/tasks/yarn.rake +14 -1
  210. data/lib/rails/tasks/zeitwerk.rake +69 -0
  211. data/lib/rails/tasks.rb +1 -4
  212. data/lib/rails/templates/rails/mailers/email.html.erb +11 -7
  213. data/lib/rails/templates/rails/welcome/index.html.erb +3 -3
  214. data/lib/rails/test_help.rb +11 -9
  215. data/lib/rails/test_unit/reporter.rb +3 -2
  216. data/lib/rails/test_unit/runner.rb +25 -8
  217. data/lib/rails/test_unit/testing.rake +7 -1
  218. data/lib/rails.rb +10 -8
  219. metadata +45 -39
  220. data/lib/rails/generators/js/assets/assets_generator.rb +0 -15
  221. data/lib/rails/generators/js/assets/templates/javascript.js +0 -2
  222. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +0 -22
  223. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt +0 -13
  224. data/lib/rails/generators/rails/app/templates/bin/bundle.tt +0 -2
  225. data/lib/rails/generators/rails/app/templates/bin/update.tt +0 -34
  226. data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt +0 -50
  227. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt +0 -86
  228. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt +0 -35
  229. data/lib/rails/generators/rails/assets/templates/javascript.js +0 -2
  230. data/lib/rails/generators/rails/plugin/templates/rails/application.rb.tt +0 -23
  231. data/lib/rails/tasks/annotations.rake +0 -22
  232. data/lib/rails/tasks/dev.rake +0 -10
  233. data/lib/rails/tasks/initializers.rake +0 -8
  234. data/lib/rails/tasks/routes.rake +0 -31
data/lib/rails/engine.rb CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  require "rails/railtie"
4
4
  require "rails/engine/railties"
5
+ require "active_support/callbacks"
5
6
  require "active_support/core_ext/module/delegation"
7
+ require "active_support/core_ext/object/try"
6
8
  require "pathname"
7
9
  require "thread"
8
10
 
@@ -35,10 +37,10 @@ module Rails
35
37
  #
36
38
  # == Configuration
37
39
  #
38
- # Besides the +Railtie+ configuration which is shared across the application, in a
39
- # <tt>Rails::Engine</tt> you can access <tt>autoload_paths</tt>, <tt>eager_load_paths</tt>
40
- # and <tt>autoload_once_paths</tt>, which, differently from a <tt>Railtie</tt>, are scoped to
41
- # the current engine.
40
+ # Like railties, engines can access a config object which contains configuration shared by
41
+ # all railties and the application.
42
+ # Additionally, each engine can access <tt>autoload_paths</tt>, <tt>eager_load_paths</tt> and
43
+ # <tt>autoload_once_paths</tt> settings which are scoped to that engine.
42
44
  #
43
45
  # class MyEngine < Rails::Engine
44
46
  # # Add a load path for this specific Engine
@@ -112,7 +114,7 @@ module Rails
112
114
  # == Endpoint
113
115
  #
114
116
  # An engine can also be a Rack application. It can be useful if you have a Rack application that
115
- # you would like to wrap with +Engine+ and provide with some of the +Engine+'s features.
117
+ # you would like to provide with some of the +Engine+'s features.
116
118
  #
117
119
  # To do that, use the +endpoint+ method:
118
120
  #
@@ -122,7 +124,7 @@ module Rails
122
124
  # end
123
125
  # end
124
126
  #
125
- # Now you can mount your engine in application's routes just like that:
127
+ # Now you can mount your engine in application's routes:
126
128
  #
127
129
  # Rails.application.routes.draw do
128
130
  # mount MyEngine::Engine => "/engine"
@@ -228,9 +230,9 @@ module Rails
228
230
  # resources :articles
229
231
  # end
230
232
  #
231
- # If +MyEngine+ is isolated, The routes above will point to
233
+ # If +MyEngine+ is isolated, the routes above will point to
232
234
  # <tt>MyEngine::ArticlesController</tt>. You also don't need to use longer
233
- # url helpers like +my_engine_articles_path+. Instead, you should simply use
235
+ # URL helpers like +my_engine_articles_path+. Instead, you should simply use
234
236
  # +articles_path+, like you would do with your main application.
235
237
  #
236
238
  # To make this behavior consistent with other parts of the framework,
@@ -238,7 +240,7 @@ module Rails
238
240
  # normal Rails app, when you use a namespaced model such as
239
241
  # <tt>Namespace::Article</tt>, <tt>ActiveModel::Naming</tt> will generate
240
242
  # names with the prefix "namespace". In an isolated engine, the prefix will
241
- # be omitted in url helpers and form fields, for convenience.
243
+ # be omitted in URL helpers and form fields, for convenience.
242
244
  #
243
245
  # polymorphic_url(MyEngine::Article.new)
244
246
  # # => "articles_path" # not "my_engine_articles_path"
@@ -286,11 +288,11 @@ module Rails
286
288
  # Note that the <tt>:as</tt> option given to mount takes the <tt>engine_name</tt> as default, so most of the time
287
289
  # you can simply omit it.
288
290
  #
289
- # Finally, if you want to generate a url to an engine's route using
291
+ # Finally, if you want to generate a URL to an engine's route using
290
292
  # <tt>polymorphic_url</tt>, you also need to pass the engine helper. Let's
291
293
  # say that you want to create a form pointing to one of the engine's routes.
292
294
  # All you need to do is pass the helper as the first element in array with
293
- # attributes for url:
295
+ # attributes for URL:
294
296
  #
295
297
  # form_for([my_engine, @user])
296
298
  #
@@ -313,7 +315,7 @@ module Rails
313
315
  # helper MyEngine::Engine.helpers
314
316
  # end
315
317
  #
316
- # It will include all of the helpers from engine's directory. Take into account that this does
318
+ # It will include all of the helpers from engine's directory. Take into account this does
317
319
  # not include helpers defined in controllers with helper_method or other similar solutions,
318
320
  # only helpers defined in the helpers directory will be included.
319
321
  #
@@ -362,7 +364,7 @@ module Rails
362
364
  base.called_from = begin
363
365
  call_stack = caller_locations.map { |l| l.absolute_path || l.path }
364
366
 
365
- File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
367
+ File.dirname(call_stack.detect { |p| !p.match?(%r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack]) })
366
368
  end
367
369
  end
368
370
 
@@ -421,6 +423,9 @@ module Rails
421
423
  end
422
424
  end
423
425
 
426
+ include ActiveSupport::Callbacks
427
+ define_callbacks :load_seed
428
+
424
429
  delegate :middleware, :root, :paths, to: :config
425
430
  delegate :engine_name, :isolated?, to: :class
426
431
 
@@ -469,13 +474,23 @@ module Rails
469
474
  self
470
475
  end
471
476
 
472
- # Eager load the application by loading all ruby
473
- # files inside eager_load paths.
477
+ # Invoke the server registered hooks.
478
+ # Check <tt>Rails::Railtie.server</tt> for more info.
479
+ def load_server(app = self)
480
+ run_server_blocks(app)
481
+ self
482
+ end
483
+
474
484
  def eager_load!
485
+ # Already done by Zeitwerk::Loader.eager_load_all. We need this guard to
486
+ # easily provide a compatible API for both zeitwerk and classic modes.
487
+ return if Rails.autoloaders.zeitwerk_enabled?
488
+
475
489
  config.eager_load_paths.each do |load_path|
476
- matcher = /\A#{Regexp.escape(load_path.to_s)}\/(.*)\.rb\Z/
490
+ # Starts after load_path plus a slash, ends before ".rb".
491
+ relname_range = (load_path.to_s.length + 1)...-3
477
492
  Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
478
- require_dependency file.sub(matcher, '\1')
493
+ require_dependency file[relname_range]
479
494
  end
480
495
  end
481
496
  end
@@ -531,9 +546,9 @@ module Rails
531
546
 
532
547
  # Defines the routes for this engine. If a block is given to
533
548
  # routes, it is appended to the engine.
534
- def routes
549
+ def routes(&block)
535
550
  @routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
536
- @routes.append(&Proc.new) if block_given?
551
+ @routes.append(&block) if block_given?
537
552
  @routes
538
553
  end
539
554
 
@@ -548,12 +563,17 @@ module Rails
548
563
  # Blog::Engine.load_seed
549
564
  def load_seed
550
565
  seed_file = paths["db/seeds.rb"].existent.first
551
- load(seed_file) if seed_file
566
+ run_callbacks(:load_seed) { load(seed_file) } if seed_file
567
+ end
568
+
569
+ initializer :load_environment_config, before: :load_environment_hook, group: :all do
570
+ paths["config/environments"].existent.each do |environment|
571
+ require environment
572
+ end
552
573
  end
553
574
 
554
- # Add configured load paths to Ruby's load path, and remove duplicate entries.
555
- initializer :set_load_path, before: :bootstrap_hook do
556
- _all_load_paths.reverse_each do |path|
575
+ initializer :set_load_path, before: :bootstrap_hook do |app|
576
+ _all_load_paths(app.config.add_autoload_paths_to_load_path).reverse_each do |path|
557
577
  $LOAD_PATH.unshift(path) if File.directory?(path)
558
578
  end
559
579
  $LOAD_PATH.uniq!
@@ -568,18 +588,24 @@ module Rails
568
588
  ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
569
589
  ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths)
570
590
 
571
- # Freeze so future modifications will fail rather than do nothing mysteriously
572
591
  config.autoload_paths.freeze
573
- config.eager_load_paths.freeze
574
592
  config.autoload_once_paths.freeze
575
593
  end
576
594
 
595
+ initializer :set_eager_load_paths, before: :bootstrap_hook do
596
+ ActiveSupport::Dependencies._eager_load_paths.merge(config.eager_load_paths)
597
+ config.eager_load_paths.freeze
598
+ end
599
+
577
600
  initializer :add_routing_paths do |app|
578
601
  routing_paths = paths["config/routes.rb"].existent
602
+ external_paths = self.paths["config/routes"].paths
603
+ routes.draw_paths.concat(external_paths)
579
604
 
580
605
  if routes? || routing_paths.any?
581
606
  app.routes_reloader.paths.unshift(*routing_paths)
582
607
  app.routes_reloader.route_sets << routes
608
+ app.routes_reloader.external_routes.unshift(*external_paths)
583
609
  end
584
610
  end
585
611
 
@@ -597,12 +623,6 @@ module Rails
597
623
  end
598
624
  end
599
625
 
600
- initializer :load_environment_config, before: :load_environment_hook, group: :all do
601
- paths["config/environments"].existent.each do |environment|
602
- require environment
603
- end
604
- end
605
-
606
626
  initializer :prepend_helpers_path do |app|
607
627
  if !isolated? || (app == self)
608
628
  app.config.helpers_paths.unshift(*paths["app/helpers"].existent)
@@ -615,6 +635,12 @@ module Rails
615
635
  end
616
636
  end
617
637
 
638
+ initializer :wrap_executor_around_load_seed do |app|
639
+ self.class.set_callback(:load_seed, :around) do |engine, seeds_block|
640
+ app.executor.wrap(&seeds_block)
641
+ end
642
+ end
643
+
618
644
  initializer :engines_blank_point do
619
645
  # We need this initializer so all extra initializers added in engines are
620
646
  # consistently executed after all the initializers above across all engines.
@@ -644,14 +670,12 @@ module Rails
644
670
  end
645
671
 
646
672
  protected
647
-
648
673
  def run_tasks_blocks(*) #:nodoc:
649
674
  super
650
675
  paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
651
676
  end
652
677
 
653
678
  private
654
-
655
679
  def load_config_initializer(initializer) # :doc:
656
680
  ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do
657
681
  load(initializer)
@@ -686,8 +710,12 @@ module Rails
686
710
  @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
687
711
  end
688
712
 
689
- def _all_load_paths
690
- @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
713
+ def _all_load_paths(add_autoload_paths_to_load_path)
714
+ @_all_load_paths ||= begin
715
+ load_paths = config.paths.load_paths
716
+ load_paths += _all_autoload_paths if add_autoload_paths_to_load_path
717
+ load_paths.uniq
718
+ end
691
719
  end
692
720
 
693
721
  def build_request(env)
@@ -7,8 +7,8 @@ module Rails
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 5
11
- MINOR = 2
10
+ MAJOR = 6
11
+ MINOR = 1
12
12
  TINY = 0
13
13
  PRE = nil
14
14
 
@@ -19,6 +19,11 @@ module Rails
19
19
  exists? && File.binread(existing_migration) == render
20
20
  end
21
21
 
22
+ def invoke!
23
+ invoked_file = super
24
+ File.exist?(@destination) ? invoked_file : relative_existing_migration
25
+ end
26
+
22
27
  def revoke!
23
28
  say_destination = exists? ? relative_existing_migration : relative_destination
24
29
  say_status :remove, :red, say_destination
@@ -40,7 +45,6 @@ module Rails
40
45
  alias :exists? :existing_migration
41
46
 
42
47
  private
43
-
44
48
  def on_conflict_behavior # :doc:
45
49
  options = base.options.merge(config)
46
50
  if identical?
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "shellwords"
4
+ require "active_support/core_ext/kernel/reporting"
5
+ require "active_support/core_ext/string/strip"
6
+
3
7
  module Rails
4
8
  module Generators
5
9
  module Actions
6
10
  def initialize(*) # :nodoc:
7
11
  super
8
- @in_group = nil
9
- @after_bundle_callbacks = []
12
+ @indentation = 0
10
13
  end
11
14
 
12
15
  # Adds an entry into +Gemfile+ for the supplied gem.
@@ -34,15 +37,12 @@ module Rails
34
37
 
35
38
  log :gemfile, message
36
39
 
37
- options.each do |option, value|
38
- parts << "#{option}: #{quote(value)}"
39
- end
40
+ parts << quote(options) unless options.empty?
40
41
 
41
42
  in_root do
42
43
  str = "gem #{parts.join(", ")}"
43
- str = " " + str if @in_group
44
- str = "\n" + str
45
- append_file "Gemfile", str, verbose: false
44
+ str = indentation + str
45
+ append_file_with_newline "Gemfile", str, verbose: false
46
46
  end
47
47
  end
48
48
 
@@ -52,17 +52,33 @@ module Rails
52
52
  # gem "rspec-rails"
53
53
  # end
54
54
  def gem_group(*names, &block)
55
- name = names.map(&:inspect).join(", ")
56
- log :gemfile, "group #{name}"
55
+ options = names.extract_options!
56
+ str = names.map(&:inspect)
57
+ str << quote(options) unless options.empty?
58
+ str = str.join(", ")
59
+ log :gemfile, "group #{str}"
57
60
 
58
61
  in_root do
59
- append_file "Gemfile", "\ngroup #{name} do", force: true
62
+ append_file_with_newline "Gemfile", "\ngroup #{str} do", force: true
63
+ with_indentation(&block)
64
+ append_file_with_newline "Gemfile", "end", force: true
65
+ end
66
+ end
60
67
 
61
- @in_group = true
62
- instance_eval(&block)
63
- @in_group = false
68
+ def github(repo, options = {}, &block)
69
+ str = [quote(repo)]
70
+ str << quote(options) unless options.empty?
71
+ str = str.join(", ")
72
+ log :github, "github #{str}"
64
73
 
65
- append_file "Gemfile", "\nend\n", force: true
74
+ in_root do
75
+ if @indentation.zero?
76
+ append_file_with_newline "Gemfile", "\ngithub #{str} do", force: true
77
+ else
78
+ append_file_with_newline "Gemfile", "#{indentation}github #{str} do", force: true
79
+ end
80
+ with_indentation(&block)
81
+ append_file_with_newline "Gemfile", "#{indentation}end", force: true
66
82
  end
67
83
  end
68
84
 
@@ -80,11 +96,9 @@ module Rails
80
96
 
81
97
  in_root do
82
98
  if block
83
- append_file "Gemfile", "\nsource #{quote(source)} do", force: true
84
- @in_group = true
85
- instance_eval(&block)
86
- @in_group = false
87
- append_file "Gemfile", "\nend\n", force: true
99
+ append_file_with_newline "Gemfile", "\nsource #{quote(source)} do", force: true
100
+ with_indentation(&block)
101
+ append_file_with_newline "Gemfile", "end", force: true
88
102
  else
89
103
  prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
90
104
  end
@@ -97,11 +111,11 @@ module Rails
97
111
  # file in <tt>config/environments</tt>.
98
112
  #
99
113
  # environment do
100
- # "config.action_controller.asset_host = 'cdn.provider.com'"
114
+ # "config.asset_host = 'cdn.provider.com'"
101
115
  # end
102
116
  #
103
117
  # environment(nil, env: "development") do
104
- # "config.action_controller.asset_host = 'localhost:3000'"
118
+ # "config.asset_host = 'localhost:3000'"
105
119
  # end
106
120
  def environment(data = nil, options = {})
107
121
  sentinel = "class Application < Rails::Application\n"
@@ -211,9 +225,11 @@ module Rails
211
225
  # generate(:authenticated, "user session")
212
226
  def generate(what, *args)
213
227
  log :generate, what
214
- argument = args.flat_map(&:to_s).join(" ")
215
228
 
216
- in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) }
229
+ options = args.extract_options!
230
+ options[:abort_on_failure] = !options[:inline]
231
+
232
+ rails_command "generate #{what} #{args.join(" ")}", options
217
233
  end
218
234
 
219
235
  # Runs the supplied rake task (invoked with 'rake ...')
@@ -233,22 +249,28 @@ module Rails
233
249
  # rails_command("gems:install", sudo: true)
234
250
  # rails_command("gems:install", capture: true)
235
251
  def rails_command(command, options = {})
236
- execute_command :rails, command, options
237
- end
238
-
239
- # Just run the capify command in root
240
- #
241
- # capify!
242
- def capify!
243
- ActiveSupport::Deprecation.warn("`capify!` is deprecated and will be removed in the next version of Rails.")
244
- log :capify, ""
245
- in_root { run("#{extify(:capify)} .", verbose: false) }
252
+ if options[:inline]
253
+ log :rails, command
254
+ command, *args = Shellwords.split(command)
255
+ in_root do
256
+ silence_warnings do
257
+ ::Rails::Command.invoke(command, args, **options)
258
+ end
259
+ end
260
+ else
261
+ execute_command :rails, command, options
262
+ end
246
263
  end
247
264
 
248
265
  # Make an entry in Rails routing file <tt>config/routes.rb</tt>
249
266
  #
250
267
  # route "root 'welcome#index'"
251
- def route(routing_code)
268
+ # route "root 'admin#index'", namespace: :admin
269
+ def route(routing_code, namespace: nil)
270
+ routing_code = Array(namespace).reverse.reduce(routing_code) do |code, ns|
271
+ "namespace :#{ns} do\n#{indent(code, 2)}\nend"
272
+ end
273
+
252
274
  log :route, routing_code
253
275
  sentinel = /\.routes\.draw do\s*\n/m
254
276
 
@@ -264,18 +286,7 @@ module Rails
264
286
  log File.read(find_in_source_paths(path))
265
287
  end
266
288
 
267
- # Registers a callback to be executed after bundle and spring binstubs
268
- # have run.
269
- #
270
- # after_bundle do
271
- # git add: '.'
272
- # end
273
- def after_bundle(&block)
274
- @after_bundle_callbacks << block
275
- end
276
-
277
289
  private
278
-
279
290
  # Define log for backwards compatibility. If just one argument is sent,
280
291
  # invoke say, otherwise invoke say_status. Differently from say and
281
292
  # similarly to say_status, this method respects the quiet? option given.
@@ -292,13 +303,15 @@ module Rails
292
303
  # based on the executor parameter provided.
293
304
  def execute_command(executor, command, options = {}) # :doc:
294
305
  log executor, command
295
- env = options[:env] || ENV["RAILS_ENV"] || "development"
296
306
  sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
297
- config = { verbose: false }
298
-
299
- config.merge!(capture: options[:capture]) if options[:capture]
300
-
301
- in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", config) }
307
+ config = {
308
+ env: { "RAILS_ENV" => (options[:env] || ENV["RAILS_ENV"] || "development") },
309
+ verbose: false,
310
+ capture: options[:capture],
311
+ abort_on_failure: options[:abort_on_failure],
312
+ }
313
+
314
+ in_root { run("#{sudo}#{extify(executor)} #{command}", config) }
302
315
  end
303
316
 
304
317
  # Add an extension to the given name based on the platform.
@@ -313,6 +326,11 @@ module Rails
313
326
  # Surround string with single quotes if there is no quotes.
314
327
  # Otherwise fall back to double quotes
315
328
  def quote(value) # :doc:
329
+ if value.respond_to? :each_pair
330
+ return value.map do |k, v|
331
+ "#{k}: #{quote(v)}"
332
+ end.join(", ")
333
+ end
316
334
  return value.inspect unless value.is_a? String
317
335
 
318
336
  if value.include?("'")
@@ -325,11 +343,26 @@ module Rails
325
343
  # Returns optimized string with indentation
326
344
  def optimize_indentation(value, amount = 0) # :doc:
327
345
  return "#{value}\n" unless value.is_a?(String)
346
+ "#{value.strip_heredoc.indent(amount).chomp}\n"
347
+ end
328
348
 
329
- if value.lines.size > 1
330
- value.strip_heredoc.indent(amount)
331
- else
332
- "#{value.strip.indent(amount)}\n"
349
+ # Indent the +Gemfile+ to the depth of @indentation
350
+ def indentation # :doc:
351
+ " " * @indentation
352
+ end
353
+
354
+ # Manage +Gemfile+ indentation for a DSL action block
355
+ def with_indentation(&block) # :doc:
356
+ @indentation += 1
357
+ instance_eval(&block)
358
+ ensure
359
+ @indentation -= 1
360
+ end
361
+
362
+ # Append string to a file with a newline if necessary
363
+ def append_file_with_newline(path, str, options = {})
364
+ gsub_file path, /\n?\z/, options do |match|
365
+ match.end_with?("\n") ? "" : "\n#{str}\n"
333
366
  end
334
367
  end
335
368
  end