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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
require 'rubygems'
require 'rubygems/dependency'
require 'rubygems/dependency_resolver'
require 'rubygems/dependency_list'
require 'rubygems/installer'
require 'tsort'
module Gem
class RequestSet
include TSort
def initialize(*deps)
@dependencies = deps
yield self if block_given?
end
attr_reader :dependencies
# Declare that a gem of name +name+ with +reqs+ requirements
# is needed.
#
def gem(name, *reqs)
@dependencies << Gem::Dependency.new(name, reqs)
end
# Add +deps+ Gem::Depedency objects to the set.
#
def import(deps)
@dependencies += deps
end
# Resolve the requested dependencies and return an Array of
# Specification objects to be activated.
#
def resolve(set=nil)
r = Gem::DependencyResolver.new(@dependencies, set)
@requests = r.resolve
end
# Resolve the requested dependencies against the gems
# available via Gem.path and return an Array of Specification
# objects to be activated.
#
def resolve_current
resolve DependencyResolver::CurrentSet.new
end
# Load a dependency management file.
#
def load_gemdeps(path)
gf = GemDepedencyAPI.new(self, path)
gf.load
end
def specs
@specs ||= @requests.map { |r| r.full_spec }
end
def tsort_each_node(&block)
@requests.each(&block)
end
def tsort_each_child(node)
node.spec.dependencies.each do |dep|
next if dep.type == :development
match = @requests.find { |r| dep.match? r.spec.name, r.spec.version }
if match
begin
yield match
rescue TSort::Cyclic
end
else
raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}"
end
end
end
def sorted_requests
@sorted ||= strongly_connected_components.flatten
end
def specs_in(dir)
Dir["#{dir}/specifications/*.gemspec"].map do |g|
Gem::Specification.load g
end
end
def install_into(dir, force=true, &b)
existing = force ? [] : specs_in(dir)
dir = File.expand_path dir
installed = []
sorted_requests.each do |req|
if existing.find { |s| s.full_name == req.spec.full_name }
b.call req, nil if b
next
end
path = req.download(dir)
inst = Gem::Installer.new path, :install_dir => dir,
:only_install_dir => true
b.call req, inst if b
inst.install
installed << req
end
installed
end
def install(options, &b)
if dir = options[:install_dir]
return install_into(dir, false, &b)
end
cache_dir = options[:cache_dir] || Gem.dir
specs = []
sorted_requests.each do |req|
if req.installed?
b.call req, nil if b
next
end
path = req.download cache_dir
inst = Gem::Installer.new path, options
b.call req, inst if b
specs << inst.install
end
specs
end
# A semi-compatible DSL for Bundler's Gemfile format
#
class GemDepedencyAPI
def initialize(set, path)
@set = set
@path = path
end
def load
instance_eval File.read(@path).untaint, @path, 1
end
# DSL
def source(url)
end
def gem(name, *reqs)
# Ignore the opts for now.
reqs.pop if reqs.last.kind_of?(Hash)
@set.gem name, *reqs
end
def platform(what)
if what == :ruby
yield
end
end
alias_method :platforms, :platform
def group(*what)
end
end
end
end
|