railties 3.0.20 → 3.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/CHANGELOG +36 -49
  2. data/README.rdoc +2 -1
  3. data/guides/assets/stylesheets/fixes.css +16 -0
  4. data/guides/rails_guides.rb +2 -2
  5. data/guides/rails_guides/generator.rb +8 -3
  6. data/guides/rails_guides/textile_extensions.rb +4 -2
  7. data/guides/source/2_2_release_notes.textile +3 -3
  8. data/guides/source/2_3_release_notes.textile +2 -2
  9. data/guides/source/3_0_release_notes.textile +14 -14
  10. data/guides/source/action_controller_overview.textile +54 -79
  11. data/guides/source/action_mailer_basics.textile +39 -9
  12. data/guides/source/action_view_overview.textile +257 -211
  13. data/guides/source/active_record_basics.textile +1 -1
  14. data/guides/source/active_record_querying.textile +217 -27
  15. data/guides/source/active_record_validations_callbacks.textile +94 -25
  16. data/guides/source/active_support_core_extensions.textile +109 -77
  17. data/guides/source/ajax_on_rails.textile +15 -150
  18. data/guides/source/api_documentation_guidelines.textile +12 -12
  19. data/guides/source/association_basics.textile +74 -60
  20. data/guides/source/caching_with_rails.textile +59 -60
  21. data/guides/source/command_line.textile +46 -47
  22. data/guides/source/configuring.textile +55 -37
  23. data/guides/source/contribute.textile +7 -7
  24. data/guides/source/contributing_to_ruby_on_rails.textile +14 -23
  25. data/guides/source/credits.html.erb +3 -3
  26. data/guides/source/debugging_rails_applications.textile +59 -46
  27. data/guides/source/form_helpers.textile +76 -31
  28. data/guides/source/generators.textile +39 -40
  29. data/guides/source/getting_started.textile +73 -94
  30. data/guides/source/i18n.textile +64 -58
  31. data/guides/source/index.html.erb +3 -3
  32. data/guides/source/initialization.textile +634 -3284
  33. data/guides/source/layout.html.erb +6 -7
  34. data/guides/source/layouts_and_rendering.textile +59 -60
  35. data/guides/source/migrations.textile +63 -59
  36. data/guides/source/nested_model_forms.textile +2 -2
  37. data/guides/source/performance_testing.textile +16 -16
  38. data/guides/source/plugins.textile +236 -1280
  39. data/guides/source/rails_application_templates.textile +37 -29
  40. data/guides/source/rails_on_rack.textile +4 -9
  41. data/guides/source/routing.textile +96 -75
  42. data/guides/source/ruby_on_rails_guides_guidelines.textile +19 -12
  43. data/guides/source/security.textile +57 -30
  44. data/guides/source/testing.textile +26 -24
  45. data/guides/w3c_validator.rb +2 -2
  46. data/lib/rails.rb +1 -7
  47. data/lib/rails/application.rb +46 -76
  48. data/lib/rails/application/bootstrap.rb +6 -11
  49. data/lib/rails/application/configuration.rb +43 -40
  50. data/lib/rails/application/finisher.rb +16 -4
  51. data/lib/rails/application/railties.rb +6 -24
  52. data/lib/rails/application/routes_reloader.rb +45 -0
  53. data/lib/rails/backtrace_cleaner.rb +1 -1
  54. data/lib/rails/cli.rb +7 -5
  55. data/lib/rails/commands.rb +27 -2
  56. data/lib/rails/commands/application.rb +14 -1
  57. data/lib/rails/commands/benchmarker.rb +3 -1
  58. data/lib/rails/commands/dbconsole.rb +2 -2
  59. data/lib/rails/commands/destroy.rb +3 -1
  60. data/lib/rails/commands/generate.rb +3 -1
  61. data/lib/rails/commands/plugin.rb +2 -7
  62. data/lib/rails/commands/plugin_new.rb +10 -0
  63. data/lib/rails/commands/profiler.rb +3 -1
  64. data/lib/rails/commands/server.rb +4 -0
  65. data/lib/rails/configuration.rb +8 -81
  66. data/lib/rails/console/app.rb +2 -2
  67. data/lib/rails/engine.rb +460 -78
  68. data/lib/rails/engine/configuration.rb +46 -49
  69. data/lib/rails/engine/railties.rb +33 -0
  70. data/lib/rails/generators.rb +11 -5
  71. data/lib/rails/generators/actions.rb +2 -27
  72. data/lib/rails/generators/app_base.rb +216 -0
  73. data/lib/rails/generators/base.rb +3 -2
  74. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +1 -1
  75. data/lib/rails/generators/generated_attribute.rb +2 -1
  76. data/lib/rails/generators/migration.rb +6 -2
  77. data/lib/rails/generators/named_base.rb +79 -3
  78. data/lib/rails/generators/rails/app/app_generator.rb +44 -209
  79. data/lib/rails/generators/rails/app/templates/Gemfile +15 -31
  80. data/lib/rails/generators/rails/app/templates/README +2 -2
  81. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  82. data/lib/rails/generators/rails/app/templates/{public → app/assets}/images/rails.png +0 -0
  83. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +8 -0
  84. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +5 -0
  85. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  86. data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
  87. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
  88. data/lib/rails/generators/rails/app/templates/config/application.rb +19 -3
  89. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +4 -4
  90. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +11 -6
  91. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
  92. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  93. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -2
  94. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -11
  95. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -1
  96. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -1
  97. data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +12 -0
  98. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
  99. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  100. data/lib/rails/generators/rails/app/templates/db/{seeds.rb → seeds.rb.tt} +2 -2
  101. data/lib/rails/generators/rails/app/templates/public/index.html +10 -8
  102. data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  103. data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  104. data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  105. data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  106. data/lib/rails/generators/rails/app/templates/test/{test_helper.rb.tt → test_helper.rb} +0 -0
  107. data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  108. data/lib/rails/generators/rails/assets/USAGE +20 -0
  109. data/lib/rails/generators/rails/assets/assets_generator.rb +39 -0
  110. data/lib/rails/generators/rails/assets/templates/javascript.js +2 -0
  111. data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +3 -0
  112. data/lib/rails/generators/rails/assets/templates/stylesheet.css +4 -0
  113. data/lib/rails/generators/rails/assets/templates/stylesheet.css.scss +5 -0
  114. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  115. data/lib/rails/generators/rails/controller/templates/controller.rb +2 -0
  116. data/lib/rails/generators/rails/generator/generator_generator.rb +2 -2
  117. data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
  118. data/lib/rails/generators/rails/helper/templates/helper.rb +2 -0
  119. data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -0
  120. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -4
  121. data/lib/rails/generators/rails/plugin_new/USAGE +10 -0
  122. data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +303 -0
  123. data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +9 -0
  124. data/lib/rails/generators/rails/plugin_new/templates/Gemfile +11 -0
  125. data/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +20 -0
  126. data/lib/rails/generators/rails/plugin_new/templates/README.rdoc +3 -0
  127. data/lib/rails/generators/rails/plugin_new/templates/Rakefile +21 -0
  128. data/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +4 -0
  129. data/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +4 -0
  130. data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
  131. data/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +6 -0
  132. data/lib/rails/generators/rails/plugin_new/templates/gitignore +6 -0
  133. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +6 -0
  134. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +7 -0
  135. data/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +4 -0
  136. data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +16 -0
  137. data/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +10 -0
  138. data/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +4 -0
  139. data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -0
  140. data/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +7 -0
  141. data/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +12 -0
  142. data/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +10 -0
  143. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  144. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +20 -1
  145. data/lib/rails/generators/rails/{stylesheets → scaffold}/templates/scaffold.css +0 -0
  146. data/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss +58 -0
  147. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +21 -19
  148. data/lib/rails/generators/resource_helpers.rb +3 -3
  149. data/lib/rails/generators/test_case.rb +2 -20
  150. data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +5 -4
  151. data/lib/rails/generators/test_unit/helper/templates/helper_test.rb +2 -0
  152. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +3 -4
  153. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +5 -4
  154. data/lib/rails/generators/test_unit/model/templates/fixtures.yml +1 -1
  155. data/lib/rails/generators/test_unit/model/templates/unit_test.rb +5 -4
  156. data/lib/rails/generators/test_unit/observer/templates/unit_test.rb +5 -4
  157. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +3 -4
  158. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +7 -5
  159. data/lib/rails/info.rb +0 -1
  160. data/lib/rails/paths.rb +119 -65
  161. data/lib/rails/plugin.rb +18 -19
  162. data/lib/rails/rack/log_tailer.rb +1 -1
  163. data/lib/rails/railtie.rb +50 -47
  164. data/lib/rails/railtie/configurable.rb +20 -10
  165. data/lib/rails/railtie/configuration.rb +20 -19
  166. data/lib/rails/source_annotation_extractor.rb +5 -5
  167. data/lib/rails/tasks.rb +1 -0
  168. data/lib/rails/tasks/assets.rake +10 -0
  169. data/lib/rails/tasks/documentation.rake +2 -8
  170. data/lib/rails/tasks/engine.rake +69 -0
  171. data/lib/rails/tasks/framework.rake +4 -21
  172. data/lib/rails/tasks/misc.rake +1 -1
  173. data/lib/rails/tasks/routes.rake +2 -1
  174. data/lib/rails/test_help.rb +17 -1
  175. data/lib/rails/test_unit/railtie.rb +1 -1
  176. data/lib/rails/test_unit/testing.rake +8 -3
  177. data/lib/rails/version.rb +3 -3
  178. metadata +128 -100
  179. checksums.yaml +0 -7
  180. data/lib/rails/application/configurable.rb +0 -19
  181. data/lib/rails/console/sandbox.rb +0 -6
  182. data/lib/rails/deprecation.rb +0 -41
  183. data/lib/rails/engine/configurable.rb +0 -25
  184. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +0 -62
  185. data/lib/rails/generators/rails/app/templates/public/javascripts/application.js +0 -2
  186. data/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +0 -965
  187. data/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +0 -974
  188. data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +0 -1123
  189. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +0 -6001
  190. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +0 -202
  191. data/lib/rails/generators/rails/stylesheets/USAGE +0 -5
  192. data/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +0 -9
  193. data/lib/rails/info_routes.rb +0 -3
@@ -0,0 +1,45 @@
1
+ module Rails
2
+ class Application
3
+ class RoutesReloader < ::ActiveSupport::FileUpdateChecker
4
+ attr_reader :route_sets
5
+
6
+ def initialize
7
+ super([]) { reload! }
8
+ @route_sets = []
9
+ end
10
+
11
+ def reload!
12
+ clear!
13
+ load_paths
14
+ finalize!
15
+ ensure
16
+ revert
17
+ end
18
+
19
+ protected
20
+
21
+ def clear!
22
+ route_sets.each do |routes|
23
+ routes.disable_clear_and_finalize = true
24
+ routes.clear!
25
+ end
26
+ end
27
+
28
+ def load_paths
29
+ paths.each { |path| load(path) }
30
+ end
31
+
32
+ def finalize!
33
+ route_sets.each do |routes|
34
+ ActiveSupport.on_load(:action_controller) { routes.finalize! }
35
+ end
36
+ end
37
+
38
+ def revert
39
+ route_sets.each do |routes|
40
+ routes.disable_clear_and_finalize = false
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -22,7 +22,7 @@ module Rails
22
22
  gems_paths = (Gem.path + [Gem.default_dir]).uniq.map!{ |p| Regexp.escape(p) }
23
23
  return if gems_paths.empty?
24
24
 
25
- gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w\.]+)/(.*)}
25
+ gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
26
26
  add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') }
27
27
  end
28
28
  end
@@ -5,10 +5,12 @@ require 'rails/script_rails_loader'
5
5
  # the rest of this script is not run.
6
6
  Rails::ScriptRailsLoader.exec_script_rails!
7
7
 
8
- railties_path = File.expand_path('../../lib', __FILE__)
9
- $:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path)
10
-
11
8
  require 'rails/ruby_version_check'
12
- Signal.trap("INT") { puts; exit }
9
+ Signal.trap("INT") { puts; exit(1) }
13
10
 
14
- require 'rails/commands/application'
11
+ if ARGV.first == 'plugin'
12
+ ARGV.shift
13
+ require 'rails/commands/plugin_new'
14
+ else
15
+ require 'rails/commands/application'
16
+ end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/object/inclusion'
2
+
1
3
  ARGV << '--help' if ARGV.empty?
2
4
 
3
5
  aliases = {
@@ -11,7 +13,21 @@ command = ARGV.shift
11
13
  command = aliases[command] || command
12
14
 
13
15
  case command
14
- when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler'
16
+ when 'generate', 'destroy', 'plugin'
17
+ if command == 'plugin' && ARGV.first == 'new'
18
+ require "rails/commands/plugin_new"
19
+ else
20
+ require APP_PATH
21
+ Rails.application.require_environment!
22
+
23
+ if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
24
+ Rails.application = engine
25
+ end
26
+
27
+ require "rails/commands/#{command}"
28
+ end
29
+
30
+ when 'benchmarker', 'profiler'
15
31
  require APP_PATH
16
32
  Rails.application.require_environment!
17
33
  require "rails/commands/#{command}"
@@ -23,8 +39,15 @@ when 'console'
23
39
  Rails::Console.start(Rails.application)
24
40
 
25
41
  when 'server'
42
+ # Change to the application's path if there is no config.ru file in current dir.
43
+ # This allows us to run script/rails server from other directories, but still get
44
+ # the main config.ru and properly set the tmp directory.
45
+ Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
46
+
26
47
  require 'rails/commands/server'
27
48
  Rails::Server.new.tap { |server|
49
+ # We need to require application after the server sets environment,
50
+ # otherwise the --environment option given to the server won't propagate.
28
51
  require APP_PATH
29
52
  Dir.chdir(Rails.application.root)
30
53
  server.start
@@ -41,13 +64,14 @@ when 'application', 'runner'
41
64
  when 'new'
42
65
  puts "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\n"
43
66
  puts "Type 'rails' for help."
67
+ exit(1)
44
68
 
45
69
  when '--version', '-v'
46
70
  ARGV.unshift '--version'
47
71
  require 'rails/commands/application'
48
72
 
49
73
  else
50
- puts "Error: Command not recognized" unless %w(-h --help).include?(command)
74
+ puts "Error: Command not recognized" unless command.in?(['-h', '--help'])
51
75
  puts <<-EOT
52
76
  Usage: rails COMMAND [ARGS]
53
77
 
@@ -70,4 +94,5 @@ In addition to those, there are:
70
94
 
71
95
  All commands can be run with -h for more information.
72
96
  EOT
97
+ exit(1)
73
98
  end
@@ -1,5 +1,6 @@
1
1
  require 'rails/version'
2
- if %w(--version -v).include? ARGV.first
2
+
3
+ if ['--version', '-v'].include?(ARGV.first)
3
4
  puts "Rails #{Rails::VERSION::STRING}"
4
5
  exit(0)
5
6
  end
@@ -15,4 +16,16 @@ require 'rubygems' if ARGV.include?("--dev")
15
16
  require 'rails/generators'
16
17
  require 'rails/generators/rails/app/app_generator'
17
18
 
19
+ module Rails
20
+ module Generators
21
+ class AppGenerator
22
+ # We want to exit on failure to be kind to other libraries
23
+ # This is only when accessing via CLI
24
+ def self.exit_on_failure?
25
+ true
26
+ end
27
+ end
28
+ end
29
+ end
30
+
18
31
  Rails::Generators::AppGenerator.start
@@ -1,4 +1,6 @@
1
- if [nil, "-h", "--help"].include?(ARGV.first)
1
+ require 'active_support/core_ext/object/inclusion'
2
+
3
+ if ARGV.first.in?([nil, "-h", "--help"])
2
4
  puts "Usage: rails benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..."
3
5
  exit 1
4
6
  end
@@ -80,7 +80,7 @@ module Rails
80
80
 
81
81
  exec(find_cmd('mysql', 'mysql5'), *args)
82
82
 
83
- when "postgresql"
83
+ when "postgresql", "postgres"
84
84
  ENV['PGUSER'] = config["username"] if config["username"]
85
85
  ENV['PGHOST'] = config["host"] if config["host"]
86
86
  ENV['PGPORT'] = config["port"].to_s if config["port"]
@@ -119,5 +119,5 @@ end
119
119
 
120
120
  # Has to set the RAILS_ENV before config/application is required
121
121
  if ARGV.first && !ARGV.first.index("-") && env = ARGV.first
122
- ENV['RAILS_ENV'] = %w(production development test).find { |e| e.index(env) } || env
122
+ ENV['RAILS_ENV'] = %w(production development test).detect {|e| e =~ /^#{env}/} || env
123
123
  end
@@ -1,7 +1,9 @@
1
1
  require 'rails/generators'
2
+ require 'active_support/core_ext/object/inclusion'
3
+
2
4
  Rails::Generators.configure!
3
5
 
4
- if [nil, "-h", "--help"].include?(ARGV.first)
6
+ if ARGV.first.in?([nil, "-h", "--help"])
5
7
  Rails::Generators.help 'destroy'
6
8
  exit
7
9
  end
@@ -1,7 +1,9 @@
1
1
  require 'rails/generators'
2
+ require 'active_support/core_ext/object/inclusion'
3
+
2
4
  Rails::Generators.configure!
3
5
 
4
- if [nil, "-h", "--help"].include?(ARGV.first)
6
+ if ARGV.first.in?([nil, "-h", "--help"])
5
7
  Rails::Generators.help 'generate'
6
8
  exit
7
9
  end
@@ -58,7 +58,7 @@ class RailsEnvironment
58
58
  else
59
59
  plugin = name_uri_or_plugin
60
60
  end
61
- unless plugin.nil?
61
+ if plugin
62
62
  plugin.install
63
63
  else
64
64
  puts "Plugin not found: #{name_uri_or_plugin}"
@@ -276,12 +276,11 @@ end
276
276
  require 'optparse'
277
277
  module Commands
278
278
  class Plugin
279
- attr_reader :environment, :script_name, :sources
279
+ attr_reader :environment, :script_name
280
280
  def initialize
281
281
  @environment = RailsEnvironment.default
282
282
  @rails_root = RailsEnvironment.default.root
283
283
  @script_name = File.basename($0)
284
- @sources = []
285
284
  end
286
285
 
287
286
  def environment=(value)
@@ -301,8 +300,6 @@ module Commands
301
300
  o.on("-r", "--root=DIR", String,
302
301
  "Set an explicit rails app directory.",
303
302
  "Default: #{@rails_root}") { |rails_root| @rails_root = rails_root; self.environment = RailsEnvironment.new(@rails_root) }
304
- o.on("-s", "--source=URL1,URL2", Array,
305
- "Use the specified plugin repositories instead of the defaults.") { |sources| @sources = sources}
306
303
 
307
304
  o.on("-v", "--verbose", "Turn on verbose output.") { |verbose| $verbose = verbose }
308
305
  o.on("-h", "--help", "Show this help message.") { puts o; exit }
@@ -315,8 +312,6 @@ module Commands
315
312
 
316
313
  o.separator ""
317
314
  o.separator "EXAMPLES"
318
- o.separator " Install a plugin:"
319
- o.separator " #{@script_name} plugin install continuous_builder\n"
320
315
  o.separator " Install a plugin from a subversion URL:"
321
316
  o.separator " #{@script_name} plugin install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
322
317
  o.separator " Install a plugin from a git URL:"
@@ -0,0 +1,10 @@
1
+ if ARGV.first != "new"
2
+ ARGV[0] = "--help"
3
+ else
4
+ ARGV.shift
5
+ end
6
+
7
+ require 'rails/generators'
8
+ require 'rails/generators/rails/plugin_new/plugin_new_generator'
9
+
10
+ Rails::Generators::PluginNewGenerator.start
@@ -1,4 +1,6 @@
1
- if [nil, "-h", "--help"].include?(ARGV.first)
1
+ require 'active_support/core_ext/object/inclusion'
2
+
3
+ if ARGV.first.in?([nil, "-h", "--help"])
2
4
  $stderr.puts "Usage: rails profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]"
3
5
  exit(1)
4
6
  end
@@ -42,6 +42,10 @@ module Rails
42
42
  set_environment
43
43
  end
44
44
 
45
+ def app
46
+ @app ||= super.instance
47
+ end
48
+
45
49
  def opt_parser
46
50
  Options.new
47
51
  end
@@ -1,5 +1,6 @@
1
1
  require 'active_support/deprecation'
2
2
  require 'active_support/ordered_options'
3
+ require 'active_support/core_ext/hash/deep_dup'
3
4
  require 'rails/paths'
4
5
  require 'rails/rack'
5
6
 
@@ -51,6 +52,13 @@ module Rails
51
52
  @colorize_logging = true
52
53
  end
53
54
 
55
+ def initialize_copy(source)
56
+ @aliases = @aliases.deep_dup
57
+ @options = @options.deep_dup
58
+ @fallbacks = @fallbacks.deep_dup
59
+ @templates = @templates.dup
60
+ end
61
+
54
62
  def method_missing(method, *args)
55
63
  method = method.to_s.sub(/=$/, '').to_sym
56
64
 
@@ -71,86 +79,5 @@ module Rails
71
79
  end
72
80
  end
73
81
  end
74
-
75
- module Deprecated
76
- def frameworks(*args)
77
- raise "config.frameworks in no longer supported. See the generated " \
78
- "config/boot.rb for steps on how to limit the frameworks that " \
79
- "will be loaded"
80
- end
81
- alias :frameworks= :frameworks
82
-
83
- def view_path=(value)
84
- ActiveSupport::Deprecation.warn "config.view_path= is deprecated, " <<
85
- "please do paths.app.views= instead", caller
86
- paths.app.views = value
87
- end
88
-
89
- def view_path
90
- ActiveSupport::Deprecation.warn "config.view_path is deprecated, " <<
91
- "please do paths.app.views instead", caller
92
- paths.app.views.to_a.first
93
- end
94
-
95
- def routes_configuration_file=(value)
96
- ActiveSupport::Deprecation.warn "config.routes_configuration_file= is deprecated, " <<
97
- "please do paths.config.routes= instead", caller
98
- paths.config.routes = value
99
- end
100
-
101
- def routes_configuration_file
102
- ActiveSupport::Deprecation.warn "config.routes_configuration_file is deprecated, " <<
103
- "please do paths.config.routes instead", caller
104
- paths.config.routes.to_a.first
105
- end
106
-
107
- def database_configuration_file=(value)
108
- ActiveSupport::Deprecation.warn "config.database_configuration_file= is deprecated, " <<
109
- "please do paths.config.database= instead", caller
110
- paths.config.database = value
111
- end
112
-
113
- def database_configuration_file
114
- ActiveSupport::Deprecation.warn "config.database_configuration_file is deprecated, " <<
115
- "please do paths.config.database instead", caller
116
- paths.config.database.to_a.first
117
- end
118
-
119
- def log_path=(value)
120
- ActiveSupport::Deprecation.warn "config.log_path= is deprecated, " <<
121
- "please do paths.log= instead", caller
122
- paths.config.log = value
123
- end
124
-
125
- def log_path
126
- ActiveSupport::Deprecation.warn "config.log_path is deprecated, " <<
127
- "please do paths.log instead", caller
128
- paths.config.log.to_a.first
129
- end
130
-
131
- def controller_paths=(value)
132
- ActiveSupport::Deprecation.warn "config.controller_paths= is deprecated, " <<
133
- "please do paths.app.controllers= instead", caller
134
- paths.app.controllers = value
135
- end
136
-
137
- def controller_paths
138
- ActiveSupport::Deprecation.warn "config.controller_paths is deprecated, " <<
139
- "please do paths.app.controllers instead", caller
140
- paths.app.controllers.to_a.uniq
141
- end
142
-
143
- def cookie_secret=(value)
144
- ActiveSupport::Deprecation.warn "config.cookie_secret= is deprecated, " <<
145
- "please use config.secret_token= instead", caller
146
- self.secret_token = value
147
- end
148
-
149
- def cookie_secret
150
- ActiveSupport::Deprecation.warn "config.cookie_secret is deprecated, " <<
151
- "please use config.secret_token instead", caller
152
- self.secret_token
153
- end
154
- end
155
82
  end
156
83
  end
@@ -26,7 +26,7 @@ end
26
26
  # reloads the environment
27
27
  def reload!(print=true)
28
28
  puts "Reloading..." if print
29
- # This triggers the to_prepare callbacks
30
- ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
29
+ ActionDispatch::Reloader.cleanup!
30
+ ActionDispatch::Reloader.prepare!
31
31
  true
32
32
  end
@@ -2,21 +2,23 @@ require 'rails/railtie'
2
2
  require 'active_support/core_ext/module/delegation'
3
3
  require 'pathname'
4
4
  require 'rbconfig'
5
+ require 'rails/engine/railties'
5
6
 
6
7
  module Rails
7
- # Rails::Engine allows you to wrap a specific Rails application and share it accross
8
- # different applications. Since Rails 3.0, every Rails::Application is nothing
9
- # more than an Engine, allowing you to share it very easily.
8
+ # Rails::Engine allows you to wrap a specific Rails application and share it across
9
+ # different applications. Since Rails 3.0, every <tt>Rails::Application</tt> is nothing
10
+ # more than an engine, allowing you to share it very easily.
10
11
  #
11
- # Any Rails::Engine is also a Rails::Railtie, so the same methods (like rake_tasks and
12
- # generators) and configuration available in the latter can also be used in the former.
12
+ # Any <tt>Rails::Engine</tt> is also a <tt>Rails::Railtie</tt>, so the same methods
13
+ # (like <tt>rake_tasks</tt> and +generators+) and configuration available in the
14
+ # latter can also be used in the former.
13
15
  #
14
16
  # == Creating an Engine
15
17
  #
16
- # In Rails versions before to 3.0, your gems automatically behaved as Engine, however
18
+ # In Rails versions prior to 3.0, your gems automatically behaved as engines, however,
17
19
  # this coupled Rails to Rubygems. Since Rails 3.0, if you want a gem to automatically
18
- # behave as Engine, you have to specify an Engine for it somewhere inside your plugin
19
- # lib folder (similar with how we spceify a Railtie):
20
+ # behave as an engine, you have to specify an +Engine+ for it somewhere inside
21
+ # your plugin's +lib+ folder (similar to how we specify a +Railtie+):
20
22
  #
21
23
  # # lib/my_engine.rb
22
24
  # module MyEngine
@@ -24,16 +26,17 @@ module Rails
24
26
  # end
25
27
  # end
26
28
  #
27
- # Then ensure that this file is loaded at the top of your config/application.rb (or in
28
- # your Gemfile) and it will automatically load models, controllers and helpers
29
- # inside app, load routes at "config/routes.rb", load locales at "config/locales/*",
30
- # load tasks at "lib/tasks/*".
29
+ # Then ensure that this file is loaded at the top of your <tt>config/application.rb</tt>
30
+ # (or in your +Gemfile+) and it will automatically load models, controllers and helpers
31
+ # inside +app+, load routes at <tt>config/routes.rb</tt>, load locales at
32
+ # <tt>config/locales/*</tt>, and load tasks at <tt>lib/tasks/*</tt>.
31
33
  #
32
34
  # == Configuration
33
35
  #
34
- # Besides the Railtie configuration which is shared across the application, in a
35
- # Rails::Engine you can access autoload_paths, eager_load_paths and autoload_once_paths,
36
- # which differently from a Railtie, are scoped to the current Engine.
36
+ # Besides the +Railtie+ configuration which is shared across the application, in a
37
+ # <tt>Rails::Engine</tt> you can access <tt>autoload_paths</tt>, <tt>eager_load_paths</tt>
38
+ # and <tt>autoload_once_paths</tt>, which, differently from a <tt>Railtie</tt>, are scoped to
39
+ # the current engine.
37
40
  #
38
41
  # Example:
39
42
  #
@@ -46,89 +49,347 @@ module Rails
46
49
  # end
47
50
  # end
48
51
  #
52
+ # == Generators
53
+ #
54
+ # You can set up generators for engines with <tt>config.generators</tt> method:
55
+ #
56
+ # class MyEngine < Rails::Engine
57
+ # config.generators do |g|
58
+ # g.orm :active_record
59
+ # g.template_engine :erb
60
+ # g.test_framework :test_unit
61
+ # end
62
+ # end
63
+ #
64
+ # You can also set generators for an application by using <tt>config.app_generators</tt>:
65
+ #
66
+ # class MyEngine < Rails::Engine
67
+ # # note that you can also pass block to app_generators in the same way you
68
+ # # can pass it to generators method
69
+ # config.app_generators.orm :datamapper
70
+ # end
71
+ #
49
72
  # == Paths
50
73
  #
51
- # Since Rails 3.0, both your Application and Engines do not have hardcoded paths.
52
- # This means that you are not required to place your controllers at "app/controllers",
74
+ # Since Rails 3.0, both your application and engines do not have hardcoded paths.
75
+ # This means that you are not required to place your controllers at <tt>app/controllers</tt>,
53
76
  # but in any place which you find convenient.
54
77
  #
55
- # For example, let's suppose you want to lay your controllers at lib/controllers, all
56
- # you need to do is:
78
+ # For example, let's suppose you want to place your controllers in <tt>lib/controllers</tt>.
79
+ # All you would need to do is:
57
80
  #
58
81
  # class MyEngine < Rails::Engine
59
- # paths.app.controllers = "lib/controllers"
82
+ # paths["app/controllers"] = "lib/controllers"
60
83
  # end
61
84
  #
62
- # You can also have your controllers being loaded from both "app/controllers" and
63
- # "lib/controllers":
85
+ # You can also have your controllers loaded from both <tt>app/controllers</tt> and
86
+ # <tt>lib/controllers</tt>:
64
87
  #
65
88
  # class MyEngine < Rails::Engine
66
- # paths.app.controllers << "lib/controllers"
89
+ # paths["app/controllers"] << "lib/controllers"
67
90
  # end
68
91
  #
69
- # The available paths in an Engine are:
92
+ # The available paths in an engine are:
70
93
  #
71
94
  # class MyEngine < Rails::Engine
72
- # paths.app = "app"
73
- # paths.app.controllers = "app/controllers"
74
- # paths.app.helpers = "app/helpers"
75
- # paths.app.models = "app/models"
76
- # paths.app.views = "app/views"
77
- # paths.lib = "lib"
78
- # paths.lib.tasks = "lib/tasks"
79
- # paths.config = "config"
80
- # paths.config.initializers = "config/initializers"
81
- # paths.config.locales = "config/locales"
82
- # paths.config.routes = "config/routes.rb"
83
- # end
84
- #
85
- # Your Application class adds a couple more paths to this set. And as in your Application,
86
- # all folders under "app" are automatically added to the load path. So if you have
87
- # "app/observers", it's added by default.
95
+ # paths["app"] # => ["app"]
96
+ # paths["app/controllers"] # => ["app/controllers"]
97
+ # paths["app/helpers"] # => ["app/helpers"]
98
+ # paths["app/models"] # => ["app/models"]
99
+ # paths["app/views"] # => ["app/views"]
100
+ # paths["lib"] # => ["lib"]
101
+ # paths["lib/tasks"] # => ["lib/tasks"]
102
+ # paths["config"] # => ["config"]
103
+ # paths["config/initializers"] # => ["config/initializers"]
104
+ # paths["config/locales"] # => ["config/locales"]
105
+ # paths["config/routes"] # => ["config/routes.rb"]
106
+ # end
107
+ #
108
+ # Your <tt>Application</tt> class adds a couple more paths to this set. And as in your
109
+ # <tt>Application</tt>,all folders under +app+ are automatically added to the load path.
110
+ # So if you have <tt>app/observers</tt>, it's added by default.
111
+ #
112
+ # == Endpoint
113
+ #
114
+ # An engine can be also a rack application. It can be useful if you have a rack application that
115
+ # you would like to wrap with +Engine+ and provide some of the +Engine+'s features.
116
+ #
117
+ # To do that, use the +endpoint+ method:
118
+ #
119
+ # module MyEngine
120
+ # class Engine < Rails::Engine
121
+ # endpoint MyRackApplication
122
+ # end
123
+ # end
124
+ #
125
+ # Now you can mount your engine in application's routes just like that:
126
+ #
127
+ # MyRailsApp::Application.routes.draw do
128
+ # mount MyEngine::Engine => "/engine"
129
+ # end
130
+ #
131
+ # == Middleware stack
132
+ #
133
+ # As an engine can now be rack endpoint, it can also have a middleware stack. The usage is exactly
134
+ # the same as in <tt>Application</tt>:
135
+ #
136
+ # module MyEngine
137
+ # class Engine < Rails::Engine
138
+ # middleware.use SomeMiddleware
139
+ # end
140
+ # end
141
+ #
142
+ # == Routes
143
+ #
144
+ # If you don't specify an endpoint, routes will be used as the default endpoint. You can use them
145
+ # just like you use an application's routes:
146
+ #
147
+ # # ENGINE/config/routes.rb
148
+ # MyEngine::Engine.routes.draw do
149
+ # match "/" => "posts#index"
150
+ # end
151
+ #
152
+ # == Mount priority
153
+ #
154
+ # Note that now there can be more than one router in your application, and it's better to avoid
155
+ # passing requests through many routers. Consider this situation:
156
+ #
157
+ # MyRailsApp::Application.routes.draw do
158
+ # mount MyEngine::Engine => "/blog"
159
+ # match "/blog/omg" => "main#omg"
160
+ # end
161
+ #
162
+ # +MyEngine+ is mounted at <tt>/blog</tt>, and <tt>/blog/omg</tt> points to application's
163
+ # controller. In such a situation, requests to <tt>/blog/omg</tt> will go through +MyEngine+,
164
+ # and if there is no such route in +Engine+'s routes, it will be dispatched to <tt>main#omg</tt>.
165
+ # It's much better to swap that:
166
+ #
167
+ # MyRailsApp::Application.routes.draw do
168
+ # match "/blog/omg" => "main#omg"
169
+ # mount MyEngine::Engine => "/blog"
170
+ # end
171
+ #
172
+ # Now, +Engine+ will get only requests that were not handled by +Application+.
173
+ #
174
+ # == Engine name
175
+ #
176
+ # There are some places where an Engine's name is used:
177
+ # * routes: when you mount an Engine with <tt>mount(MyEngine::Engine => '/my_engine')</tt>,
178
+ # it's used as default :as option
179
+ # * some of the rake tasks are based on engine name, e.g. <tt>my_engine:install:migrations</tt>,
180
+ # <tt>my_engine:install:assets</tt>
181
+ #
182
+ # Engine name is set by default based on class name. For <tt>MyEngine::Engine</tt> it will be
183
+ # <tt>my_engine_engine</tt>. You can change it manually it manually using the <tt>engine_name</tt> method:
184
+ #
185
+ # module MyEngine
186
+ # class Engine < Rails::Engine
187
+ # engine_name "my_engine"
188
+ # end
189
+ # end
190
+ #
191
+ # == Isolated Engine
192
+ #
193
+ # Normally when you create controllers, helpers and models inside an engine, they are treated
194
+ # as they were created inside the application. This means all application helpers and named routes
195
+ # will be available to your engine's controllers.
196
+ #
197
+ # However, sometimes you want to isolate your engine from the application, especially if your engine
198
+ # has its own router. To do that, you simply need to call +isolate_namespace+. This method requires
199
+ # you to pass a module where all your controllers, helpers and models should be nested to:
200
+ #
201
+ # module MyEngine
202
+ # class Engine < Rails::Engine
203
+ # isolate_namespace MyEngine
204
+ # end
205
+ # end
206
+ #
207
+ # With such an engine, everything that is inside the +MyEngine+ module will be isolated from
208
+ # the application.
209
+ #
210
+ # Consider such controller:
211
+ #
212
+ # module MyEngine
213
+ # class FooController < ActionController::Base
214
+ # end
215
+ # end
216
+ #
217
+ # If an engine is marked as isolated, +FooController+ has access only to helpers from +Engine+ and
218
+ # <tt>url_helpers</tt> from <tt>MyEngine::Engine.routes</tt>.
219
+ #
220
+ # The next thing that changes in isolated engines is the behaviour of routes. Normally, when you namespace
221
+ # your controllers, you also need to do namespace all your routes. With an isolated engine,
222
+ # the namespace is applied by default, so you can ignore it in routes:
223
+ #
224
+ # MyEngine::Engine.routes.draw do
225
+ # resources :articles
226
+ # end
227
+ #
228
+ # The routes above will automatically point to <tt>MyEngine::ApplicationContoller</tt>. Furthermore, you don't
229
+ # need to use longer url helpers like <tt>my_engine_articles_path</tt>. Instead, you should simply use
230
+ # <tt>articles_path</tt> as you would do with your application.
231
+ #
232
+ # To make that behaviour consistent with other parts of the framework, an isolated engine also has influence on
233
+ # <tt>ActiveModel::Naming</tt>. When you use a namespaced model, like <tt>MyEngine::Article</tt>, it will normally
234
+ # use the prefix "my_engine". In an isolated engine, the prefix will be omitted in url helpers and
235
+ # form fields for convenience.
236
+ #
237
+ # polymorphic_url(MyEngine::Article.new) # => "articles_path"
238
+ #
239
+ # form_for(MyEngine::Article.new) do
240
+ # text_field :title # => <input type="text" name="article[title]" id="article_title" />
241
+ # end
242
+ #
243
+ # Additionally an isolated engine will set its name according to namespace, so
244
+ # MyEngine::Engine.engine_name will be "my_engine". It will also set MyEngine.table_name_prefix
245
+ # to "my_engine_", changing MyEngine::Article model to use my_engine_article table.
246
+ #
247
+ # == Using Engine's routes outside Engine
248
+ #
249
+ # Since you can now mount an engine inside application's routes, you do not have direct access to +Engine+'s
250
+ # <tt>url_helpers</tt> inside +Application+. When you mount an engine in an application's routes, a special helper is
251
+ # created to allow you to do that. Consider such a scenario:
252
+ #
253
+ # # config/routes.rb
254
+ # MyApplication::Application.routes.draw do
255
+ # mount MyEngine::Engine => "/my_engine", :as => "my_engine"
256
+ # match "/foo" => "foo#index"
257
+ # end
258
+ #
259
+ # Now, you can use the <tt>my_engine</tt> helper inside your application:
260
+ #
261
+ # class FooController < ApplicationController
262
+ # def index
263
+ # my_engine.root_url #=> /my_engine/
264
+ # end
265
+ # end
266
+ #
267
+ # There is also a <tt>main_app</tt> helper that gives you access to application's routes inside Engine:
268
+ #
269
+ # module MyEngine
270
+ # class BarController
271
+ # def index
272
+ # main_app.foo_path #=> /foo
273
+ # end
274
+ # end
275
+ # end
276
+ #
277
+ # Note that the <tt>:as</tt> option given to mount takes the <tt>engine_name</tT> as default, so most of the time
278
+ # you can simply omit it.
279
+ #
280
+ # Finally, if you want to generate a url to an engine's route using <tt>polymorphic_url</tt>, you also need
281
+ # to pass the engine helper. Let's say that you want to create a form pointing to one of the
282
+ # engine's routes. All you need to do is pass the helper as the first element in array with
283
+ # attributes for url:
284
+ #
285
+ # form_for([my_engine, @user])
286
+ #
287
+ # This code will use <tt>my_engine.user_path(@user)</tt> to generate the proper route.
288
+ #
289
+ # == Isolated engine's helpers
290
+ #
291
+ # Sometimes you may want to isolate engine, but use helpers that are defined for it.
292
+ # If you want to share just a few specific helpers you can add them to application's
293
+ # helpers in ApplicationController:
294
+ #
295
+ # class ApplicationController < ActionController::Base
296
+ # helper MyEngine::SharedEngineHelper
297
+ # end
298
+ #
299
+ # If you want to include all of the engine's helpers, you can use #helpers method on egine's
300
+ # instance:
301
+ #
302
+ # class ApplicationController < ActionController::Base
303
+ # helper MyEngine::Engine.helpers
304
+ # end
305
+ #
306
+ # It will include all of the helpers from engine's directory. Take into account that this does
307
+ # not include helpers defined in controllers with helper_method or other similar solutions,
308
+ # only helpers defined in helpers directory will be included.
309
+ #
310
+ # == Migrations & seed data
311
+ #
312
+ # Engines can have their own migrations. The default path for migrations is exactly the same
313
+ # as in application: <tt>db/migrate</tt>
314
+ #
315
+ # To use engine's migrations in application you can use rake task, which copies them to
316
+ # application's dir:
317
+ #
318
+ # rake ENGINE_NAME:install:migrations
319
+ #
320
+ # Note that some of the migrations may be skipped if a migration with the same name already exists
321
+ # in application. In such a situation you must decide whether to leave that migration or rename the
322
+ # migration in application and rerun copying migrations.
323
+ #
324
+ # If your engine has migrations, you may also want to prepare data for the database in
325
+ # the <tt>seeds.rb</tt> file. You can load that data using the <tt>load_seed</tt> method, e.g.
326
+ #
327
+ # MyEngine::Engine.load_seed
88
328
  #
89
329
  class Engine < Railtie
90
- autoload :Configurable, "rails/engine/configurable"
91
330
  autoload :Configuration, "rails/engine/configuration"
331
+ autoload :Railties, "rails/engine/railties"
92
332
 
93
333
  class << self
94
- attr_accessor :called_from
95
-
96
- # TODO Remove this. It's deprecated.
334
+ attr_accessor :called_from, :isolated
335
+ alias :isolated? :isolated
97
336
  alias :engine_name :railtie_name
98
337
 
99
338
  def inherited(base)
100
339
  unless base.abstract_railtie?
101
340
  base.called_from = begin
102
341
  # Remove the line number from backtraces making sure we don't leave anything behind
103
- call_stack = caller.map { |p| p.split(':')[0..-2].join(':') }
104
- File.dirname(call_stack.detect { |p| p !~ %r[railties[\w\-\.]*/lib/rails|rack[\w\-\.]*/lib/rack] })
342
+ call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
343
+ File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
105
344
  end
106
345
  end
107
346
 
108
347
  super
109
348
  end
110
349
 
111
- def find_root_with_flag(flag, default=nil)
112
- root_path = self.called_from
350
+ def endpoint(endpoint = nil)
351
+ @endpoint = endpoint if endpoint
352
+ @endpoint
353
+ end
113
354
 
114
- while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
115
- parent = File.dirname(root_path)
116
- root_path = parent != root_path && parent
117
- end
355
+ def isolate_namespace(mod)
356
+ engine_name(generate_railtie_name(mod))
357
+
358
+ self.routes.default_scope = { :module => ActiveSupport::Inflector.underscore(mod.name) }
359
+ self.isolated = true
118
360
 
119
- root = File.exist?("#{root_path}/#{flag}") ? root_path : default
120
- raise "Could not find root path for #{self}" unless root
361
+ unless mod.respond_to?(:_railtie)
362
+ name = engine_name
363
+ _railtie = self
364
+ mod.singleton_class.instance_eval do
365
+ define_method(:_railtie) do
366
+ _railtie
367
+ end
368
+
369
+ unless mod.respond_to?(:table_name_prefix)
370
+ define_method(:table_name_prefix) do
371
+ "#{name}_"
372
+ end
373
+ end
374
+ end
375
+ end
376
+ end
121
377
 
122
- RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ?
123
- Pathname.new(root).expand_path : Pathname.new(root).realpath
378
+ # Finds engine with given path
379
+ def find(path)
380
+ expanded_path = File.expand_path path.to_s
381
+ Rails::Engine::Railties.engines.find { |engine|
382
+ File.expand_path(engine.root.to_s) == expanded_path
383
+ }
124
384
  end
125
385
  end
126
386
 
127
- delegate :paths, :root, :to => :config
387
+ delegate :middleware, :root, :paths, :to => :config
388
+ delegate :engine_name, :isolated?, :to => "self.class"
128
389
 
129
390
  def load_tasks
130
391
  super
131
- config.paths.lib.tasks.to_a.sort.each { |ext| load(ext) }
392
+ paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
132
393
  end
133
394
 
134
395
  def eager_load!
@@ -140,6 +401,75 @@ module Rails
140
401
  end
141
402
  end
142
403
 
404
+ def railties
405
+ @railties ||= self.class::Railties.new(config)
406
+ end
407
+
408
+ def helpers
409
+ @helpers ||= begin
410
+ helpers = Module.new
411
+
412
+ helpers_paths = if config.respond_to?(:helpers_paths)
413
+ config.helpers_paths
414
+ else
415
+ paths["app/helpers"].existent
416
+ end
417
+
418
+ all = ActionController::Base.all_helpers_from_path(helpers_paths)
419
+ ActionController::Base.modules_for_helpers(all).each do |mod|
420
+ helpers.send(:include, mod)
421
+ end
422
+ helpers
423
+ end
424
+ end
425
+
426
+ def app
427
+ @app ||= begin
428
+ config.middleware = config.middleware.merge_into(default_middleware_stack)
429
+ config.middleware.build(endpoint)
430
+ end
431
+ end
432
+
433
+ def endpoint
434
+ self.class.endpoint || routes
435
+ end
436
+
437
+ def call(env)
438
+ app.call(env.merge!(env_config))
439
+ end
440
+
441
+ def env_config
442
+ @env_config ||= {
443
+ 'action_dispatch.routes' => routes
444
+ }
445
+ end
446
+
447
+ def routes
448
+ @routes ||= ActionDispatch::Routing::RouteSet.new
449
+ @routes.append(&Proc.new) if block_given?
450
+ @routes
451
+ end
452
+
453
+ def initializers
454
+ initializers = []
455
+ railties.all { |r| initializers += r.initializers }
456
+ initializers += super
457
+ initializers
458
+ end
459
+
460
+ def config
461
+ @config ||= Engine::Configuration.new(find_root_with_flag("lib"))
462
+ end
463
+
464
+ # Load data from db/seeds.rb file. It can be used in to load engines'
465
+ # seeds, e.g.:
466
+ #
467
+ # Blog::Engine.load_seed
468
+ def load_seed
469
+ seed_file = paths["db/seeds"].existent.first
470
+ load(seed_file) if File.exist?(seed_file)
471
+ end
472
+
143
473
  # Add configured load paths to ruby load paths and remove duplicates.
144
474
  initializer :set_load_path, :before => :bootstrap_hook do
145
475
  _all_load_paths.reverse_each do |path|
@@ -155,7 +485,7 @@ module Rails
155
485
  # per engine and get the engine as a block parameter
156
486
  initializer :set_autoload_paths, :before => :bootstrap_hook do |app|
157
487
  ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
158
- ActiveSupport::Dependencies.autoload_once_paths.unshift(*config.autoload_once_paths)
488
+ ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths)
159
489
 
160
490
  # Freeze so future modifications will fail rather than do nothing mysteriously
161
491
  config.autoload_paths.freeze
@@ -164,40 +494,46 @@ module Rails
164
494
  end
165
495
 
166
496
  initializer :add_routing_paths do |app|
167
- paths.config.routes.to_a.each do |route|
168
- app.routes_reloader.paths.unshift(route) if File.exists?(route)
169
- end
170
- end
497
+ paths = self.paths["config/routes"].existent
171
498
 
172
- # DEPRECATED: Remove in 3.1
173
- initializer :add_routing_namespaces do |app|
174
- paths.app.controllers.to_a.each do |load_path|
175
- load_path = File.expand_path(load_path)
176
- Dir["#{load_path}/*/**/*_controller.rb"].collect do |path|
177
- namespace = File.dirname(path).sub(/#{Regexp.escape(load_path)}\/?/, '')
178
- app.routes.controller_namespaces << namespace unless namespace.empty?
179
- end
499
+ if routes? || paths.any?
500
+ app.routes_reloader.paths.unshift(*paths)
501
+ app.routes_reloader.route_sets << routes
180
502
  end
181
503
  end
182
504
 
183
505
  # I18n load paths are a special case since the ones added
184
506
  # later have higher priority.
185
507
  initializer :add_locales do
186
- config.i18n.railties_load_path.concat(paths.config.locales.to_a)
508
+ config.i18n.railties_load_path.concat(paths["config/locales"].existent)
187
509
  end
188
510
 
189
511
  initializer :add_view_paths do
190
- views = paths.app.views.to_a
191
- ActiveSupport.on_load(:action_controller) do
192
- prepend_view_path(views)
512
+ views = paths["app/views"].existent
513
+ unless views.empty?
514
+ ActiveSupport.on_load(:action_controller){ prepend_view_path(views) }
515
+ ActiveSupport.on_load(:action_mailer){ prepend_view_path(views) }
193
516
  end
194
- ActiveSupport.on_load(:action_mailer) do
195
- prepend_view_path(views)
517
+ end
518
+
519
+ initializer :load_environment_config, :before => :load_environment_hook do
520
+ environment = paths["config/environments"].existent.first
521
+ require environment if environment
522
+ end
523
+
524
+ initializer :append_assets_path do |app|
525
+ app.config.assets.paths.unshift *paths["vendor/assets"].existent
526
+ app.config.assets.paths.unshift *paths["app/assets"].existent
527
+ end
528
+
529
+ initializer :prepend_helpers_path do |app|
530
+ if !isolated? || (app == self)
531
+ app.config.helpers_paths.unshift(*paths["app/helpers"].existent)
196
532
  end
197
533
  end
198
534
 
199
535
  initializer :load_config_initializers do
200
- paths.config.initializers.to_a.sort.each do |initializer|
536
+ config.paths["config/initializers"].existent.sort.each do |initializer|
201
537
  load(initializer)
202
538
  end
203
539
  end
@@ -207,8 +543,54 @@ module Rails
207
543
  # consistently executed after all the initializers above across all engines.
208
544
  end
209
545
 
546
+ rake_tasks do
547
+ next if self.is_a?(Rails::Application)
548
+ next unless has_migrations?
549
+
550
+ namespace railtie_name do
551
+ namespace :install do
552
+ desc "Copy migrations from #{railtie_name} to application"
553
+ task :migrations do
554
+ ENV["FROM"] = railtie_name
555
+ Rake::Task["railties:install:migrations"].invoke
556
+ end
557
+ end
558
+ end
559
+ end
560
+
210
561
  protected
211
562
 
563
+ def routes?
564
+ defined?(@routes)
565
+ end
566
+
567
+ def has_migrations?
568
+ paths["db/migrate"].first.present?
569
+ end
570
+
571
+ def find_root_with_flag(flag, default=nil)
572
+ root_path = self.class.called_from
573
+
574
+ while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
575
+ parent = File.dirname(root_path)
576
+ root_path = parent != root_path && parent
577
+ end
578
+
579
+ root = File.exist?("#{root_path}/#{flag}") ? root_path : default
580
+ raise "Could not find root path for #{self}" unless root
581
+
582
+ RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ?
583
+ Pathname.new(root).expand_path : Pathname.new(root).realpath
584
+ end
585
+
586
+ def default_middleware_stack
587
+ ActionDispatch::MiddlewareStack.new
588
+ end
589
+
590
+ def _all_autoload_once_paths
591
+ config.autoload_once_paths
592
+ end
593
+
212
594
  def _all_autoload_paths
213
595
  @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
214
596
  end