1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
module Rails
class GemDependency
attr_accessor :name, :requirement, :version, :lib, :source
def self.unpacked_path
@unpacked_path ||= File.join(RAILS_ROOT, 'vendor', 'gems')
end
def initialize(name, options = {})
require 'rubygems' unless Object.const_defined?(:Gem)
if options[:requirement]
@requirement = options[:requirement]
elsif options[:version]
@requirement = Gem::Requirement.create(options[:version])
else
raise ArgumentError.new('Must pass either :version or :requirement')
end
@version = @requirement.instance_variable_get("@requirements").first.last if @requirement
@name = name.to_s
@lib = options[:lib]
@source = options[:source]
@loaded = @frozen = @load_paths_added = false
@unpack_directory = nil
end
def add_load_paths
return if @loaded || @load_paths_added
unpacked_paths = Dir[File.join(self.class.unpacked_path, "#{@name}-#{@version || "*"}")]
if unpacked_paths.empty?
args = [@name]
args << @requirement.to_s if @requirement
gem *args
else
$LOAD_PATH << File.join(unpacked_paths.first, 'lib')
@frozen = true
end
@load_paths_added = true
rescue Gem::LoadError
puts $!.to_s
end
def dependencies
all_dependencies = specification.dependencies.map do |dependency|
GemDependency.new(dependency.name, :requirement => dependency.version_requirements)
end
all_dependencies += all_dependencies.map(&:dependencies).flatten
all_dependencies.uniq
end
def gem_dir(base_directory)
File.join(base_directory, specification.full_name)
end
def load
return if @loaded || @load_paths_added == false
require(@lib || @name)
@loaded = true
rescue LoadError
puts $!.to_s
$!.backtrace.each { |b| puts b }
end
def frozen?
@frozen
end
def loaded?
@loaded
end
def load_paths_added?
@load_paths_added
end
def install
Gem::GemRunner.new.run(install_command)
end
def unpack_to(directory)
FileUtils.mkdir_p directory
Dir.chdir directory do
Gem::GemRunner.new.run(unpack_command)
end
# copy the gem's specification into GEMDIR/.specification so that
# we can access information about the gem on deployment systems
# without having the gem installed
spec_filename = File.join(gem_dir(directory), '.specification')
File.open(spec_filename, 'w') do |file|
file.puts specification.to_yaml
end
end
def ==(other)
self.name == other.name && self.requirement == other.requirement
end
private ###################################################################
def specification
@spec ||= Gem.source_index.search(Gem::Dependency.new(@name, @requirement)).sort_by { |s| s.version }.last
end
def install_command
cmd = %w(install) << @name
cmd << "--version" << "#{@requirement.to_s}" if @requirement
cmd << "--source" << @source if @source
cmd
end
def unpack_command
cmd = %w(unpack) << @name
cmd << "--version" << "#{@requirement.to_s}" if @requirement
cmd
end
end
end
|