railties 5.2.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +293 -89
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +39 -33
  5. data/README.rdoc +3 -3
  6. data/lib/minitest/rails_plugin.rb +24 -13
  7. data/lib/rails/all.rb +4 -0
  8. data/lib/rails/api/generator.rb +2 -1
  9. data/lib/rails/api/task.rb +17 -0
  10. data/lib/rails/app_loader.rb +2 -2
  11. data/lib/rails/app_updater.rb +4 -1
  12. data/lib/rails/application/bootstrap.rb +9 -17
  13. data/lib/rails/application/configuration.rb +177 -27
  14. data/lib/rails/application/default_middleware_stack.rb +7 -3
  15. data/lib/rails/application/dummy_erb_compiler.rb +18 -0
  16. data/lib/rails/application/finisher.rb +69 -2
  17. data/lib/rails/application/routes_reloader.rb +9 -19
  18. data/lib/rails/application.rb +96 -66
  19. data/lib/rails/application_controller.rb +0 -1
  20. data/lib/rails/autoloaders.rb +48 -0
  21. data/lib/rails/backtrace_cleaner.rb +14 -21
  22. data/lib/rails/code_statistics.rb +8 -6
  23. data/lib/rails/code_statistics_calculator.rb +6 -6
  24. data/lib/rails/command/actions.rb +10 -0
  25. data/lib/rails/command/base.rb +17 -5
  26. data/lib/rails/command/behavior.rb +8 -49
  27. data/lib/rails/command/environment_argument.rb +9 -16
  28. data/lib/rails/command/spellchecker.rb +57 -0
  29. data/lib/rails/command.rb +18 -11
  30. data/lib/rails/commands/console/console_command.rb +6 -0
  31. data/lib/rails/commands/credentials/USAGE +33 -0
  32. data/lib/rails/commands/credentials/credentials_command/diffing.rb +41 -0
  33. data/lib/rails/commands/credentials/credentials_command.rb +78 -21
  34. data/lib/rails/commands/db/system/change/change_command.rb +25 -0
  35. data/lib/rails/commands/dbconsole/dbconsole_command.rb +66 -51
  36. data/lib/rails/commands/dev/dev_command.rb +19 -0
  37. data/lib/rails/commands/encrypted/USAGE +28 -0
  38. data/lib/rails/commands/encrypted/encrypted_command.rb +5 -4
  39. data/lib/rails/commands/generate/generate_command.rb +1 -1
  40. data/lib/rails/commands/help/help_command.rb +1 -1
  41. data/lib/rails/commands/initializers/initializers_command.rb +23 -0
  42. data/lib/rails/commands/new/new_command.rb +2 -2
  43. data/lib/rails/commands/notes/notes_command.rb +29 -0
  44. data/lib/rails/commands/plugin/plugin_command.rb +1 -1
  45. data/lib/rails/commands/rake/rake_command.rb +9 -8
  46. data/lib/rails/commands/routes/routes_command.rb +37 -0
  47. data/lib/rails/commands/runner/runner_command.rb +13 -9
  48. data/lib/rails/commands/secrets/USAGE +6 -0
  49. data/lib/rails/commands/secrets/secrets_command.rb +3 -3
  50. data/lib/rails/commands/server/server_command.rb +92 -56
  51. data/lib/rails/commands/test/test_command.rb +2 -2
  52. data/lib/rails/configuration.rb +48 -19
  53. data/lib/rails/engine/configuration.rb +6 -2
  54. data/lib/rails/engine/updater.rb +1 -1
  55. data/lib/rails/engine.rb +63 -35
  56. data/lib/rails/gem_version.rb +2 -2
  57. data/lib/rails/generators/actions/create_migration.rb +5 -1
  58. data/lib/rails/generators/actions.rb +89 -56
  59. data/lib/rails/generators/app_base.rb +80 -108
  60. data/lib/rails/generators/app_name.rb +50 -0
  61. data/lib/rails/generators/base.rb +19 -12
  62. data/lib/rails/generators/database.rb +57 -0
  63. data/lib/rails/generators/erb/mailer/mailer_generator.rb +1 -2
  64. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +0 -1
  65. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +7 -4
  66. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +1 -1
  67. data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +9 -1
  68. data/lib/rails/generators/erb.rb +0 -1
  69. data/lib/rails/generators/generated_attribute.rb +50 -31
  70. data/lib/rails/generators/migration.rb +3 -3
  71. data/lib/rails/generators/model_helpers.rb +33 -2
  72. data/lib/rails/generators/named_base.rb +3 -7
  73. data/lib/rails/generators/rails/app/USAGE +2 -1
  74. data/lib/rails/generators/rails/app/app_generator.rb +127 -84
  75. data/lib/rails/generators/rails/app/templates/Gemfile.tt +18 -21
  76. data/lib/rails/generators/rails/app/templates/Rakefile.tt +1 -1
  77. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -3
  78. data/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js +6 -0
  79. data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +5 -0
  80. data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +23 -0
  81. data/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt +5 -0
  82. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +6 -5
  83. data/lib/rails/generators/rails/app/templates/bin/rails.tt +5 -2
  84. data/lib/rails/generators/rails/app/templates/bin/rake.tt +5 -2
  85. data/lib/rails/generators/rails/app/templates/bin/setup.tt +9 -9
  86. data/lib/rails/generators/rails/app/templates/bin/spring.tt +9 -0
  87. data/lib/rails/generators/rails/app/templates/bin/yarn.tt +11 -3
  88. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +16 -7
  89. data/lib/rails/generators/rails/app/templates/config/boot.rb.tt +2 -2
  90. data/lib/rails/generators/rails/app/templates/config/cable.yml.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +4 -5
  92. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +12 -11
  93. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +13 -12
  94. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +1 -1
  95. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +13 -12
  96. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +12 -11
  97. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +16 -15
  98. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
  99. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +11 -10
  100. data/lib/rails/generators/rails/app/templates/config/environment.rb.tt +1 -1
  101. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +22 -5
  102. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +43 -17
  103. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +26 -7
  104. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
  105. data/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt +4 -3
  106. data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +7 -0
  107. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -1
  108. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_1.rb.tt +63 -0
  109. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -0
  110. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
  111. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +13 -4
  112. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +1 -1
  113. data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +6 -6
  114. data/lib/rails/generators/rails/app/templates/config.ru.tt +2 -1
  115. data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +1 -1
  116. data/lib/rails/generators/rails/app/templates/gitattributes.tt +14 -0
  117. data/lib/rails/generators/rails/app/templates/gitignore.tt +10 -7
  118. data/lib/rails/generators/rails/app/templates/package.json.tt +8 -2
  119. data/lib/rails/generators/rails/app/templates/public/robots.txt +1 -1
  120. data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
  121. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +11 -0
  122. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -2
  123. data/lib/rails/generators/rails/assets/USAGE +3 -7
  124. data/lib/rails/generators/rails/assets/assets_generator.rb +0 -1
  125. data/lib/rails/generators/rails/benchmark/USAGE +19 -0
  126. data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +29 -0
  127. data/lib/rails/generators/rails/benchmark/templates/benchmark.rb.tt +15 -0
  128. data/lib/rails/generators/rails/controller/USAGE +2 -2
  129. data/lib/rails/generators/rails/controller/controller_generator.rb +10 -39
  130. data/lib/rails/generators/rails/credentials/credentials_generator.rb +6 -7
  131. data/lib/rails/generators/rails/db/system/change/change_generator.rb +65 -0
  132. data/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb +10 -7
  133. data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -0
  134. data/lib/rails/generators/rails/generator/USAGE +2 -2
  135. data/lib/rails/generators/rails/generator/generator_generator.rb +0 -1
  136. data/lib/rails/generators/rails/generator/templates/USAGE.tt +1 -1
  137. data/lib/rails/generators/rails/helper/USAGE +2 -3
  138. data/lib/rails/generators/rails/helper/helper_generator.rb +5 -0
  139. data/lib/rails/generators/rails/integration_test/USAGE +2 -2
  140. data/lib/rails/generators/rails/migration/USAGE +4 -4
  141. data/lib/rails/generators/rails/model/USAGE +15 -16
  142. data/lib/rails/generators/rails/plugin/plugin_generator.rb +32 -56
  143. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +18 -18
  144. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +3 -10
  145. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -18
  146. data/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +1 -2
  147. data/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt +1 -1
  148. data/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt +1 -1
  149. data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +1 -1
  150. data/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +1 -1
  151. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +3 -3
  152. data/lib/rails/generators/rails/plugin/templates/gitignore.tt +14 -11
  153. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +1 -1
  154. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt +1 -1
  155. data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb.tt +1 -0
  156. data/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt +1 -1
  157. data/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb.tt +4 -4
  158. data/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb.tt +1 -1
  159. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +0 -4
  160. data/lib/rails/generators/rails/resource/USAGE +4 -4
  161. data/lib/rails/generators/rails/resource_route/resource_route_generator.rb +2 -27
  162. data/lib/rails/generators/rails/scaffold/USAGE +5 -5
  163. data/lib/rails/generators/rails/scaffold_controller/USAGE +2 -2
  164. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +19 -0
  165. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
  166. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +2 -2
  167. data/lib/rails/generators/rails/system_test/USAGE +2 -2
  168. data/lib/rails/generators/rails/task/USAGE +3 -3
  169. data/lib/rails/generators/resource_helpers.rb +1 -6
  170. data/lib/rails/generators/test_case.rb +1 -1
  171. data/lib/rails/generators/test_unit/controller/controller_generator.rb +2 -0
  172. data/lib/rails/generators/test_unit/controller/templates/functional_test.rb.tt +3 -3
  173. data/lib/rails/generators/test_unit/generator/generator_generator.rb +0 -1
  174. data/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt +2 -2
  175. data/lib/rails/generators/test_unit/integration/integration_generator.rb +5 -0
  176. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb.tt +1 -1
  177. data/lib/rails/generators/test_unit/job/job_generator.rb +5 -0
  178. data/lib/rails/generators/test_unit/job/templates/unit_test.rb.tt +1 -1
  179. data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +1 -1
  180. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +1 -1
  181. data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +3 -3
  182. data/lib/rails/generators/test_unit/model/templates/unit_test.rb.tt +1 -1
  183. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +1 -1
  184. data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +2 -2
  185. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +12 -3
  186. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +1 -1
  187. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +1 -1
  188. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +10 -2
  189. data/lib/rails/generators/test_unit/system/system_generator.rb +5 -0
  190. data/lib/rails/generators/testing/assertions.rb +2 -2
  191. data/lib/rails/generators/testing/behaviour.rb +4 -2
  192. data/lib/rails/generators.rb +38 -24
  193. data/lib/rails/info.rb +4 -4
  194. data/lib/rails/info_controller.rb +2 -3
  195. data/lib/rails/mailers_controller.rb +10 -4
  196. data/lib/rails/paths.rb +26 -10
  197. data/lib/rails/rack/logger.rb +5 -6
  198. data/lib/rails/railtie/configurable.rb +0 -1
  199. data/lib/rails/railtie/configuration.rb +3 -3
  200. data/lib/rails/railtie.rb +33 -13
  201. data/lib/rails/ruby_version_check.rb +3 -3
  202. data/lib/rails/secrets.rb +0 -1
  203. data/lib/rails/source_annotation_extractor.rb +124 -117
  204. data/lib/rails/tasks/engine.rake +1 -4
  205. data/lib/rails/tasks/framework.rake +13 -3
  206. data/lib/rails/tasks/log.rake +0 -1
  207. data/lib/rails/tasks/misc.rake +1 -1
  208. data/lib/rails/tasks/statistics.rake +5 -1
  209. data/lib/rails/tasks/yarn.rake +14 -1
  210. data/lib/rails/tasks/zeitwerk.rake +69 -0
  211. data/lib/rails/tasks.rb +1 -4
  212. data/lib/rails/templates/rails/mailers/email.html.erb +11 -7
  213. data/lib/rails/templates/rails/welcome/index.html.erb +3 -3
  214. data/lib/rails/test_help.rb +11 -9
  215. data/lib/rails/test_unit/reporter.rb +3 -2
  216. data/lib/rails/test_unit/runner.rb +25 -8
  217. data/lib/rails/test_unit/testing.rake +7 -1
  218. data/lib/rails.rb +10 -8
  219. metadata +45 -39
  220. data/lib/rails/generators/js/assets/assets_generator.rb +0 -15
  221. data/lib/rails/generators/js/assets/templates/javascript.js +0 -2
  222. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +0 -22
  223. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt +0 -13
  224. data/lib/rails/generators/rails/app/templates/bin/bundle.tt +0 -2
  225. data/lib/rails/generators/rails/app/templates/bin/update.tt +0 -34
  226. data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt +0 -50
  227. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt +0 -86
  228. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt +0 -35
  229. data/lib/rails/generators/rails/assets/templates/javascript.js +0 -2
  230. data/lib/rails/generators/rails/plugin/templates/rails/application.rb.tt +0 -23
  231. data/lib/rails/tasks/annotations.rake +0 -22
  232. data/lib/rails/tasks/dev.rake +0 -10
  233. data/lib/rails/tasks/initializers.rake +0 -8
  234. data/lib/rails/tasks/routes.rake +0 -31
@@ -38,24 +38,24 @@ module Rails
38
38
  end
39
39
 
40
40
  private
41
-
42
- # parse possible attribute options like :limit for string/text/binary/integer, :precision/:scale for decimals or :polymorphic for references/belongs_to
43
- # when declaring options curly brackets should be used
44
- def parse_type_and_options(type)
45
- case type
46
- when /(string|text|binary|integer)\{(\d+)\}/
47
- return $1, limit: $2.to_i
48
- when /decimal\{(\d+)[,.-](\d+)\}/
49
- return :decimal, precision: $1.to_i, scale: $2.to_i
50
- when /(references|belongs_to)\{(.+)\}/
51
- type = $1
52
- provided_options = $2.split(/[,.-]/)
53
- options = Hash[provided_options.map { |opt| [opt.to_sym, true] }]
54
- return type, options
55
- else
56
- return type, {}
41
+ # parse possible attribute options like :limit for string/text/binary/integer, :precision/:scale for decimals or :polymorphic for references/belongs_to
42
+ # when declaring options curly brackets should be used
43
+ def parse_type_and_options(type)
44
+ case type
45
+ when /(string|text|binary|integer)\{(\d+)\}/
46
+ return $1, limit: $2.to_i
47
+ when /decimal\{(\d+)[,.-](\d+)\}/
48
+ return :decimal, precision: $1.to_i, scale: $2.to_i
49
+ when /(references|belongs_to)\{(.+)\}/
50
+ type = $1
51
+ provided_options = $2.split(/[,.-]/)
52
+ options = Hash[provided_options.map { |opt| [opt.to_sym, true] }]
53
+
54
+ return type, options
55
+ else
56
+ return type, {}
57
+ end
57
58
  end
58
- end
59
59
  end
60
60
 
61
61
  def initialize(name, type = nil, index_type = false, attr_options = {})
@@ -68,13 +68,15 @@ module Rails
68
68
 
69
69
  def field_type
70
70
  @field_type ||= case type
71
- when :integer then :number_field
72
- when :float, :decimal then :text_field
73
- when :time then :time_select
74
- when :datetime, :timestamp then :datetime_select
75
- when :date then :date_select
76
- when :text then :text_area
77
- when :boolean then :check_box
71
+ when :integer then :number_field
72
+ when :float, :decimal then :text_field
73
+ when :time then :time_select
74
+ when :datetime, :timestamp then :datetime_select
75
+ when :date then :date_select
76
+ when :text then :text_area
77
+ when :rich_text then :rich_text_area
78
+ when :boolean then :check_box
79
+ when :attachment, :attachments then :file_field
78
80
  else
79
81
  :text_field
80
82
  end
@@ -90,18 +92,20 @@ module Rails
90
92
  when :string then name == "type" ? "" : "MyString"
91
93
  when :text then "MyText"
92
94
  when :boolean then false
93
- when :references, :belongs_to then nil
95
+ when :references, :belongs_to,
96
+ :attachment, :attachments,
97
+ :rich_text then nil
94
98
  else
95
99
  ""
96
100
  end
97
101
  end
98
102
 
99
103
  def plural_name
100
- name.sub(/_id$/, "").pluralize
104
+ name.delete_suffix("_id").pluralize
101
105
  end
102
106
 
103
107
  def singular_name
104
- name.sub(/_id$/, "").singularize
108
+ name.delete_suffix("_id").singularize
105
109
  end
106
110
 
107
111
  def human_name
@@ -121,7 +125,7 @@ module Rails
121
125
  end
122
126
 
123
127
  def foreign_key?
124
- !!(name =~ /_id$/)
128
+ name.end_with?("_id")
125
129
  end
126
130
 
127
131
  def reference?
@@ -133,7 +137,7 @@ module Rails
133
137
  end
134
138
 
135
139
  def required?
136
- attr_options[:required]
140
+ reference? && Rails.application.config.active_record.belongs_to_required_by_default
137
141
  end
138
142
 
139
143
  def has_index?
@@ -152,8 +156,24 @@ module Rails
152
156
  type == :token
153
157
  end
154
158
 
159
+ def rich_text?
160
+ type == :rich_text
161
+ end
162
+
163
+ def attachment?
164
+ type == :attachment
165
+ end
166
+
167
+ def attachments?
168
+ type == :attachments
169
+ end
170
+
171
+ def virtual?
172
+ rich_text? || attachment? || attachments?
173
+ end
174
+
155
175
  def inject_options
156
- "".dup.tap { |s| options_for_migration.each { |k, v| s << ", #{k}: #{v.inspect}" } }
176
+ (+"").tap { |s| options_for_migration.each { |k, v| s << ", #{k}: #{v.inspect}" } }
157
177
  end
158
178
 
159
179
  def inject_index_options
@@ -163,7 +183,6 @@ module Rails
163
183
  def options_for_migration
164
184
  @attr_options.dup.tap do |options|
165
185
  if required?
166
- options.delete(:required)
167
186
  options[:null] = false
168
187
  end
169
188
 
@@ -62,14 +62,14 @@ module Rails
62
62
  dir, base = File.split(destination)
63
63
  numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
64
64
 
65
- create_migration numbered_destination, nil, config do
66
- match = ERB.version.match(/\Aerb\.rb \[(?<version>[^ ]+) /)
67
- if match && match[:version] >= "2.2.0" # Ruby 2.6+
65
+ file = create_migration numbered_destination, nil, config do
66
+ if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
68
67
  ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(context)
69
68
  else
70
69
  ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
71
70
  end
72
71
  end
72
+ Rails::Generators.add_generated_file(file)
73
73
  end
74
74
  end
75
75
  end
@@ -7,6 +7,15 @@ module Rails
7
7
  module ModelHelpers # :nodoc:
8
8
  PLURAL_MODEL_NAME_WARN_MESSAGE = "[WARNING] The model name '%s' was recognized as a plural, using the singular '%s' instead. " \
9
9
  "Override with --force-plural or setup custom inflection rules for this noun before running the generator."
10
+ IRREGULAR_MODEL_NAME_WARN_MESSAGE = <<~WARNING
11
+ [WARNING] Rails cannot recover singular form from its plural form '%s'.
12
+ Please setup custom inflection rules for this noun before running the generator in config/initializers/inflections.rb.
13
+ WARNING
14
+ INFLECTION_IMPOSSIBLE_ERROR_MESSAGE = <<~ERROR
15
+ Rails cannot recover the underscored form from its camelcase form '%s'.
16
+ Please use an underscored name instead, either '%s' or '%s'.
17
+ Or setup custom inflection rules for this noun before running the generator in config/initializers/inflections.rb.
18
+ ERROR
10
19
  mattr_accessor :skip_warn
11
20
 
12
21
  def self.included(base) #:nodoc:
@@ -15,16 +24,38 @@ module Rails
15
24
 
16
25
  def initialize(args, *_options)
17
26
  super
18
- if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
27
+ if plural_model_name?(name) && !options[:force_plural]
19
28
  singular = name.singularize
20
29
  unless ModelHelpers.skip_warn
21
30
  say PLURAL_MODEL_NAME_WARN_MESSAGE % [name, singular]
22
- ModelHelpers.skip_warn = true
23
31
  end
24
32
  name.replace singular
25
33
  assign_names!(name)
26
34
  end
35
+ if inflection_impossible?(name)
36
+ option1 = name.singularize.underscore
37
+ option2 = name.pluralize.underscore.singularize
38
+ raise Error, INFLECTION_IMPOSSIBLE_ERROR_MESSAGE % [name, option1, option2]
39
+ end
40
+ if irregular_model_name?(name) && ! ModelHelpers.skip_warn
41
+ say IRREGULAR_MODEL_NAME_WARN_MESSAGE % [name.pluralize]
42
+ end
43
+ ModelHelpers.skip_warn = true
27
44
  end
45
+
46
+ private
47
+ def plural_model_name?(name)
48
+ name == name.pluralize && name.singularize != name.pluralize
49
+ end
50
+
51
+ def irregular_model_name?(name)
52
+ name.singularize != name.pluralize.singularize
53
+ end
54
+
55
+ def inflection_impossible?(name)
56
+ name != name.underscore &&
57
+ name.singularize.underscore != name.pluralize.underscore.singularize
58
+ end
28
59
  end
29
60
  end
30
61
  end
@@ -22,7 +22,7 @@ module Rails
22
22
  no_tasks do
23
23
  def template(source, *args, &block)
24
24
  inside_template do
25
- super
25
+ Rails::Generators.add_generated_file(super)
26
26
  end
27
27
  end
28
28
 
@@ -31,12 +31,8 @@ module Rails
31
31
  end
32
32
  end
33
33
 
34
- # TODO Change this to private once we've dropped Ruby 2.2 support.
35
- # Workaround for Ruby 2.2 "private attribute?" warning.
36
- protected
37
- attr_reader :file_name
38
-
39
34
  private
35
+ attr_reader :file_name
40
36
 
41
37
  # FIXME: We are avoiding to use alias because a bug on thor that make
42
38
  # this method public and add it to the task list.
@@ -217,7 +213,7 @@ module Rails
217
213
  #
218
214
  def self.check_class_collision(options = {}) # :doc:
219
215
  define_method :check_class_collision do
220
- name = if respond_to?(:controller_class_name) # for ResourceHelpers
216
+ name = if respond_to?(:controller_class_name, true) # for ResourceHelpers
221
217
  controller_class_name
222
218
  else
223
219
  class_name
@@ -3,7 +3,8 @@ Description:
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
+ or in $XDG_CONFIG_HOME/rails/railsrc if XDG_CONFIG_HOME is set.
7
8
 
8
9
  Note that the arguments specified in the .railsrc file don't affect the
9
10
  defaults values shown above in this help message.
@@ -21,7 +21,6 @@ module Rails
21
21
  RUBY
22
22
  end
23
23
 
24
- # TODO: Remove once this is fully in place
25
24
  def method_missing(meth, *args, &block)
26
25
  @generator.send(meth, *args, &block)
27
26
  end
@@ -67,9 +66,13 @@ module Rails
67
66
  template "gitignore", ".gitignore"
68
67
  end
69
68
 
69
+ def gitattributes
70
+ template "gitattributes", ".gitattributes"
71
+ end
72
+
70
73
  def version_control
71
74
  if !options[:skip_git] && !options[:pretend]
72
- run "git init", capture: options[:quiet]
75
+ run "git init", capture: options[:quiet], abort_on_failure: false
73
76
  end
74
77
  end
75
78
 
@@ -80,8 +83,7 @@ module Rails
80
83
  def app
81
84
  directory "app"
82
85
 
83
- keep_file "app/assets/images"
84
- empty_directory_with_keep_file "app/assets/javascripts/channels" unless options[:skip_action_cable]
86
+ empty_directory_with_keep_file "app/assets/images"
85
87
 
86
88
  keep_file "app/controllers/concerns"
87
89
  keep_file "app/models/concerns"
@@ -92,16 +94,23 @@ module Rails
92
94
  "#{shebang}\n" + content
93
95
  end
94
96
  chmod "bin", 0755 & ~File.umask, verbose: false
97
+
98
+ remove_file "bin/spring" unless spring_install?
99
+ remove_file "bin/yarn" if options[:skip_javascript]
95
100
  end
96
101
 
97
102
  def bin_when_updating
98
- bin_yarn_exist = File.exist?("bin/yarn")
99
-
100
103
  bin
104
+ end
105
+
106
+ def yarn_when_updating
107
+ return if File.exist?("bin/yarn")
101
108
 
102
- if options[:api] && !bin_yarn_exist
103
- remove_file "bin/yarn"
109
+ template "bin/yarn" do |content|
110
+ "#{shebang}\n" + content
104
111
  end
112
+
113
+ chmod "bin", 0755 & ~File.umask, verbose: false
105
114
  end
106
115
 
107
116
  def config
@@ -129,10 +138,12 @@ module Rails
129
138
  rack_cors_config_exist = File.exist?("config/initializers/cors.rb")
130
139
  assets_config_exist = File.exist?("config/initializers/assets.rb")
131
140
  csp_config_exist = File.exist?("config/initializers/content_security_policy.rb")
141
+ permissions_policy_config_exist = File.exist?("config/initializers/permissions_policy.rb")
132
142
 
133
143
  @config_target_version = Rails.application.config.loaded_config_version || "5.0"
134
144
 
135
145
  config
146
+ configru
136
147
 
137
148
  unless cookie_serializer_config_exist
138
149
  gsub_file "config/initializers/cookies_serializer.rb", /json(?!,)/, "marshal"
@@ -146,6 +157,10 @@ module Rails
146
157
  template "config/storage.yml"
147
158
  end
148
159
 
160
+ if options[:skip_sprockets] && !assets_config_exist
161
+ remove_file "config/initializers/assets.rb"
162
+ end
163
+
149
164
  unless rack_cors_config_exist
150
165
  remove_file "config/initializers/cors.rb"
151
166
  end
@@ -155,13 +170,13 @@ module Rails
155
170
  remove_file "config/initializers/cookies_serializer.rb"
156
171
  end
157
172
 
158
- unless assets_config_exist
159
- remove_file "config/initializers/assets.rb"
160
- end
161
-
162
173
  unless csp_config_exist
163
174
  remove_file "config/initializers/content_security_policy.rb"
164
175
  end
176
+
177
+ unless permissions_policy_config_exist
178
+ remove_file "config/initializers/permissions_policy.rb"
179
+ end
165
180
  end
166
181
  end
167
182
 
@@ -209,7 +224,6 @@ module Rails
209
224
  end
210
225
 
211
226
  def test
212
- empty_directory_with_keep_file "test/fixtures"
213
227
  empty_directory_with_keep_file "test/fixtures/files"
214
228
  empty_directory_with_keep_file "test/controllers"
215
229
  empty_directory_with_keep_file "test/mailers"
@@ -217,6 +231,7 @@ module Rails
217
231
  empty_directory_with_keep_file "test/helpers"
218
232
  empty_directory_with_keep_file "test/integration"
219
233
 
234
+ template "test/channels/application_cable/connection_test.rb"
220
235
  template "test/test_helper.rb"
221
236
  end
222
237
 
@@ -228,6 +243,7 @@ module Rails
228
243
 
229
244
  def tmp
230
245
  empty_directory_with_keep_file "tmp"
246
+ empty_directory_with_keep_file "tmp/pids"
231
247
  empty_directory "tmp/cache"
232
248
  empty_directory "tmp/cache/assets"
233
249
  end
@@ -245,38 +261,70 @@ module Rails
245
261
  # We need to store the RAILS_DEV_PATH in a constant, otherwise the path
246
262
  # can change in Ruby 1.8.7 when we FileUtils.cd.
247
263
  RAILS_DEV_PATH = File.expand_path("../../../../../..", __dir__)
248
- RESERVED_NAMES = %w[application destroy plugin runner test]
249
264
 
250
- class AppGenerator < AppBase # :nodoc:
265
+ class AppGenerator < AppBase
266
+ # :stopdoc:
267
+
251
268
  WEBPACKS = %w( react vue angular elm stimulus )
252
269
 
253
270
  add_shared_options_for "application"
254
271
 
255
- # Add bin/rails options
272
+ # Add rails command options
256
273
  class_option :version, type: :boolean, aliases: "-v", group: :rails,
257
274
  desc: "Show Rails version number and quit"
258
275
 
259
276
  class_option :api, type: :boolean,
260
277
  desc: "Preconfigure smaller stack for API only apps"
261
278
 
279
+ class_option :minimal, type: :boolean,
280
+ desc: "Preconfigure a minimal rails app"
281
+
262
282
  class_option :skip_bundle, type: :boolean, aliases: "-B", default: false,
263
283
  desc: "Don't run bundle install"
264
284
 
265
- class_option :webpack, type: :string, default: nil,
266
- desc: "Preconfigure for app-like JavaScript with Webpack (options: #{WEBPACKS.join('/')})"
285
+ class_option :webpack, type: :string, aliases: "--webpacker", default: nil,
286
+ desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join(", ")})"
287
+
288
+ class_option :skip_webpack_install, type: :boolean, default: false,
289
+ desc: "Don't run Webpack install"
267
290
 
268
291
  def initialize(*args)
269
292
  super
270
293
 
271
294
  if !options[:skip_active_record] && !DATABASES.include?(options[:database])
272
- raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
295
+ raise Error, "Invalid value for --database option. Supported preconfigurations are: #{DATABASES.join(", ")}."
273
296
  end
274
297
 
275
298
  # Force sprockets and yarn to be skipped when generating API only apps.
276
299
  # Can't modify options hash as it's frozen by default.
277
300
  if options[:api]
278
- self.options = options.merge(skip_sprockets: true, skip_javascript: true, skip_yarn: true).freeze
301
+ self.options = options.merge(skip_sprockets: true, skip_javascript: true).freeze
302
+ end
303
+
304
+ if options[:minimal]
305
+ self.options = options.merge(
306
+ skip_action_cable: true,
307
+ skip_action_mailer: true,
308
+ skip_action_mailbox: true,
309
+ skip_action_text: true,
310
+ skip_active_job: true,
311
+ skip_active_storage: true,
312
+ skip_bootsnap: true,
313
+ skip_dev_gems: true,
314
+ skip_javascript: true,
315
+ skip_jbuilder: true,
316
+ skip_spring: true,
317
+ skip_system_test: true,
318
+ skip_webpack_install: true,
319
+ skip_turbolinks: true).tap do |option|
320
+ if option[:webpack]
321
+ option[:skip_webpack_install] = false
322
+ option[:skip_javascript] = false
323
+ end
324
+ end.freeze
279
325
  end
326
+
327
+ @after_bundle_callbacks = []
280
328
  end
281
329
 
282
330
  public_task :set_default_accessors!
@@ -287,10 +335,15 @@ module Rails
287
335
  build(:rakefile)
288
336
  build(:ruby_version)
289
337
  build(:configru)
290
- build(:gitignore) unless options[:skip_git]
291
- build(:gemfile) unless options[:skip_gemfile]
338
+
339
+ unless options[:skip_git]
340
+ build(:gitignore)
341
+ build(:gitattributes)
342
+ end
343
+
344
+ build(:gemfile) unless options[:skip_gemfile]
292
345
  build(:version_control)
293
- build(:package_json) unless options[:skip_yarn]
346
+ build(:package_json) unless options[:skip_javascript]
294
347
  end
295
348
 
296
349
  def create_app_files
@@ -306,6 +359,18 @@ module Rails
306
359
  end
307
360
  remove_task :update_bin_files
308
361
 
362
+ def update_bin_yarn
363
+ build(:yarn_when_updating)
364
+ end
365
+ remove_task :update_bin_yarn
366
+
367
+ def update_active_storage
368
+ unless skip_active_storage?
369
+ rails_command "active_storage:update", inline: true
370
+ end
371
+ end
372
+ remove_task :update_active_storage
373
+
309
374
  def create_config_files
310
375
  build(:config)
311
376
  end
@@ -324,7 +389,7 @@ module Rails
324
389
  end
325
390
 
326
391
  def display_upgrade_guide_info
327
- say "\nAfter this, check Rails upgrade guide at http://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app."
392
+ say "\nAfter this, check Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app."
328
393
  end
329
394
  remove_task :display_upgrade_guide_info
330
395
 
@@ -411,8 +476,15 @@ module Rails
411
476
  end
412
477
 
413
478
  def delete_js_folder_skipping_javascript
414
- if options[:skip_javascript]
415
- remove_dir "app/assets/javascripts"
479
+ if options[:skip_javascript] && !options[:minimal]
480
+ remove_dir "app/javascript"
481
+ end
482
+ end
483
+
484
+ def delete_js_packs_when_minimal_skipping_webpack
485
+ if options[:minimal] && options[:skip_webpack_install]
486
+ remove_dir "app/javascript/packs"
487
+ keep_file "app/javascript"
416
488
  end
417
489
  end
418
490
 
@@ -428,6 +500,12 @@ module Rails
428
500
  end
429
501
  end
430
502
 
503
+ def delete_active_job_folder_if_skipping_active_job
504
+ if options[:skip_active_job]
505
+ remove_dir "app/jobs"
506
+ end
507
+ end
508
+
431
509
  def delete_action_mailer_files_skipping_action_mailer
432
510
  if options[:skip_action_mailer]
433
511
  remove_file "app/views/layouts/mailer.html.erb"
@@ -439,8 +517,9 @@ module Rails
439
517
 
440
518
  def delete_action_cable_files_skipping_action_cable
441
519
  if options[:skip_action_cable]
442
- remove_file "app/assets/javascripts/cable.js"
520
+ remove_dir "app/javascript/channels"
443
521
  remove_dir "app/channels"
522
+ remove_dir "test/channels"
444
523
  end
445
524
  end
446
525
 
@@ -448,6 +527,7 @@ module Rails
448
527
  if options[:api]
449
528
  remove_file "config/initializers/cookies_serializer.rb"
450
529
  remove_file "config/initializers/content_security_policy.rb"
530
+ remove_file "config/initializers/permissions_policy.rb"
451
531
  end
452
532
  end
453
533
 
@@ -459,20 +539,17 @@ module Rails
459
539
 
460
540
  def delete_new_framework_defaults
461
541
  unless options[:update]
462
- remove_file "config/initializers/new_framework_defaults_5_2.rb"
542
+ remove_file "config/initializers/new_framework_defaults_6_1.rb"
463
543
  end
464
544
  end
465
545
 
466
- def delete_bin_yarn_if_skip_yarn_option
467
- remove_file "bin/yarn" if options[:skip_yarn]
468
- end
469
-
470
546
  def finish_template
471
547
  build(:leftovers)
472
548
  end
473
549
 
474
550
  public_task :apply_rails_template, :run_bundle
475
- public_task :run_webpack, :generate_spring_binstubs
551
+ public_task :generate_bundler_binstub
552
+ public_task :run_webpack
476
553
 
477
554
  def run_after_bundle_callbacks
478
555
  @after_bundle_callbacks.each(&:call)
@@ -482,61 +559,22 @@ module Rails
482
559
  "rails new #{arguments.map(&:usage).join(' ')} [options]"
483
560
  end
484
561
 
485
- private
562
+ # :startdoc:
486
563
 
564
+ private
487
565
  # Define file as an alias to create_file for backwards compatibility.
488
566
  def file(*args, &block)
489
567
  create_file(*args, &block)
490
568
  end
491
569
 
492
- def app_name
493
- @app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr('\\', "").tr(". ", "_")
494
- end
495
-
496
- def defined_app_name
497
- defined_app_const_base.underscore
498
- end
499
-
500
- def defined_app_const_base
501
- Rails.respond_to?(:application) && defined?(Rails::Application) &&
502
- Rails.application.is_a?(Rails::Application) && Rails.application.class.name.sub(/::Application$/, "")
503
- end
504
-
505
- alias :defined_app_const_base? :defined_app_const_base
506
-
507
- def app_const_base
508
- @app_const_base ||= defined_app_const_base || app_name.gsub(/\W/, "_").squeeze("_").camelize
509
- end
510
- alias :camelized :app_const_base
511
-
512
- def app_const
513
- @app_const ||= "#{app_const_base}::Application"
514
- end
515
-
516
- def valid_const?
517
- if app_const =~ /^\d/
518
- raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
519
- elsif RESERVED_NAMES.include?(app_name)
520
- raise Error, "Invalid application name #{app_name}. Please give a " \
521
- "name which does not match one of the reserved rails " \
522
- "words: #{RESERVED_NAMES.join(", ")}"
523
- elsif Object.const_defined?(app_const_base)
524
- raise Error, "Invalid application name #{app_name}, constant #{app_const_base} is already in use. Please choose another application name."
525
- end
526
- end
527
-
528
- def mysql_socket
529
- @mysql_socket ||= [
530
- "/tmp/mysql.sock", # default
531
- "/var/run/mysqld/mysqld.sock", # debian/gentoo
532
- "/var/tmp/mysql.sock", # freebsd
533
- "/var/lib/mysql/mysql.sock", # fedora
534
- "/opt/local/lib/mysql/mysql.sock", # fedora
535
- "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
536
- "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
537
- "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
538
- "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
539
- ].find { |f| File.exist?(f) } unless Gem.win_platform?
570
+ # Registers a callback to be executed after bundle and spring binstubs
571
+ # have run.
572
+ #
573
+ # after_bundle do
574
+ # git add: '.'
575
+ # end
576
+ def after_bundle(&block) # :doc:
577
+ @after_bundle_callbacks << block
540
578
  end
541
579
 
542
580
  def get_builder_class
@@ -564,11 +602,16 @@ module Rails
564
602
  end
565
603
 
566
604
  def self.default_rc_file
567
- File.expand_path("~/.railsrc")
605
+ xdg_config_home = ENV["XDG_CONFIG_HOME"].presence || "~/.config"
606
+ xdg_railsrc = File.expand_path("rails/railsrc", xdg_config_home)
607
+ if File.exist?(xdg_railsrc)
608
+ xdg_railsrc
609
+ else
610
+ File.expand_path("~/.railsrc")
611
+ end
568
612
  end
569
613
 
570
614
  private
571
-
572
615
  def handle_version_request!(argument)
573
616
  if ["--version", "-v"].include?(argument)
574
617
  require "rails/version"