mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
0dea211f44
Signed-off-by: Michael Koziarski <michael@koziarski.com> [#1128 state:committed]
93 lines
No EOL
2.9 KiB
Ruby
93 lines
No EOL
2.9 KiB
Ruby
require 'rubygems'
|
|
require 'yaml'
|
|
|
|
module Rails
|
|
|
|
class VendorGemSourceIndex
|
|
# VendorGemSourceIndex acts as a proxy for the Gem source index, allowing
|
|
# gems to be loaded from vendor/gems. Rather than the standard gem repository format,
|
|
# vendor/gems contains unpacked gems, with YAML specifications in .specification in
|
|
# each gem directory.
|
|
include Enumerable
|
|
|
|
attr_reader :installed_source_index
|
|
attr_reader :vendor_source_index
|
|
|
|
def initialize(installed_index, vendor_dir=Rails::GemDependency.unpacked_path)
|
|
@installed_source_index = installed_index
|
|
@vendor_dir = vendor_dir
|
|
refresh!
|
|
end
|
|
|
|
def refresh!
|
|
# reload the installed gems
|
|
@installed_source_index.refresh!
|
|
vendor_gems = {}
|
|
|
|
# handle vendor Rails gems - they are identified by having loaded_from set to ""
|
|
# we add them manually to the list, so that other gems can find them via dependencies
|
|
Gem.loaded_specs.each do |n, s|
|
|
next unless s.loaded_from.empty?
|
|
vendor_gems[s.full_name] = s
|
|
end
|
|
|
|
# load specifications from vendor/gems
|
|
Dir[File.join(Rails::GemDependency.unpacked_path, '*')].each do |d|
|
|
spec = load_specification(d)
|
|
next unless spec
|
|
# NOTE: this is a bit of a hack - the gem system expects a different structure
|
|
# than we have.
|
|
# It's looking for:
|
|
# repository
|
|
# -> specifications
|
|
# - gem_name.spec <= loaded_from points to this
|
|
# -> gems
|
|
# - gem_name <= gem files here
|
|
# and therefore goes up one directory from loaded_from, then adds gems/gem_name
|
|
# to the path.
|
|
# But we have:
|
|
# vendor
|
|
# -> gems
|
|
# -> gem_name <= gem files here
|
|
# - .specification
|
|
# so we set loaded_from to vendor/gems/.specification (not a real file) to
|
|
# get the correct behavior.
|
|
spec.loaded_from = File.join(Rails::GemDependency.unpacked_path, '.specification')
|
|
vendor_gems[File.basename(d)] = spec
|
|
end
|
|
@vendor_source_index = Gem::SourceIndex.new(vendor_gems)
|
|
end
|
|
|
|
def load_specification(gem_dir)
|
|
spec_file = File.join(gem_dir, '.specification')
|
|
YAML.load_file(spec_file) if File.exist?(spec_file)
|
|
end
|
|
|
|
def find_name(*args)
|
|
@installed_source_index.find_name(*args) + @vendor_source_index.find_name(*args)
|
|
end
|
|
|
|
def search(*args)
|
|
# look for vendor gems, and then installed gems - later elements take priority
|
|
@installed_source_index.search(*args) + @vendor_source_index.search(*args)
|
|
end
|
|
|
|
def each(&block)
|
|
@vendor_source_index.each(&block)
|
|
@installed_source_index.each(&block)
|
|
end
|
|
|
|
def add_spec(spec)
|
|
@vendor_source_index.add_spec spec
|
|
end
|
|
|
|
def remove_spec(spec)
|
|
@vendor_source_index.remove_spec spec
|
|
end
|
|
|
|
def size
|
|
@vendor_source_index.size + @installed_source_index.size
|
|
end
|
|
|
|
end
|
|
end |