railties 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -567
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +3 -3
  5. data/README.rdoc +1 -1
  6. data/exe/rails +2 -2
  7. data/lib/rails.rb +18 -18
  8. data/lib/rails/all.rb +1 -1
  9. data/lib/rails/api/generator.rb +28 -0
  10. data/lib/rails/api/task.rb +54 -42
  11. data/lib/rails/app_loader.rb +9 -9
  12. data/lib/rails/application.rb +30 -35
  13. data/lib/rails/application/bootstrap.rb +13 -7
  14. data/lib/rails/application/configuration.rb +30 -53
  15. data/lib/rails/application/default_middleware_stack.rb +3 -5
  16. data/lib/rails/application/finisher.rb +16 -7
  17. data/lib/rails/application/routes_reloader.rb +16 -1
  18. data/lib/rails/application_controller.rb +10 -10
  19. data/lib/rails/backtrace_cleaner.rb +5 -5
  20. data/lib/rails/cli.rb +7 -5
  21. data/lib/rails/code_statistics.rb +16 -17
  22. data/lib/rails/code_statistics_calculator.rb +3 -3
  23. data/lib/rails/command.rb +111 -0
  24. data/lib/rails/command/actions.rb +42 -0
  25. data/lib/rails/command/base.rb +149 -0
  26. data/lib/rails/command/behavior.rb +123 -0
  27. data/lib/rails/command/environment_argument.rb +34 -0
  28. data/lib/rails/commands.rb +2 -4
  29. data/lib/rails/commands/application/application_command.rb +29 -0
  30. data/lib/rails/commands/console/console_command.rb +89 -0
  31. data/lib/rails/commands/dbconsole/dbconsole_command.rb +155 -0
  32. data/lib/rails/commands/destroy/destroy_command.rb +21 -0
  33. data/lib/rails/commands/generate/generate_command.rb +23 -0
  34. data/lib/rails/commands/help/USAGE +15 -0
  35. data/lib/rails/commands/help/help_command.rb +13 -0
  36. data/lib/rails/commands/new/new_command.rb +15 -0
  37. data/lib/rails/commands/plugin/plugin_command.rb +43 -0
  38. data/lib/rails/commands/rake/rake_command.rb +49 -0
  39. data/lib/rails/commands/runner/USAGE +17 -0
  40. data/lib/rails/commands/runner/runner_command.rb +46 -0
  41. data/lib/rails/commands/secrets/USAGE +52 -0
  42. data/lib/rails/commands/secrets/secrets_command.rb +36 -0
  43. data/lib/rails/commands/server/server_command.rb +177 -0
  44. data/lib/rails/commands/test/test_command.rb +20 -0
  45. data/lib/rails/commands/version/version_command.rb +9 -0
  46. data/lib/rails/configuration.rb +7 -7
  47. data/lib/rails/console/app.rb +4 -4
  48. data/lib/rails/dev_caching.rb +8 -8
  49. data/lib/rails/engine.rb +62 -63
  50. data/lib/rails/engine/commands.rb +6 -13
  51. data/lib/rails/engine/configuration.rb +2 -2
  52. data/lib/rails/gem_version.rb +3 -3
  53. data/lib/rails/generators.rb +229 -313
  54. data/lib/rails/generators/actions.rb +20 -21
  55. data/lib/rails/generators/actions/create_migration.rb +24 -25
  56. data/lib/rails/generators/active_model.rb +3 -3
  57. data/lib/rails/generators/app_base.rb +123 -93
  58. data/lib/rails/generators/base.rb +32 -33
  59. data/lib/rails/generators/css/assets/assets_generator.rb +1 -1
  60. data/lib/rails/generators/erb.rb +14 -14
  61. data/lib/rails/generators/erb/controller/controller_generator.rb +1 -1
  62. data/lib/rails/generators/erb/mailer/mailer_generator.rb +12 -12
  63. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +3 -3
  64. data/lib/rails/generators/generated_attribute.rb +27 -27
  65. data/lib/rails/generators/js/assets/assets_generator.rb +1 -1
  66. data/lib/rails/generators/migration.rb +8 -8
  67. data/lib/rails/generators/model_helpers.rb +2 -2
  68. data/lib/rails/generators/named_base.rb +56 -56
  69. data/lib/rails/generators/rails/app/app_generator.rb +98 -81
  70. data/lib/rails/generators/rails/app/templates/Gemfile +7 -2
  71. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
  72. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +6 -4
  73. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js +1 -1
  74. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +2 -2
  75. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -1
  76. data/lib/rails/generators/rails/app/templates/bin/{setup → setup.tt} +6 -0
  77. data/lib/rails/generators/rails/app/templates/bin/{update → update.tt} +2 -1
  78. data/lib/rails/generators/rails/app/templates/bin/yarn +9 -0
  79. data/lib/rails/generators/rails/app/templates/config/cable.yml +1 -0
  80. data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml +1 -0
  81. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +1 -0
  82. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +1 -0
  83. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +2 -1
  84. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +1 -0
  85. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +1 -0
  86. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +2 -2
  87. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -0
  88. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +1 -1
  89. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml +1 -1
  90. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +10 -1
  92. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +1 -1
  93. data/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb +4 -6
  94. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +8 -3
  95. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt +6 -5
  96. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +10 -0
  97. data/lib/rails/generators/rails/app/templates/config/puma.rb +16 -7
  98. data/lib/rails/generators/rails/app/templates/config/secrets.yml +12 -2
  99. data/lib/rails/generators/rails/app/templates/gitignore +5 -1
  100. data/lib/rails/generators/rails/app/templates/package.json +5 -0
  101. data/lib/rails/generators/rails/app/templates/public/404.html +6 -6
  102. data/lib/rails/generators/rails/app/templates/public/422.html +6 -6
  103. data/lib/rails/generators/rails/app/templates/public/500.html +6 -6
  104. data/lib/rails/generators/rails/app/templates/public/robots.txt +0 -4
  105. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb +5 -0
  106. data/lib/rails/generators/rails/app/templates/test/test_helper.rb +0 -1
  107. data/lib/rails/generators/rails/assets/assets_generator.rb +10 -10
  108. data/lib/rails/generators/rails/controller/controller_generator.rb +15 -12
  109. data/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb +66 -0
  110. data/lib/rails/generators/rails/encrypted_secrets/templates/config/secrets.yml.enc +3 -0
  111. data/lib/rails/generators/rails/generator/generator_generator.rb +2 -3
  112. data/lib/rails/generators/rails/helper/helper_generator.rb +1 -1
  113. data/lib/rails/generators/rails/model/model_generator.rb +1 -1
  114. data/lib/rails/generators/rails/plugin/plugin_generator.rb +21 -26
  115. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -0
  116. data/lib/rails/generators/rails/plugin/templates/bin/test.tt +3 -9
  117. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb +5 -0
  118. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb +0 -3
  119. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  120. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +5 -1
  121. data/lib/rails/generators/rails/scaffold/templates/scaffold.css +4 -8
  122. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +2 -3
  123. data/lib/rails/generators/rails/system_test/USAGE +10 -0
  124. data/lib/rails/generators/rails/system_test/system_test_generator.rb +7 -0
  125. data/lib/rails/generators/rails/task/task_generator.rb +1 -2
  126. data/lib/rails/generators/resource_helpers.rb +13 -10
  127. data/lib/rails/generators/test_case.rb +5 -6
  128. data/lib/rails/generators/test_unit.rb +1 -1
  129. data/lib/rails/generators/test_unit/controller/controller_generator.rb +3 -3
  130. data/lib/rails/generators/test_unit/generator/generator_generator.rb +3 -3
  131. data/lib/rails/generators/test_unit/helper/helper_generator.rb +1 -1
  132. data/lib/rails/generators/test_unit/integration/integration_generator.rb +2 -2
  133. data/lib/rails/generators/test_unit/job/job_generator.rb +3 -3
  134. data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +5 -5
  135. data/lib/rails/generators/test_unit/model/model_generator.rb +3 -4
  136. data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +2 -2
  137. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +3 -3
  138. data/lib/rails/generators/test_unit/system/system_generator.rb +17 -0
  139. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb +5 -0
  140. data/lib/rails/generators/test_unit/system/templates/system_test.rb +9 -0
  141. data/lib/rails/generators/testing/assertions.rb +4 -4
  142. data/lib/rails/generators/testing/behaviour.rb +20 -21
  143. data/lib/rails/info.rb +20 -20
  144. data/lib/rails/info_controller.rb +15 -15
  145. data/lib/rails/initializable.rb +6 -2
  146. data/lib/rails/mailers_controller.rb +11 -11
  147. data/lib/rails/paths.rb +4 -5
  148. data/lib/rails/plugin/test.rb +7 -0
  149. data/lib/rails/rack/logger.rb +44 -46
  150. data/lib/rails/railtie.rb +41 -38
  151. data/lib/rails/railtie/configurable.rb +6 -6
  152. data/lib/rails/railtie/configuration.rb +1 -1
  153. data/lib/rails/ruby_version_check.rb +1 -1
  154. data/lib/rails/secrets.rb +111 -0
  155. data/lib/rails/source_annotation_extractor.rb +15 -9
  156. data/lib/rails/tasks.rb +3 -2
  157. data/lib/rails/tasks/annotations.rake +3 -3
  158. data/lib/rails/tasks/dev.rake +2 -2
  159. data/lib/rails/tasks/engine.rake +4 -4
  160. data/lib/rails/tasks/framework.rake +4 -18
  161. data/lib/rails/tasks/initializers.rake +1 -1
  162. data/lib/rails/tasks/log.rake +14 -10
  163. data/lib/rails/tasks/middleware.rake +1 -1
  164. data/lib/rails/tasks/misc.rake +10 -10
  165. data/lib/rails/tasks/restart.rake +4 -4
  166. data/lib/rails/tasks/routes.rake +3 -12
  167. data/lib/rails/tasks/statistics.rake +3 -3
  168. data/lib/rails/tasks/tmp.rake +7 -7
  169. data/lib/rails/tasks/yarn.rake +11 -0
  170. data/lib/rails/templates/rails/mailers/email.html.erb +4 -1
  171. data/lib/rails/test_help.rb +28 -10
  172. data/lib/rails/test_unit/line_filtering.rb +69 -3
  173. data/lib/rails/test_unit/minitest_plugin.rb +139 -0
  174. data/lib/rails/test_unit/railtie.rb +2 -1
  175. data/lib/rails/test_unit/reporter.rb +3 -8
  176. data/lib/rails/test_unit/test_requirer.rb +28 -0
  177. data/lib/rails/test_unit/testing.rake +19 -14
  178. data/lib/rails/version.rb +1 -1
  179. data/lib/rails/welcome_controller.rb +1 -1
  180. metadata +53 -30
  181. data/lib/minitest/rails_plugin.rb +0 -49
  182. data/lib/rails/commands/application.rb +0 -17
  183. data/lib/rails/commands/commands_tasks.rb +0 -180
  184. data/lib/rails/commands/console.rb +0 -68
  185. data/lib/rails/commands/console_helper.rb +0 -34
  186. data/lib/rails/commands/dbconsole.rb +0 -173
  187. data/lib/rails/commands/destroy.rb +0 -11
  188. data/lib/rails/commands/generate.rb +0 -13
  189. data/lib/rails/commands/plugin.rb +0 -23
  190. data/lib/rails/commands/rake_proxy.rb +0 -41
  191. data/lib/rails/commands/runner.rb +0 -71
  192. data/lib/rails/commands/server.rb +0 -163
  193. data/lib/rails/commands/test.rb +0 -10
  194. data/lib/rails/engine/commands_tasks.rb +0 -118
  195. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +0 -3
  196. data/lib/rails/rack/debugger.rb +0 -3
  197. data/lib/rails/test_unit/runner.rb +0 -141
@@ -68,7 +68,7 @@ module Rails
68
68
  # add_source "http://gems.github.com/" do
69
69
  # gem "rspec-rails"
70
70
  # end
71
- def add_source(source, options={}, &block)
71
+ def add_source(source, options = {}, &block)
72
72
  log :source, source
73
73
 
74
74
  in_root do
@@ -96,14 +96,14 @@ module Rails
96
96
  # environment(nil, env: "development") do
97
97
  # "config.action_controller.asset_host = 'localhost:3000'"
98
98
  # end
99
- def environment(data=nil, options={})
99
+ def environment(data = nil, options = {})
100
100
  sentinel = /class [a-z_:]+ < Rails::Application/i
101
101
  env_file_sentinel = /Rails\.application\.configure do/
102
102
  data = yield if !data && block_given?
103
103
 
104
104
  in_root do
105
105
  if options[:env].nil?
106
- inject_into_file 'config/application.rb', "\n #{data}", after: sentinel, verbose: false
106
+ inject_into_file "config/application.rb", "\n #{data}", after: sentinel, verbose: false
107
107
  else
108
108
  Array(options[:env]).each do |env|
109
109
  inject_into_file "config/environments/#{env}.rb", "\n #{data}", after: env_file_sentinel, verbose: false
@@ -118,7 +118,7 @@ module Rails
118
118
  # git :init
119
119
  # git add: "this.file that.rb"
120
120
  # git add: "onefile.rb", rm: "badfile.cxx"
121
- def git(commands={})
121
+ def git(commands = {})
122
122
  if commands.is_a?(Symbol)
123
123
  run "git #{commands}"
124
124
  else
@@ -137,7 +137,7 @@ module Rails
137
137
  # end
138
138
  #
139
139
  # vendor("foreign.rb", "# Foreign code is fun")
140
- def vendor(filename, data=nil, &block)
140
+ def vendor(filename, data = nil, &block)
141
141
  log :vendor, filename
142
142
  create_file("vendor/#{filename}", data, verbose: false, &block)
143
143
  end
@@ -150,7 +150,7 @@ module Rails
150
150
  # end
151
151
  #
152
152
  # lib("foreign.rb", "# Foreign code is fun")
153
- def lib(filename, data=nil, &block)
153
+ def lib(filename, data = nil, &block)
154
154
  log :lib, filename
155
155
  create_file("lib/#{filename}", data, verbose: false, &block)
156
156
  end
@@ -170,7 +170,7 @@ module Rails
170
170
  # end
171
171
  #
172
172
  # rakefile('seed.rake', 'puts "Planting seeds"')
173
- def rakefile(filename, data=nil, &block)
173
+ def rakefile(filename, data = nil, &block)
174
174
  log :rakefile, filename
175
175
  create_file("lib/tasks/#{filename}", data, verbose: false, &block)
176
176
  end
@@ -188,7 +188,7 @@ module Rails
188
188
  # end
189
189
  #
190
190
  # initializer("api.rb", "API_KEY = '123456'")
191
- def initializer(filename, data=nil, &block)
191
+ def initializer(filename, data = nil, &block)
192
192
  log :initializer, filename
193
193
  create_file("config/initializers/#{filename}", data, verbose: false, &block)
194
194
  end
@@ -210,7 +210,7 @@ module Rails
210
210
  # rake("db:migrate")
211
211
  # rake("db:migrate", env: "production")
212
212
  # rake("gems:install", sudo: true)
213
- def rake(command, options={})
213
+ def rake(command, options = {})
214
214
  execute_command :rake, command, options
215
215
  end
216
216
 
@@ -219,7 +219,7 @@ module Rails
219
219
  # rails("db:migrate")
220
220
  # rails("db:migrate", env: "production")
221
221
  # rails("gems:install", sudo: true)
222
- def rails_command(command, options={})
222
+ def rails_command(command, options = {})
223
223
  execute_command :rails, command, options
224
224
  end
225
225
 
@@ -239,7 +239,7 @@ module Rails
239
239
  sentinel = /\.routes\.draw do\s*\n/m
240
240
 
241
241
  in_root do
242
- inject_into_file 'config/routes.rb', " #{routing_code}\n", { after: sentinel, verbose: false, force: false }
242
+ inject_into_file "config/routes.rb", " #{routing_code}\n", after: sentinel, verbose: false, force: false
243
243
  end
244
244
  end
245
245
 
@@ -260,33 +260,32 @@ module Rails
260
260
  @after_bundle_callbacks << block
261
261
  end
262
262
 
263
- protected
263
+ private
264
264
 
265
265
  # Define log for backwards compatibility. If just one argument is sent,
266
266
  # invoke say, otherwise invoke say_status. Differently from say and
267
267
  # similarly to say_status, this method respects the quiet? option given.
268
- def log(*args)
268
+ def log(*args) # :doc:
269
269
  if args.size == 1
270
270
  say args.first.to_s unless options.quiet?
271
271
  else
272
- args << (self.behavior == :invoke ? :green : :red)
272
+ args << (behavior == :invoke ? :green : :red)
273
273
  say_status(*args)
274
274
  end
275
275
  end
276
276
 
277
-
278
277
  # Runs the supplied command using either "rake ..." or "rails ..."
279
278
  # based on the executor parameter provided.
280
- def execute_command(executor, command, options={})
279
+ def execute_command(executor, command, options = {}) # :doc:
281
280
  log executor, command
282
- env = options[:env] || ENV["RAILS_ENV"] || 'development'
283
- sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : ''
281
+ env = options[:env] || ENV["RAILS_ENV"] || "development"
282
+ sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
284
283
  in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", verbose: false) }
285
284
  end
286
285
 
287
286
  # Add an extension to the given name based on the platform.
288
- def extify(name)
289
- if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
287
+ def extify(name) # :doc:
288
+ if Gem.win_platform?
290
289
  "#{name}.bat"
291
290
  else
292
291
  name
@@ -295,7 +294,7 @@ module Rails
295
294
 
296
295
  # Surround string with single quotes if there is no quotes.
297
296
  # Otherwise fall back to double quotes
298
- def quote(value)
297
+ def quote(value) # :doc:
299
298
  return value.inspect unless value.is_a? String
300
299
 
301
300
  if value.include?("'")
@@ -1,11 +1,10 @@
1
- require 'fileutils'
2
- require 'thor/actions'
1
+ require "fileutils"
2
+ require "thor/actions"
3
3
 
4
4
  module Rails
5
5
  module Generators
6
6
  module Actions
7
7
  class CreateMigration < Thor::Actions::CreateFile #:nodoc:
8
-
9
8
  def migration_dir
10
9
  File.dirname(@destination)
11
10
  end
@@ -38,32 +37,32 @@ module Rails
38
37
  end
39
38
  alias :exists? :existing_migration
40
39
 
41
- protected
40
+ private
42
41
 
43
- def on_conflict_behavior
44
- options = base.options.merge(config)
45
- if identical?
46
- say_status :identical, :blue, relative_existing_migration
47
- elsif options[:force]
48
- say_status :remove, :green, relative_existing_migration
49
- say_status :create, :green
50
- unless pretend?
51
- ::FileUtils.rm_rf(existing_migration)
52
- yield
42
+ def on_conflict_behavior # :doc:
43
+ options = base.options.merge(config)
44
+ if identical?
45
+ say_status :identical, :blue, relative_existing_migration
46
+ elsif options[:force]
47
+ say_status :remove, :green, relative_existing_migration
48
+ say_status :create, :green
49
+ unless pretend?
50
+ ::FileUtils.rm_rf(existing_migration)
51
+ yield
52
+ end
53
+ elsif options[:skip]
54
+ say_status :skip, :yellow
55
+ else
56
+ say_status :conflict, :red
57
+ raise Error, "Another migration is already named #{migration_file_name}: " \
58
+ "#{existing_migration}. Use --force to replace this migration " \
59
+ "or --skip to ignore conflicted file."
53
60
  end
54
- elsif options[:skip]
55
- say_status :skip, :yellow
56
- else
57
- say_status :conflict, :red
58
- raise Error, "Another migration is already named #{migration_file_name}: " +
59
- "#{existing_migration}. Use --force to replace this migration " +
60
- "or --skip to ignore conflicted file."
61
61
  end
62
- end
63
62
 
64
- def say_status(status, color, message = relative_destination)
65
- base.shell.say_status(status, message, color) if config[:verbose]
66
- end
63
+ def say_status(status, color, message = relative_destination) # :doc:
64
+ base.shell.say_status(status, message, color) if config[:verbose]
65
+ end
67
66
  end
68
67
  end
69
68
  end
@@ -39,13 +39,13 @@ module Rails
39
39
  # GET edit
40
40
  # PATCH/PUT update
41
41
  # DELETE destroy
42
- def self.find(klass, params=nil)
42
+ def self.find(klass, params = nil)
43
43
  "#{klass}.find(#{params})"
44
44
  end
45
45
 
46
46
  # GET new
47
47
  # POST create
48
- def self.build(klass, params=nil)
48
+ def self.build(klass, params = nil)
49
49
  if params
50
50
  "#{klass}.new(#{params})"
51
51
  else
@@ -59,7 +59,7 @@ module Rails
59
59
  end
60
60
 
61
61
  # PATCH/PUT update
62
- def update(params=nil)
62
+ def update(params = nil)
63
63
  "#{name}.update(#{params})"
64
64
  end
65
65
 
@@ -1,16 +1,16 @@
1
- require 'fileutils'
2
- require 'digest/md5'
3
- require 'active_support/core_ext/string/strip'
4
- require 'rails/version' unless defined?(Rails::VERSION)
5
- require 'open-uri'
6
- require 'uri'
7
- require 'rails/generators'
8
- require 'active_support/core_ext/array/extract_options'
1
+ require "fileutils"
2
+ require "digest/md5"
3
+ require "active_support/core_ext/string/strip"
4
+ require "rails/version" unless defined?(Rails::VERSION)
5
+ require "open-uri"
6
+ require "uri"
7
+ require "rails/generators"
8
+ require "active_support/core_ext/array/extract_options"
9
9
 
10
10
  module Rails
11
11
  module Generators
12
12
  class AppBase < Base # :nodoc:
13
- DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver )
13
+ DATABASES = %w( mysql postgresql sqlite3 oracle frontbase ibm_db sqlserver )
14
14
  JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
15
15
  DATABASES.concat(JDBC_DATABASES)
16
16
 
@@ -24,42 +24,45 @@ module Rails
24
24
  end
25
25
 
26
26
  def self.add_shared_options_for(name)
27
- class_option :template, type: :string, aliases: '-m',
27
+ class_option :template, type: :string, aliases: "-m",
28
28
  desc: "Path to some #{name} template (can be a filesystem path or URL)"
29
29
 
30
- class_option :database, type: :string, aliases: '-d', default: 'sqlite3',
30
+ class_option :database, type: :string, aliases: "-d", default: "sqlite3",
31
31
  desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
32
32
 
33
- class_option :javascript, type: :string, aliases: '-j', default: 'jquery',
34
- desc: 'Preconfigure for selected JavaScript library'
33
+ class_option :javascript, type: :string, aliases: "-j",
34
+ desc: "Preconfigure for selected JavaScript library"
35
+
36
+ class_option :webpack, type: :string, default: nil,
37
+ desc: "Preconfigure for app-like JavaScript with Webpack"
38
+
39
+ class_option :skip_yarn, type: :boolean, default: false,
40
+ desc: "Don't use Yarn for managing JavaScript dependencies"
35
41
 
36
42
  class_option :skip_gemfile, type: :boolean, default: false,
37
43
  desc: "Don't create a Gemfile"
38
44
 
39
- class_option :skip_bundle, type: :boolean, aliases: '-B', default: false,
40
- desc: "Don't run bundle install"
41
-
42
- class_option :skip_git, type: :boolean, aliases: '-G', default: false,
43
- desc: 'Skip .gitignore file'
45
+ class_option :skip_git, type: :boolean, aliases: "-G", default: false,
46
+ desc: "Skip .gitignore file"
44
47
 
45
48
  class_option :skip_keeps, type: :boolean, default: false,
46
- desc: 'Skip source control .keep files'
49
+ desc: "Skip source control .keep files"
47
50
 
48
51
  class_option :skip_action_mailer, type: :boolean, aliases: "-M",
49
52
  default: false,
50
53
  desc: "Skip Action Mailer files"
51
54
 
52
- class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
53
- desc: 'Skip Active Record files'
55
+ class_option :skip_active_record, type: :boolean, aliases: "-O", default: false,
56
+ desc: "Skip Active Record files"
54
57
 
55
- class_option :skip_puma, type: :boolean, aliases: '-P', default: false,
56
- desc: 'Skip Puma related files'
58
+ class_option :skip_puma, type: :boolean, aliases: "-P", default: false,
59
+ desc: "Skip Puma related files"
57
60
 
58
- class_option :skip_action_cable, type: :boolean, aliases: '-C', default: false,
59
- desc: 'Skip Action Cable files'
61
+ class_option :skip_action_cable, type: :boolean, aliases: "-C", default: false,
62
+ desc: "Skip Action Cable files"
60
63
 
61
- class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false,
62
- desc: 'Skip Sprockets files'
64
+ class_option :skip_sprockets, type: :boolean, aliases: "-S", default: false,
65
+ desc: "Skip Sprockets files"
63
66
 
64
67
  class_option :skip_spring, type: :boolean, default: false,
65
68
  desc: "Don't install Spring application preloader"
@@ -67,14 +70,20 @@ module Rails
67
70
  class_option :skip_listen, type: :boolean, default: false,
68
71
  desc: "Don't generate configuration that depends on the listen gem"
69
72
 
70
- class_option :skip_javascript, type: :boolean, aliases: '-J', default: false,
71
- desc: 'Skip JavaScript files'
73
+ class_option :skip_coffee, type: :boolean, default: false,
74
+ desc: "Don't use CoffeeScript"
75
+
76
+ class_option :skip_javascript, type: :boolean, aliases: "-J", default: false,
77
+ desc: "Skip JavaScript files"
72
78
 
73
79
  class_option :skip_turbolinks, type: :boolean, default: false,
74
- desc: 'Skip turbolinks gem'
80
+ desc: "Skip turbolinks gem"
81
+
82
+ class_option :skip_test, type: :boolean, aliases: "-T", default: false,
83
+ desc: "Skip test files"
75
84
 
76
- class_option :skip_test, type: :boolean, aliases: '-T', default: false,
77
- desc: 'Skip test files'
85
+ class_option :skip_system_test, type: :boolean, default: false,
86
+ desc: "Skip system test files"
78
87
 
79
88
  class_option :dev, type: :boolean, default: false,
80
89
  desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
@@ -86,10 +95,10 @@ module Rails
86
95
  desc: "Path to file containing extra configuration options for rails command"
87
96
 
88
97
  class_option :no_rc, type: :boolean, default: false,
89
- desc: 'Skip loading of extra configuration options from .railsrc file'
98
+ desc: "Skip loading of extra configuration options from .railsrc file"
90
99
 
91
- class_option :help, type: :boolean, aliases: '-h', group: :rails,
92
- desc: 'Show this help message and quit'
100
+ class_option :help, type: :boolean, aliases: "-h", group: :rails,
101
+ desc: "Show this help message and quit"
93
102
  end
94
103
 
95
104
  def initialize(*args)
@@ -99,9 +108,9 @@ module Rails
99
108
  convert_database_option_for_jruby
100
109
  end
101
110
 
102
- protected
111
+ private
103
112
 
104
- def gemfile_entry(name, *args)
113
+ def gemfile_entry(name, *args) # :doc:
105
114
  options = args.extract_options!
106
115
  version = args.first
107
116
  github = options[:github]
@@ -117,11 +126,12 @@ module Rails
117
126
  self
118
127
  end
119
128
 
120
- def gemfile_entries
129
+ def gemfile_entries # :doc:
121
130
  [rails_gemfile_entry,
122
131
  database_gemfile_entry,
123
132
  webserver_gemfile_entry,
124
133
  assets_gemfile_entry,
134
+ webpacker_gemfile_entry,
125
135
  javascript_gemfile_entry,
126
136
  jbuilder_gemfile_entry,
127
137
  psych_gemfile_entry,
@@ -129,13 +139,13 @@ module Rails
129
139
  @extra_entries].flatten.find_all(&@gem_filter)
130
140
  end
131
141
 
132
- def add_gem_entry_filter
142
+ def add_gem_entry_filter # :doc:
133
143
  @gem_filter = lambda { |next_filter, entry|
134
144
  yield(entry) && next_filter.call(entry)
135
145
  }.curry[@gem_filter]
136
146
  end
137
147
 
138
- def builder
148
+ def builder # :doc:
139
149
  @builder ||= begin
140
150
  builder_class = get_builder_class
141
151
  builder_class.include(ActionMethods)
@@ -143,62 +153,63 @@ module Rails
143
153
  end
144
154
  end
145
155
 
146
- def build(meth, *args)
156
+ def build(meth, *args) # :doc:
147
157
  builder.send(meth, *args) if builder.respond_to?(meth)
148
158
  end
149
159
 
150
- def create_root
160
+ def create_root # :doc:
151
161
  valid_const?
152
162
 
153
- empty_directory '.'
163
+ empty_directory "."
154
164
  FileUtils.cd(destination_root) unless options[:pretend]
155
165
  end
156
166
 
157
- def apply_rails_template
167
+ def apply_rails_template # :doc:
158
168
  apply rails_template if rails_template
159
169
  rescue Thor::Error, LoadError, Errno::ENOENT => e
160
170
  raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
161
171
  end
162
172
 
163
- def set_default_accessors!
173
+ def set_default_accessors! # :doc:
164
174
  self.destination_root = File.expand_path(app_path, destination_root)
165
- self.rails_template = case options[:template]
175
+ self.rails_template = \
176
+ case options[:template]
166
177
  when /^https?:\/\//
167
178
  options[:template]
168
179
  when String
169
180
  File.expand_path(options[:template], Dir.pwd)
170
181
  else
171
182
  options[:template]
172
- end
183
+ end
173
184
  end
174
185
 
175
- def database_gemfile_entry
186
+ def database_gemfile_entry # :doc:
176
187
  return [] if options[:skip_active_record]
177
188
  gem_name, gem_version = gem_for_database
178
189
  GemfileEntry.version gem_name, gem_version,
179
190
  "Use #{options[:database]} as the database for Active Record"
180
191
  end
181
192
 
182
- def webserver_gemfile_entry
193
+ def webserver_gemfile_entry # :doc:
183
194
  return [] if options[:skip_puma]
184
- comment = 'Use Puma as the app server'
185
- GemfileEntry.new('puma', '~> 3.0', comment)
195
+ comment = "Use Puma as the app server"
196
+ GemfileEntry.new("puma", "~> 3.7", comment)
186
197
  end
187
198
 
188
- def include_all_railties?
199
+ def include_all_railties? # :doc:
189
200
  options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none?
190
201
  end
191
202
 
192
- def comment_if(value)
193
- options[value] ? '# ' : ''
203
+ def comment_if(value) # :doc:
204
+ options[value] ? "# " : ""
194
205
  end
195
206
 
196
- def keeps?
207
+ def keeps? # :doc:
197
208
  !options[:skip_keeps]
198
209
  end
199
210
 
200
- def sqlite3?
201
- !options[:skip_active_record] && options[:database] == 'sqlite3'
211
+ def sqlite3? # :doc:
212
+ !options[:skip_active_record] && options[:database] == "sqlite3"
202
213
  end
203
214
 
204
215
  class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
@@ -238,40 +249,39 @@ module Rails
238
249
  ]
239
250
  if options.dev?
240
251
  [
241
- GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH)
252
+ GemfileEntry.path("rails", Rails::Generators::RAILS_DEV_PATH)
242
253
  ] + dev_edge_common
243
254
  elsif options.edge?
244
255
  [
245
- GemfileEntry.github('rails', 'rails/rails', '5-0-stable')
256
+ GemfileEntry.github("rails", "rails/rails")
246
257
  ] + dev_edge_common
247
258
  else
248
- [GemfileEntry.version('rails',
259
+ [GemfileEntry.version("rails",
249
260
  rails_version_specifier,
250
261
  "Bundle edge Rails instead: gem 'rails', github: 'rails/rails'")]
251
262
  end
252
263
  end
253
264
 
254
265
  def rails_version_specifier(gem_version = Rails.gem_version)
255
- if gem_version.prerelease?
256
- next_series = gem_version
257
- next_series = next_series.bump while next_series.segments.size > 2
258
-
259
- [">= #{gem_version}", "< #{next_series}"]
260
- elsif gem_version.segments.size == 3
266
+ if gem_version.segments.size == 3 || gem_version.release.segments.size == 3
267
+ # ~> 1.2.3
268
+ # ~> 1.2.3.pre4
261
269
  "~> #{gem_version}"
262
270
  else
271
+ # ~> 1.2.3, >= 1.2.3.4
272
+ # ~> 1.2.3, >= 1.2.3.4.pre5
263
273
  patch = gem_version.segments[0, 3].join(".")
264
274
  ["~> #{patch}", ">= #{gem_version}"]
265
275
  end
266
276
  end
267
277
 
268
278
  def gem_for_database
269
- # %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql )
279
+ # %w( mysql postgresql sqlite3 oracle frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql )
270
280
  case options[:database]
281
+ when "mysql" then ["mysql2", [">= 0.3.18", "< 0.5"]]
282
+ when "postgresql" then ["pg", ["~> 0.18"]]
271
283
  when "oracle" then ["ruby-oci8", nil]
272
- when "postgresql" then ["pg", [">= 0.18", "< 2.0"]]
273
284
  when "frontbase" then ["ruby-frontbase", nil]
274
- when "mysql" then ["mysql2", [">= 0.3.18", "< 0.6.0"]]
275
285
  when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
276
286
  when "jdbcmysql" then ["activerecord-jdbcmysql-adapter", nil]
277
287
  when "jdbcsqlite3" then ["activerecord-jdbcsqlite3-adapter", nil]
@@ -284,9 +294,9 @@ module Rails
284
294
  def convert_database_option_for_jruby
285
295
  if defined?(JRUBY_VERSION)
286
296
  case options[:database]
287
- when "oracle" then options[:database].replace "jdbc"
288
297
  when "postgresql" then options[:database].replace "jdbcpostgresql"
289
298
  when "mysql" then options[:database].replace "jdbcmysql"
299
+ when "oracle" then options[:database].replace "jdbc"
290
300
  when "sqlite3" then options[:database].replace "jdbcsqlite3"
291
301
  end
292
302
  end
@@ -296,32 +306,45 @@ module Rails
296
306
  return [] if options[:skip_sprockets]
297
307
 
298
308
  gems = []
299
- gems << GemfileEntry.version('sass-rails', '~> 5.0',
300
- 'Use SCSS for stylesheets')
309
+ gems << GemfileEntry.github("sass-rails", "rails/sass-rails", nil,
310
+ "Use SCSS for stylesheets")
301
311
 
302
- gems << GemfileEntry.version('uglifier',
303
- '>= 1.3.0',
304
- 'Use Uglifier as compressor for JavaScript assets')
312
+ if !options[:skip_javascript]
313
+ gems << GemfileEntry.version("uglifier",
314
+ ">= 1.3.0",
315
+ "Use Uglifier as compressor for JavaScript assets")
316
+ end
305
317
 
306
318
  gems
307
319
  end
308
320
 
321
+ def webpacker_gemfile_entry
322
+ return [] unless options[:webpack]
323
+
324
+ comment = "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker"
325
+ GemfileEntry.github "webpacker", "rails/webpacker", nil, comment
326
+ end
327
+
309
328
  def jbuilder_gemfile_entry
310
- comment = 'Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder'
311
- GemfileEntry.new 'jbuilder', '~> 2.5', comment, {}, options[:api]
329
+ comment = "Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder"
330
+ GemfileEntry.new "jbuilder", "~> 2.5", comment, {}, options[:api]
312
331
  end
313
332
 
314
333
  def coffee_gemfile_entry
315
- GemfileEntry.version 'coffee-rails', '~> 4.2', 'Use CoffeeScript for .coffee assets and views'
334
+ GemfileEntry.version "coffee-rails", "~> 4.2", "Use CoffeeScript for .coffee assets and views"
316
335
  end
317
336
 
318
337
  def javascript_gemfile_entry
319
338
  if options[:skip_javascript] || options[:skip_sprockets]
320
339
  []
321
340
  else
322
- gems = [coffee_gemfile_entry, javascript_runtime_gemfile_entry]
323
- gems << GemfileEntry.version("#{options[:javascript]}-rails", nil,
324
- "Use #{options[:javascript]} as the JavaScript library")
341
+ gems = [javascript_runtime_gemfile_entry]
342
+ gems << coffee_gemfile_entry unless options[:skip_coffee]
343
+
344
+ if options[:javascript]
345
+ gems << GemfileEntry.version("#{options[:javascript]}-rails", nil,
346
+ "Use #{options[:javascript]} as the JavaScript library")
347
+ end
325
348
 
326
349
  unless options[:skip_turbolinks]
327
350
  gems << GemfileEntry.version("turbolinks", "~> 5",
@@ -333,27 +356,27 @@ module Rails
333
356
  end
334
357
 
335
358
  def javascript_runtime_gemfile_entry
336
- comment = 'See https://github.com/rails/execjs#readme for more supported runtimes'
359
+ comment = "See https://github.com/rails/execjs#readme for more supported runtimes"
337
360
  if defined?(JRUBY_VERSION)
338
- GemfileEntry.version 'therubyrhino', nil, comment
361
+ GemfileEntry.version "therubyrhino", nil, comment
339
362
  else
340
- GemfileEntry.new 'therubyracer', nil, comment, { platforms: :ruby }, true
363
+ GemfileEntry.new "therubyracer", nil, comment, { platforms: :ruby }, true
341
364
  end
342
365
  end
343
366
 
344
367
  def psych_gemfile_entry
345
368
  return [] unless defined?(Rubinius)
346
369
 
347
- comment = 'Use Psych as the YAML engine, instead of Syck, so serialized ' \
348
- 'data can be read safely from different rubies (see http://git.io/uuLVag)'
349
- GemfileEntry.new('psych', '~> 2.0', comment, platforms: :rbx)
370
+ comment = "Use Psych as the YAML engine, instead of Syck, so serialized " \
371
+ "data can be read safely from different rubies (see http://git.io/uuLVag)"
372
+ GemfileEntry.new("psych", "~> 2.0", comment, platforms: :rbx)
350
373
  end
351
374
 
352
375
  def cable_gemfile_entry
353
376
  return [] if options[:skip_action_cable]
354
- comment = 'Use Redis adapter to run Action Cable in production'
377
+ comment = "Use Redis adapter to run Action Cable in production"
355
378
  gems = []
356
- gems << GemfileEntry.new("redis", '~> 3.0', comment, {}, true)
379
+ gems << GemfileEntry.new("redis", "~> 3.0", comment, {}, true)
357
380
  gems
358
381
  end
359
382
 
@@ -368,9 +391,9 @@ module Rails
368
391
  # We unset temporary bundler variables to load proper bundler and Gemfile.
369
392
  #
370
393
  # Thanks to James Tucker for the Gem tricks involved in this call.
371
- _bundle_command = Gem.bin_path('bundler', 'bundle')
394
+ _bundle_command = Gem.bin_path("bundler", "bundle")
372
395
 
373
- require 'bundler'
396
+ require "bundler"
374
397
  Bundler.with_clean_env do
375
398
  full_command = %Q["#{Gem.ruby}" "#{_bundle_command}" #{command}]
376
399
  if options[:quiet]
@@ -394,11 +417,18 @@ module Rails
394
417
  end
395
418
 
396
419
  def os_supports_listen_out_of_the_box?
397
- RbConfig::CONFIG['host_os'] =~ /darwin|linux/
420
+ RbConfig::CONFIG["host_os"] =~ /darwin|linux/
398
421
  end
399
422
 
400
423
  def run_bundle
401
- bundle_command('install') if bundle_install?
424
+ bundle_command("install") if bundle_install?
425
+ end
426
+
427
+ def run_webpack
428
+ if !(webpack = options[:webpack]).nil?
429
+ rails_command "webpacker:install"
430
+ rails_command "webpacker:install:#{webpack}" unless webpack == "webpack"
431
+ end
402
432
  end
403
433
 
404
434
  def generate_spring_binstubs