aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-09-30 10:30:58 +0200
committerJosé Valim <jose.valim@gmail.com>2010-09-30 10:30:58 +0200
commit1ba22bcde1d5ee1e16e14d4d2dd23cbeb01cd59f (patch)
tree0c74273f34c20e56975a6b7845a034fa3df8c469
parent69f97f469747777ed1c457715f5361f6b8a0ab7b (diff)
parent9f569c60adb3505cd7ca1723481199bf26619038 (diff)
downloadrails-1ba22bcde1d5ee1e16e14d4d2dd23cbeb01cd59f.tar.gz
rails-1ba22bcde1d5ee1e16e14d4d2dd23cbeb01cd59f.tar.bz2
rails-1ba22bcde1d5ee1e16e14d4d2dd23cbeb01cd59f.zip
Merge remote branch 'drogus/engines'
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb3
-rw-r--r--actionpack/test/dispatch/prefix_generation_test.rb93
-rw-r--r--activerecord/lib/active_record/railtie.rb2
-rw-r--r--railties/lib/rails/application.rb13
-rw-r--r--railties/lib/rails/application/configuration.rb1
-rw-r--r--railties/lib/rails/application/routes_reloader.rb55
-rw-r--r--railties/lib/rails/commands.rb17
-rw-r--r--railties/lib/rails/engine.rb32
-rw-r--r--railties/lib/rails/railtie/configuration.rb19
-rw-r--r--railties/lib/rails/test_unit/railtie.rb2
-rw-r--r--railties/test/railties/engine_test.rb99
11 files changed, 289 insertions, 47 deletions
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 5d18dfe369..32f41934f1 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -1,6 +1,7 @@
require 'rack/mount'
require 'forwardable'
require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/hash/slice'
module ActionDispatch
module Routing
@@ -511,7 +512,7 @@ module ActionDispatch
end
script_name = options.delete(:script_name)
- path = (script_name.blank? ? _generate_prefix(options) : script_name).to_s
+ path = (script_name.blank? ? _generate_prefix(options) : script_name.chomp('/')).to_s
path_options = options.except(*RESERVED_OPTIONS)
path_options = yield(path_options) if block_given?
diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb
index 26d76557dd..18f28deee4 100644
--- a/actionpack/test/dispatch/prefix_generation_test.rb
+++ b/actionpack/test/dispatch/prefix_generation_test.rb
@@ -1,8 +1,23 @@
require 'abstract_unit'
+require 'rack/test'
module TestGenerationPrefix
+ class Post
+ extend ActiveModel::Naming
+
+ def to_param
+ "1"
+ end
+
+ def self.model_name
+ klass = "Post"
+ def klass.name; self end
+
+ ActiveModel::Name.new(klass)
+ end
+ end
+
class WithMountedEngine < ActionDispatch::IntegrationTest
- require 'rack/test'
include Rack::Test::Methods
class BlogEngine
@@ -55,21 +70,6 @@ module TestGenerationPrefix
# force draw
RailsApplication.routes
- class Post
- extend ActiveModel::Naming
-
- def to_param
- "1"
- end
-
- def self.model_name
- klass = "Post"
- def klass.name; self end
-
- ActiveModel::Name.new(klass)
- end
- end
-
class ::InsideEngineGeneratingController < ActionController::Base
include BlogEngine.routes.url_helpers
include RailsApplication.routes.mounted_helpers
@@ -253,4 +253,65 @@ module TestGenerationPrefix
assert_equal "http://www.example.com/awesome/blog/posts/1", path
end
end
+
+ class EngineMountedAtRoot < ActionDispatch::IntegrationTest
+ include Rack::Test::Methods
+
+ class BlogEngine
+ def self.routes
+ @routes ||= begin
+ routes = ActionDispatch::Routing::RouteSet.new
+ routes.draw do
+ match "/posts/:id", :to => "posts#show", :as => :post
+ end
+
+ routes
+ end
+ end
+
+ def self.call(env)
+ env['action_dispatch.routes'] = routes
+ routes.call(env)
+ end
+ end
+
+ class RailsApplication
+ def self.routes
+ @routes ||= begin
+ routes = ActionDispatch::Routing::RouteSet.new
+ routes.draw do
+ mount BlogEngine => "/"
+ end
+
+ routes
+ end
+ end
+
+ def self.call(env)
+ env['action_dispatch.routes'] = routes
+ routes.call(env)
+ end
+ end
+
+ # force draw
+ RailsApplication.routes
+
+ class ::PostsController < ActionController::Base
+ include BlogEngine.routes.url_helpers
+ include RailsApplication.routes.mounted_helpers
+
+ def show
+ render :text => post_path(:id => params[:id])
+ end
+ end
+
+ def app
+ RailsApplication
+ end
+
+ test "generating path inside engine" do
+ get "/posts/1"
+ assert_equal "/posts/1", last_response.body
+ end
+ end
end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 94dda4e413..868fd6c3ff 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -13,7 +13,7 @@ module ActiveRecord
class Railtie < Rails::Railtie
config.active_record = ActiveSupport::OrderedOptions.new
- config.generators.orm :active_record, :migration => true,
+ config.app_generators.orm :active_record, :migration => true,
:timestamps => true
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 0e85e6d1d5..aafbbc29ee 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -39,6 +39,7 @@ module Rails
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
+ autoload :RoutesReloader, 'rails/application/routes_reloader'
class << self
def inherited(base)
@@ -81,17 +82,7 @@ module Rails
end
def routes_reloader
- @routes_reloader ||= ActiveSupport::FileUpdateChecker.new([]){ reload_routes! }
- end
-
- def reload_routes!
- _routes = self.routes
- _routes.disable_clear_and_finalize = true
- _routes.clear!
- routes_reloader.paths.each { |path| load(path) }
- ActiveSupport.on_load(:action_controller) { _routes.finalize! }
- ensure
- _routes.disable_clear_and_finalize = false
+ @routes_reloader ||= RoutesReloader.new
end
def initialize!
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index a0ecbc0fc8..f902c3ded2 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -24,6 +24,7 @@ module Rails
@time_zone = "UTC"
@middleware = app_middleware
@asset_path = '/'
+ @generators = app_generators
end
def asset_path=(value)
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
new file mode 100644
index 0000000000..23b72a0ec6
--- /dev/null
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -0,0 +1,55 @@
+module Rails
+ class Application
+ class RoutesReloader < ::ActiveSupport::FileUpdateChecker
+ def initialize
+ super([]) { reload! }
+ end
+
+ def blocks
+ @blocks ||= {}
+ end
+ private
+ def reload!
+ clear!
+ load_blocks
+ load_paths
+ finalize!
+ ensure
+ revert
+ end
+
+ def clear!
+ routers.each do |routes|
+ routes.disable_clear_and_finalize = true
+ routes.clear!
+ end
+ end
+
+ def load_blocks
+ blocks.each do |routes, block|
+ routes.draw(&block) if block
+ end
+ end
+
+ def load_paths
+ paths.each { |path| load(path) }
+ end
+
+ def finalize!
+ routers.each do |routes|
+ ActiveSupport.on_load(:action_controller) { routes.finalize! }
+ end
+ end
+
+ def revert
+ routers.each do |routes|
+ routes.disable_clear_and_finalize = false
+ end
+ end
+
+ def routers
+ blocks.keys
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 60a93c9848..60b9a55d80 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -11,7 +11,17 @@ command = ARGV.shift
command = aliases[command] || command
case command
-when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler'
+when 'generate', 'destroy', 'plugin'
+ require APP_PATH
+ Rails.application.require_environment!
+
+ if defined?(ENGINE_PATH)
+ engine = Rails.application.railties.engines.find { |r| r.root.to_s == ENGINE_PATH }
+ Rails.application = engine
+ end
+ require "rails/commands/#{command}"
+
+when 'benchmarker', 'profiler'
require APP_PATH
Rails.application.require_environment!
require "rails/commands/#{command}"
@@ -23,8 +33,13 @@ when 'console'
Rails::Console.start(Rails.application)
when 'server'
+ # try to guess application's path if there is no config.ru file in current dir
+ # it allows to run script/rails server from other directories
+ Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
+
require 'rails/commands/server'
Rails::Server.new.tap { |server|
+ # we need to require application after the server sets environment
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 0620b8608e..9ae235b818 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -333,21 +333,22 @@ module Rails
def namespace(mod)
engine_name(generate_railtie_name(mod))
- _railtie = self
name = engine_name
- mod.singleton_class.instance_eval do
- define_method(:_railtie) do
- _railtie
- end
-
- define_method(:table_name_prefix) do
- "#{name}_"
- end
- end
-
self.routes.default_scope = {:module => name}
-
self.namespaced = true
+
+ unless mod.respond_to?(:_railtie)
+ _railtie = self
+ mod.singleton_class.instance_eval do
+ define_method(:_railtie) do
+ _railtie
+ end
+
+ define_method(:table_name_prefix) do
+ "#{name}_"
+ end
+ end
+ end
end
def namespaced?
@@ -398,8 +399,10 @@ module Rails
}
end
- def routes
+ def routes(&block)
@routes ||= ActionDispatch::Routing::RouteSet.new
+ self.routes_draw_block = block if block_given?
+ @routes
end
def initializers
@@ -446,6 +449,7 @@ module Rails
end
initializer :add_routing_paths do |app|
+ app.routes_reloader.blocks[routes] = routes_draw_block
paths.config.routes.to_a.each do |route|
app.routes_reloader.paths.unshift(route) if File.exists?(route)
end
@@ -498,6 +502,8 @@ module Rails
end
protected
+ attr_accessor :routes_draw_block
+
def find_root_with_flag(flag, default=nil)
root_path = self.class.called_from
diff --git a/railties/lib/rails/railtie/configuration.rb b/railties/lib/rails/railtie/configuration.rb
index f09e3940cc..e0e4324a4a 100644
--- a/railties/lib/rails/railtie/configuration.rb
+++ b/railties/lib/rails/railtie/configuration.rb
@@ -17,6 +17,19 @@ module Rails
@@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
end
+ # This allows you to modify application's generators from Railties.
+ #
+ # Values set on app_generators will become defaults for applicaiton, unless
+ # application overwrites them.
+ def app_generators
+ @@app_generators ||= Rails::Configuration::Generators.new
+ if block_given?
+ yield @@app_generators
+ else
+ @@app_generators
+ end
+ end
+
# Holds generators configuration:
#
# config.generators do |g|
@@ -30,11 +43,11 @@ module Rails
# config.generators.colorize_logging = false
#
def generators
- @@generators ||= Rails::Configuration::Generators.new
+ @generators ||= Rails::Configuration::Generators.new
if block_given?
- yield @@generators
+ yield @generators
else
- @@generators
+ @generators
end
end
diff --git a/railties/lib/rails/test_unit/railtie.rb b/railties/lib/rails/test_unit/railtie.rb
index e3fafc4b9d..2b6170ebfb 100644
--- a/railties/lib/rails/test_unit/railtie.rb
+++ b/railties/lib/rails/test_unit/railtie.rb
@@ -1,6 +1,6 @@
module Rails
class TestUnitRailtie < Rails::Railtie
- config.generators do |c|
+ config.app_generators do |c|
c.test_framework :test_unit, :fixture => true,
:fixture_replacement => nil
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index a9dd7d4c1b..c75639d740 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -643,5 +643,104 @@ module RailtiesTest
Bukkits::Engine.load_seed
assert Bukkits::Engine.config.bukkits_seeds_loaded
end
+
+ test "using namespace more than once on one module should not overwrite _railtie method" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module AppTemplate
+ class Engine < ::Rails::Engine
+ namespace(AppTemplate)
+ end
+ end
+ RUBY
+
+ add_to_config "namespace AppTemplate"
+
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do end
+ RUBY
+
+ boot_rails
+
+ assert_equal AppTemplate._railtie, AppTemplate::Engine
+ end
+
+ test "properly reload routes" do
+ # when routes are inside application class definition
+ # they should not be reloaded when engine's routes
+ # file has changed
+ add_to_config <<-RUBY
+ routes do
+ mount lambda{|env| [200, {}, ["foo"]]} => "/foo"
+ mount Bukkits::Engine => "/bukkits"
+ end
+ RUBY
+
+ FileUtils.rm(File.join(app_path, "config/routes.rb"))
+
+ @plugin.write "config/routes.rb", <<-RUBY
+ Bukkits::Engine.routes.draw do
+ mount lambda{|env| [200, {}, ["bar"]]} => "/bar"
+ end
+ RUBY
+
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ namespace(Bukkits)
+ end
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+
+ boot_rails
+
+ require "#{rails_root}/config/environment"
+ get "/foo"
+ assert_equal "foo", last_response.body
+
+ get "/bukkits/bar"
+ assert_equal "bar", last_response.body
+ end
+
+ test "setting generators for engine and overriding app generator's" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ config.generators do |g|
+ g.orm :datamapper
+ g.template_engine :haml
+ g.test_framework :rspec
+ end
+
+ config.app_generators do |g|
+ g.orm :mongoid
+ g.template_engine :liquid
+ g.test_framework :shoulda
+ end
+ end
+ end
+ RUBY
+
+ add_to_config <<-RUBY
+ config.generators do |g|
+ g.test_framework :test_unit
+ end
+ RUBY
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ app_generators = Rails.application.config.generators.options[:rails]
+ assert_equal :mongoid , app_generators[:orm]
+ assert_equal :liquid , app_generators[:template_engine]
+ assert_equal :test_unit, app_generators[:test_framework]
+
+ generators = Bukkits::Engine.config.generators.options[:rails]
+ assert_equal :datamapper, generators[:orm]
+ assert_equal :haml , generators[:template_engine]
+ assert_equal :rspec , generators[:test_framework]
+ end
end
end