railties 7.0.8.7 → 7.1.5.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 (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +723 -215
  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 +63 -0
  7. data/lib/rails/api/task.rb +35 -4
  8. data/lib/rails/app_updater.rb +14 -2
  9. data/lib/rails/application/bootstrap.rb +23 -4
  10. data/lib/rails/application/configuration.rb +190 -69
  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 +43 -33
  14. data/lib/rails/application.rb +141 -33
  15. data/lib/rails/backtrace_cleaner.rb +5 -3
  16. data/lib/rails/cli.rb +5 -2
  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/application/application_command.rb +2 -0
  24. data/lib/rails/commands/console/console_command.rb +14 -14
  25. data/lib/rails/commands/credentials/USAGE +53 -55
  26. data/lib/rails/commands/credentials/credentials_command/diffing.rb +5 -3
  27. data/lib/rails/commands/credentials/credentials_command.rb +64 -70
  28. data/lib/rails/commands/db/system/change/change_command.rb +2 -1
  29. data/lib/rails/commands/dbconsole/dbconsole_command.rb +25 -115
  30. data/lib/rails/commands/destroy/destroy_command.rb +3 -2
  31. data/lib/rails/commands/dev/dev_command.rb +1 -6
  32. data/lib/rails/commands/encrypted/USAGE +15 -20
  33. data/lib/rails/commands/encrypted/encrypted_command.rb +46 -35
  34. data/lib/rails/commands/gem_help/USAGE +16 -0
  35. data/lib/rails/commands/gem_help/gem_help_command.rb +13 -0
  36. data/lib/rails/commands/generate/generate_command.rb +2 -2
  37. data/lib/rails/commands/help/USAGE +13 -13
  38. data/lib/rails/commands/help/help_command.rb +21 -2
  39. data/lib/rails/commands/initializers/initializers_command.rb +1 -4
  40. data/lib/rails/commands/middleware/middleware_command.rb +17 -0
  41. data/lib/rails/commands/new/new_command.rb +2 -0
  42. data/lib/rails/commands/notes/notes_command.rb +2 -1
  43. data/lib/rails/commands/plugin/plugin_command.rb +2 -0
  44. data/lib/rails/commands/rake/rake_command.rb +25 -22
  45. data/lib/rails/commands/restart/restart_command.rb +14 -0
  46. data/lib/rails/commands/routes/routes_command.rb +13 -1
  47. data/lib/rails/commands/runner/USAGE +14 -12
  48. data/lib/rails/commands/runner/runner_command.rb +32 -20
  49. data/lib/rails/commands/secret/secret_command.rb +13 -0
  50. data/lib/rails/commands/secrets/USAGE +44 -49
  51. data/lib/rails/commands/secrets/secrets_command.rb +20 -38
  52. data/lib/rails/commands/server/server_command.rb +33 -32
  53. data/lib/rails/commands/test/USAGE +14 -0
  54. data/lib/rails/commands/test/test_command.rb +56 -14
  55. data/lib/rails/commands/unused_routes/unused_routes_command.rb +75 -0
  56. data/lib/rails/commands/version/version_command.rb +1 -0
  57. data/lib/rails/configuration.rb +5 -5
  58. data/lib/rails/console/app.rb +1 -4
  59. data/lib/rails/deprecator.rb +7 -0
  60. data/lib/rails/engine/configuration.rb +50 -6
  61. data/lib/rails/engine.rb +49 -21
  62. data/lib/rails/gem_version.rb +4 -4
  63. data/lib/rails/generators/actions.rb +6 -15
  64. data/lib/rails/generators/active_model.rb +28 -14
  65. data/lib/rails/generators/app_base.rb +355 -82
  66. data/lib/rails/generators/app_name.rb +3 -14
  67. data/lib/rails/generators/base.rb +17 -9
  68. data/lib/rails/generators/database.rb +40 -2
  69. data/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt +1 -1
  70. data/lib/rails/generators/generated_attribute.rb +12 -0
  71. data/lib/rails/generators/migration.rb +4 -5
  72. data/lib/rails/generators/model_helpers.rb +2 -1
  73. data/lib/rails/generators/rails/app/USAGE +22 -6
  74. data/lib/rails/generators/rails/app/app_generator.rb +85 -64
  75. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +103 -0
  76. data/lib/rails/generators/rails/app/templates/Gemfile.tt +9 -11
  77. data/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt +1 -1
  78. data/lib/rails/generators/rails/app/templates/bin/setup.tt +10 -1
  79. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +6 -17
  80. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +4 -4
  81. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +3 -3
  82. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +4 -6
  83. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +3 -3
  84. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +59 -0
  85. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -2
  86. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +32 -28
  87. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +13 -9
  88. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +2 -0
  89. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +2 -2
  90. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -3
  92. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +280 -0
  93. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -9
  94. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +11 -13
  95. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +21 -20
  96. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +5 -1
  97. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +6 -4
  98. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +10 -0
  99. data/lib/rails/generators/rails/app/templates/dockerignore.tt +43 -0
  100. data/lib/rails/generators/rails/app/templates/gitignore.tt +4 -8
  101. data/lib/rails/generators/rails/app/templates/node-version.tt +1 -0
  102. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +10 -8
  103. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -7
  104. data/lib/rails/generators/rails/application_record/application_record_generator.rb +4 -0
  105. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +2 -1
  106. data/lib/rails/generators/rails/controller/USAGE +12 -4
  107. data/lib/rails/generators/rails/controller/controller_generator.rb +5 -0
  108. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +1 -1
  109. data/lib/rails/generators/rails/credentials/credentials_generator.rb +29 -24
  110. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +8 -0
  111. data/lib/rails/generators/rails/db/system/change/change_generator.rb +30 -0
  112. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -2
  113. data/lib/rails/generators/rails/migration/USAGE +21 -11
  114. data/lib/rails/generators/rails/model/model_generator.rb +4 -0
  115. data/lib/rails/generators/rails/plugin/USAGE +17 -6
  116. data/lib/rails/generators/rails/plugin/plugin_generator.rb +5 -15
  117. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +2 -2
  118. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +1 -1
  119. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -17
  120. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -2
  121. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +4 -4
  122. data/lib/rails/generators/rails/resource/resource_generator.rb +6 -0
  123. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -1
  124. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +1 -1
  125. data/lib/rails/generators/test_case.rb +2 -2
  126. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +1 -1
  127. data/lib/rails/generators/testing/{behaviour.rb → behavior.rb} +4 -1
  128. data/lib/rails/generators.rb +6 -14
  129. data/lib/rails/health_controller.rb +55 -0
  130. data/lib/rails/info.rb +1 -1
  131. data/lib/rails/info_controller.rb +33 -11
  132. data/lib/rails/mailers_controller.rb +15 -5
  133. data/lib/rails/paths.rb +13 -10
  134. data/lib/rails/rack/logger.rb +15 -12
  135. data/lib/rails/rackup/server.rb +15 -0
  136. data/lib/rails/railtie/configuration.rb +14 -1
  137. data/lib/rails/railtie.rb +31 -31
  138. data/lib/rails/ruby_version_check.rb +2 -0
  139. data/lib/rails/source_annotation_extractor.rb +67 -18
  140. data/lib/rails/tasks/engine.rake +8 -8
  141. data/lib/rails/tasks/framework.rake +4 -10
  142. data/lib/rails/tasks/log.rake +1 -1
  143. data/lib/rails/tasks/misc.rake +3 -14
  144. data/lib/rails/tasks/statistics.rake +5 -4
  145. data/lib/rails/tasks/tmp.rake +5 -5
  146. data/lib/rails/tasks/zeitwerk.rake +15 -35
  147. data/lib/rails/tasks.rb +0 -2
  148. data/lib/rails/templates/rails/mailers/email.html.erb +32 -0
  149. data/lib/rails/templates/rails/mailers/index.html.erb +14 -7
  150. data/lib/rails/templates/rails/mailers/mailer.html.erb +11 -5
  151. data/lib/rails/templates/rails/welcome/index.html.erb +1 -0
  152. data/lib/rails/test_help.rb +9 -14
  153. data/lib/rails/test_unit/line_filtering.rb +1 -1
  154. data/lib/rails/test_unit/reporter.rb +6 -2
  155. data/lib/rails/test_unit/runner.rb +36 -18
  156. data/lib/rails/test_unit/test_parser.rb +88 -0
  157. data/lib/rails/test_unit/testing.rake +13 -33
  158. data/lib/rails/testing/maintain_test_schema.rb +16 -0
  159. data/lib/rails/version.rb +1 -1
  160. data/lib/rails/zeitwerk_checker.rb +15 -0
  161. data/lib/rails.rb +15 -15
  162. metadata +64 -27
  163. data/RDOC_MAIN.rdoc +0 -97
  164. data/lib/rails/application/dummy_erb_compiler.rb +0 -18
  165. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +0 -143
  166. data/lib/rails/generators/rails/model/USAGE +0 -113
  167. data/lib/rails/tasks/middleware.rake +0 -9
  168. data/lib/rails/tasks/restart.rake +0 -9
@@ -3,10 +3,10 @@
3
3
  require "rails/application_controller"
4
4
 
5
5
  class Rails::MailersController < Rails::ApplicationController # :nodoc:
6
- prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATH
6
+ prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATHS
7
7
 
8
- around_action :set_locale, only: :preview
9
- before_action :find_preview, only: :preview
8
+ around_action :set_locale, only: [:preview, :download]
9
+ before_action :find_preview, only: [:preview, :download]
10
10
  before_action :require_local!, unless: :show_previews?
11
11
 
12
12
  helper_method :part_query, :locale_query
@@ -15,12 +15,22 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
15
15
 
16
16
  def index
17
17
  @previews = ActionMailer::Preview.all
18
- @page_title = "Mailer Previews"
18
+ @page_title = "Action Mailer Previews"
19
+ end
20
+
21
+ def download
22
+ @email_action = File.basename(params[:path])
23
+ if @preview.email_exists?(@email_action)
24
+ @email = @preview.call(@email_action, params)
25
+ send_data @email.to_s, filename: "#{@email_action}.eml"
26
+ else
27
+ raise AbstractController::ActionNotFound, "Email '#{@email_action}' not found in #{@preview.name}"
28
+ end
19
29
  end
20
30
 
21
31
  def preview
22
32
  if params[:path] == @preview.preview_name
23
- @page_title = "Mailer Previews for #{@preview.preview_name}"
33
+ @page_title = "Action Mailer Previews for #{@preview.preview_name}"
24
34
  render action: "mailer"
25
35
  else
26
36
  @email_action = File.basename(params[:path])
data/lib/rails/paths.rb CHANGED
@@ -4,9 +4,9 @@ require "pathname"
4
4
 
5
5
  module Rails
6
6
  module Paths
7
- # This object is an extended hash that behaves as root of the <tt>Rails::Paths</tt> system.
7
+ # This object is an extended hash that behaves as root of the Rails::Paths system.
8
8
  # It allows you to collect information about how you want to structure your application
9
- # paths through a Hash-like API. It requires you to give a physical path on initialization.
9
+ # paths through a Hash-like \API. It requires you to give a physical path on initialization.
10
10
  #
11
11
  # root = Root.new "/rails"
12
12
  # root.add "app/controllers", eager_load: true
@@ -18,7 +18,8 @@ module Rails
18
18
  # path.eager_load? # => true
19
19
  # path.is_a?(Rails::Paths::Path) # => true
20
20
  #
21
- # The +Path+ object is simply an enumerable and allows you to easily add extra paths:
21
+ # The Path[rdoc-ref:Rails::Paths::Path] object is simply an enumerable and
22
+ # allows you to easily add extra paths:
22
23
  #
23
24
  # path.is_a?(Enumerable) # => true
24
25
  # path.to_ary.inspect # => ["app/controllers"]
@@ -26,17 +27,19 @@ module Rails
26
27
  # path << "lib/controllers"
27
28
  # path.to_ary.inspect # => ["app/controllers", "lib/controllers"]
28
29
  #
29
- # Notice that when you add a path using +add+, the path object created already
30
- # contains the path with the same path value given to +add+. In some situations,
31
- # you may not want this behavior, so you can give <tt>:with</tt> as option.
30
+ # Notice that when you add a path using #add, the
31
+ # Path[rdoc-ref:Rails::Paths::Path] object created already contains the path
32
+ # with the same path value given to #add. In some situations, you may not
33
+ # want this behavior, so you can give <tt>:with</tt> as option.
32
34
  #
33
35
  # root.add "config/routes", with: "config/routes.rb"
34
36
  # root["config/routes"].inspect # => ["config/routes.rb"]
35
37
  #
36
- # The +add+ method accepts the following options as arguments:
37
- # eager_load, autoload, autoload_once, and glob.
38
+ # The #add method accepts the following options as arguments:
39
+ # +eager_load+, +autoload+, +autoload_once+, and +glob+.
38
40
  #
39
- # Finally, the +Path+ object also provides a few helpers:
41
+ # Finally, the Path[rdoc-ref:Rails::Paths::Path] object also provides a few
42
+ # helpers:
40
43
  #
41
44
  # root = Root.new "/rails"
42
45
  # root.add "app/controllers"
@@ -44,7 +47,7 @@ module Rails
44
47
  # root["app/controllers"].expanded # => ["/rails/app/controllers"]
45
48
  # root["app/controllers"].existent # => ["/rails/app/controllers"]
46
49
  #
47
- # Check the <tt>Rails::Paths::Path</tt> documentation for more information.
50
+ # Check the Rails::Paths::Path documentation for more information.
48
51
  class Root
49
52
  attr_accessor :path
50
53
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/time/conversions"
4
- require "active_support/core_ext/object/blank"
5
4
  require "active_support/log_subscriber"
6
5
  require "rack/body_proxy"
7
6
 
@@ -22,7 +21,7 @@ module Rails
22
21
  request = ActionDispatch::Request.new(env)
23
22
 
24
23
  if logger.respond_to?(:tagged)
25
- logger.tagged(compute_tags(request)) { call_app(request, env) }
24
+ logger.tagged(*compute_tags(request)) { call_app(request, env) }
26
25
  else
27
26
  call_app(request, env)
28
27
  end
@@ -31,17 +30,21 @@ module Rails
31
30
  private
32
31
  def call_app(request, env) # :doc:
33
32
  instrumenter = ActiveSupport::Notifications.instrumenter
34
- instrumenter_state = instrumenter.start "request.action_dispatch", request: request
35
- instrumenter_finish = -> () {
36
- instrumenter.finish_with_state(instrumenter_state, "request.action_dispatch", request: request)
37
- }
33
+ handle = instrumenter.build_handle("request.action_dispatch", { request: request })
34
+ handle.start
38
35
 
39
36
  logger.info { started_request_message(request) }
40
- status, headers, body = @app.call(env)
41
- body = ::Rack::BodyProxy.new(body, &instrumenter_finish)
42
- [status, headers, body]
37
+ status, headers, body = response = @app.call(env)
38
+ body = ::Rack::BodyProxy.new(body, &handle.method(:finish))
39
+
40
+ if response.frozen?
41
+ [status, headers, body]
42
+ else
43
+ response[2] = body
44
+ response
45
+ end
43
46
  rescue Exception
44
- instrumenter_finish.call
47
+ handle.finish
45
48
  raise
46
49
  ensure
47
50
  ActiveSupport::LogSubscriber.flush_all!
@@ -49,11 +52,11 @@ module Rails
49
52
 
50
53
  # Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
51
54
  def started_request_message(request) # :doc:
52
- 'Started %s "%s" for %s at %s' % [
55
+ sprintf('Started %s "%s" for %s at %s',
53
56
  request.raw_request_method,
54
57
  request.filtered_path,
55
58
  request.remote_ip,
56
- Time.now.to_default_s ]
59
+ Time.now)
57
60
  end
58
61
 
59
62
  def compute_tags(request) # :doc:
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :enddoc:
4
+
5
+ module Rails
6
+ module Rackup
7
+ begin
8
+ require "rackup/server"
9
+ Server = ::Rackup::Server
10
+ rescue LoadError
11
+ require "rack/server"
12
+ Server = ::Rack::Server
13
+ end
14
+ end
15
+ end
@@ -71,6 +71,11 @@ module Rails
71
71
  ActiveSupport.on_load(:after_initialize, yield: true, &block)
72
72
  end
73
73
 
74
+ # Called after application routes have been loaded.
75
+ def after_routes_loaded(&block)
76
+ ActiveSupport.on_load(:after_routes_loaded, yield: true, &block)
77
+ end
78
+
74
79
  # Array of callbacks defined by #to_prepare.
75
80
  def to_prepare_blocks
76
81
  @@to_prepare_blocks ||= []
@@ -87,9 +92,17 @@ module Rails
87
92
  end
88
93
 
89
94
  private
95
+ def actual_method?(key)
96
+ !@@options.key?(key) && respond_to?(key)
97
+ end
98
+
90
99
  def method_missing(name, *args, &blk)
91
100
  if name.end_with?("=")
92
- @@options[:"#{name[0..-2]}"] = args.first
101
+ key = name[0..-2].to_sym
102
+ if actual_method?(key)
103
+ raise NoMethodError.new("Cannot assign to `#{key}`, it is a configuration method")
104
+ end
105
+ @@options[key] = args.first
93
106
  elsif @@options.key?(name)
94
107
  @@options[name]
95
108
  else
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
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :stopdoc:
4
+
3
5
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7.0") && RUBY_ENGINE == "ruby"
4
6
  desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
5
7
  abort <<-end_message
@@ -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
 
@@ -2,17 +2,15 @@
2
2
 
3
3
  namespace :app do
4
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" ]
5
+ task update: [ "update:configs", "update:bin", "update:active_storage", "update:upgrade_guide_info" ]
6
6
 
7
- desc "Applies the template supplied by LOCATION=(/path/to/template) or URL"
7
+ desc "Apply the template supplied by LOCATION=(/path/to/template) or URL"
8
8
  task template: :environment do
9
9
  template = ENV["LOCATION"]
10
10
  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
11
  require "rails/generators"
13
12
  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
13
+ Rails::Generators::AppGenerator.apply_rails_template(template, Rails.root)
16
14
  end
17
15
 
18
16
  namespace :templates do
@@ -46,15 +44,11 @@ namespace :app do
46
44
  Rails::AppUpdater.invoke_from_app_generator :update_config_files
47
45
  end
48
46
 
49
- # desc "Adds new executables to the application bin/ directory"
47
+ # desc "Add new executables to the application bin/ directory"
50
48
  task :bin do
51
49
  Rails::AppUpdater.invoke_from_app_generator :update_bin_files
52
50
  end
53
51
 
54
- task :db do
55
- Rails::AppUpdater.invoke_from_app_generator :update_db_schema
56
- end
57
-
58
52
  task :active_storage do
59
53
  Rails::AppUpdater.invoke_from_app_generator :update_active_storage
60
54
  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