rubygems-update 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- data/ChangeLog +2335 -0
- data/README +54 -0
- data/Rakefile +293 -0
- data/Releases +98 -0
- data/TODO +7 -0
- data/bin/gem +11 -0
- data/bin/gem_server +111 -0
- data/bin/generate_yaml_index.rb +58 -0
- data/bin/update_rubygems +18 -0
- data/doc/doc.css +73 -0
- data/doc/makedoc.rb +4 -0
- data/examples/application/an-app.gemspec +26 -0
- data/examples/application/bin/myapp +3 -0
- data/examples/application/lib/somefunctionality.rb +3 -0
- data/gemspecs/README +4 -0
- data/gemspecs/cgikit-1.1.0.gemspec +18 -0
- data/gemspecs/jabber4r.gemspec +26 -0
- data/gemspecs/linguistics.gemspec +22 -0
- data/gemspecs/ook.gemspec +21 -0
- data/gemspecs/progressbar.gemspec +22 -0
- data/gemspecs/redcloth.gemspec +22 -0
- data/gemspecs/rublog.gemspec +23 -0
- data/gemspecs/ruby-doom.gemspec +21 -0
- data/gemspecs/rubyjdwp.gemspec +21 -0
- data/gemspecs/statistics.gemspec +21 -0
- data/lib/rubygems.rb +353 -0
- data/lib/rubygems/builder.rb +54 -0
- data/lib/rubygems/cmd_manager.rb +127 -0
- data/lib/rubygems/command.rb +191 -0
- data/lib/rubygems/config_file.rb +57 -0
- data/lib/rubygems/doc_manager.rb +94 -0
- data/lib/rubygems/format.rb +65 -0
- data/lib/rubygems/gem_commands.rb +925 -0
- data/lib/rubygems/gem_runner.rb +23 -0
- data/lib/rubygems/installer.rb +621 -0
- data/lib/rubygems/loadpath_manager.rb +108 -0
- data/lib/rubygems/old_format.rb +150 -0
- data/lib/rubygems/open-uri.rb +604 -0
- data/lib/rubygems/package.rb +740 -0
- data/lib/rubygems/remote_installer.rb +499 -0
- data/lib/rubygems/rubygems_version.rb +6 -0
- data/lib/rubygems/source_index.rb +130 -0
- data/lib/rubygems/specification.rb +613 -0
- data/lib/rubygems/user_interaction.rb +176 -0
- data/lib/rubygems/validator.rb +148 -0
- data/lib/rubygems/version.rb +279 -0
- data/lib/ubygems.rb +4 -0
- data/pkgs/sources/lib/sources.rb +6 -0
- data/pkgs/sources/sources.gemspec +14 -0
- data/post-install.rb +75 -0
- data/redist/session.gem +433 -0
- data/scripts/buildtests.rb +25 -0
- data/scripts/gemdoc.rb +62 -0
- data/scripts/runtest.rb +17 -0
- data/scripts/specdoc.rb +164 -0
- data/setup.rb +1360 -0
- data/test/bogussources.rb +5 -0
- data/test/data/legacy/keyedlist-0.4.0.ruby +11 -0
- data/test/data/legacy/keyedlist-0.4.0.yaml +16 -0
- data/test/data/lib/code.rb +1 -0
- data/test/data/one/README.one +1 -0
- data/test/data/one/lib/one.rb +3 -0
- data/test/data/one/one.gemspec +17 -0
- data/test/data/one/one.yaml +40 -0
- data/test/functional.rb +145 -0
- data/test/gemenvironment.rb +45 -0
- data/test/gemutilities.rb +18 -0
- data/test/insure_session.rb +46 -0
- data/test/mock/gems/gems/sources-0.0.1/lib/sources.rb +5 -0
- data/test/mock/gems/specifications/sources-0.0.1.gemspec +8 -0
- data/test/mockgemui.rb +45 -0
- data/test/onegem.rb +23 -0
- data/test/simple_gem.rb +66 -0
- data/test/test_builder.rb +13 -0
- data/test/test_cached_fetcher.rb +60 -0
- data/test/test_check_command.rb +28 -0
- data/test/test_command.rb +130 -0
- data/test/test_configfile.rb +36 -0
- data/test/test_format.rb +70 -0
- data/test/test_gemloadpaths.rb +45 -0
- data/test/test_gempaths.rb +115 -0
- data/test/test_loadmanager.rb +40 -0
- data/test/test_local_cache.rb +157 -0
- data/test/test_package.rb +600 -0
- data/test/test_parse_commands.rb +179 -0
- data/test/test_process_commands.rb +21 -0
- data/test/test_remote_fetcher.rb +162 -0
- data/test/test_remote_installer.rb +154 -0
- data/test/test_source_index.rb +58 -0
- data/test/test_specification.rb +286 -0
- data/test/test_validator.rb +53 -0
- data/test/test_version_comparison.rb +204 -0
- data/test/testgem.rc +6 -0
- data/test/user_capture.rb +1 -0
- data/test/yaml_data.rb +59 -0
- metadata +151 -0
@@ -0,0 +1,499 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'socket'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Gem
|
6
|
+
class DependencyError < Gem::Exception; end
|
7
|
+
class RemoteSourceException < Gem::Exception; end
|
8
|
+
class GemNotFoundException < Gem::Exception; end
|
9
|
+
class RemoteInstallationCancelled < Gem::Exception; end
|
10
|
+
|
11
|
+
# RemoteSourceFetcher handles the details of fetching gems and gem
|
12
|
+
# information from a remote source.
|
13
|
+
class RemoteSourceFetcher
|
14
|
+
include UserInteraction
|
15
|
+
|
16
|
+
# Initialize a remote fetcher using the source URI (and possible
|
17
|
+
# proxy information).
|
18
|
+
def initialize(source_uri, proxy)
|
19
|
+
@uri = source_uri
|
20
|
+
@http_proxy = proxy
|
21
|
+
if @http_proxy == true
|
22
|
+
@http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The uncompressed +size+ of the source's directory (e.g. source
|
27
|
+
# info).
|
28
|
+
def size
|
29
|
+
@size ||= get_size("/yaml")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Fetch the data from the source at the given path.
|
33
|
+
def fetch_path(path="")
|
34
|
+
read_data(@uri + path)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the source index from the gem source. The source index is a
|
38
|
+
# directory of the gems available on the source, formatted as a
|
39
|
+
# Gem::Cache object. The cache object allows easy searching for
|
40
|
+
# gems by name and version requirement.
|
41
|
+
#
|
42
|
+
# Notice that the gem specs in the cache are adequate for searches
|
43
|
+
# and queries, but may have some information elided (hence
|
44
|
+
# "abbreviated").
|
45
|
+
def source_index
|
46
|
+
say "Updating Gem source index for: #{@uri}"
|
47
|
+
begin
|
48
|
+
require 'zlib'
|
49
|
+
yaml_spec = fetch_path("/yaml.Z")
|
50
|
+
yaml_spec = Zlib::Inflate.inflate(yaml_spec)
|
51
|
+
rescue
|
52
|
+
yaml_spec = nil
|
53
|
+
end
|
54
|
+
begin
|
55
|
+
yaml_spec = fetch_path("/yaml") unless yaml_spec
|
56
|
+
r = convert_spec(yaml_spec)
|
57
|
+
rescue SocketError => e
|
58
|
+
raise RemoteSourceException.new("Error fetching remote gem cache: #{e.to_s}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Connect to the source host/port, using a proxy if needed.
|
65
|
+
def connect_to(host, port)
|
66
|
+
if @http_proxy
|
67
|
+
proxy_uri = URI.parse(@http_proxy)
|
68
|
+
Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new(host, port)
|
69
|
+
else
|
70
|
+
Net::HTTP.new(host, port)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Get the size of the (non-compressed) data from the source at the
|
75
|
+
# given path.
|
76
|
+
def get_size(path)
|
77
|
+
read_size(@uri + path)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Read the size of the (source based) URI using an HTTP HEAD
|
81
|
+
# command.
|
82
|
+
def read_size(uri)
|
83
|
+
require 'net/http'
|
84
|
+
require 'uri'
|
85
|
+
u = URI.parse(uri)
|
86
|
+
http = connect_to(u.host, u.port)
|
87
|
+
path = (u.path == "") ? "/" : u.path
|
88
|
+
resp = http.head(path)
|
89
|
+
fail RemoteSourceException, "HTTP Response #{resp.code}" if resp.code !~ /^2/
|
90
|
+
resp['content-length'].to_i
|
91
|
+
end
|
92
|
+
|
93
|
+
# Read the data from the (source based) URI.
|
94
|
+
def read_data(uri)
|
95
|
+
require 'rubygems/open-uri'
|
96
|
+
open(uri,
|
97
|
+
"User-Agent" => "RubyGems/#{Gem::RubyGemsVersion}",
|
98
|
+
:proxy => @http_proxy
|
99
|
+
) do |input|
|
100
|
+
input.read
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Convert the yamlized string spec into a real spec (actually,
|
105
|
+
# these are hashes of specs.).
|
106
|
+
def convert_spec(yaml_spec)
|
107
|
+
YAML.load(reduce_spec(yaml_spec)) or
|
108
|
+
raise "Didn't get a valid YAML document"
|
109
|
+
end
|
110
|
+
|
111
|
+
# This reduces the source spec in size so that YAML bugs with
|
112
|
+
# large data sets will be dodged. Obviously this is a workaround,
|
113
|
+
# but it allows Gems to continue to work until the YAML bug is
|
114
|
+
# fixed.
|
115
|
+
def reduce_spec(yaml_spec)
|
116
|
+
result = ""
|
117
|
+
state = :copy
|
118
|
+
yaml_spec.each do |line|
|
119
|
+
if state == :copy && line =~ /^\s+files:\s*$/
|
120
|
+
state = :skip
|
121
|
+
result << line.sub(/$/, " []")
|
122
|
+
elsif state == :skip
|
123
|
+
if line !~ /^\s+-/
|
124
|
+
state = :copy
|
125
|
+
end
|
126
|
+
end
|
127
|
+
result << line if state == :copy
|
128
|
+
end
|
129
|
+
result
|
130
|
+
end
|
131
|
+
|
132
|
+
class << self
|
133
|
+
# Sent by the client when it is done with all the sources,
|
134
|
+
# allowing any cleanup activity to take place.
|
135
|
+
def finish
|
136
|
+
# Nothing to do
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# LocalSourceInfoCache implements the cache management policy on
|
142
|
+
# where the source info is stored on local file system. There are
|
143
|
+
# two possible cache locations: (1) the system wide cache, and (2)
|
144
|
+
# the user specific cache.
|
145
|
+
#
|
146
|
+
# * The system cache is prefered if it is writable (or can be
|
147
|
+
# created).
|
148
|
+
# * The user cache is used if the system cache is not writable (or
|
149
|
+
# can not be created).
|
150
|
+
#
|
151
|
+
# Once a cache is selected, it will be used for all operations. It
|
152
|
+
# will not switch between cache files dynamically.
|
153
|
+
#
|
154
|
+
class LocalSourceInfoCache
|
155
|
+
|
156
|
+
# The most recent cache data.
|
157
|
+
def cache_data
|
158
|
+
@dirty = false
|
159
|
+
@cache_data ||= read_cache
|
160
|
+
end
|
161
|
+
|
162
|
+
# Write data to the proper cache.
|
163
|
+
def write_cache
|
164
|
+
data = cache_data
|
165
|
+
open(writable_file, "w") do |f|
|
166
|
+
f.puts data.to_yaml
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# The name of the system cache file.
|
171
|
+
def system_cache_file
|
172
|
+
@sysetm_cache ||= File.join(Gem.dir, "source_cache")
|
173
|
+
end
|
174
|
+
|
175
|
+
# The name of the user cache file.
|
176
|
+
def user_cache_file
|
177
|
+
@user_cache ||=
|
178
|
+
ENV['GEMCACHE'] || File.join(Gem.user_home, ".gem/source_cache")
|
179
|
+
end
|
180
|
+
|
181
|
+
# Mark the cache as updated (i.e. dirty).
|
182
|
+
def update
|
183
|
+
@dirty = true
|
184
|
+
end
|
185
|
+
|
186
|
+
# Write the cache to a local file (if it is dirty).
|
187
|
+
def flush
|
188
|
+
write_cache if @dirty
|
189
|
+
@dirty = false
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
# Find a writable cache file.
|
195
|
+
def writable_file
|
196
|
+
@cache_file
|
197
|
+
end
|
198
|
+
|
199
|
+
# Read the most current cache data.
|
200
|
+
def read_cache
|
201
|
+
@cache_file = select_cache_file
|
202
|
+
open(@cache_file) { |f| YAML.load(f) } || {}
|
203
|
+
end
|
204
|
+
|
205
|
+
# Select a writable cache file
|
206
|
+
def select_cache_file
|
207
|
+
try_file(system_cache_file) or
|
208
|
+
try_file(user_cache_file) or
|
209
|
+
fail "Unable to locate a writable cache file."
|
210
|
+
end
|
211
|
+
|
212
|
+
# Determine if +fn+ is a candidate for a cache file. Return fn if
|
213
|
+
# it is. Return nil if it is not.
|
214
|
+
def try_file(fn)
|
215
|
+
return fn if File.writable?(fn)
|
216
|
+
return nil if File.exist?(fn)
|
217
|
+
dir = File.dirname(fn)
|
218
|
+
if ! File.exist? dir
|
219
|
+
begin
|
220
|
+
FileUtils.mkdir_p(dir)
|
221
|
+
rescue RuntimeError
|
222
|
+
return nil
|
223
|
+
end
|
224
|
+
end
|
225
|
+
if File.writable?(dir)
|
226
|
+
FileUtils.touch fn
|
227
|
+
return fn
|
228
|
+
end
|
229
|
+
nil
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# CachedFetcher is a decorator that adds local file caching to
|
235
|
+
# RemoteSourceFetcher objects.
|
236
|
+
class CachedFetcher
|
237
|
+
|
238
|
+
# Create a cached fetcher (based on a RemoteSourceFetcher) for the
|
239
|
+
# source at +source_uri+ (through the proxy +proxy+).
|
240
|
+
def initialize(source_uri, proxy)
|
241
|
+
@source_uri = source_uri
|
242
|
+
@fetcher = RemoteSourceFetcher.new(source_uri, proxy)
|
243
|
+
end
|
244
|
+
|
245
|
+
# The uncompressed +size+ of the source's directory (e.g. source
|
246
|
+
# info).
|
247
|
+
def size
|
248
|
+
@fetcher.size
|
249
|
+
end
|
250
|
+
|
251
|
+
# Fetch the data from the source at the given path.
|
252
|
+
def fetch_path(path="")
|
253
|
+
@fetcher.fetch_path(path)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Get the source index from the gem source. The source index is a
|
257
|
+
# directory of the gems available on the source, formatted as a
|
258
|
+
# Gem::Cache object. The cache object allows easy searching for
|
259
|
+
# gems by name and version requirement.
|
260
|
+
#
|
261
|
+
# Notice that the gem specs in the cache are adequate for searches
|
262
|
+
# and queries, but may have some information elided (hence
|
263
|
+
# "abbreviated").
|
264
|
+
def source_index
|
265
|
+
cache = manager.cache_data[@source_uri]
|
266
|
+
if cache && cache['size'] == @fetcher.size
|
267
|
+
cache['cache']
|
268
|
+
else
|
269
|
+
result = @fetcher.source_index
|
270
|
+
manager.cache_data[@source_uri] = {
|
271
|
+
'size' => @fetcher.size,
|
272
|
+
'cache' => result,
|
273
|
+
}
|
274
|
+
manager.update
|
275
|
+
result
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Flush the cache to a local file, if needed.
|
280
|
+
def flush
|
281
|
+
manager.flush
|
282
|
+
end
|
283
|
+
|
284
|
+
private
|
285
|
+
|
286
|
+
# The cache manager for this cached source.
|
287
|
+
def manager
|
288
|
+
self.class.manager
|
289
|
+
end
|
290
|
+
|
291
|
+
# The cache is shared between all caching fetchers, so the cache
|
292
|
+
# is put in the class object.
|
293
|
+
class << self
|
294
|
+
|
295
|
+
# The Cache manager for all instances of this class.
|
296
|
+
def manager
|
297
|
+
@manager ||= LocalSourceInfoCache.new
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
# Sent by the client when it is done with all the sources,
|
302
|
+
# allowing any cleanup activity to take place.
|
303
|
+
def finish
|
304
|
+
manager.flush
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
class RemoteInstaller
|
311
|
+
include UserInteraction
|
312
|
+
|
313
|
+
# <tt>http_proxy</tt>::
|
314
|
+
# * [String]: explicit specification of proxy; overrides any
|
315
|
+
# environment variable setting
|
316
|
+
# * nil: respect environment variables
|
317
|
+
# * <tt>:no_proxy</tt>: ignore environment variables and _don't_
|
318
|
+
# use a proxy
|
319
|
+
#
|
320
|
+
def initialize(http_proxy=nil)
|
321
|
+
# Ensure http_proxy env vars are used if no proxy explicitly supplied.
|
322
|
+
@http_proxy =
|
323
|
+
case http_proxy
|
324
|
+
when :no_proxy
|
325
|
+
false
|
326
|
+
when nil
|
327
|
+
true
|
328
|
+
else
|
329
|
+
http_proxy.to_str
|
330
|
+
end
|
331
|
+
@fetcher_class = CachedFetcher
|
332
|
+
end
|
333
|
+
|
334
|
+
# This method will install package_name onto the local system.
|
335
|
+
#
|
336
|
+
# gem_name::
|
337
|
+
# [String] Name of the Gem to install
|
338
|
+
#
|
339
|
+
# version_requirement::
|
340
|
+
# [default = "> 0.0.0"] Gem version requirement to install
|
341
|
+
#
|
342
|
+
# Returns::
|
343
|
+
# an array of Gem::Specification objects, one for each gem installed.
|
344
|
+
#
|
345
|
+
def install(gem_name,
|
346
|
+
version_requirement = "> 0.0.0",
|
347
|
+
force=false,
|
348
|
+
install_dir=Gem.dir,
|
349
|
+
install_stub=true)
|
350
|
+
unless version_requirement.respond_to?(:satisfied_by?)
|
351
|
+
version_requirement = Version::Requirement.new(version_requirement)
|
352
|
+
end
|
353
|
+
installed_gems = []
|
354
|
+
caches = source_index_hash
|
355
|
+
spec, source = find_gem_to_install(gem_name, version_requirement, caches)
|
356
|
+
dependencies = find_dependencies_not_installed(spec.dependencies)
|
357
|
+
installed_gems << install_dependencies(dependencies, force, install_dir)
|
358
|
+
cache_dir = File.join(install_dir, "cache")
|
359
|
+
destination_file = File.join(cache_dir, spec.full_name + ".gem")
|
360
|
+
download_gem(destination_file, source, spec)
|
361
|
+
installer = new_installer(destination_file)
|
362
|
+
installed_gems.unshift installer.install(force, install_dir, install_stub)
|
363
|
+
installed_gems.flatten
|
364
|
+
end
|
365
|
+
|
366
|
+
# Search Gem repository for a gem by specifying all or part of
|
367
|
+
# the Gem's name
|
368
|
+
def search(pattern_to_match)
|
369
|
+
results = []
|
370
|
+
caches = source_index_hash
|
371
|
+
caches.each do |cache|
|
372
|
+
results << cache[1].search(pattern_to_match)
|
373
|
+
end
|
374
|
+
results
|
375
|
+
end
|
376
|
+
|
377
|
+
# Return a list of the sources that we can download gems from
|
378
|
+
def sources
|
379
|
+
unless @sources
|
380
|
+
require_gem("sources")
|
381
|
+
@sources = Gem.sources
|
382
|
+
end
|
383
|
+
@sources
|
384
|
+
end
|
385
|
+
|
386
|
+
# Return a hash mapping the available source names to the source
|
387
|
+
# index of that source.
|
388
|
+
def source_index_hash
|
389
|
+
result = {}
|
390
|
+
sources.each do |source|
|
391
|
+
result[source] = fetch_source(source)
|
392
|
+
end
|
393
|
+
@fetcher_class.finish
|
394
|
+
result
|
395
|
+
end
|
396
|
+
|
397
|
+
# Return the source info for the given source. The
|
398
|
+
def fetch_source(source)
|
399
|
+
rsf = @fetcher_class.new(source, @http_proxy)
|
400
|
+
rsf.source_index
|
401
|
+
end
|
402
|
+
|
403
|
+
# Find a gem to be installed by interacting with the user.
|
404
|
+
def find_gem_to_install(gem_name, version_requirement, caches)
|
405
|
+
max_version = Version.new("0.0.0")
|
406
|
+
specs_n_sources = []
|
407
|
+
caches.each do |source, cache|
|
408
|
+
cache.each do |name, spec|
|
409
|
+
if (/#{gem_name}/i === name &&
|
410
|
+
version_requirement.satisfied_by?(spec.version))
|
411
|
+
specs_n_sources << [spec, source]
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
if specs_n_sources.size == 0
|
416
|
+
raise GemNotFoundException.new(
|
417
|
+
"Could not find #{gem_name} (#{version_requirement}) in the repository")
|
418
|
+
end
|
419
|
+
specs_n_sources = specs_n_sources.sort_by { |x| x[0].version }.reverse
|
420
|
+
if specs_n_sources.reject { |item|
|
421
|
+
item[0].platform.nil? || item[0].platform==Platform::RUBY
|
422
|
+
}.size == 0
|
423
|
+
# only non-binary gems...return latest
|
424
|
+
return specs_n_sources.first
|
425
|
+
end
|
426
|
+
list = specs_n_sources.collect {|item|
|
427
|
+
"#{item[0].name} #{item[0].version} (#{item[0].platform.to_s})"
|
428
|
+
}
|
429
|
+
list << "Cancel installation"
|
430
|
+
string, index = choose_from_list(
|
431
|
+
"Select which gem to install for your platform (#{RUBY_PLATFORM})",
|
432
|
+
list)
|
433
|
+
raise RemoteInstallationCancelled.new("Installation of #{gem_name} cancelled.") if
|
434
|
+
index == (list.size - 1)
|
435
|
+
specs_n_sources[index]
|
436
|
+
end
|
437
|
+
|
438
|
+
def find_dependencies_not_installed(dependencies)
|
439
|
+
to_install = []
|
440
|
+
dependencies.each do |dependency|
|
441
|
+
begin
|
442
|
+
require_gem(dependency.name, *dependency.requirement_list)
|
443
|
+
rescue LoadError => e
|
444
|
+
to_install.push dependency
|
445
|
+
end
|
446
|
+
end
|
447
|
+
to_install
|
448
|
+
end
|
449
|
+
|
450
|
+
# Install all the given dependencies. Returns an array of
|
451
|
+
# Gem::Specification objects, one for each dependency installed.
|
452
|
+
#
|
453
|
+
# TODO: For now, we recursively install, but this is not the right
|
454
|
+
# way to do things (e.g. if a package fails to download, we
|
455
|
+
# shouldn't install anything).
|
456
|
+
def install_dependencies(dependencies, force, install_dir)
|
457
|
+
installed_gems = []
|
458
|
+
dependencies.each do |dependency|
|
459
|
+
if ask_yes_no("Install required dependency #{dependency.name}?", true)
|
460
|
+
remote_installer = RemoteInstaller.new(
|
461
|
+
if @http_proxy == false
|
462
|
+
:no_proxy
|
463
|
+
elsif @http_proxy == true
|
464
|
+
else
|
465
|
+
@http_proxy
|
466
|
+
end
|
467
|
+
)
|
468
|
+
installed_gems << remote_installer.install(
|
469
|
+
dependency.name,
|
470
|
+
dependency.version_requirements,
|
471
|
+
force,
|
472
|
+
install_dir)
|
473
|
+
else
|
474
|
+
raise DependencyError.new("Required dependency #{dependency.name} not installed")
|
475
|
+
end
|
476
|
+
end
|
477
|
+
installed_gems
|
478
|
+
end
|
479
|
+
|
480
|
+
def download_gem(destination_file, source, spec)
|
481
|
+
rsf = @fetcher_class.new(source, @http_proxy)
|
482
|
+
path = "/gems/#{spec.full_name}.gem"
|
483
|
+
response = rsf.fetch_path(path)
|
484
|
+
write_gem_to_file(response, destination_file)
|
485
|
+
end
|
486
|
+
|
487
|
+
def write_gem_to_file(body, destination_file)
|
488
|
+
FileUtils.mkdir_p(File.dirname(destination_file)) unless File.exist?(destination_file)
|
489
|
+
File.open(destination_file, 'wb') do |out|
|
490
|
+
out.write(body)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
def new_installer(gem)
|
495
|
+
return Installer.new(gem)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
end
|