railties 7.0.10 → 7.1.0.beta1

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 (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +565 -234
  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 +1 -1
  9. data/lib/rails/application/bootstrap.rb +12 -3
  10. data/lib/rails/application/configuration.rb +179 -67
  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 +40 -33
  14. data/lib/rails/application.rb +116 -31
  15. data/lib/rails/backtrace_cleaner.rb +1 -1
  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 +19 -38
  52. data/lib/rails/commands/server/server_command.rb +32 -31
  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 +5 -0
  61. data/lib/rails/engine.rb +36 -16
  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 +14 -28
  65. data/lib/rails/generators/app_base.rb +353 -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 +19 -1
  69. data/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt +1 -1
  70. data/lib/rails/generators/generated_attribute.rb +2 -1
  71. data/lib/rails/generators/migration.rb +1 -2
  72. data/lib/rails/generators/model_helpers.rb +2 -1
  73. data/lib/rails/generators/rails/app/USAGE +15 -6
  74. data/lib/rails/generators/rails/app/app_generator.rb +84 -60
  75. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +107 -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 +4 -17
  80. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +3 -3
  81. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +0 -2
  82. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +3 -3
  83. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +59 -0
  84. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +10 -2
  85. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +28 -24
  86. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +11 -7
  87. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +2 -0
  88. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +2 -2
  89. data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +1 -1
  90. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +223 -0
  91. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -9
  92. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +11 -13
  93. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +10 -19
  94. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -0
  95. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +6 -4
  96. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +10 -0
  97. data/lib/rails/generators/rails/app/templates/dockerignore.tt +43 -0
  98. data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -9
  99. data/lib/rails/generators/rails/app/templates/node-version.tt +1 -0
  100. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +10 -8
  101. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -7
  102. data/lib/rails/generators/rails/application_record/application_record_generator.rb +4 -0
  103. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +2 -1
  104. data/lib/rails/generators/rails/controller/USAGE +12 -4
  105. data/lib/rails/generators/rails/controller/controller_generator.rb +5 -0
  106. data/lib/rails/generators/rails/controller/templates/controller.rb.tt +1 -1
  107. data/lib/rails/generators/rails/credentials/credentials_generator.rb +29 -24
  108. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +8 -0
  109. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -2
  110. data/lib/rails/generators/rails/migration/USAGE +21 -11
  111. data/lib/rails/generators/rails/model/model_generator.rb +4 -0
  112. data/lib/rails/generators/rails/plugin/USAGE +17 -6
  113. data/lib/rails/generators/rails/plugin/plugin_generator.rb +5 -15
  114. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +2 -2
  115. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +1 -1
  116. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -17
  117. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -2
  118. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +4 -4
  119. data/lib/rails/generators/rails/resource/resource_generator.rb +6 -0
  120. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -1
  121. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +1 -1
  122. data/lib/rails/generators/test_case.rb +2 -2
  123. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +1 -1
  124. data/lib/rails/generators/testing/{behaviour.rb → behavior.rb} +4 -1
  125. data/lib/rails/generators.rb +6 -14
  126. data/lib/rails/health_controller.rb +55 -0
  127. data/lib/rails/info.rb +1 -1
  128. data/lib/rails/info_controller.rb +31 -11
  129. data/lib/rails/mailers_controller.rb +15 -5
  130. data/lib/rails/rack/logger.rb +15 -12
  131. data/lib/rails/rackup/server.rb +15 -0
  132. data/lib/rails/railtie/configuration.rb +14 -1
  133. data/lib/rails/railtie.rb +18 -18
  134. data/lib/rails/ruby_version_check.rb +2 -0
  135. data/lib/rails/source_annotation_extractor.rb +67 -18
  136. data/lib/rails/tasks/engine.rake +8 -8
  137. data/lib/rails/tasks/framework.rake +4 -10
  138. data/lib/rails/tasks/log.rake +1 -1
  139. data/lib/rails/tasks/misc.rake +3 -14
  140. data/lib/rails/tasks/statistics.rake +5 -4
  141. data/lib/rails/tasks/tmp.rake +5 -5
  142. data/lib/rails/tasks/zeitwerk.rake +1 -1
  143. data/lib/rails/tasks.rb +0 -2
  144. data/lib/rails/templates/rails/mailers/email.html.erb +25 -0
  145. data/lib/rails/templates/rails/mailers/index.html.erb +14 -7
  146. data/lib/rails/templates/rails/mailers/mailer.html.erb +11 -5
  147. data/lib/rails/templates/rails/welcome/index.html.erb +1 -0
  148. data/lib/rails/test_help.rb +7 -7
  149. data/lib/rails/test_unit/line_filtering.rb +1 -1
  150. data/lib/rails/test_unit/reporter.rb +6 -2
  151. data/lib/rails/test_unit/runner.rb +36 -18
  152. data/lib/rails/test_unit/test_parser.rb +88 -0
  153. data/lib/rails/test_unit/testing.rake +13 -33
  154. data/lib/rails/version.rb +1 -1
  155. data/lib/rails.rb +15 -15
  156. metadata +69 -31
  157. data/RDOC_MAIN.rdoc +0 -97
  158. data/lib/rails/application/dummy_erb_compiler.rb +0 -18
  159. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +0 -143
  160. data/lib/rails/generators/rails/model/USAGE +0 -113
  161. data/lib/rails/tasks/middleware.rake +0 -9
  162. 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,6 +14,7 @@ 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
19
  when "sqlite3" then ["sqlite3", ["~> 1.4"]]
19
20
  when "oracle" then ["activerecord-oracle_enhanced-adapter", nil]
@@ -38,6 +39,23 @@ module Rails
38
39
  end
39
40
  end
40
41
 
42
+ def build_package_for_database(database = options[:database])
43
+ case database
44
+ when "mysql" then "default-libmysqlclient-dev"
45
+ when "postgresql" then "libpq-dev"
46
+ else nil
47
+ end
48
+ end
49
+
50
+ def deploy_package_for_database(database = options[:database])
51
+ case database
52
+ when "mysql" then "default-mysql-client"
53
+ when "postgresql" then "postgresql-client"
54
+ when "sqlite3" then "libsqlite3-0"
55
+ else nil
56
+ end
57
+ end
58
+
41
59
  private
42
60
  def mysql_socket
43
61
  @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>
@@ -62,7 +62,6 @@ module Rails
62
62
 
63
63
  def valid_type?(type)
64
64
  DEFAULT_TYPES.include?(type.to_s) ||
65
- !defined?(ActiveRecord::Base) ||
66
65
  ActiveRecord::Base.connection.valid_type?(type)
67
66
  end
68
67
 
@@ -79,6 +78,8 @@ module Rails
79
78
  # when declaring options curly brackets should be used
80
79
  def parse_type_and_options(type)
81
80
  case type
81
+ when /(text|binary)\{([a-z]+)\}/
82
+ return $1, size: $2.to_sym
82
83
  when /(string|text|binary|integer)\{(\d+)\}/
83
84
  return $1, limit: $2.to_i
84
85
  when /decimal\{(\d+)[,.-](\d+)\}/
@@ -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,24 @@
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
+ Examples:
13
+ `rails new ~/Code/Ruby/weblog`
14
14
 
15
- This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
15
+ This generates a new Rails app in ~/Code/Ruby/weblog.
16
+
17
+ `rails new weblog --api`
18
+
19
+ This generates a new Rails app in API mode in ./weblog.
20
+
21
+ `rails new weblog --skip-action-mailer`
22
+
23
+ This generates a new Rails app without Action Mailer in ./weblog.
24
+ 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
 
@@ -182,7 +191,15 @@ module Rails
182
191
  return if options[:pretend] || options[:dummy_app]
183
192
 
184
193
  require "rails/generators/rails/credentials/credentials_generator"
185
- Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently
194
+ Rails::Generators::CredentialsGenerator.new([], quiet: true).add_credentials_file
195
+ end
196
+
197
+ def credentials_diff_enroll
198
+ return if options[:skip_decrypted_diffs] || options[:dummy_app] || options[:pretend]
199
+
200
+ @generator.shell.mute do
201
+ rails_command "credentials:diff --enroll", inline: true, shell: @generator.shell
202
+ end
186
203
  end
187
204
 
188
205
  def database_yml
@@ -193,14 +210,6 @@ module Rails
193
210
  directory "db"
194
211
  end
195
212
 
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
213
  def lib
205
214
  empty_directory "lib"
206
215
  empty_directory_with_keep_file "lib/tasks"
@@ -252,11 +261,6 @@ module Rails
252
261
  def config_target_version
253
262
  defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
254
263
  end
255
-
256
- private
257
- def user_default_branch
258
- @user_default_branch ||= `git config init.defaultbranch`
259
- end
260
264
  end
261
265
 
262
266
  module Generators
@@ -273,42 +277,59 @@ module Rails
273
277
  class_option :version, type: :boolean, aliases: "-v", group: :rails, desc: "Show Rails version number and quit"
274
278
  class_option :api, type: :boolean, desc: "Preconfigure smaller stack for API only apps"
275
279
  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"
280
+ class_option :javascript, type: :string, aliases: ["-j", "--js"], default: "importmap", desc: "Choose JavaScript approach [options: importmap (default), bun, webpack, esbuild, rollup]"
281
+ 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"
282
+ class_option :skip_bundle, type: :boolean, aliases: "-B", default: nil, desc: "Don't run bundle install"
283
+ class_option :skip_decrypted_diffs, type: :boolean, default: nil, desc: "Don't configure git to show decrypted diffs of encrypted credentials"
284
+
285
+ OPTION_IMPLICATIONS = # :nodoc:
286
+ AppBase::OPTION_IMPLICATIONS.merge(
287
+ skip_git: [:skip_decrypted_diffs],
288
+ minimal: [
289
+ :skip_action_cable,
290
+ :skip_action_mailbox,
291
+ :skip_action_mailer,
292
+ :skip_action_text,
293
+ :skip_active_job,
294
+ :skip_active_storage,
295
+ :skip_bootsnap,
296
+ :skip_dev_gems,
297
+ :skip_hotwire,
298
+ :skip_javascript,
299
+ :skip_jbuilder,
300
+ :skip_system_test,
301
+ ],
302
+ api: [
303
+ :skip_asset_pipeline,
304
+ :skip_javascript,
305
+ ],
306
+ ) do |option, implications, more_implications|
307
+ implications + more_implications
308
+ end
309
+
310
+ META_OPTIONS = [:minimal] # :nodoc:
311
+
312
+ def self.apply_rails_template(template, destination) # :nodoc:
313
+ generator = new([destination], { template: template }, { destination_root: destination })
314
+ generator.set_default_accessors!
315
+ generator.apply_rails_template
316
+ generator.run_bundle
317
+ generator.run_after_bundle_callbacks
318
+ end
279
319
 
280
320
  def initialize(*args)
281
321
  super
282
322
 
323
+ imply_options(OPTION_IMPLICATIONS, meta_options: META_OPTIONS)
324
+
283
325
  if !options[:skip_active_record] && !DATABASES.include?(options[:database])
284
326
  raise Error, "Invalid value for --database option. Supported preconfigurations are: #{DATABASES.join(", ")}."
285
327
  end
286
328
 
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
329
  @after_bundle_callbacks = []
310
330
  end
311
331
 
332
+ public_task :report_implied_options
312
333
  public_task :set_default_accessors!
313
334
  public_task :create_root
314
335
  public_task :target_rails_prerelease
@@ -316,6 +337,7 @@ module Rails
316
337
  def create_root_files
317
338
  build(:readme)
318
339
  build(:rakefile)
340
+ build(:node_version) if using_node?
319
341
  build(:ruby_version)
320
342
  build(:configru)
321
343
 
@@ -341,11 +363,6 @@ module Rails
341
363
  end
342
364
  remove_task :update_bin_files
343
365
 
344
- def update_db_schema
345
- build(:db_when_updating)
346
- end
347
- remove_task :update_db_schema
348
-
349
366
  def update_active_storage
350
367
  unless skip_active_storage?
351
368
  rails_command "active_storage:update", inline: true
@@ -353,6 +370,11 @@ module Rails
353
370
  end
354
371
  remove_task :update_active_storage
355
372
 
373
+ def create_dockerfiles
374
+ return if options[:skip_docker] || options[:dummy_app]
375
+ build(:dockerfiles)
376
+ end
377
+
356
378
  def create_config_files
357
379
  build(:config)
358
380
  end
@@ -368,6 +390,7 @@ module Rails
368
390
 
369
391
  def create_credentials
370
392
  build(:credentials)
393
+ build(:credentials_diff_enroll)
371
394
  end
372
395
 
373
396
  def display_upgrade_guide_info
@@ -418,7 +441,7 @@ module Rails
418
441
  end
419
442
 
420
443
  def create_storage_files
421
- build(:storage) unless skip_active_storage?
444
+ build(:storage)
422
445
  end
423
446
 
424
447
  def delete_app_assets_if_api_option
@@ -438,7 +461,7 @@ module Rails
438
461
 
439
462
  def delete_app_views_if_api_option
440
463
  if options[:api]
441
- if skip_action_mailer?
464
+ if options[:skip_action_mailer]
442
465
  remove_dir "app/views"
443
466
  else
444
467
  remove_file "app/views/layouts/application.html.erb"
@@ -483,7 +506,7 @@ module Rails
483
506
  end
484
507
 
485
508
  def delete_action_mailer_files_skipping_action_mailer
486
- if skip_action_mailer?
509
+ if options[:skip_action_mailer]
487
510
  remove_file "app/views/layouts/mailer.html.erb"
488
511
  remove_file "app/views/layouts/mailer.text.erb"
489
512
  remove_dir "app/mailers"
@@ -514,7 +537,7 @@ module Rails
514
537
 
515
538
  def delete_new_framework_defaults
516
539
  unless options[:update]
517
- remove_file "config/initializers/new_framework_defaults_7_0.rb"
540
+ remove_file "config/initializers/new_framework_defaults_#{Rails::VERSION::MAJOR}_#{Rails::VERSION::MINOR}.rb"
518
541
  end
519
542
  end
520
543
 
@@ -522,7 +545,8 @@ module Rails
522
545
  build(:leftovers)
523
546
  end
524
547
 
525
- public_task :apply_rails_template, :run_bundle
548
+ public_task :apply_rails_template
549
+ public_task :run_bundle
526
550
  public_task :generate_bundler_binstub
527
551
  public_task :run_javascript
528
552
  public_task :run_hotwire
@@ -0,0 +1,107 @@
1
+ # syntax = docker/dockerfile:1
2
+
3
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
4
+ ARG RUBY_VERSION=<%= Gem.ruby_version %>
5
+ FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
6
+
7
+ # Rails app lives here
8
+ WORKDIR /rails
9
+
10
+ # Set production environment
11
+ ENV RAILS_ENV="production" \
12
+ BUNDLE_DEPLOYMENT="1" \
13
+ BUNDLE_PATH="/usr/local/bundle" \
14
+ BUNDLE_WITHOUT="development"
15
+
16
+
17
+ # Throw-away build stage to reduce size of final image
18
+ FROM base as build
19
+
20
+ # Install packages needed to build gems<%= using_node? ? " and node modules" : "" %>
21
+ RUN apt-get update -qq && \
22
+ apt-get install --no-install-recommends -y <%= dockerfile_build_packages.join(" ") %>
23
+
24
+ <% if using_node? -%>
25
+ # Install JavaScript dependencies
26
+ ARG NODE_VERSION=<%= node_version %>
27
+ ARG YARN_VERSION=<%= dockerfile_yarn_version %>
28
+ ENV PATH=/usr/local/node/bin:$PATH
29
+ RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
30
+ /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
31
+ npm install -g yarn@$YARN_VERSION && \
32
+ rm -rf /tmp/node-build-master
33
+
34
+ <% end -%>
35
+
36
+ <% if using_bun? -%>
37
+ ENV BUN_INSTALL=/usr/local/bun
38
+ ENV PATH=/usr/local/bun/bin:$PATH
39
+ ARG BUN_VERSION=<%= dockerfile_bun_version %>
40
+ RUN curl -fsSL https://bun.sh/install | bash -s -- "${BUN_VERSION}"
41
+
42
+ <% end -%>
43
+
44
+ # Install application gems
45
+ COPY Gemfile Gemfile.lock ./
46
+ RUN bundle install && \
47
+ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git<% if depend_on_bootsnap? -%> && \
48
+ bundle exec bootsnap precompile --gemfile
49
+ <% end %>
50
+
51
+ <% if using_node? -%>
52
+ # Install node modules
53
+ COPY package.json yarn.lock ./
54
+ RUN yarn install --frozen-lockfile
55
+
56
+ <% end -%>
57
+
58
+ <% if using_bun? -%>
59
+ # Install node modules
60
+ COPY package.json bun.lockb ./
61
+ RUN bun install --frozen-lockfile
62
+
63
+ <% end -%>
64
+ # Copy application code
65
+ COPY . .
66
+
67
+ <% if depend_on_bootsnap? -%>
68
+ # Precompile bootsnap code for faster boot times
69
+ RUN bundle exec bootsnap precompile app/ lib/
70
+
71
+ <% end -%>
72
+ <% unless dockerfile_binfile_fixups.empty? -%>
73
+ # Adjust binfiles to be executable on Linux
74
+ <%= "RUN " + dockerfile_binfile_fixups.join(" && \\\n ") %>
75
+
76
+ <% end -%>
77
+ <% unless options.api? || skip_asset_pipeline? -%>
78
+ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
79
+ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
80
+
81
+ <% end -%>
82
+
83
+ # Final stage for app image
84
+ FROM base
85
+
86
+ <% unless dockerfile_deploy_packages.empty? -%>
87
+ # Install packages needed for deployment
88
+ RUN apt-get update -qq && \
89
+ apt-get install --no-install-recommends -y <%= dockerfile_deploy_packages.join(" ") %> && \
90
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
91
+
92
+ <% end -%>
93
+ # Copy built artifacts: gems, application
94
+ COPY --from=build /usr/local/bundle /usr/local/bundle
95
+ COPY --from=build /rails /rails
96
+
97
+ # Run and own only the runtime files as a non-root user for security
98
+ RUN useradd rails --create-home --shell /bin/bash && \
99
+ chown -R rails:rails <%= dockerfile_chown_directories.join(" ") %>
100
+ USER rails:rails
101
+
102
+ # Entrypoint prepares the database.
103
+ ENTRYPOINT ["/rails/bin/docker-entrypoint"]
104
+
105
+ # Start the server by default, this can be overwritten at runtime
106
+ EXPOSE 3000
107
+ CMD ["./bin/rails", "server"]