railties 6.1.4.1 → 7.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -361
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +16 -16
  5. data/README.rdoc +0 -1
  6. data/lib/rails/app_updater.rb +2 -4
  7. data/lib/rails/application/bootstrap.rb +17 -5
  8. data/lib/rails/application/configuration.rb +51 -26
  9. data/lib/rails/application/default_middleware_stack.rb +6 -3
  10. data/lib/rails/application/finisher.rb +43 -85
  11. data/lib/rails/application/routes_reloader.rb +8 -0
  12. data/lib/rails/application.rb +24 -50
  13. data/lib/rails/application_controller.rb +2 -2
  14. data/lib/rails/autoloaders/inflector.rb +21 -0
  15. data/lib/rails/autoloaders.rb +12 -16
  16. data/lib/rails/code_statistics.rb +2 -2
  17. data/lib/rails/code_statistics_calculator.rb +10 -1
  18. data/lib/rails/command/base.rb +26 -12
  19. data/lib/rails/command/behavior.rb +1 -1
  20. data/lib/rails/command/environment_argument.rb +1 -1
  21. data/lib/rails/command.rb +8 -5
  22. data/lib/rails/commands/credentials/USAGE +4 -2
  23. data/lib/rails/commands/credentials/credentials_command/diffing.rb +26 -16
  24. data/lib/rails/commands/credentials/credentials_command.rb +8 -3
  25. data/lib/rails/commands/dbconsole/dbconsole_command.rb +10 -6
  26. data/lib/rails/commands/help/USAGE +3 -2
  27. data/lib/rails/commands/runner/runner_command.rb +3 -2
  28. data/lib/rails/commands/server/server_command.rb +2 -5
  29. data/lib/rails/configuration.rb +18 -23
  30. data/lib/rails/engine/configuration.rb +2 -2
  31. data/lib/rails/engine.rb +23 -27
  32. data/lib/rails/gem_version.rb +4 -4
  33. data/lib/rails/generators/actions/create_migration.rb +2 -4
  34. data/lib/rails/generators/actions.rb +35 -13
  35. data/lib/rails/generators/app_base.rb +66 -102
  36. data/lib/rails/generators/app_name.rb +1 -1
  37. data/lib/rails/generators/base.rb +9 -13
  38. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +2 -0
  39. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +8 -4
  40. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +5 -27
  41. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +7 -3
  42. data/lib/rails/generators/erb/scaffold/templates/partial.html.erb.tt +20 -0
  43. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +7 -16
  44. data/lib/rails/generators/erb.rb +1 -1
  45. data/lib/rails/generators/generated_attribute.rb +40 -4
  46. data/lib/rails/generators/migration.rb +2 -6
  47. data/lib/rails/generators/model_helpers.rb +1 -1
  48. data/lib/rails/generators/named_base.rb +1 -1
  49. data/lib/rails/generators/rails/app/app_generator.rb +44 -88
  50. data/lib/rails/generators/rails/app/templates/Gemfile.tt +41 -52
  51. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +2 -2
  52. data/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt +2 -2
  53. data/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt +1 -1
  54. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +3 -10
  55. data/lib/rails/generators/rails/app/templates/bin/rails.tt +1 -4
  56. data/lib/rails/generators/rails/app/templates/bin/rake.tt +0 -3
  57. data/lib/rails/generators/rails/app/templates/bin/setup.tt +9 -14
  58. data/lib/rails/generators/rails/app/templates/config/boot.rb.tt +1 -1
  59. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +2 -2
  60. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +3 -3
  61. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +3 -3
  62. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +2 -2
  63. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  64. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +2 -2
  65. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  67. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +5 -5
  68. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +2 -11
  69. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +9 -15
  70. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +2 -7
  71. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -5
  72. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +0 -5
  73. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +2 -2
  74. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt +4 -4
  75. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +85 -0
  76. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +3 -3
  77. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +1 -1
  78. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -0
  79. data/lib/rails/generators/rails/app/templates/config/storage.yml.tt +5 -5
  80. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +2 -2
  81. data/lib/rails/generators/rails/app/templates/gitattributes.tt +0 -5
  82. data/lib/rails/generators/rails/app/templates/gitignore.tt +0 -1
  83. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  84. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -2
  85. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +0 -4
  86. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  87. data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +1 -1
  88. data/lib/rails/generators/rails/plugin/plugin_generator.rb +40 -15
  89. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +4 -2
  90. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +9 -9
  91. data/lib/rails/generators/rails/plugin/templates/README.md.tt +1 -1
  92. data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +2 -2
  93. data/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +1 -1
  94. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +0 -3
  95. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +4 -4
  96. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -5
  97. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +2 -2
  98. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt +1 -1
  99. data/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt +2 -2
  100. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +3 -3
  101. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +0 -19
  102. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -5
  103. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +6 -10
  104. data/lib/rails/generators/resource_helpers.rb +2 -2
  105. data/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt +1 -1
  106. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
  107. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +3 -3
  108. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +5 -5
  109. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  110. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +3 -3
  111. data/lib/rails/generators/testing/behaviour.rb +1 -2
  112. data/lib/rails/generators.rb +9 -22
  113. data/lib/rails/info.rb +1 -1
  114. data/lib/rails/info_controller.rb +1 -3
  115. data/lib/rails/initializable.rb +1 -1
  116. data/lib/rails/mailers_controller.rb +2 -4
  117. data/lib/rails/rack/logger.rb +0 -1
  118. data/lib/rails/railtie/configuration.rb +1 -2
  119. data/lib/rails/railtie.rb +9 -9
  120. data/lib/rails/ruby_version_check.rb +3 -3
  121. data/lib/rails/secrets.rb +4 -1
  122. data/lib/rails/tasks/framework.rake +2 -8
  123. data/lib/rails/tasks/statistics.rake +3 -1
  124. data/lib/rails/tasks/tmp.rake +8 -1
  125. data/lib/rails/tasks/yarn.rake +5 -1
  126. data/lib/rails/tasks/zeitwerk.rake +2 -10
  127. data/lib/rails/templates/layouts/application.html.erb +15 -0
  128. data/lib/rails/templates/rails/mailers/email.html.erb +12 -10
  129. data/lib/rails/templates/rails/welcome/index.html.erb +3 -0
  130. data/lib/rails/test_unit/railtie.rb +0 -4
  131. data/lib/rails/test_unit/runner.rb +7 -5
  132. data/lib/rails/test_unit/testing.rake +4 -9
  133. data/lib/rails.rb +1 -0
  134. metadata +35 -36
  135. data/lib/rails/command/spellchecker.rb +0 -57
  136. data/lib/rails/generators/css/assets/assets_generator.rb +0 -15
  137. data/lib/rails/generators/css/assets/templates/stylesheet.css +0 -4
  138. data/lib/rails/generators/css/scaffold/scaffold_generator.rb +0 -18
  139. data/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js +0 -6
  140. data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +0 -5
  141. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +0 -23
  142. data/lib/rails/generators/rails/app/templates/bin/spring.tt +0 -13
  143. data/lib/rails/generators/rails/app/templates/bin/yarn.tt +0 -16
  144. data/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt +0 -8
  145. data/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt +0 -5
  146. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_1.rb.tt +0 -67
  147. data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +0 -6
  148. data/lib/rails/generators/rails/app/templates/package.json.tt +0 -11
  149. data/lib/rails/generators/rails/assets/USAGE +0 -16
  150. data/lib/rails/generators/rails/assets/assets_generator.rb +0 -26
  151. data/lib/rails/generators/rails/assets/templates/stylesheet.css +0 -4
  152. data/lib/rails/generators/rails/scaffold/templates/scaffold.css +0 -80
@@ -7,10 +7,10 @@ module Rails
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 6
11
- MINOR = 1
12
- TINY = 4
13
- PRE = "1"
10
+ MAJOR = 7
11
+ MINOR = 0
12
+ TINY = 0
13
+ PRE = "alpha1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -6,7 +6,7 @@ require "thor/actions"
6
6
  module Rails
7
7
  module Generators
8
8
  module Actions
9
- class CreateMigration < Thor::Actions::CreateFile #:nodoc:
9
+ class CreateMigration < Thor::Actions::CreateFile # :nodoc:
10
10
  def migration_dir
11
11
  File.dirname(@destination)
12
12
  end
@@ -39,10 +39,8 @@ module Rails
39
39
  end
40
40
 
41
41
  def existing_migration
42
- @existing_migration ||= begin
43
- @base.class.migration_exists?(migration_dir, migration_file_name) ||
42
+ @existing_migration ||= @base.class.migration_exists?(migration_dir, migration_file_name) ||
44
43
  File.exist?(@destination) && @destination
45
- end
46
44
  end
47
45
  alias :exists? :existing_migration
48
46
 
@@ -18,6 +18,7 @@ module Rails
18
18
  # gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
19
19
  # gem "rails", "3.0", git: "https://github.com/rails/rails"
20
20
  # gem "RedCloth", ">= 4.1.0", "< 4.2.0"
21
+ # gem "rspec", comment: "Put this comment above the gem declaration"
21
22
  def gem(*args)
22
23
  options = args.extract_options!
23
24
  name, *versions = args
@@ -26,6 +27,9 @@ module Rails
26
27
  # otherwise use name (version).
27
28
  parts, message = [ quote(name) ], name.dup
28
29
 
30
+ # Output a comment above the gem declaration.
31
+ comment = options.delete(:comment)
32
+
29
33
  if versions = versions.any? ? versions : options.delete(:version)
30
34
  _versions = Array(versions)
31
35
  _versions.each do |version|
@@ -40,9 +44,17 @@ module Rails
40
44
  parts << quote(options) unless options.empty?
41
45
 
42
46
  in_root do
43
- str = "gem #{parts.join(", ")}"
44
- str = indentation + str
45
- append_file_with_newline "Gemfile", str, verbose: false
47
+ str = []
48
+ if comment
49
+ comment.each_line do |comment_line|
50
+ str << indentation
51
+ str << "# #{comment_line}"
52
+ end
53
+ str << "\n"
54
+ end
55
+ str << indentation
56
+ str << "gem #{parts.join(", ")}"
57
+ append_file_with_newline "Gemfile", str.join, verbose: false
46
58
  end
47
59
  end
48
60
 
@@ -268,14 +280,25 @@ module Rails
268
280
  # route "root 'admin#index'", namespace: :admin
269
281
  def route(routing_code, namespace: nil)
270
282
  routing_code = Array(namespace).reverse.reduce(routing_code) do |code, ns|
271
- "namespace :#{ns} do\n#{indent(code, 2)}\nend"
283
+ "namespace :#{ns} do\n#{optimize_indentation(code, 2)}end"
272
284
  end
273
285
 
274
286
  log :route, routing_code
275
- sentinel = /\.routes\.draw do\s*\n/m
287
+
288
+ after_pattern = Array(namespace).each_with_index.reverse_each.reduce(nil) do |pattern, (ns, i)|
289
+ margin = "\\#{i + 1}[ ]{2}"
290
+ "(?:(?:^[ ]*\n|^#{margin}.*\n)*?^(#{margin})namespace :#{ns} do\n#{pattern})?"
291
+ end.then do |pattern|
292
+ /^([ ]*).+\.routes\.draw do[ ]*\n#{pattern}/
293
+ end
276
294
 
277
295
  in_root do
278
- inject_into_file "config/routes.rb", optimize_indentation(routing_code, 2), after: sentinel, verbose: false, force: false
296
+ if existing = match_file("config/routes.rb", after_pattern)
297
+ base_indent, *, prev_indent = existing.captures.compact.map(&:length)
298
+ routing_code = optimize_indentation(routing_code, base_indent + 2).lines.grep_v(/^[ ]{,#{prev_indent}}\S/).join
299
+ end
300
+
301
+ inject_into_file "config/routes.rb", routing_code, after: after_pattern, verbose: false, force: false
279
302
  end
280
303
  end
281
304
 
@@ -323,8 +346,7 @@ module Rails
323
346
  end
324
347
  end
325
348
 
326
- # Surround string with single quotes if there is no quotes.
327
- # Otherwise fall back to double quotes
349
+ # Always returns value in double quotes.
328
350
  def quote(value) # :doc:
329
351
  if value.respond_to? :each_pair
330
352
  return value.map do |k, v|
@@ -333,11 +355,7 @@ module Rails
333
355
  end
334
356
  return value.inspect unless value.is_a? String
335
357
 
336
- if value.include?("'")
337
- value.inspect
338
- else
339
- "'#{value}'"
340
- end
358
+ "\"#{value.tr("'", '"')}\""
341
359
  end
342
360
 
343
361
  # Returns optimized string with indentation
@@ -365,6 +383,10 @@ module Rails
365
383
  match.end_with?("\n") ? "" : "\n#{str}\n"
366
384
  end
367
385
  end
386
+
387
+ def match_file(path, pattern)
388
+ File.read(path).match(pattern) if File.exist?(path)
389
+ end
368
390
  end
369
391
  end
370
392
  end
@@ -30,9 +30,6 @@ module Rails
30
30
  class_option :database, type: :string, aliases: "-d", default: "sqlite3",
31
31
  desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
32
32
 
33
- class_option :skip_gemfile, type: :boolean, default: false,
34
- desc: "Don't create a Gemfile"
35
-
36
33
  class_option :skip_git, type: :boolean, aliases: "-G", default: false,
37
34
  desc: "Skip .gitignore file"
38
35
 
@@ -58,26 +55,17 @@ module Rails
58
55
  class_option :skip_active_storage, type: :boolean, default: false,
59
56
  desc: "Skip Active Storage files"
60
57
 
61
- class_option :skip_puma, type: :boolean, aliases: "-P", default: false,
62
- desc: "Skip Puma related files"
63
-
64
58
  class_option :skip_action_cable, type: :boolean, aliases: "-C", default: false,
65
59
  desc: "Skip Action Cable files"
66
60
 
67
61
  class_option :skip_sprockets, type: :boolean, aliases: "-S", default: false,
68
62
  desc: "Skip Sprockets files"
69
63
 
70
- class_option :skip_spring, type: :boolean, default: false,
71
- desc: "Don't install Spring application preloader"
72
-
73
- class_option :skip_listen, type: :boolean, default: false,
74
- desc: "Don't generate configuration that depends on the listen gem"
75
-
76
64
  class_option :skip_javascript, type: :boolean, aliases: "-J", default: name == "plugin",
77
65
  desc: "Skip JavaScript files"
78
66
 
79
- class_option :skip_turbolinks, type: :boolean, default: false,
80
- desc: "Skip turbolinks gem"
67
+ class_option :skip_hotwire, type: :boolean, default: false,
68
+ desc: "Skip Hotwire integration"
81
69
 
82
70
  class_option :skip_jbuilder, type: :boolean, default: false,
83
71
  desc: "Skip jbuilder gem"
@@ -97,7 +85,7 @@ module Rails
97
85
  class_option :edge, type: :boolean, default: false,
98
86
  desc: "Set up the #{name} with Gemfile pointing to Rails repository"
99
87
 
100
- class_option :master, type: :boolean, default: false,
88
+ class_option :main, type: :boolean, default: false, aliases: "--master",
101
89
  desc: "Set up the #{name} with Gemfile pointing to Rails repository main branch"
102
90
 
103
91
  class_option :rc, type: :string, default: nil,
@@ -110,47 +98,22 @@ module Rails
110
98
  desc: "Show this help message and quit"
111
99
  end
112
100
 
113
- def initialize(positional_argv, option_argv, *)
114
- @argv = [*positional_argv, *option_argv]
101
+ def initialize(*)
115
102
  @gem_filter = lambda { |gem| true }
116
- @extra_entries = []
117
103
  super
118
104
  end
119
105
 
120
106
  private
121
- def gemfile_entry(name, *args) # :doc:
122
- options = args.extract_options!
123
- version = args.first
124
- github = options[:github]
125
- path = options[:path]
126
-
127
- if github
128
- @extra_entries << GemfileEntry.github(name, github)
129
- elsif path
130
- @extra_entries << GemfileEntry.path(name, path)
131
- else
132
- @extra_entries << GemfileEntry.version(name, version)
133
- end
134
- self
135
- end
136
-
137
107
  def gemfile_entries # :doc:
138
108
  [rails_gemfile_entry,
139
109
  database_gemfile_entry,
140
110
  web_server_gemfile_entry,
141
- assets_gemfile_entry,
142
- webpacker_gemfile_entry,
143
111
  javascript_gemfile_entry,
112
+ hotwire_gemfile_entry,
113
+ css_gemfile_entry,
144
114
  jbuilder_gemfile_entry,
145
115
  psych_gemfile_entry,
146
- cable_gemfile_entry,
147
- @extra_entries].flatten.find_all(&@gem_filter)
148
- end
149
-
150
- def add_gem_entry_filter # :doc:
151
- @gem_filter = lambda { |next_filter, entry|
152
- yield(entry) && next_filter.call(entry)
153
- }.curry[@gem_filter]
116
+ cable_gemfile_entry].flatten.find_all(&@gem_filter)
154
117
  end
155
118
 
156
119
  def builder # :doc:
@@ -173,14 +136,9 @@ module Rails
173
136
  end
174
137
 
175
138
  def apply_rails_template # :doc:
176
- original_argv = ARGV.dup
177
- ARGV.replace(@argv)
178
-
179
139
  apply rails_template if rails_template
180
140
  rescue Thor::Error, LoadError, Errno::ENOENT => e
181
141
  raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
182
- ensure
183
- ARGV.replace(original_argv)
184
142
  end
185
143
 
186
144
  def set_default_accessors! # :doc:
@@ -200,13 +158,11 @@ module Rails
200
158
  return [] if options[:skip_active_record]
201
159
  gem_name, gem_version = gem_for_database
202
160
  GemfileEntry.version gem_name, gem_version,
203
- "Use #{options[:database]} as the database for Active Record"
161
+ "Use #{options[:database]} as the database for Active Record"
204
162
  end
205
163
 
206
164
  def web_server_gemfile_entry # :doc:
207
- return [] if options[:skip_puma]
208
- comment = "Use Puma as the app server"
209
- GemfileEntry.new("puma", "~> 5.0", comment)
165
+ GemfileEntry.new "puma", "~> 5.0", "Use the Puma web server [https://github.com/puma/puma]"
210
166
  end
211
167
 
212
168
  def include_all_railties? # :doc:
@@ -287,7 +243,7 @@ module Rails
287
243
  version = super
288
244
 
289
245
  if version.is_a?(Array)
290
- version.join("', '")
246
+ version.join('", "')
291
247
  else
292
248
  version
293
249
  end
@@ -297,20 +253,21 @@ module Rails
297
253
  def rails_gemfile_entry
298
254
  if options.dev?
299
255
  [
300
- GemfileEntry.path("rails", Rails::Generators::RAILS_DEV_PATH)
256
+ GemfileEntry.path("rails", Rails::Generators::RAILS_DEV_PATH, "Use local checkout of Rails")
301
257
  ]
302
258
  elsif options.edge?
259
+ edge_branch = Rails.gem_version.prerelease? ? "main" : [*Rails.gem_version.segments.first(2), "stable"].join("-")
303
260
  [
304
- GemfileEntry.github("rails", "rails/rails", "6-1-stable")
261
+ GemfileEntry.github("rails", "rails/rails", edge_branch, "Use specific branch of Rails")
305
262
  ]
306
- elsif options.master?
263
+ elsif options.main?
307
264
  [
308
- GemfileEntry.github("rails", "rails/rails", "main")
265
+ GemfileEntry.github("rails", "rails/rails", "main", "Use main development branch of Rails")
309
266
  ]
310
267
  else
311
268
  [GemfileEntry.version("rails",
312
269
  rails_version_specifier,
313
- "Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'")]
270
+ %(Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"))]
314
271
  end
315
272
  end
316
273
 
@@ -327,30 +284,45 @@ module Rails
327
284
  end
328
285
  end
329
286
 
330
- def assets_gemfile_entry
331
- return [] if options[:skip_sprockets]
332
-
333
- GemfileEntry.version("sass-rails", ">= 6", "Use SCSS for stylesheets")
287
+ def jbuilder_gemfile_entry
288
+ return [] if options[:skip_jbuilder]
289
+ comment = "Build JSON APIs with ease [https://github.com/rails/jbuilder]"
290
+ GemfileEntry.new "jbuilder", "~> 2.7", comment, {}, options[:api]
334
291
  end
335
292
 
336
- def webpacker_gemfile_entry
293
+ def javascript_gemfile_entry
337
294
  return [] if options[:skip_javascript]
338
295
 
339
- GemfileEntry.version "webpacker", "~> 5.0", "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker"
296
+ if options[:javascript] == "importmap"
297
+ GemfileEntry.version("importmap-rails", ">= 0.3.4", "Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]")
298
+ else
299
+ GemfileEntry.version "jsbundling-rails", "~> 0.1.0", "Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]"
300
+ end
340
301
  end
341
302
 
342
- def jbuilder_gemfile_entry
343
- return [] if options[:skip_jbuilder]
344
- comment = "Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder"
345
- GemfileEntry.new "jbuilder", "~> 2.7", comment, {}, options[:api]
303
+ def hotwire_gemfile_entry
304
+ return [] if options[:skip_javascript] || options[:skip_hotwire]
305
+
306
+ turbo_rails_entry =
307
+ GemfileEntry.version("turbo-rails", ">= 0.7.11", "Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]")
308
+
309
+ stimulus_rails_entry =
310
+ GemfileEntry.version("stimulus-rails", ">= 0.4.0", "Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]")
311
+
312
+ [ turbo_rails_entry, stimulus_rails_entry ]
346
313
  end
347
314
 
348
- def javascript_gemfile_entry
349
- if options[:skip_javascript] || options[:skip_turbolinks]
350
- []
315
+ def using_node?
316
+ options[:javascript] && options[:javascript] != "importmap"
317
+ end
318
+
319
+ def css_gemfile_entry
320
+ return [] unless options[:css]
321
+
322
+ if !using_node? && options[:css] == "tailwind"
323
+ GemfileEntry.version("tailwindcss-rails", ">= 0.4.3", "Use Tailwind CSS [https://github.com/rails/tailwindcss-rails]")
351
324
  else
352
- [ GemfileEntry.version("turbolinks", "~> 5",
353
- "Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks") ]
325
+ GemfileEntry.version("cssbundling-rails", ">= 0.1.0", "Bundle and process CSS [https://github.com/rails/cssbundling-rails]")
354
326
  end
355
327
  end
356
328
 
@@ -397,51 +369,43 @@ module Rails
397
369
  end
398
370
 
399
371
  def bundle_install?
400
- !(options[:skip_gemfile] || options[:skip_bundle] || options[:pretend])
401
- end
402
-
403
- def spring_install?
404
- !options[:skip_spring] && !options.dev? && Process.respond_to?(:fork) && !RUBY_PLATFORM.include?("cygwin")
405
- end
406
-
407
- def webpack_install?
408
- !(options[:skip_javascript] || options[:skip_webpack_install])
372
+ !(options[:skip_bundle] || options[:pretend])
409
373
  end
410
374
 
411
375
  def depends_on_system_test?
412
376
  !(options[:skip_system_test] || options[:skip_test] || options[:api])
413
377
  end
414
378
 
415
- def depend_on_listen?
416
- !options[:skip_listen] && os_supports_listen_out_of_the_box?
417
- end
418
-
419
379
  def depend_on_bootsnap?
420
380
  !options[:skip_bootsnap] && !options[:dev] && !defined?(JRUBY_VERSION)
421
381
  end
422
382
 
423
- def os_supports_listen_out_of_the_box?
424
- /darwin|linux/.match?(RbConfig::CONFIG["host_os"])
425
- end
426
-
427
383
  def run_bundle
428
384
  bundle_command("install", "BUNDLE_IGNORE_MESSAGES" => "1") if bundle_install?
429
385
  end
430
386
 
431
- def run_webpack
432
- return unless webpack_install?
387
+ def run_javascript
388
+ return if options[:skip_javascript] || !bundle_install?
433
389
 
434
- unless bundle_install?
435
- say <<~EXPLAIN
436
- Skipping `rails webpacker:install` because `bundle install` was skipped.
437
- To complete setup, you must run `bundle install` followed by `rails webpacker:install`.
438
- EXPLAIN
439
- return
390
+ case options[:javascript]
391
+ when "importmap" then rails_command "importmap:install"
392
+ when "webpack", "esbuild", "rollup" then rails_command "javascript:install:#{options[:javascript]}"
440
393
  end
394
+ end
441
395
 
442
- rails_command "webpacker:install"
443
- if options[:webpack] && options[:webpack] != "webpack"
444
- rails_command "webpacker:install:#{options[:webpack]}"
396
+ def run_hotwire
397
+ return if options[:skip_javascript] || options[:skip_hotwire] || !bundle_install?
398
+
399
+ rails_command "turbo:install stimulus:install"
400
+ end
401
+
402
+ def run_css
403
+ return if !options[:css] || !bundle_install?
404
+
405
+ if !using_node? && options[:css] == "tailwind"
406
+ rails_command "tailwindcss:install"
407
+ else
408
+ rails_command "css:install:#{options[:css]}"
445
409
  end
446
410
  end
447
411
 
@@ -7,7 +7,7 @@ module Rails
7
7
 
8
8
  private
9
9
  def app_name
10
- @app_name ||= original_app_name.tr('\\', "").tr("-. ", "_")
10
+ @app_name ||= original_app_name.tr("\\", "").tr("-. ", "_")
11
11
  end
12
12
 
13
13
  def original_app_name
@@ -206,7 +206,7 @@ module Rails
206
206
  end
207
207
 
208
208
  # Make class option aware of Rails::Generators.options and Rails::Generators.aliases.
209
- def self.class_option(name, options = {}) #:nodoc:
209
+ def self.class_option(name, options = {}) # :nodoc:
210
210
  options[:desc] = "Indicates when to generate #{name.to_s.humanize.downcase}" unless options.key?(:desc)
211
211
  options[:aliases] = default_aliases_for_option(name, options)
212
212
  options[:default] = default_value_for_option(name, options)
@@ -231,7 +231,7 @@ module Rails
231
231
 
232
232
  # Cache source root and add lib/generators/base/generator/templates to
233
233
  # source paths.
234
- def self.inherited(base) #:nodoc:
234
+ def self.inherited(base) # :nodoc:
235
235
  super
236
236
 
237
237
  # Invoke source_root so the default_source_root is set.
@@ -324,21 +324,17 @@ module Rails
324
324
 
325
325
  # Sets the base_name taking into account the current class namespace.
326
326
  def self.base_name # :doc:
327
- @base_name ||= begin
328
- if base = name.to_s.split("::").first
329
- base.underscore
330
- end
327
+ @base_name ||= if base = name.to_s.split("::").first
328
+ base.underscore
331
329
  end
332
330
  end
333
331
 
334
332
  # Removes the namespaces and get the generator name. For example,
335
333
  # Rails::Generators::ModelGenerator will return "model" as generator name.
336
334
  def self.generator_name # :doc:
337
- @generator_name ||= begin
338
- if generator = name.to_s.split("::").last
339
- generator.delete_suffix!("Generator")
340
- generator.underscore
341
- end
335
+ @generator_name ||= if generator = name.to_s.split("::").last
336
+ generator.delete_suffix!("Generator")
337
+ generator.underscore
342
338
  end
343
339
  end
344
340
 
@@ -368,13 +364,13 @@ module Rails
368
364
  end
369
365
 
370
366
  # Keep hooks configuration that are used on prepare_for_invocation.
371
- def self.hooks #:nodoc:
367
+ def self.hooks # :nodoc:
372
368
  @hooks ||= from_superclass(:hooks, {})
373
369
  end
374
370
 
375
371
  # Prepare class invocation to search on Rails namespace if a previous
376
372
  # added hook is being used.
377
- def self.prepare_for_invocation(name, value) #:nodoc:
373
+ def self.prepare_for_invocation(name, value) # :nodoc:
378
374
  return super unless value.is_a?(String) || value.is_a?(Symbol)
379
375
 
380
376
  if value && constants = hooks[name]