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
data/lib/rails/railtie.rb CHANGED
@@ -7,34 +7,34 @@ require "active_support/core_ext/module/introspection"
7
7
  require "active_support/core_ext/module/delegation"
8
8
 
9
9
  module Rails
10
- # <tt>Rails::Railtie</tt> is the core of the Rails framework and provides
11
- # several hooks to extend Rails and/or modify the initialization process.
10
+ # +Rails::Railtie+ is the core of the \Rails framework and provides
11
+ # several hooks to extend \Rails and/or modify the initialization process.
12
12
  #
13
- # Every major component of Rails (Action Mailer, Action Controller, Active
13
+ # Every major component of \Rails (Action Mailer, Action Controller, Active
14
14
  # Record, etc.) implements a railtie. Each of them is responsible for their
15
- # own initialization. This makes Rails itself absent of any component hooks,
16
- # allowing other components to be used in place of any of the Rails defaults.
15
+ # own initialization. This makes \Rails itself absent of any component hooks,
16
+ # allowing other components to be used in place of any of the \Rails defaults.
17
17
  #
18
- # Developing a Rails extension does _not_ require implementing a railtie, but
19
- # if you need to interact with the Rails framework during or after boot, then
18
+ # Developing a \Rails extension does _not_ require implementing a railtie, but
19
+ # if you need to interact with the \Rails framework during or after boot, then
20
20
  # a railtie is needed.
21
21
  #
22
22
  # For example, an extension doing any of the following would need a railtie:
23
23
  #
24
24
  # * creating initializers
25
- # * configuring a Rails framework for the application, like setting a generator
25
+ # * configuring a \Rails framework for the application, like setting a generator
26
26
  # * adding <tt>config.*</tt> keys to the environment
27
27
  # * setting up a subscriber with ActiveSupport::Notifications
28
28
  # * adding Rake tasks
29
29
  #
30
30
  # == Creating a Railtie
31
31
  #
32
- # To extend Rails using a railtie, create a subclass of <tt>Rails::Railtie</tt>.
33
- # This class must be loaded during the Rails boot process, and is conventionally
34
- # called <tt>MyNamespace::Railtie</tt>.
32
+ # To extend \Rails using a railtie, create a subclass of +Rails::Railtie+.
33
+ # This class must be loaded during the \Rails boot process, and is conventionally
34
+ # called +MyNamespace::Railtie+.
35
35
  #
36
36
  # The following example demonstrates an extension which can be used with or
37
- # without Rails.
37
+ # without \Rails.
38
38
  #
39
39
  # # lib/my_gem/railtie.rb
40
40
  # module MyGem
@@ -47,11 +47,11 @@ module Rails
47
47
  #
48
48
  # == Initializers
49
49
  #
50
- # To add an initialization step to the Rails boot process from your railtie, just
50
+ # To add an initialization step to the \Rails boot process from your railtie, just
51
51
  # define the initialization code with the +initializer+ macro:
52
52
  #
53
- # class MyRailtie < Rails::Railtie
54
- # initializer "my_railtie.configure_rails_initialization" do
53
+ # class MyGem::Railtie < Rails::Railtie
54
+ # initializer "my_gem.configure_rails_initialization" do
55
55
  # # some initialization behavior
56
56
  # end
57
57
  # end
@@ -59,9 +59,9 @@ module Rails
59
59
  # If specified, the block can also receive the application object, in case you
60
60
  # need to access some application-specific configuration, like middleware:
61
61
  #
62
- # class MyRailtie < Rails::Railtie
63
- # initializer "my_railtie.configure_rails_initialization" do |app|
64
- # app.middleware.use MyRailtie::Middleware
62
+ # class MyGem::Railtie < Rails::Railtie
63
+ # initializer "my_gem.configure_rails_initialization" do |app|
64
+ # app.middleware.use MyGem::Middleware
65
65
  # end
66
66
  # end
67
67
  #
@@ -74,53 +74,53 @@ module Rails
74
74
  # Railties can access a config object which contains configuration shared by all
75
75
  # railties and the application:
76
76
  #
77
- # class MyRailtie < Rails::Railtie
77
+ # class MyGem::Railtie < Rails::Railtie
78
78
  # # Customize the ORM
79
- # config.app_generators.orm :my_railtie_orm
79
+ # config.app_generators.orm :my_gem_orm
80
80
  #
81
81
  # # Add a to_prepare block which is executed once in production
82
82
  # # and before each request in development.
83
83
  # config.to_prepare do
84
- # MyRailtie.setup!
84
+ # MyGem.setup!
85
85
  # end
86
86
  # end
87
87
  #
88
88
  # == Loading Rake Tasks and Generators
89
89
  #
90
- # If your railtie has Rake tasks, you can tell Rails to load them through the method
90
+ # If your railtie has Rake tasks, you can tell \Rails to load them through the method
91
91
  # +rake_tasks+:
92
92
  #
93
- # class MyRailtie < Rails::Railtie
93
+ # class MyGem::Railtie < Rails::Railtie
94
94
  # rake_tasks do
95
- # load "path/to/my_railtie.tasks"
95
+ # load "path/to/my_gem.tasks"
96
96
  # end
97
97
  # end
98
98
  #
99
- # By default, Rails loads generators from your load path. However, if you want to place
99
+ # By default, \Rails loads generators from your load path. However, if you want to place
100
100
  # your generators at a different location, you can specify in your railtie a block which
101
101
  # will load them during normal generators lookup:
102
102
  #
103
- # class MyRailtie < Rails::Railtie
103
+ # class MyGem::Railtie < Rails::Railtie
104
104
  # generators do
105
- # require "path/to/my_railtie_generator"
105
+ # require "path/to/my_gem_generator"
106
106
  # end
107
107
  # end
108
108
  #
109
109
  # Since filenames on the load path are shared across gems, be sure that files you load
110
110
  # through a railtie have unique names.
111
111
  #
112
- # == Run another program when the Rails server starts
112
+ # == Run another program when the \Rails server starts
113
113
  #
114
- # In development, it's very usual to have to run another process next to the Rails Server. In example
114
+ # In development, it's very usual to have to run another process next to the \Rails Server. In example
115
115
  # you might want to start the Webpack or React server. Or maybe you need to run your job scheduler process
116
116
  # like Sidekiq. This is usually done by opening a new shell and running the program from here.
117
117
  #
118
- # Rails allow you to specify a +server+ block which will get called when a Rails server starts.
118
+ # \Rails allow you to specify a +server+ block which will get called when a \Rails server starts.
119
119
  # This way, your users don't need to remember to have to open a new shell and run another program, making
120
120
  # this less confusing for everyone.
121
121
  # It can be used like this:
122
122
  #
123
- # class MyRailtie < Rails::Railtie
123
+ # class MyGem::Railtie < Rails::Railtie
124
124
  # server do
125
125
  # WebpackServer.start
126
126
  # end
@@ -221,14 +221,13 @@ module Rails
221
221
 
222
222
  # If the class method does not have a method, then send the method call
223
223
  # to the Railtie instance.
224
- def method_missing(name, *args, &block)
224
+ def method_missing(name, ...)
225
225
  if !abstract_railtie? && instance.respond_to?(name)
226
- instance.public_send(name, *args, &block)
226
+ instance.public_send(name, ...)
227
227
  else
228
228
  super
229
229
  end
230
230
  end
231
- ruby2_keywords(:method_missing)
232
231
 
233
232
  # receives an instance variable identifier, set the variable value if is
234
233
  # blank and append given block to value, which will be used later in
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "ripper"
4
+
3
5
  module Rails
4
- # Implements the logic behind <tt>Rails::Command::NotesCommand</tt>. See <tt>rails notes --help</tt> for usage information.
6
+ # Implements the logic behind +Rails::Command::NotesCommand+. See <tt>rails notes --help</tt> for usage information.
5
7
  #
6
8
  # Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
7
9
  # represent the line where the annotation lives, its tag, and its text. Note
@@ -11,6 +13,44 @@ module Rails
11
13
  # start with the tag optionally followed by a colon. Everything up to the end
12
14
  # of the line (or closing ERB comment tag) is considered to be their text.
13
15
  class SourceAnnotationExtractor
16
+ # Wraps a regular expression that will be tested against each of the source
17
+ # file's comments.
18
+ class ParserExtractor < Struct.new(:pattern)
19
+ class Parser < Ripper
20
+ attr_reader :comments, :pattern
21
+
22
+ def initialize(source, pattern:)
23
+ super(source)
24
+ @pattern = pattern
25
+ @comments = []
26
+ end
27
+
28
+ def on_comment(value)
29
+ @comments << Annotation.new(lineno, $1, $2) if value =~ pattern
30
+ end
31
+ end
32
+
33
+ def annotations(file)
34
+ contents = File.read(file, encoding: Encoding::BINARY)
35
+ parser = Parser.new(contents, pattern: pattern).tap(&:parse)
36
+ parser.error? ? [] : parser.comments
37
+ end
38
+ end
39
+
40
+ # Wraps a regular expression that will iterate through a file's lines and
41
+ # test each one for the given pattern.
42
+ class PatternExtractor < Struct.new(:pattern)
43
+ def annotations(file)
44
+ lineno = 0
45
+
46
+ File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
47
+ lineno += 1
48
+ next list unless line =~ pattern
49
+ list << Annotation.new(lineno, $1, $2)
50
+ end
51
+ end
52
+ end
53
+
14
54
  class Annotation < Struct.new(:line, :tag, :text)
15
55
  def self.directories
16
56
  @@directories ||= %w(app config db lib test)
@@ -42,9 +82,21 @@ module Rails
42
82
  extensions[/\.(#{exts.join("|")})$/] = block
43
83
  end
44
84
 
45
- register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
46
- register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
47
- register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }
85
+ register_extensions("builder", "rb", "rake", "ruby") do |tag|
86
+ ParserExtractor.new(/#\s*(#{tag}):?\s*(.*)$/)
87
+ end
88
+
89
+ register_extensions("yml", "yaml") do |tag|
90
+ PatternExtractor.new(/#\s*(#{tag}):?\s*(.*)$/)
91
+ end
92
+
93
+ register_extensions("css", "js") do |tag|
94
+ PatternExtractor.new(/\/\/\s*(#{tag}):?\s*(.*)$/)
95
+ end
96
+
97
+ register_extensions("erb") do |tag|
98
+ PatternExtractor.new(/<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/)
99
+ end
48
100
 
49
101
  # Returns a representation of the annotation that looks like this:
50
102
  #
@@ -111,7 +163,17 @@ module Rails
111
163
 
112
164
  if extension
113
165
  pattern = extension.last.call(tag)
114
- results.update(extract_annotations_from(item, pattern)) if pattern
166
+
167
+ # In case a user-defined pattern returns nothing for the given set
168
+ # of tags, we exit early.
169
+ next unless pattern
170
+
171
+ # If a user-defined pattern returns a regular expression, we will
172
+ # wrap it in a PatternExtractor to keep the same API.
173
+ pattern = PatternExtractor.new(pattern) if pattern.is_a?(Regexp)
174
+
175
+ annotations = pattern.annotations(item)
176
+ results.update(item => annotations) if annotations.any?
115
177
  end
116
178
  end
117
179
  end
@@ -119,19 +181,6 @@ module Rails
119
181
  results
120
182
  end
121
183
 
122
- # If +file+ is the filename of a file that contains annotations this method returns
123
- # a hash with a single entry that maps +file+ to an array of its annotations.
124
- # Otherwise it returns an empty hash.
125
- def extract_annotations_from(file, pattern)
126
- lineno = 0
127
- result = File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
128
- lineno += 1
129
- next list unless line =~ pattern
130
- list << Annotation.new(lineno, $1, $2)
131
- end
132
- result.empty? ? {} : { file => result }
133
- end
134
-
135
184
  # Prints the mapping from filenames to annotations in +results+ ordered by filename.
136
185
  # The +options+ hash is passed to each annotation's +to_s+.
137
186
  def display(results, options = {})
@@ -18,7 +18,7 @@ task "load_app" do
18
18
  task environment: "app:environment"
19
19
 
20
20
  if !defined?(ENGINE_ROOT) || !ENGINE_ROOT
21
- ENGINE_ROOT = find_engine_path(APP_RAKEFILE)
21
+ ENGINE_ROOT = find_engine_path(Pathname.new(APP_RAKEFILE))
22
22
  end
23
23
  end
24
24
 
@@ -43,17 +43,17 @@ namespace :db do
43
43
  app_task "create"
44
44
  app_task "create:all"
45
45
 
46
- desc "Drops the database for the current Rails.env (use db:drop:all to drop all databases)"
46
+ desc "Drop the database for the current Rails.env (use db:drop:all to drop all databases)"
47
47
  app_task "drop"
48
48
  app_task "drop:all"
49
49
 
50
50
  desc "Load fixtures into the current environment's database."
51
51
  app_task "fixtures:load"
52
52
 
53
- desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
53
+ desc "Roll the schema back to the previous version (specify steps w/ STEP=n)."
54
54
  app_task "rollback"
55
55
 
56
- desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
56
+ desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
57
57
  app_task "schema:dump"
58
58
 
59
59
  desc "Load a schema.rb file into the database"
@@ -65,7 +65,7 @@ namespace :db do
65
65
  desc "Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first)"
66
66
  app_task "setup"
67
67
 
68
- desc "Retrieves the current schema version number"
68
+ desc "Retrieve the current schema version number"
69
69
  app_task "version"
70
70
 
71
71
  # desc 'Load the test schema'
@@ -73,12 +73,12 @@ namespace :db do
73
73
  end
74
74
 
75
75
  def find_engine_path(path)
76
- return File.expand_path(Dir.pwd) if path == "/"
76
+ return File.expand_path(Dir.pwd) if path.root?
77
77
 
78
78
  if Rails::Engine.find(path)
79
- path
79
+ path.to_s
80
80
  else
81
- find_engine_path(File.expand_path("..", path))
81
+ find_engine_path(path.join(".."))
82
82
  end
83
83
  end
84
84
 
@@ -1,18 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :app do
4
- desc "Update configs and some other initially generated files (or use just update:configs or update:bin)"
5
- task update: [ "update:configs", "update:bin", "update:db", "update:active_storage", "update:upgrade_guide_info" ]
6
-
7
- desc "Applies the template supplied by LOCATION=(/path/to/template) or URL"
4
+ desc "Apply the template supplied by LOCATION=(/path/to/template) or URL"
8
5
  task template: :environment do
9
6
  template = ENV["LOCATION"]
10
7
  raise "No LOCATION value given. Please set LOCATION either as path to a file or a URL" if template.blank?
11
- template = File.expand_path(template) unless %r{\A[A-Za-z][A-Za-z0-9+\-.]*://}.match?(template)
12
8
  require "rails/generators"
13
9
  require "rails/generators/rails/app/app_generator"
14
- generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
15
- generator.apply template, verbose: false
10
+ Rails::Generators::AppGenerator.apply_rails_template(template, Rails.root)
16
11
  end
17
12
 
18
13
  namespace :templates do
@@ -36,31 +31,4 @@ namespace :app do
36
31
  end
37
32
  end
38
33
  end
39
-
40
- namespace :update do
41
- require "rails/app_updater"
42
-
43
- # desc "Update config files from your current rails install"
44
- task :configs do
45
- Rails::AppUpdater.invoke_from_app_generator :create_boot_file
46
- Rails::AppUpdater.invoke_from_app_generator :update_config_files
47
- end
48
-
49
- # desc "Adds new executables to the application bin/ directory"
50
- task :bin do
51
- Rails::AppUpdater.invoke_from_app_generator :update_bin_files
52
- end
53
-
54
- task :db do
55
- Rails::AppUpdater.invoke_from_app_generator :update_db_schema
56
- end
57
-
58
- task :active_storage do
59
- Rails::AppUpdater.invoke_from_app_generator :update_active_storage
60
- end
61
-
62
- task :upgrade_guide_info do
63
- Rails::AppUpdater.invoke_from_app_generator :display_upgrade_guide_info
64
- end
65
- end
66
34
  end
@@ -7,7 +7,7 @@ namespace :log do
7
7
  # - defaults to all environments log files i.e. 'development,test,production'
8
8
  # - ENV['LOGS']=all truncates all files i.e. log/*.log
9
9
  # - ENV['LOGS']='test,development' truncates only specified files
10
- desc "Truncates all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)"
10
+ desc "Truncate all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)"
11
11
  task :clear do
12
12
  log_files.each do |file|
13
13
  clear_log_file(file)
@@ -1,16 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- desc "Generate a cryptographically secure secret key (this is typically used to generate a secret for cookie sessions)."
4
- task :secret do
5
- require "securerandom"
6
- puts SecureRandom.hex(64)
7
- end
8
-
9
- desc "List versions of all Rails frameworks and the environment"
10
- task about: :environment do
11
- puts Rails::Info
12
- end
13
-
14
3
  namespace :time do
15
4
  desc "List all time zones, list by two-letter country code (`bin/rails time:zones[US]`), or list by UTC offset (`bin/rails time:zones[-8]`)"
16
5
  task :zones, :country_or_offset do |t, args|
@@ -28,17 +17,17 @@ namespace :time do
28
17
  end
29
18
 
30
19
  namespace :zones do
31
- # desc 'Displays all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6'
20
+ # desc 'Display all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6'
32
21
  task :all do
33
22
  build_time_zone_list ActiveSupport::TimeZone.all
34
23
  end
35
24
 
36
- # desc 'Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset. Results can be filtered with optional OFFSET parameter, e.g., OFFSET=-6'
25
+ # desc 'Display names of US time zones recognized by the Rails TimeZone class, grouped by offset. Results can be filtered with optional OFFSET parameter, e.g., OFFSET=-6'
37
26
  task :us do
38
27
  build_time_zone_list ActiveSupport::TimeZone.us_zones
39
28
  end
40
29
 
41
- # desc 'Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time'
30
+ # desc 'Display names of time zones recognized by the Rails TimeZone class with the same offset as the system local time'
42
31
  task :local do
43
32
  require "active_support"
44
33
  require "active_support/time"
@@ -26,12 +26,13 @@ STATS_DIRECTORIES ||= [
26
26
  %w(Channel\ tests test/channels),
27
27
  %w(Integration\ tests test/integration),
28
28
  %w(System\ tests test/system),
29
- ].collect do |name, dir|
30
- [ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
31
- end.select { |name, dir| File.directory?(dir) }
29
+ ]
32
30
 
33
31
  desc "Report code statistics (KLOCs, etc) from the application or engine"
34
32
  task :stats do
35
33
  require "rails/code_statistics"
36
- CodeStatistics.new(*STATS_DIRECTORIES).to_s
34
+ stat_directories = STATS_DIRECTORIES.collect do |name, dir|
35
+ [ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
36
+ end.select { |name, dir| File.directory?(dir) }
37
+ CodeStatistics.new(*stat_directories).to_s
37
38
  end
@@ -7,36 +7,36 @@ namespace :tmp do
7
7
  tmp_dirs = [ "tmp/cache",
8
8
  "tmp/sockets",
9
9
  "tmp/pids",
10
- "tmp/cache/assets" ]
10
+ ]
11
11
 
12
12
  tmp_dirs.each { |d| directory d }
13
13
 
14
- desc "Creates tmp directories for cache, sockets, and pids"
14
+ desc "Create tmp directories for cache, sockets, and pids"
15
15
  task create: tmp_dirs
16
16
 
17
17
  namespace :cache do
18
- # desc "Clears all files and directories in tmp/cache"
18
+ # desc "Clear all files and directories in tmp/cache"
19
19
  task :clear do
20
20
  rm_rf Dir["tmp/cache/[^.]*"], verbose: false
21
21
  end
22
22
  end
23
23
 
24
24
  namespace :sockets do
25
- # desc "Clears all files in tmp/sockets"
25
+ # desc "Clear all files in tmp/sockets"
26
26
  task :clear do
27
27
  rm Dir["tmp/sockets/[^.]*"], verbose: false
28
28
  end
29
29
  end
30
30
 
31
31
  namespace :pids do
32
- # desc "Clears all files in tmp/pids"
32
+ # desc "Clear all files in tmp/pids"
33
33
  task :clear do
34
34
  rm Dir["tmp/pids/[^.]*"], verbose: false
35
35
  end
36
36
  end
37
37
 
38
38
  namespace :screenshots do
39
- # desc "Clears all files in tmp/screenshots"
39
+ # desc "Clear all files in tmp/screenshots"
40
40
  task :clear do
41
41
  rm Dir["tmp/screenshots/[^.]*"], verbose: false
42
42
  end
@@ -1,11 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- eager_load = ->() do
4
- puts "Hold on, I am eager loading the application."
5
- Zeitwerk::Loader.eager_load_all
6
- end
3
+ require "rails/zeitwerk_checker"
7
4
 
8
- report_not_checked = ->(not_checked) do
5
+ report_unchecked = ->(unchecked) do
9
6
  puts
10
7
  puts <<~EOS
11
8
  WARNING: The following directories will only be checked if you configure
@@ -13,7 +10,7 @@ report_not_checked = ->(not_checked) do
13
10
  EOS
14
11
  puts
15
12
 
16
- not_checked.each { |dir| puts " #{dir}" }
13
+ unchecked.each { |dir| puts " #{dir}" }
17
14
  puts
18
15
 
19
16
  puts <<~EOS
@@ -23,39 +20,22 @@ report_not_checked = ->(not_checked) do
23
20
  puts
24
21
  end
25
22
 
26
- report = ->(not_checked) do
27
- if not_checked.any?
28
- report_not_checked[not_checked]
29
- puts "Otherwise, all is good!"
30
- else
31
- puts "All is good!"
32
- end
33
- end
34
-
35
23
  namespace :zeitwerk do
36
- desc "Checks project structure for Zeitwerk compatibility"
24
+ desc "Check project structure for Zeitwerk compatibility"
37
25
  task check: :environment do
26
+ puts "Hold on, I am eager loading the application."
27
+
38
28
  begin
39
- eager_load[]
40
- rescue NameError => e
41
- if e.message =~ /expected file .*? to define constant [\w:]+/
42
- abort $&.sub(/expected file #{Regexp.escape(Rails.root.to_s)}./, "expected file ")
43
- else
44
- raise
45
- end
29
+ unchecked = Rails::ZeitwerkChecker.check
30
+ rescue Zeitwerk::NameError => e
31
+ abort e.message.sub(/#{Regexp.escape(Rails.root.to_s)}./, "")
46
32
  end
47
33
 
48
- require "active_support/core_ext/object/try"
49
- eager_load_paths = Rails.configuration.eager_load_namespaces.filter_map do |eln|
50
- # Quick regression fix for 6.0.3 to support namespaces that do not have
51
- # eager load paths, like the recently added i18n. I'll rewrite this task.
52
- eln.try(:config).try(:eager_load_paths)
53
- end.flatten
54
-
55
- not_checked = ActiveSupport::Dependencies.autoload_paths - eager_load_paths
56
- not_checked.select! { |dir| Dir.exist?(dir) }
57
- not_checked.reject! { |dir| Dir.empty?(dir) }
58
-
59
- report[not_checked]
34
+ if unchecked.empty?
35
+ puts "All is good!"
36
+ else
37
+ report_unchecked[unchecked]
38
+ puts "Otherwise, all is good!"
39
+ end
60
40
  end
61
41
  end
data/lib/rails/tasks.rb CHANGED
@@ -6,9 +6,7 @@ require "rake"
6
6
  %w(
7
7
  framework
8
8
  log
9
- middleware
10
9
  misc
11
- restart
12
10
  tmp
13
11
  yarn
14
12
  zeitwerk
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en">
2
+ <html>
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <title><%= @page_title %></title>