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
@@ -7,26 +7,15 @@ 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.parameterize(preserve_case: true).underscore
11
11
  end
12
12
 
13
13
  def original_app_name
14
- @original_app_name ||= defined_app_const_base? ? defined_app_name : File.basename(destination_root)
14
+ @original_app_name ||= (options[:name] || File.basename(destination_root))
15
15
  end
16
16
 
17
- def defined_app_name
18
- defined_app_const_base.underscore
19
- end
20
-
21
- def defined_app_const_base
22
- Rails.respond_to?(:application) && defined?(Rails::Application) &&
23
- Rails.application.is_a?(Rails::Application) && Rails.application.class.name.chomp("::Application")
24
- end
25
-
26
- alias :defined_app_const_base? :defined_app_const_base
27
-
28
17
  def app_const_base
29
- @app_const_base ||= defined_app_const_base || app_name.gsub(/\W/, "_").squeeze("_").camelize
18
+ @app_const_base ||= app_name.gsub(/\W/, "_").squeeze("_").camelize
30
19
  end
31
20
  alias :camelized :app_const_base
32
21
 
@@ -79,15 +79,15 @@ module Rails
79
79
  #
80
80
  # For example, if the user invoke the controller generator as:
81
81
  #
82
- # bin/rails generate controller Account --test-framework=test_unit
82
+ # $ bin/rails generate controller Account --test-framework=test_unit
83
83
  #
84
84
  # The controller generator will then try to invoke the following generators:
85
85
  #
86
86
  # "rails:test_unit", "test_unit:controller", "test_unit"
87
87
  #
88
88
  # Notice that "rails:generators:test_unit" could be loaded as well, what
89
- # Rails looks for is the first and last parts of the namespace. This is what
90
- # allows any test framework to hook into Rails as long as it provides any
89
+ # \Rails looks for is the first and last parts of the namespace. This is what
90
+ # allows any test framework to hook into \Rails as long as it provides any
91
91
  # of the hooks above.
92
92
  #
93
93
  # ==== Options
@@ -134,11 +134,11 @@ module Rails
134
134
  # All hooks come with switches for user interface. If you do not want
135
135
  # to use any test framework, you can do:
136
136
  #
137
- # bin/rails generate controller Account --skip-test-framework
137
+ # $ bin/rails generate controller Account --skip-test-framework
138
138
  #
139
139
  # Or similarly:
140
140
  #
141
- # bin/rails generate controller Account --no-test-framework
141
+ # $ bin/rails generate controller Account --no-test-framework
142
142
  #
143
143
  # ==== Boolean hooks
144
144
  #
@@ -150,7 +150,7 @@ module Rails
150
150
  #
151
151
  # Then, if you want webrat to be invoked, just supply:
152
152
  #
153
- # bin/rails generate controller Account --webrat
153
+ # $ bin/rails generate controller Account --webrat
154
154
  #
155
155
  # The hooks lookup is similar as above:
156
156
  #
@@ -189,6 +189,13 @@ module Rails
189
189
  class_option(name, defaults.merge!(options))
190
190
  end
191
191
 
192
+ klass = self
193
+
194
+ singleton_class.define_method("#{name}_generator") do
195
+ value = class_options[name].default
196
+ Rails::Generators.find_by_namespace(klass.generator_name, value)
197
+ end
198
+
192
199
  hooks[name] = [ in_base, as_hook ]
193
200
  invoke_from_option(name, options, &block)
194
201
  end
@@ -201,6 +208,7 @@ module Rails
201
208
  remove_invocation(*names)
202
209
 
203
210
  names.each do |name|
211
+ singleton_class.undef_method("#{name}_generator")
204
212
  hooks.delete(name)
205
213
  end
206
214
  end
@@ -214,7 +222,7 @@ module Rails
214
222
  end
215
223
 
216
224
  # Returns the default source root for a given generator. This is used internally
217
- # by rails to set its generators source root. If you want to customize your source
225
+ # by \Rails to set its generators source root. If you want to customize your source
218
226
  # root, you should use source_root.
219
227
  def self.default_source_root
220
228
  return unless base_name && generator_name
@@ -317,9 +325,9 @@ module Rails
317
325
  @namespaced_path ||= namespace_dirs.join("/")
318
326
  end
319
327
 
320
- # Use Rails default banner.
328
+ # Use \Rails default banner.
321
329
  def self.banner # :doc:
322
- "rails generate #{namespace.delete_prefix("rails:")} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
330
+ "bin/rails generate #{namespace.delete_prefix("rails:")} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
323
331
  end
324
332
 
325
333
  # Sets the base_name taking into account the current class namespace.
@@ -4,7 +4,7 @@ module Rails
4
4
  module Generators
5
5
  module Database # :nodoc:
6
6
  JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
7
- DATABASES = %w( mysql postgresql sqlite3 oracle sqlserver ) + JDBC_DATABASES
7
+ DATABASES = %w( mysql trilogy postgresql sqlite3 oracle sqlserver ) + JDBC_DATABASES
8
8
 
9
9
  def initialize(*)
10
10
  super
@@ -14,8 +14,9 @@ module Rails
14
14
  def gem_for_database(database = options[:database])
15
15
  case database
16
16
  when "mysql" then ["mysql2", ["~> 0.5"]]
17
+ when "trilogy" then ["trilogy", ["~> 2.4"]]
17
18
  when "postgresql" then ["pg", ["~> 1.1"]]
18
- when "sqlite3" then ["sqlite3", ["~> 1.4"]]
19
+ when "sqlite3" then ["sqlite3", [">= 1.4"]]
19
20
  when "oracle" then ["activerecord-oracle_enhanced-adapter", nil]
20
21
  when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
21
22
  when "jdbcmysql" then ["activerecord-jdbcmysql-adapter", nil]
@@ -26,6 +27,26 @@ module Rails
26
27
  end
27
28
  end
28
29
 
30
+ def docker_for_database_build(database = options[:database])
31
+ case database
32
+ when "mysql" then "build-essential default-libmysqlclient-dev git"
33
+ when "trilogy" then "build-essential default-libmysqlclient-dev git"
34
+ when "postgresql" then "build-essential git libpq-dev"
35
+ when "sqlite3" then "build-essential git"
36
+ else nil
37
+ end
38
+ end
39
+
40
+ def docker_for_database_deploy(database = options[:database])
41
+ case database
42
+ when "mysql" then "curl default-mysql-client libvips"
43
+ when "trilogy" then "curl default-mysql-client libvips"
44
+ when "postgresql" then "curl libvips postgresql-client"
45
+ when "sqlite3" then "curl libsqlite3-0 libvips"
46
+ else nil
47
+ end
48
+ end
49
+
29
50
  def convert_database_option_for_jruby
30
51
  if defined?(JRUBY_VERSION)
31
52
  opt = options.dup
@@ -38,6 +59,23 @@ module Rails
38
59
  end
39
60
  end
40
61
 
62
+ def build_package_for_database(database = options[:database])
63
+ case database
64
+ when "mysql" then "default-libmysqlclient-dev"
65
+ when "postgresql" then "libpq-dev"
66
+ else nil
67
+ end
68
+ end
69
+
70
+ def deploy_package_for_database(database = options[:database])
71
+ case database
72
+ when "mysql" then "default-mysql-client"
73
+ when "postgresql" then "postgresql-client"
74
+ when "sqlite3" then "libsqlite3-0"
75
+ else nil
76
+ end
77
+ end
78
+
41
79
  private
42
80
  def mysql_socket
43
81
  @mysql_socket ||= [
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
5
  <style>
6
6
  /* Email styles need to be inline */
7
7
  </style>
@@ -43,6 +43,10 @@ module Rails
43
43
  type, attr_options = *parse_type_and_options(type)
44
44
  type = type.to_sym if type
45
45
 
46
+ if dangerous_name?(name)
47
+ raise Error, "Could not generate field '#{name}', as it is already defined by Active Record."
48
+ end
49
+
46
50
  if type && !valid_type?(type)
47
51
  raise Error, "Could not generate field '#{name}' with unknown type '#{type}'."
48
52
  end
@@ -60,8 +64,14 @@ module Rails
60
64
  new(name, type, index_type, attr_options)
61
65
  end
62
66
 
67
+ def dangerous_name?(name)
68
+ defined?(ActiveRecord::Base) &&
69
+ ActiveRecord::Base.dangerous_attribute_method?(name)
70
+ end
71
+
63
72
  def valid_type?(type)
64
73
  DEFAULT_TYPES.include?(type.to_s) ||
74
+ !defined?(ActiveRecord::Base) ||
65
75
  ActiveRecord::Base.connection.valid_type?(type)
66
76
  end
67
77
 
@@ -78,6 +88,8 @@ module Rails
78
88
  # when declaring options curly brackets should be used
79
89
  def parse_type_and_options(type)
80
90
  case type
91
+ when /(text|binary)\{([a-z]+)\}/
92
+ return $1, size: $2.to_sym
81
93
  when /(string|text|binary|integer)\{(\d+)\}/
82
94
  return $1, limit: $2.to_i
83
95
  when /decimal\{(\d+)[,.-](\d+)\}/
@@ -7,7 +7,7 @@ module Rails
7
7
  module Generators
8
8
  # Holds common methods for migrations. It assumes that migrations have the
9
9
  # [0-9]*_name format and can be used by other frameworks (like Sequel)
10
- # just by implementing the next migration version method.
10
+ # just by implementing the +next_migration_number+ method.
11
11
  module Migration
12
12
  extend ActiveSupport::Concern
13
13
  attr_reader :migration_number, :migration_file_name, :migration_class_name
@@ -46,10 +46,10 @@ module Rails
46
46
  end
47
47
 
48
48
  # Creates a migration template at the given destination. The difference
49
- # to the default template method is that the migration version is appended
49
+ # to the default template method is that the migration number is prepended
50
50
  # to the destination file name.
51
51
  #
52
- # The migration version, migration file name, migration class name are
52
+ # The migration number, migration file name, migration class name are
53
53
  # available as instance variables in the template to be rendered.
54
54
  #
55
55
  # migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
@@ -57,13 +57,12 @@ module Rails
57
57
  source = File.expand_path(find_in_source_paths(source.to_s))
58
58
 
59
59
  set_migration_assigns!(destination)
60
- context = instance_eval("binding")
61
60
 
62
61
  dir, base = File.split(destination)
63
62
  numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
64
63
 
65
64
  file = create_migration numbered_destination, nil, config do
66
- ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(context)
65
+ ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(binding)
67
66
  end
68
67
  Rails::Generators.add_generated_file(file)
69
68
  end
@@ -19,7 +19,8 @@ module Rails
19
19
  mattr_accessor :skip_warn
20
20
 
21
21
  def self.included(base) # :nodoc:
22
- base.class_option :force_plural, type: :boolean, default: false, desc: "Forces the use of the given model name"
22
+ base.class_option :force_plural, type: :boolean, default: false,
23
+ desc: "Do not singularize the model name, even if it appears plural"
23
24
  end
24
25
 
25
26
  def initialize(args, *_options)
@@ -1,15 +1,31 @@
1
1
  Description:
2
- The 'rails new' command creates a new Rails application with a default
2
+ The `rails new` command creates a new Rails application with a default
3
3
  directory structure and configuration at the path you specify.
4
4
 
5
5
  You can specify extra command-line arguments to be used every time
6
- 'rails new' runs in the .railsrc configuration file in your home directory,
6
+ `rails new` runs in the .railsrc configuration file in your home directory,
7
7
  or in $XDG_CONFIG_HOME/rails/railsrc if XDG_CONFIG_HOME is set.
8
8
 
9
9
  Note that the arguments specified in the .railsrc file don't affect the
10
- defaults values shown above in this help message.
10
+ default values shown above in this help message.
11
11
 
12
- Example:
13
- rails new ~/Code/Ruby/weblog
12
+ You can specify which version to use when creating a new rails application
13
+ using `rails _<version>_ new`.
14
14
 
15
- This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
15
+ Examples:
16
+ `rails new ~/Code/Ruby/weblog`
17
+
18
+ This generates a new Rails app in ~/Code/Ruby/weblog.
19
+
20
+ `rails _<version>_ new weblog`
21
+
22
+ This generates a new Rails app with the provided version in ./weblog.
23
+
24
+ `rails new weblog --api`
25
+
26
+ This generates a new Rails app in API mode in ./weblog.
27
+
28
+ `rails new weblog --skip-action-mailer`
29
+
30
+ This generates a new Rails app without Action Mailer in ./weblog.
31
+ Any part of Rails can be skipped during app generation.
@@ -21,8 +21,8 @@ module Rails
21
21
  RUBY
22
22
  end
23
23
 
24
- def method_missing(meth, *args, &block)
25
- @generator.send(meth, *args, &block)
24
+ def method_missing(...)
25
+ @generator.send(...)
26
26
  end
27
27
  end
28
28
 
@@ -54,6 +54,10 @@ module Rails
54
54
  template "ruby-version", ".ruby-version"
55
55
  end
56
56
 
57
+ def node_version
58
+ template "node-version", ".node-version"
59
+ end
60
+
57
61
  def gemfile
58
62
  template "Gemfile"
59
63
  end
@@ -70,12 +74,17 @@ module Rails
70
74
  template "gitattributes", ".gitattributes"
71
75
  end
72
76
 
77
+ def dockerfiles
78
+ template "Dockerfile"
79
+ template "dockerignore", ".dockerignore"
80
+
81
+ template "docker-entrypoint", "bin/docker-entrypoint"
82
+ chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
83
+ end
84
+
73
85
  def version_control
74
86
  if !options[:skip_git] && !options[:pretend]
75
- run "git init", capture: options[:quiet], abort_on_failure: false
76
- if user_default_branch.strip.empty?
77
- `git symbolic-ref HEAD refs/heads/main`
78
- end
87
+ run git_init_command, capture: options[:quiet], abort_on_failure: false
79
88
  end
80
89
  end
81
90
 
@@ -103,16 +112,16 @@ module Rails
103
112
  empty_directory "config"
104
113
 
105
114
  inside "config" do
106
- template "routes.rb" unless options[:updating]
115
+ template "routes.rb" unless options[:update]
107
116
  template "application.rb"
108
117
  template "environment.rb"
109
- template "cable.yml" unless options[:updating] || options[:skip_action_cable]
110
- template "puma.rb" unless options[:updating]
111
- template "storage.yml" unless options[:updating] || skip_active_storage?
118
+ template "cable.yml" unless options[:update] || options[:skip_action_cable]
119
+ template "puma.rb" unless options[:update]
120
+ template "storage.yml" unless options[:update] || skip_active_storage?
112
121
 
113
122
  directory "environments"
114
123
  directory "initializers"
115
- directory "locales" unless options[:updating]
124
+ directory "locales" unless options[:update]
116
125
  end
117
126
  end
118
127
 
@@ -163,10 +172,6 @@ module Rails
163
172
  remove_file "config/initializers/permissions_policy.rb"
164
173
  end
165
174
  end
166
-
167
- if !skip_sprockets?
168
- insert_into_file "config/application.rb", %(require "sprockets/railtie"), after: /require\(["']rails\/all["']\)\n/
169
- end
170
175
  end
171
176
 
172
177
  def master_key
@@ -182,7 +187,15 @@ module Rails
182
187
  return if options[:pretend] || options[:dummy_app]
183
188
 
184
189
  require "rails/generators/rails/credentials/credentials_generator"
185
- Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently
190
+ Rails::Generators::CredentialsGenerator.new([], quiet: true).add_credentials_file
191
+ end
192
+
193
+ def credentials_diff_enroll
194
+ return if options[:skip_decrypted_diffs] || options[:dummy_app] || options[:pretend]
195
+
196
+ @generator.shell.mute do
197
+ rails_command "credentials:diff --enroll", inline: true, shell: @generator.shell
198
+ end
186
199
  end
187
200
 
188
201
  def database_yml
@@ -193,14 +206,6 @@ module Rails
193
206
  directory "db"
194
207
  end
195
208
 
196
- def db_when_updating
197
- path = File.expand_path("db/schema.rb", destination_root)
198
-
199
- if File.exist?(path)
200
- gsub_file("db/schema.rb", /ActiveRecord::Schema\.define/, "ActiveRecord::Schema[6.1].define")
201
- end
202
- end
203
-
204
209
  def lib
205
210
  empty_directory "lib"
206
211
  empty_directory_with_keep_file "lib/tasks"
@@ -252,11 +257,6 @@ module Rails
252
257
  def config_target_version
253
258
  defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
254
259
  end
255
-
256
- private
257
- def user_default_branch
258
- @user_default_branch ||= `git config init.defaultbranch`
259
- end
260
260
  end
261
261
 
262
262
  module Generators
@@ -273,42 +273,59 @@ module Rails
273
273
  class_option :version, type: :boolean, aliases: "-v", group: :rails, desc: "Show Rails version number and quit"
274
274
  class_option :api, type: :boolean, desc: "Preconfigure smaller stack for API only apps"
275
275
  class_option :minimal, type: :boolean, desc: "Preconfigure a minimal rails app"
276
- class_option :javascript, type: :string, aliases: "-j", default: "importmap", desc: "Choose JavaScript approach [options: importmap (default), webpack, esbuild, rollup]"
277
- class_option :css, type: :string, aliases: "-c", desc: "Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass] check https://github.com/rails/cssbundling-rails"
278
- class_option :skip_bundle, type: :boolean, aliases: "-B", default: false, desc: "Don't run bundle install"
276
+ class_option :javascript, type: :string, aliases: ["-j", "--js"], default: "importmap", desc: "Choose JavaScript approach [options: importmap (default), bun, webpack, esbuild, rollup]"
277
+ class_option :css, type: :string, aliases: "-c", desc: "Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass] check https://github.com/rails/cssbundling-rails for more options"
278
+ class_option :skip_bundle, type: :boolean, aliases: "-B", default: nil, desc: "Don't run bundle install"
279
+ class_option :skip_decrypted_diffs, type: :boolean, default: nil, desc: "Don't configure git to show decrypted diffs of encrypted credentials"
280
+
281
+ OPTION_IMPLICATIONS = # :nodoc:
282
+ AppBase::OPTION_IMPLICATIONS.merge(
283
+ skip_git: [:skip_decrypted_diffs],
284
+ minimal: [
285
+ :skip_action_cable,
286
+ :skip_action_mailbox,
287
+ :skip_action_mailer,
288
+ :skip_action_text,
289
+ :skip_active_job,
290
+ :skip_active_storage,
291
+ :skip_bootsnap,
292
+ :skip_dev_gems,
293
+ :skip_hotwire,
294
+ :skip_javascript,
295
+ :skip_jbuilder,
296
+ :skip_system_test,
297
+ ],
298
+ api: [
299
+ :skip_asset_pipeline,
300
+ :skip_javascript,
301
+ ],
302
+ ) do |option, implications, more_implications|
303
+ implications + more_implications
304
+ end
305
+
306
+ META_OPTIONS = [:minimal] # :nodoc:
307
+
308
+ def self.apply_rails_template(template, destination) # :nodoc:
309
+ generator = new([destination], { template: template }, { destination_root: destination })
310
+ generator.set_default_accessors!
311
+ generator.apply_rails_template
312
+ generator.run_bundle
313
+ generator.run_after_bundle_callbacks
314
+ end
279
315
 
280
316
  def initialize(*args)
281
317
  super
282
318
 
319
+ imply_options(OPTION_IMPLICATIONS, meta_options: META_OPTIONS)
320
+
283
321
  if !options[:skip_active_record] && !DATABASES.include?(options[:database])
284
322
  raise Error, "Invalid value for --database option. Supported preconfigurations are: #{DATABASES.join(", ")}."
285
323
  end
286
324
 
287
- # Force sprockets and JavaScript to be skipped when generating API only apps.
288
- # Can't modify options hash as it's frozen by default.
289
- if options[:api]
290
- self.options = options.merge(skip_asset_pipeline: true, skip_javascript: true).freeze
291
- end
292
-
293
- if options[:minimal]
294
- self.options = options.merge(
295
- skip_action_cable: true,
296
- skip_action_mailer: true,
297
- skip_action_mailbox: true,
298
- skip_action_text: true,
299
- skip_active_job: true,
300
- skip_active_storage: true,
301
- skip_bootsnap: true,
302
- skip_dev_gems: true,
303
- skip_javascript: true,
304
- skip_jbuilder: true,
305
- skip_system_test: true,
306
- skip_hotwire: true).freeze
307
- end
308
-
309
325
  @after_bundle_callbacks = []
310
326
  end
311
327
 
328
+ public_task :report_implied_options
312
329
  public_task :set_default_accessors!
313
330
  public_task :create_root
314
331
  public_task :target_rails_prerelease
@@ -316,6 +333,7 @@ module Rails
316
333
  def create_root_files
317
334
  build(:readme)
318
335
  build(:rakefile)
336
+ build(:node_version) if using_node?
319
337
  build(:ruby_version)
320
338
  build(:configru)
321
339
 
@@ -341,11 +359,6 @@ module Rails
341
359
  end
342
360
  remove_task :update_bin_files
343
361
 
344
- def update_db_schema
345
- build(:db_when_updating)
346
- end
347
- remove_task :update_db_schema
348
-
349
362
  def update_active_storage
350
363
  unless skip_active_storage?
351
364
  rails_command "active_storage:update", inline: true
@@ -353,6 +366,11 @@ module Rails
353
366
  end
354
367
  remove_task :update_active_storage
355
368
 
369
+ def create_dockerfiles
370
+ return if options[:skip_docker] || options[:dummy_app]
371
+ build(:dockerfiles)
372
+ end
373
+
356
374
  def create_config_files
357
375
  build(:config)
358
376
  end
@@ -368,6 +386,7 @@ module Rails
368
386
 
369
387
  def create_credentials
370
388
  build(:credentials)
389
+ build(:credentials_diff_enroll)
371
390
  end
372
391
 
373
392
  def display_upgrade_guide_info
@@ -418,7 +437,7 @@ module Rails
418
437
  end
419
438
 
420
439
  def create_storage_files
421
- build(:storage) unless skip_active_storage?
440
+ build(:storage)
422
441
  end
423
442
 
424
443
  def delete_app_assets_if_api_option
@@ -438,7 +457,7 @@ module Rails
438
457
 
439
458
  def delete_app_views_if_api_option
440
459
  if options[:api]
441
- if skip_action_mailer?
460
+ if options[:skip_action_mailer]
442
461
  remove_dir "app/views"
443
462
  else
444
463
  remove_file "app/views/layouts/application.html.erb"
@@ -483,7 +502,7 @@ module Rails
483
502
  end
484
503
 
485
504
  def delete_action_mailer_files_skipping_action_mailer
486
- if skip_action_mailer?
505
+ if options[:skip_action_mailer]
487
506
  remove_file "app/views/layouts/mailer.html.erb"
488
507
  remove_file "app/views/layouts/mailer.text.erb"
489
508
  remove_dir "app/mailers"
@@ -514,7 +533,7 @@ module Rails
514
533
 
515
534
  def delete_new_framework_defaults
516
535
  unless options[:update]
517
- remove_file "config/initializers/new_framework_defaults_7_0.rb"
536
+ remove_file "config/initializers/new_framework_defaults_#{Rails::VERSION::MAJOR}_#{Rails::VERSION::MINOR}.rb"
518
537
  end
519
538
  end
520
539
 
@@ -522,7 +541,9 @@ module Rails
522
541
  build(:leftovers)
523
542
  end
524
543
 
525
- public_task :apply_rails_template, :run_bundle
544
+ public_task :apply_rails_template
545
+ public_task :run_bundle
546
+ public_task :add_bundler_platforms
526
547
  public_task :generate_bundler_binstub
527
548
  public_task :run_javascript
528
549
  public_task :run_hotwire