mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge remote branch 'drogus/engines'
This commit is contained in:
commit
1ba22bcde1
11 changed files with 289 additions and 47 deletions
|
@ -1,6 +1,7 @@
|
||||||
require 'rack/mount'
|
require 'rack/mount'
|
||||||
require 'forwardable'
|
require 'forwardable'
|
||||||
require 'active_support/core_ext/object/to_query'
|
require 'active_support/core_ext/object/to_query'
|
||||||
|
require 'active_support/core_ext/hash/slice'
|
||||||
|
|
||||||
module ActionDispatch
|
module ActionDispatch
|
||||||
module Routing
|
module Routing
|
||||||
|
@ -511,7 +512,7 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
script_name = options.delete(:script_name)
|
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 = options.except(*RESERVED_OPTIONS)
|
||||||
path_options = yield(path_options) if block_given?
|
path_options = yield(path_options) if block_given?
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
require 'abstract_unit'
|
require 'abstract_unit'
|
||||||
|
require 'rack/test'
|
||||||
|
|
||||||
module TestGenerationPrefix
|
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
|
class WithMountedEngine < ActionDispatch::IntegrationTest
|
||||||
require 'rack/test'
|
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|
||||||
class BlogEngine
|
class BlogEngine
|
||||||
|
@ -55,21 +70,6 @@ module TestGenerationPrefix
|
||||||
# force draw
|
# force draw
|
||||||
RailsApplication.routes
|
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
|
class ::InsideEngineGeneratingController < ActionController::Base
|
||||||
include BlogEngine.routes.url_helpers
|
include BlogEngine.routes.url_helpers
|
||||||
include RailsApplication.routes.mounted_helpers
|
include RailsApplication.routes.mounted_helpers
|
||||||
|
@ -253,4 +253,65 @@ module TestGenerationPrefix
|
||||||
assert_equal "http://www.example.com/awesome/blog/posts/1", path
|
assert_equal "http://www.example.com/awesome/blog/posts/1", path
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ module ActiveRecord
|
||||||
class Railtie < Rails::Railtie
|
class Railtie < Rails::Railtie
|
||||||
config.active_record = ActiveSupport::OrderedOptions.new
|
config.active_record = ActiveSupport::OrderedOptions.new
|
||||||
|
|
||||||
config.generators.orm :active_record, :migration => true,
|
config.app_generators.orm :active_record, :migration => true,
|
||||||
:timestamps => true
|
:timestamps => true
|
||||||
|
|
||||||
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
|
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
|
||||||
|
|
|
@ -39,6 +39,7 @@ module Rails
|
||||||
autoload :Configuration, 'rails/application/configuration'
|
autoload :Configuration, 'rails/application/configuration'
|
||||||
autoload :Finisher, 'rails/application/finisher'
|
autoload :Finisher, 'rails/application/finisher'
|
||||||
autoload :Railties, 'rails/application/railties'
|
autoload :Railties, 'rails/application/railties'
|
||||||
|
autoload :RoutesReloader, 'rails/application/routes_reloader'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def inherited(base)
|
def inherited(base)
|
||||||
|
@ -81,17 +82,7 @@ module Rails
|
||||||
end
|
end
|
||||||
|
|
||||||
def routes_reloader
|
def routes_reloader
|
||||||
@routes_reloader ||= ActiveSupport::FileUpdateChecker.new([]){ reload_routes! }
|
@routes_reloader ||= RoutesReloader.new
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize!
|
def initialize!
|
||||||
|
|
|
@ -24,6 +24,7 @@ module Rails
|
||||||
@time_zone = "UTC"
|
@time_zone = "UTC"
|
||||||
@middleware = app_middleware
|
@middleware = app_middleware
|
||||||
@asset_path = '/'
|
@asset_path = '/'
|
||||||
|
@generators = app_generators
|
||||||
end
|
end
|
||||||
|
|
||||||
def asset_path=(value)
|
def asset_path=(value)
|
||||||
|
|
55
railties/lib/rails/application/routes_reloader.rb
Normal file
55
railties/lib/rails/application/routes_reloader.rb
Normal file
|
@ -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
|
|
@ -11,7 +11,17 @@ command = ARGV.shift
|
||||||
command = aliases[command] || command
|
command = aliases[command] || command
|
||||||
|
|
||||||
case 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
|
require APP_PATH
|
||||||
Rails.application.require_environment!
|
Rails.application.require_environment!
|
||||||
require "rails/commands/#{command}"
|
require "rails/commands/#{command}"
|
||||||
|
@ -23,8 +33,13 @@ when 'console'
|
||||||
Rails::Console.start(Rails.application)
|
Rails::Console.start(Rails.application)
|
||||||
|
|
||||||
when 'server'
|
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'
|
require 'rails/commands/server'
|
||||||
Rails::Server.new.tap { |server|
|
Rails::Server.new.tap { |server|
|
||||||
|
# we need to require application after the server sets environment
|
||||||
require APP_PATH
|
require APP_PATH
|
||||||
Dir.chdir(Rails.application.root)
|
Dir.chdir(Rails.application.root)
|
||||||
server.start
|
server.start
|
||||||
|
|
|
@ -333,8 +333,12 @@ module Rails
|
||||||
def namespace(mod)
|
def namespace(mod)
|
||||||
engine_name(generate_railtie_name(mod))
|
engine_name(generate_railtie_name(mod))
|
||||||
|
|
||||||
_railtie = self
|
|
||||||
name = engine_name
|
name = engine_name
|
||||||
|
self.routes.default_scope = {:module => name}
|
||||||
|
self.namespaced = true
|
||||||
|
|
||||||
|
unless mod.respond_to?(:_railtie)
|
||||||
|
_railtie = self
|
||||||
mod.singleton_class.instance_eval do
|
mod.singleton_class.instance_eval do
|
||||||
define_method(:_railtie) do
|
define_method(:_railtie) do
|
||||||
_railtie
|
_railtie
|
||||||
|
@ -344,10 +348,7 @@ module Rails
|
||||||
"#{name}_"
|
"#{name}_"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
self.routes.default_scope = {:module => name}
|
|
||||||
|
|
||||||
self.namespaced = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def namespaced?
|
def namespaced?
|
||||||
|
@ -398,8 +399,10 @@ module Rails
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def routes
|
def routes(&block)
|
||||||
@routes ||= ActionDispatch::Routing::RouteSet.new
|
@routes ||= ActionDispatch::Routing::RouteSet.new
|
||||||
|
self.routes_draw_block = block if block_given?
|
||||||
|
@routes
|
||||||
end
|
end
|
||||||
|
|
||||||
def initializers
|
def initializers
|
||||||
|
@ -446,6 +449,7 @@ module Rails
|
||||||
end
|
end
|
||||||
|
|
||||||
initializer :add_routing_paths do |app|
|
initializer :add_routing_paths do |app|
|
||||||
|
app.routes_reloader.blocks[routes] = routes_draw_block
|
||||||
paths.config.routes.to_a.each do |route|
|
paths.config.routes.to_a.each do |route|
|
||||||
app.routes_reloader.paths.unshift(route) if File.exists?(route)
|
app.routes_reloader.paths.unshift(route) if File.exists?(route)
|
||||||
end
|
end
|
||||||
|
@ -498,6 +502,8 @@ module Rails
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
attr_accessor :routes_draw_block
|
||||||
|
|
||||||
def find_root_with_flag(flag, default=nil)
|
def find_root_with_flag(flag, default=nil)
|
||||||
root_path = self.class.called_from
|
root_path = self.class.called_from
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,19 @@ module Rails
|
||||||
@@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
|
@@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
|
||||||
end
|
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:
|
# Holds generators configuration:
|
||||||
#
|
#
|
||||||
# config.generators do |g|
|
# config.generators do |g|
|
||||||
|
@ -30,11 +43,11 @@ module Rails
|
||||||
# config.generators.colorize_logging = false
|
# config.generators.colorize_logging = false
|
||||||
#
|
#
|
||||||
def generators
|
def generators
|
||||||
@@generators ||= Rails::Configuration::Generators.new
|
@generators ||= Rails::Configuration::Generators.new
|
||||||
if block_given?
|
if block_given?
|
||||||
yield @@generators
|
yield @generators
|
||||||
else
|
else
|
||||||
@@generators
|
@generators
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module Rails
|
module Rails
|
||||||
class TestUnitRailtie < Rails::Railtie
|
class TestUnitRailtie < Rails::Railtie
|
||||||
config.generators do |c|
|
config.app_generators do |c|
|
||||||
c.test_framework :test_unit, :fixture => true,
|
c.test_framework :test_unit, :fixture => true,
|
||||||
:fixture_replacement => nil
|
:fixture_replacement => nil
|
||||||
|
|
||||||
|
|
|
@ -643,5 +643,104 @@ module RailtiesTest
|
||||||
Bukkits::Engine.load_seed
|
Bukkits::Engine.load_seed
|
||||||
assert Bukkits::Engine.config.bukkits_seeds_loaded
|
assert Bukkits::Engine.config.bukkits_seeds_loaded
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue