railties 6.1.0 → 7.0.0

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 (161) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -276
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +16 -16
  5. data/README.rdoc +1 -2
  6. data/lib/rails/all.rb +0 -1
  7. data/lib/rails/api/task.rb +1 -1
  8. data/lib/rails/app_updater.rb +3 -5
  9. data/lib/rails/application/bootstrap.rb +21 -5
  10. data/lib/rails/application/configuration.rb +79 -33
  11. data/lib/rails/application/default_middleware_stack.rb +7 -3
  12. data/lib/rails/application/finisher.rb +42 -85
  13. data/lib/rails/application/routes_reloader.rb +8 -0
  14. data/lib/rails/application.rb +32 -51
  15. data/lib/rails/application_controller.rb +2 -2
  16. data/lib/rails/autoloaders/inflector.rb +21 -0
  17. data/lib/rails/autoloaders.rb +12 -16
  18. data/lib/rails/code_statistics.rb +2 -2
  19. data/lib/rails/code_statistics_calculator.rb +10 -1
  20. data/lib/rails/command/base.rb +26 -12
  21. data/lib/rails/command/behavior.rb +1 -1
  22. data/lib/rails/command/environment_argument.rb +1 -1
  23. data/lib/rails/command.rb +11 -10
  24. data/lib/rails/commands/credentials/USAGE +4 -2
  25. data/lib/rails/commands/credentials/credentials_command/diffing.rb +26 -16
  26. data/lib/rails/commands/credentials/credentials_command.rb +8 -3
  27. data/lib/rails/commands/dbconsole/dbconsole_command.rb +10 -11
  28. data/lib/rails/commands/help/USAGE +3 -2
  29. data/lib/rails/commands/notes/notes_command.rb +2 -2
  30. data/lib/rails/commands/runner/runner_command.rb +3 -2
  31. data/lib/rails/commands/server/server_command.rb +2 -5
  32. data/lib/rails/configuration.rb +18 -23
  33. data/lib/rails/engine/configuration.rb +3 -3
  34. data/lib/rails/engine.rb +18 -24
  35. data/lib/rails/gem_version.rb +2 -2
  36. data/lib/rails/generators/actions/create_migration.rb +4 -4
  37. data/lib/rails/generators/actions.rb +35 -13
  38. data/lib/rails/generators/app_base.rb +140 -102
  39. data/lib/rails/generators/app_name.rb +1 -1
  40. data/lib/rails/generators/base.rb +9 -13
  41. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +2 -0
  42. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +8 -8
  43. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +8 -4
  44. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +11 -28
  45. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +7 -3
  46. data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +17 -0
  47. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +8 -17
  48. data/lib/rails/generators/erb.rb +1 -1
  49. data/lib/rails/generators/generated_attribute.rb +45 -9
  50. data/lib/rails/generators/migration.rb +2 -6
  51. data/lib/rails/generators/model_helpers.rb +1 -1
  52. data/lib/rails/generators/named_base.rb +11 -11
  53. data/lib/rails/generators/rails/app/app_generator.rb +54 -93
  54. data/lib/rails/generators/rails/app/templates/Gemfile.tt +42 -52
  55. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +2 -2
  56. data/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt +2 -2
  57. data/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt +1 -1
  58. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +3 -9
  59. data/lib/rails/generators/rails/app/templates/bin/rails.tt +1 -4
  60. data/lib/rails/generators/rails/app/templates/bin/rake.tt +0 -3
  61. data/lib/rails/generators/rails/app/templates/bin/setup.tt +9 -14
  62. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +0 -1
  63. data/lib/rails/generators/rails/app/templates/config/boot.rb.tt +1 -1
  64. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +2 -2
  65. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +3 -3
  67. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +2 -2
  68. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  69. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +2 -2
  70. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +3 -3
  71. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  72. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +5 -5
  73. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +6 -12
  74. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +11 -38
  75. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +6 -11
  76. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -5
  77. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +19 -25
  78. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +2 -2
  79. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt +4 -4
  80. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +117 -0
  81. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +3 -3
  82. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +1 -1
  83. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -1
  84. data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +5 -5
  85. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +2 -2
  86. data/lib/rails/generators/rails/app/templates/gitattributes.tt +0 -5
  87. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -1
  88. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  89. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -2
  90. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +0 -4
  91. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  92. data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -1
  93. data/lib/rails/generators/rails/plugin/plugin_generator.rb +42 -24
  94. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +7 -3
  95. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +11 -20
  96. data/lib/rails/generators/rails/plugin/templates/README.md.tt +1 -1
  97. data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +2 -2
  98. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +0 -3
  99. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +4 -5
  100. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -5
  101. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +2 -2
  102. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt +1 -1
  103. data/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt +2 -2
  104. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -7
  105. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +0 -19
  106. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -5
  107. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +6 -10
  108. data/lib/rails/generators/resource_helpers.rb +2 -2
  109. data/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt +1 -1
  110. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
  111. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +3 -3
  112. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +5 -5
  113. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +7 -7
  114. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +9 -11
  115. data/lib/rails/generators/testing/behaviour.rb +3 -4
  116. data/lib/rails/generators.rb +9 -22
  117. data/lib/rails/info.rb +1 -1
  118. data/lib/rails/info_controller.rb +1 -3
  119. data/lib/rails/initializable.rb +1 -1
  120. data/lib/rails/mailers_controller.rb +2 -4
  121. data/lib/rails/rack/logger.rb +0 -1
  122. data/lib/rails/railtie/configuration.rb +1 -2
  123. data/lib/rails/railtie.rb +31 -14
  124. data/lib/rails/ruby_version_check.rb +3 -3
  125. data/lib/rails/secrets.rb +4 -1
  126. data/lib/rails/source_annotation_extractor.rb +1 -1
  127. data/lib/rails/tasks/framework.rake +2 -8
  128. data/lib/rails/tasks/statistics.rake +3 -1
  129. data/lib/rails/tasks/tmp.rake +8 -1
  130. data/lib/rails/tasks/yarn.rake +10 -7
  131. data/lib/rails/tasks/zeitwerk.rake +2 -10
  132. data/lib/rails/templates/layouts/application.html.erb +15 -0
  133. data/lib/rails/templates/rails/mailers/email.html.erb +13 -11
  134. data/lib/rails/templates/rails/welcome/index.html.erb +62 -47
  135. data/lib/rails/test_unit/railtie.rb +0 -4
  136. data/lib/rails/test_unit/runner.rb +16 -9
  137. data/lib/rails/test_unit/testing.rake +4 -9
  138. data/lib/rails/welcome_controller.rb +1 -0
  139. data/lib/rails.rb +5 -0
  140. metadata +33 -36
  141. data/lib/rails/command/spellchecker.rb +0 -57
  142. data/lib/rails/generators/css/assets/assets_generator.rb +0 -15
  143. data/lib/rails/generators/css/assets/templates/stylesheet.css +0 -4
  144. data/lib/rails/generators/css/scaffold/scaffold_generator.rb +0 -18
  145. data/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js +0 -6
  146. data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +0 -5
  147. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +0 -23
  148. data/lib/rails/generators/rails/app/templates/bin/spring.tt +0 -9
  149. data/lib/rails/generators/rails/app/templates/bin/yarn.tt +0 -18
  150. data/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt +0 -8
  151. data/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt +0 -8
  152. data/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt +0 -5
  153. data/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb.tt +0 -4
  154. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_1.rb.tt +0 -63
  155. data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +0 -16
  156. data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +0 -6
  157. data/lib/rails/generators/rails/app/templates/package.json.tt +0 -11
  158. data/lib/rails/generators/rails/assets/USAGE +0 -16
  159. data/lib/rails/generators/rails/assets/assets_generator.rb +0 -26
  160. data/lib/rails/generators/rails/assets/templates/stylesheet.css +0 -4
  161. data/lib/rails/generators/rails/scaffold/templates/scaffold.css +0 -80
@@ -45,13 +45,13 @@ module TestUnit # :nodoc:
45
45
  def attributes_hash
46
46
  return {} if attributes_names.empty?
47
47
 
48
- attributes_names.map do |name|
48
+ attributes_names.filter_map do |name|
49
49
  if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?)
50
- ["#{name}", "'secret'"]
50
+ ["#{name}", '"secret"']
51
51
  elsif !virtual?(name)
52
52
  ["#{name}", "@#{singular_table_name}.#{name}"]
53
53
  end
54
- end.compact.sort.to_h
54
+ end.sort.to_h
55
55
  end
56
56
 
57
57
  def boolean?(name)
@@ -16,11 +16,11 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
16
16
  end
17
17
 
18
18
  test "should create <%= singular_table_name %>" do
19
- assert_difference('<%= class_name %>.count') do
19
+ assert_difference("<%= class_name %>.count") do
20
20
  post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json
21
21
  end
22
22
 
23
- assert_response 201
23
+ assert_response :created
24
24
  end
25
25
 
26
26
  test "should show <%= singular_table_name %>" do
@@ -30,15 +30,15 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
30
30
 
31
31
  test "should update <%= singular_table_name %>" do
32
32
  patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json
33
- assert_response 200
33
+ assert_response :success
34
34
  end
35
35
 
36
36
  test "should destroy <%= singular_table_name %>" do
37
- assert_difference('<%= class_name %>.count', -1) do
37
+ assert_difference("<%= class_name %>.count", -1) do
38
38
  delete <%= show_helper %>, as: :json
39
39
  end
40
40
 
41
- assert_response 204
41
+ assert_response :no_content
42
42
  end
43
43
  end
44
44
  <% end -%>
@@ -11,7 +11,7 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
11
11
  end
12
12
 
13
13
  test "should get index" do
14
- get <%= index_helper %>_url
14
+ get <%= index_helper(type: :url) %>
15
15
  assert_response :success
16
16
  end
17
17
 
@@ -21,11 +21,11 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
21
21
  end
22
22
 
23
23
  test "should create <%= singular_table_name %>" do
24
- assert_difference('<%= class_name %>.count') do
25
- post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }
24
+ assert_difference("<%= class_name %>.count") do
25
+ post <%= index_helper(type: :url) %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }
26
26
  end
27
27
 
28
- assert_redirected_to <%= singular_table_name %>_url(<%= class_name %>.last)
28
+ assert_redirected_to <%= show_helper("#{class_name}.last") %>
29
29
  end
30
30
 
31
31
  test "should show <%= singular_table_name %>" do
@@ -40,15 +40,15 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
40
40
 
41
41
  test "should update <%= singular_table_name %>" do
42
42
  patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }
43
- assert_redirected_to <%= singular_table_name %>_url(<%= "@#{singular_table_name}" %>)
43
+ assert_redirected_to <%= show_helper %>
44
44
  end
45
45
 
46
46
  test "should destroy <%= singular_table_name %>" do
47
- assert_difference('<%= class_name %>.count', -1) do
47
+ assert_difference("<%= class_name %>.count", -1) do
48
48
  delete <%= show_helper %>
49
49
  end
50
50
 
51
- assert_redirected_to <%= index_helper %>_url
51
+ assert_redirected_to <%= index_helper(type: :url) %>
52
52
  end
53
53
  end
54
54
  <% end -%>
@@ -8,12 +8,12 @@ class <%= class_name.pluralize %>Test < ApplicationSystemTestCase
8
8
 
9
9
  test "visiting the index" do
10
10
  visit <%= plural_table_name %>_url
11
- assert_selector "h1", text: "<%= class_name.pluralize.titleize %>"
11
+ assert_selector "h1", text: "<%= human_name.pluralize %>"
12
12
  end
13
13
 
14
- test "creating a <%= human_name %>" do
14
+ test "should create <%= human_name.downcase %>" do
15
15
  visit <%= plural_table_name %>_url
16
- click_on "New <%= class_name.titleize %>"
16
+ click_on "New <%= human_name.downcase %>"
17
17
 
18
18
  <%- attributes_hash.each do |attr, value| -%>
19
19
  <%- if boolean?(attr) -%>
@@ -28,9 +28,9 @@ class <%= class_name.pluralize %>Test < ApplicationSystemTestCase
28
28
  click_on "Back"
29
29
  end
30
30
 
31
- test "updating a <%= human_name %>" do
32
- visit <%= plural_table_name %>_url
33
- click_on "Edit", match: :first
31
+ test "should update <%= human_name %>" do
32
+ visit <%= singular_table_name %>_url(@<%= singular_table_name %>)
33
+ click_on "Edit this <%= human_name.downcase %>", match: :first
34
34
 
35
35
  <%- attributes_hash.each do |attr, value| -%>
36
36
  <%- if boolean?(attr) -%>
@@ -45,11 +45,9 @@ class <%= class_name.pluralize %>Test < ApplicationSystemTestCase
45
45
  click_on "Back"
46
46
  end
47
47
 
48
- test "destroying a <%= human_name %>" do
49
- visit <%= plural_table_name %>_url
50
- page.accept_confirm do
51
- click_on "Destroy", match: :first
52
- end
48
+ test "should destroy <%= human_name %>" do
49
+ visit <%= singular_table_name %>_url(@<%= singular_table_name %>)
50
+ click_on "Destroy this <%= human_name.downcase %>", match: :first
53
51
 
54
52
  assert_text "<%= human_name %> was successfully destroyed"
55
53
  end
@@ -66,9 +66,8 @@ module Rails
66
66
  # printed by the generator.
67
67
  def run_generator(args = default_arguments, config = {})
68
68
  capture(:stdout) do
69
- args += ["--skip-bundle"] unless args.include? "--dev"
70
- args |= ["--skip-bootsnap"] unless args.include? "--no-skip-bootsnap"
71
- args |= ["--skip-webpack-install"] unless args.include? "--no-skip-webpack-install"
69
+ args += ["--skip-bundle"] unless args.include?("--no-skip-bundle") || args.include?("--dev")
70
+ args |= ["--skip-bootsnap"] unless args.include?("--no-skip-bootsnap")
72
71
 
73
72
  generator_class.start(args, config.reverse_merge(destination_root: destination_root))
74
73
  end
@@ -82,7 +81,7 @@ module Rails
82
81
  # Create a Rails::Generators::GeneratedAttribute by supplying the
83
82
  # attribute type and, optionally, the attribute name:
84
83
  #
85
- # create_generated_attribute(:string, 'name')
84
+ # create_generated_attribute(:string, "name")
86
85
  def create_generated_attribute(attribute_type, name = "test", index = nil)
87
86
  Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(":"))
88
87
  end
@@ -34,12 +34,9 @@ module Rails
34
34
  actions: "-a",
35
35
  orm: "-o",
36
36
  javascripts: "-j",
37
- javascript_engine: "-je",
38
37
  resource_controller: "-c",
39
38
  scaffold_controller: "-c",
40
39
  stylesheets: "-y",
41
- stylesheet_engine: "-se",
42
- scaffold_stylesheet: "-ss",
43
40
  template_engine: "-e",
44
41
  test_framework: "-t"
45
42
  },
@@ -60,9 +57,6 @@ module Rails
60
57
  resource_controller: :controller,
61
58
  resource_route: true,
62
59
  scaffold_controller: :scaffold_controller,
63
- stylesheets: true,
64
- stylesheet_engine: :css,
65
- scaffold_stylesheet: true,
66
60
  system_tests: nil,
67
61
  test_framework: nil,
68
62
  template_engine: :erb
@@ -70,7 +64,7 @@ module Rails
70
64
  }
71
65
 
72
66
  class << self
73
- def configure!(config) #:nodoc:
67
+ def configure!(config) # :nodoc:
74
68
  api_only! if config.api_only
75
69
  no_color! unless config.colorize_logging
76
70
  aliases.deep_merge! config.aliases
@@ -82,15 +76,15 @@ module Rails
82
76
  after_generate_callbacks.replace config.after_generate_callbacks
83
77
  end
84
78
 
85
- def templates_path #:nodoc:
79
+ def templates_path # :nodoc:
86
80
  @templates_path ||= []
87
81
  end
88
82
 
89
- def aliases #:nodoc:
83
+ def aliases # :nodoc:
90
84
  @aliases ||= DEFAULT_ALIASES.dup
91
85
  end
92
86
 
93
- def options #:nodoc:
87
+ def options # :nodoc:
94
88
  @options ||= DEFAULT_OPTIONS.dup
95
89
  end
96
90
 
@@ -135,14 +129,12 @@ module Rails
135
129
  # Returns an array of generator namespaces that are hidden.
136
130
  # Generator namespaces may be hidden for a variety of reasons.
137
131
  # Some are aliased such as "rails:migration" and can be
138
- # invoked with the shorter "migration", others are private to other generators
139
- # such as "css:scaffold".
132
+ # invoked with the shorter "migration".
140
133
  def hidden_namespaces
141
134
  @hidden_namespaces ||= begin
142
135
  orm = options[:rails][:orm]
143
136
  test = options[:rails][:test_framework]
144
137
  template = options[:rails][:template_engine]
145
- css = options[:rails][:stylesheet_engine]
146
138
 
147
139
  [
148
140
  "rails",
@@ -161,10 +153,6 @@ module Rails
161
153
  "#{template}:controller",
162
154
  "#{template}:scaffold",
163
155
  "#{template}:mailer",
164
- "#{css}:scaffold",
165
- "#{css}:assets",
166
- "css:assets",
167
- "css:scaffold",
168
156
  "action_text:install",
169
157
  "action_mailbox:install"
170
158
  ]
@@ -241,7 +229,7 @@ module Rails
241
229
  #
242
230
  # Notice that "rails:generators:webrat" could be loaded as well, what
243
231
  # Rails looks for is the first and last parts of the namespace.
244
- def find_by_namespace(name, base = nil, context = nil) #:nodoc:
232
+ def find_by_namespace(name, base = nil, context = nil) # :nodoc:
245
233
  lookups = []
246
234
  lookups << "#{base}:#{name}" if base
247
235
  lookups << "#{name}:#{context}" if context
@@ -275,12 +263,11 @@ module Rails
275
263
  klass.start(args, config)
276
264
  run_after_generate_callback if config[:behavior] == :invoke
277
265
  else
278
- options = sorted_groups.flat_map(&:last)
279
- suggestion = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options)
280
- suggestion_msg = "Maybe you meant #{suggestion.inspect}?" if suggestion
266
+ options = sorted_groups.flat_map(&:last)
267
+ error = Command::Base::CorrectableError.new("Could not find generator '#{namespace}'.", namespace, options)
281
268
 
282
269
  puts <<~MSG
283
- Could not find generator '#{namespace}'. #{suggestion_msg}
270
+ #{error.message}
284
271
  Run `bin/rails generate --help` for more options.
285
272
  MSG
286
273
  end
data/lib/rails/info.rb CHANGED
@@ -21,7 +21,7 @@ module Rails
21
21
  end
22
22
  end
23
23
 
24
- class << self #:nodoc:
24
+ class << self # :nodoc:
25
25
  def property(name, value = nil)
26
26
  value ||= yield
27
27
  properties << [name, value] if value
@@ -34,9 +34,7 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc:
34
34
 
35
35
  private
36
36
  def match_route
37
- _routes.routes.select { |route|
38
- yield route.path
39
- }.map { |route| route.path.spec.to_s }
37
+ _routes.routes.filter_map { |route| route.path.spec.to_s if yield route.path }
40
38
  end
41
39
 
42
40
  def with_leading_slash(path)
@@ -4,7 +4,7 @@ require "tsort"
4
4
 
5
5
  module Rails
6
6
  module Initializable
7
- def self.included(base) #:nodoc:
7
+ def self.included(base) # :nodoc:
8
8
  base.extend ClassMethods
9
9
  end
10
10
 
@@ -93,9 +93,7 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
93
93
  request.query_parameters.merge(locale: locale).to_query
94
94
  end
95
95
 
96
- def set_locale
97
- I18n.with_locale(params[:locale] || I18n.default_locale) do
98
- yield
99
- end
96
+ def set_locale(&block)
97
+ I18n.with_locale(params[:locale] || I18n.default_locale, &block)
100
98
  end
101
99
  end
@@ -3,7 +3,6 @@
3
3
  require "active_support/core_ext/time/conversions"
4
4
  require "active_support/core_ext/object/blank"
5
5
  require "active_support/log_subscriber"
6
- require "action_dispatch/http/request"
7
6
  require "rack/body_proxy"
8
7
 
9
8
  module Rails
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/configuration"
4
- require "active_support/core_ext/symbol/starts_ends_with"
5
4
 
6
5
  module Rails
7
6
  class Railtie
@@ -11,7 +10,7 @@ module Rails
11
10
  end
12
11
 
13
12
  # Expose the eager_load_namespaces at "module" level for convenience.
14
- def self.eager_load_namespaces #:nodoc:
13
+ def self.eager_load_namespaces # :nodoc:
15
14
  @@eager_load_namespaces ||= []
16
15
  end
17
16
 
data/lib/rails/railtie.rb CHANGED
@@ -120,11 +120,11 @@ module Rails
120
120
  # this less confusing for everyone.
121
121
  # It can be used like this:
122
122
  #
123
- # class MyRailtie < Rails::Railtie
124
- # server do
125
- # WebpackServer.start
123
+ # class MyRailtie < Rails::Railtie
124
+ # server do
125
+ # WebpackServer.start
126
+ # end
126
127
  # end
127
- # end
128
128
  #
129
129
  # == Application and Engine
130
130
  #
@@ -146,7 +146,7 @@ module Rails
146
146
  delegate :config, to: :instance
147
147
 
148
148
  def subclasses
149
- super.reject(&:abstract_railtie?)
149
+ super.reject(&:abstract_railtie?).sort
150
150
  end
151
151
 
152
152
  def rake_tasks(&blk)
@@ -191,6 +191,23 @@ module Rails
191
191
  instance.configure(&block)
192
192
  end
193
193
 
194
+ def <=>(other) # :nodoc:
195
+ load_index <=> other.load_index
196
+ end
197
+
198
+ def inherited(subclass)
199
+ subclass.increment_load_index
200
+ super
201
+ end
202
+
203
+ protected
204
+ attr_reader :load_index
205
+
206
+ def increment_load_index
207
+ @@load_counter ||= 0
208
+ @load_index = (@@load_counter += 1)
209
+ end
210
+
194
211
  private
195
212
  def generate_railtie_name(string)
196
213
  ActiveSupport::Inflector.underscore(string).tr("/", "_")
@@ -209,7 +226,7 @@ module Rails
209
226
  super
210
227
  end
211
228
  end
212
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
229
+ ruby2_keywords(:method_missing)
213
230
 
214
231
  # receives an instance variable identifier, set the variable value if is
215
232
  # blank and append given block to value, which will be used later in
@@ -224,13 +241,13 @@ module Rails
224
241
 
225
242
  delegate :railtie_name, to: :class
226
243
 
227
- def initialize #:nodoc:
244
+ def initialize # :nodoc:
228
245
  if self.class.abstract_railtie?
229
246
  raise "#{self.class.name} is abstract, you cannot instantiate it directly."
230
247
  end
231
248
  end
232
249
 
233
- def configure(&block) #:nodoc:
250
+ def configure(&block) # :nodoc:
234
251
  instance_eval(&block)
235
252
  end
236
253
 
@@ -241,29 +258,29 @@ module Rails
241
258
  @config ||= Railtie::Configuration.new
242
259
  end
243
260
 
244
- def railtie_namespace #:nodoc:
261
+ def railtie_namespace # :nodoc:
245
262
  @railtie_namespace ||= self.class.module_parents.detect { |n| n.respond_to?(:railtie_namespace) }
246
263
  end
247
264
 
248
265
  protected
249
- def run_console_blocks(app) #:nodoc:
266
+ def run_console_blocks(app) # :nodoc:
250
267
  each_registered_block(:console) { |block| block.call(app) }
251
268
  end
252
269
 
253
- def run_generators_blocks(app) #:nodoc:
270
+ def run_generators_blocks(app) # :nodoc:
254
271
  each_registered_block(:generators) { |block| block.call(app) }
255
272
  end
256
273
 
257
- def run_runner_blocks(app) #:nodoc:
274
+ def run_runner_blocks(app) # :nodoc:
258
275
  each_registered_block(:runner) { |block| block.call(app) }
259
276
  end
260
277
 
261
- def run_tasks_blocks(app) #:nodoc:
278
+ def run_tasks_blocks(app) # :nodoc:
262
279
  extend Rake::DSL
263
280
  each_registered_block(:rake_tasks) { |block| instance_exec(app, &block) }
264
281
  end
265
282
 
266
- def run_server_blocks(app) #:nodoc:
283
+ def run_server_blocks(app) # :nodoc:
267
284
  each_registered_block(:server) { |block| block.call(app) }
268
285
  end
269
286
 
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0") && RUBY_ENGINE == "ruby"
3
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7.0") && RUBY_ENGINE == "ruby"
4
4
  desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
5
5
  abort <<-end_message
6
6
 
7
- Rails 6 requires Ruby 2.5.0 or newer.
7
+ Rails 7 requires Ruby 2.7.0 or newer.
8
8
 
9
9
  You're running
10
10
  #{desc}
11
11
 
12
- Please upgrade to Ruby 2.5.0 or newer to continue.
12
+ Please upgrade to Ruby 2.7.0 or newer to continue.
13
13
 
14
14
  end_message
15
15
  end
data/lib/rails/secrets.rb CHANGED
@@ -25,7 +25,10 @@ module Rails
25
25
  paths.each_with_object(Hash.new) do |path, all_secrets|
26
26
  require "erb"
27
27
 
28
- secrets = YAML.load(ERB.new(preprocess(path)).result) || {}
28
+ source = ERB.new(preprocess(path)).result
29
+ secrets = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(source) : YAML.load(source)
30
+ secrets ||= {}
31
+
29
32
  all_secrets.merge!(secrets["shared"].deep_symbolize_keys) if secrets["shared"]
30
33
  all_secrets.merge!(secrets[env].deep_symbolize_keys) if secrets[env]
31
34
  end
@@ -72,7 +72,7 @@ module Rails
72
72
  #
73
73
  # See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
74
74
  #
75
- # This class method is the single entry point for the `rails notes` command.
75
+ # This class method is the single entry point for the <tt>rails notes</tt> command.
76
76
  def self.enumerate(tag = nil, options = {})
77
77
  tag ||= Annotation.tags.join("|")
78
78
  extractor = new(tag)
@@ -8,7 +8,7 @@ namespace :app do
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)
11
+ template = File.expand_path(template) unless %r{\A[A-Za-z][A-Za-z0-9+\-.]*://}.match?(template)
12
12
  require "rails/generators"
13
13
  require "rails/generators/rails/app/app_generator"
14
14
  generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
@@ -22,7 +22,7 @@ namespace :app do
22
22
  project_templates = "#{Rails.root}/lib/templates"
23
23
 
24
24
  default_templates = { "erb" => %w{controller mailer scaffold},
25
- "rails" => %w{controller helper scaffold_controller assets} }
25
+ "rails" => %w{controller helper scaffold_controller} }
26
26
 
27
27
  default_templates.each do |type, names|
28
28
  local_template_type_dir = File.join(project_templates, type)
@@ -59,10 +59,4 @@ namespace :app do
59
59
  Rails::AppUpdater.invoke_from_app_generator :display_upgrade_guide_info
60
60
  end
61
61
  end
62
-
63
- namespace :binstub do
64
- task :yarn do
65
- Rails::AppUpdater.invoke_from_app_generator :update_bin_yarn
66
- end
67
- end
68
62
  end
@@ -11,17 +11,19 @@ STATS_DIRECTORIES ||= [
11
11
  %w(Mailers app/mailers),
12
12
  %w(Mailboxes app/mailboxes),
13
13
  %w(Channels app/channels),
14
+ %w(Views app/views),
14
15
  %w(JavaScripts app/assets/javascripts),
16
+ %w(Stylesheets app/assets/stylesheets),
15
17
  %w(JavaScript app/javascript),
16
18
  %w(Libraries lib/),
17
19
  %w(APIs app/apis),
18
20
  %w(Controller\ tests test/controllers),
19
21
  %w(Helper\ tests test/helpers),
22
+ %w(Job\ tests test/jobs),
20
23
  %w(Model\ tests test/models),
21
24
  %w(Mailer\ tests test/mailers),
22
25
  %w(Mailbox\ tests test/mailboxes),
23
26
  %w(Channel\ tests test/channels),
24
- %w(Job\ tests test/jobs),
25
27
  %w(Integration\ tests test/integration),
26
28
  %w(System\ tests test/system),
27
29
  ].collect do |name, dir|
@@ -2,7 +2,7 @@
2
2
 
3
3
  namespace :tmp do
4
4
  desc "Clear cache, socket and screenshot files from tmp/ (narrow w/ tmp:cache:clear, tmp:sockets:clear, tmp:screenshots:clear)"
5
- task clear: ["tmp:cache:clear", "tmp:sockets:clear", "tmp:screenshots:clear"]
5
+ task clear: ["tmp:cache:clear", "tmp:sockets:clear", "tmp:screenshots:clear", "tmp:storage:clear"]
6
6
 
7
7
  tmp_dirs = [ "tmp/cache",
8
8
  "tmp/sockets",
@@ -41,4 +41,11 @@ namespace :tmp do
41
41
  rm Dir["tmp/screenshots/[^.]*"], verbose: false
42
42
  end
43
43
  end
44
+
45
+ namespace :storage do
46
+ # desc "Clear all files and directories in tmp/storage"
47
+ task :clear do
48
+ rm_rf Dir["tmp/storage/[^.]*"], verbose: false
49
+ end
50
+ end
44
51
  end
@@ -10,17 +10,20 @@ namespace :yarn do
10
10
  end
11
11
 
12
12
  yarn_flags =
13
- if `#{Rails.root}/bin/yarn --version`.start_with?("1")
13
+ if `yarn --version`.start_with?("1")
14
14
  "--no-progress --frozen-lockfile"
15
15
  else
16
16
  "--immutable"
17
17
  end
18
18
 
19
- system({ "NODE_ENV" => node_env }, "#{Rails.root}/bin/yarn install #{yarn_flags}")
19
+ system(
20
+ { "NODE_ENV" => node_env },
21
+ "yarn install #{yarn_flags}",
22
+ exception: true
23
+ )
24
+ rescue Errno::ENOENT
25
+ $stderr.puts "yarn install failed to execute."
26
+ $stderr.puts "Ensure yarn is installed and `yarn --version` runs without errors."
27
+ exit 1
20
28
  end
21
29
  end
22
-
23
- # Run Yarn prior to Sprockets assets precompilation, so dependencies are available for use.
24
- if Rake::Task.task_defined?("assets:precompile")
25
- Rake::Task["assets:precompile"].enhance [ "yarn:install" ]
26
- end
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ensure_zeitwerk_mode = ->() do
4
- unless Rails.autoloaders.zeitwerk_enabled?
5
- abort "Please, enable :zeitwerk mode in config/application.rb and try again."
6
- end
7
- end
8
-
9
3
  eager_load = ->() do
10
4
  puts "Hold on, I am eager loading the application."
11
5
  Zeitwerk::Loader.eager_load_all
@@ -41,8 +35,6 @@ end
41
35
  namespace :zeitwerk do
42
36
  desc "Checks project structure for Zeitwerk compatibility"
43
37
  task check: :environment do
44
- ensure_zeitwerk_mode[]
45
-
46
38
  begin
47
39
  eager_load[]
48
40
  rescue NameError => e
@@ -54,11 +46,11 @@ namespace :zeitwerk do
54
46
  end
55
47
 
56
48
  require "active_support/core_ext/object/try"
57
- eager_load_paths = Rails.configuration.eager_load_namespaces.map do |eln|
49
+ eager_load_paths = Rails.configuration.eager_load_namespaces.filter_map do |eln|
58
50
  # Quick regression fix for 6.0.3 to support namespaces that do not have
59
51
  # eager load paths, like the recently added i18n. I'll rewrite this task.
60
52
  eln.try(:config).try(:eager_load_paths)
61
- end.compact.flatten
53
+ end.flatten
62
54
 
63
55
  not_checked = ActiveSupport::Dependencies.autoload_paths - eager_load_paths
64
56
  not_checked.select! { |dir| Dir.exist?(dir) }
@@ -25,6 +25,21 @@
25
25
 
26
26
  h2 { padding-left: 10px; }
27
27
 
28
+ @media (prefers-color-scheme: dark) {
29
+ body {
30
+ background-color: #222;
31
+ color: #ececec;
32
+ }
33
+
34
+ pre {
35
+ background-color: #333;
36
+ }
37
+
38
+ a { color: #fff; }
39
+ a:visited { color: #999; }
40
+ a:hover { color: #000; background-color: #fff; }
41
+ }
42
+
28
43
  <%= yield :style %>
29
44
  </style>
30
45
  </head>