mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
9b19a6f16c
* Added :autoload to engines path API and redefine usage to be in sync with 6f83a5036d8a9c3f8ed7; * Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins); * Always autoload code in app/ for engines and plugins. This makes engines behave closer to an application and should allow us to get rid of the unloadable hack required when controllers inside engines inherit from ApplicationController;
167 lines
No EOL
3 KiB
Ruby
167 lines
No EOL
3 KiB
Ruby
require 'set'
|
|
|
|
module Rails
|
|
module Paths
|
|
module PathParent
|
|
attr_reader :children
|
|
|
|
def method_missing(id, *args)
|
|
name = id.to_s
|
|
|
|
if name =~ /^(.*)=$/ || args.any?
|
|
@children[$1 || name] = Path.new(@root, *args)
|
|
elsif path = @children[name]
|
|
path
|
|
else
|
|
super
|
|
end
|
|
end
|
|
end
|
|
|
|
class Root
|
|
include PathParent
|
|
|
|
attr_accessor :path
|
|
|
|
def initialize(path)
|
|
raise if path.is_a?(Array)
|
|
@children = {}
|
|
@path = path
|
|
@root = self
|
|
@all_paths = []
|
|
end
|
|
|
|
def all_paths
|
|
@all_paths.uniq!
|
|
@all_paths
|
|
end
|
|
|
|
def autoload_once
|
|
filter_by(:autoload_once?)
|
|
end
|
|
|
|
def eager_load
|
|
filter_by(:eager_load?)
|
|
end
|
|
|
|
def autoload_paths
|
|
filter_by(:autoload?)
|
|
end
|
|
|
|
def load_paths
|
|
filter_by(:load_path?)
|
|
end
|
|
|
|
def push(*)
|
|
raise "Application root can only have one physical path"
|
|
end
|
|
|
|
alias unshift push
|
|
alias << push
|
|
alias concat push
|
|
|
|
protected
|
|
|
|
def filter_by(constraint)
|
|
all = []
|
|
all_paths.each do |path|
|
|
if path.send(constraint)
|
|
paths = path.paths
|
|
paths -= path.children.values.map { |p| p.send(constraint) ? [] : p.paths }.flatten
|
|
all.concat(paths)
|
|
end
|
|
end
|
|
all.uniq!
|
|
all.reject! { |p| !File.exists?(p) }
|
|
all
|
|
end
|
|
end
|
|
|
|
class Path
|
|
include PathParent, Enumerable
|
|
|
|
attr_reader :path
|
|
attr_accessor :glob
|
|
|
|
def initialize(root, *paths)
|
|
options = paths.last.is_a?(::Hash) ? paths.pop : {}
|
|
@children = {}
|
|
@root = root
|
|
@paths = paths.flatten
|
|
@glob = options[:glob]
|
|
|
|
autoload_once! if options[:autoload_once]
|
|
eager_load! if options[:eager_load]
|
|
autoload! if options[:autoload]
|
|
load_path! if options[:load_path]
|
|
|
|
@root.all_paths << self
|
|
end
|
|
|
|
def each
|
|
to_a.each { |p| yield p }
|
|
end
|
|
|
|
def push(path)
|
|
@paths.push path
|
|
end
|
|
|
|
alias << push
|
|
|
|
def unshift(path)
|
|
@paths.unshift path
|
|
end
|
|
|
|
def concat(paths)
|
|
@paths.concat paths
|
|
end
|
|
|
|
def autoload_once!
|
|
@autoload_once = true
|
|
end
|
|
|
|
def autoload_once?
|
|
@autoload_once
|
|
end
|
|
|
|
def eager_load!
|
|
@eager_load = true
|
|
end
|
|
|
|
def eager_load?
|
|
@eager_load
|
|
end
|
|
|
|
def autoload!
|
|
@autoload = true
|
|
end
|
|
|
|
def autoload?
|
|
@autoload
|
|
end
|
|
|
|
def load_path!
|
|
@load_path = true
|
|
end
|
|
|
|
def load_path?
|
|
@load_path
|
|
end
|
|
|
|
def paths
|
|
raise "You need to set a path root" unless @root.path
|
|
|
|
result = @paths.map do |p|
|
|
path = File.expand_path(p, @root.path)
|
|
@glob ? Dir[File.join(path, @glob)] : path
|
|
end
|
|
|
|
result.flatten!
|
|
result.uniq!
|
|
result
|
|
end
|
|
|
|
alias to_a paths
|
|
end
|
|
end
|
|
end |