Enhanced Rails Metal - the load order of metals can now be configured [#2057 state:resolved]
Signed-off-by: Joshua Peek <josh@joshpeek.com>
This commit is contained in:
parent
818556ec4f
commit
4d4d2c3896
|
@ -559,6 +559,7 @@ Run `rake gems:install` to install the missing gems.
|
|||
end
|
||||
|
||||
def initialize_metal
|
||||
Rails::Rack::Metal.requested_metals = configuration.metals
|
||||
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
|
||||
|
||||
configuration.middleware.insert_before(
|
||||
|
@ -715,6 +716,11 @@ Run `rake gems:install` to install the missing gems.
|
|||
@plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym }
|
||||
end
|
||||
|
||||
# The list of metals to load. If this is set to <tt>nil</tt>, all metals will
|
||||
# be loaded in alphabetical order. If this is set to <tt>[]</tt>, no metals will
|
||||
# be loaded. Otherwise metals will be loaded in the order specified
|
||||
attr_accessor :metals
|
||||
|
||||
# The path to the root of the plugins directory. By default, it is in
|
||||
# <tt>vendor/plugins</tt>.
|
||||
attr_accessor :plugin_paths
|
||||
|
|
|
@ -8,16 +8,26 @@ module Rails
|
|||
|
||||
cattr_accessor :metal_paths
|
||||
self.metal_paths = ["#{Rails.root}/app/metal"]
|
||||
cattr_accessor :requested_metals
|
||||
|
||||
def self.metals
|
||||
matcher = /#{Regexp.escape('/app/metal/')}(.*)\.rb\Z/
|
||||
metal_glob = metal_paths.map{ |base| "#{base}/**/*.rb" }
|
||||
all_metals = {}
|
||||
|
||||
Dir[*metal_glob].sort.map do |file|
|
||||
path = file.match(matcher)[1]
|
||||
require path
|
||||
path.classify.constantize
|
||||
file = file.match(matcher)[1]
|
||||
all_metals[file.classify] = file
|
||||
end
|
||||
|
||||
load_list = requested_metals || all_metals.keys
|
||||
|
||||
load_list.map do |requested_metal|
|
||||
if metal = all_metals[requested_metal]
|
||||
require metal
|
||||
requested_metal.constantize
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
def initialize(app)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class MetalA < Rails::Rack::Metal
|
||||
def self.call(env)
|
||||
[200, { "Content-Type" => "text/html"}, "Hi"]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class MetalB < Rails::Rack::Metal
|
||||
def self.call(env)
|
||||
[200, { "Content-Type" => "text/html"}, "Hi"]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class FooMetal < Rails::Rack::Metal
|
||||
def self.call(env)
|
||||
[200, { "Content-Type" => "text/html"}, "Hi"]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
module Folder
|
||||
class MetalA < Rails::Rack::Metal
|
||||
def self.call(env)
|
||||
[200, { "Content-Type" => "text/html"}, "Hi"]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
module Folder
|
||||
class MetalB < Rails::Rack::Metal
|
||||
def self.call(env)
|
||||
[200, { "Content-Type" => "text/html"}, "Hi"]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
require 'abstract_unit'
|
||||
require 'initializer'
|
||||
|
||||
class MetalTest < Test::Unit::TestCase
|
||||
def test_metals_should_return_list_of_found_metal_apps
|
||||
use_appdir("singlemetal") do
|
||||
assert_equal(["FooMetal"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
|
||||
def test_metals_should_return_alphabetical_list_of_found_metal_apps
|
||||
use_appdir("multiplemetals") do
|
||||
assert_equal(["MetalA", "MetalB"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
|
||||
def test_metals_load_order_should_be_overriden_by_requested_metals
|
||||
use_appdir("multiplemetals") do
|
||||
Rails::Rack::Metal.requested_metals = ["MetalB", "MetalA"]
|
||||
assert_equal(["MetalB", "MetalA"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
|
||||
def test_metals_not_listed_should_not_load
|
||||
use_appdir("multiplemetals") do
|
||||
Rails::Rack::Metal.requested_metals = ["MetalB"]
|
||||
assert_equal(["MetalB"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
p
|
||||
def test_metal_finding_should_work_with_subfolders
|
||||
use_appdir("subfolders") do
|
||||
assert_equal(["Folder::MetalA", "Folder::MetalB"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
|
||||
def test_metal_finding_with_requested_metals_should_work_with_subfolders
|
||||
use_appdir("subfolders") do
|
||||
Rails::Rack::Metal.requested_metals = ["Folder::MetalB"]
|
||||
assert_equal(["Folder::MetalB"], found_metals_as_string_array)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def use_appdir(root)
|
||||
dir = "#{File.dirname(__FILE__)}/fixtures/metal/#{root}"
|
||||
Rails::Rack::Metal.metal_paths = ["#{dir}/app/metal"]
|
||||
Rails::Rack::Metal.requested_metals = nil
|
||||
$LOAD_PATH << "#{dir}/app/metal"
|
||||
yield
|
||||
end
|
||||
|
||||
def found_metals_as_string_array
|
||||
Rails::Rack::Metal.metals.map { |m| m.to_s }
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue