rubygems-update 2.2.5 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +4 -1
- data/CONTRIBUTING +20 -0
- data/History.txt +117 -14
- data/Manifest.txt +11 -2
- data/README.rdoc +1 -1
- data/Rakefile +0 -3
- data/lib/rubygems.rb +31 -11
- data/lib/rubygems/available_set.rb +1 -1
- data/lib/rubygems/basic_specification.rb +20 -10
- data/lib/rubygems/command.rb +4 -1
- data/lib/rubygems/commands/cert_command.rb +11 -13
- data/lib/rubygems/commands/cleanup_command.rb +2 -2
- data/lib/rubygems/commands/dependency_command.rb +2 -2
- data/lib/rubygems/commands/environment_command.rb +5 -2
- data/lib/rubygems/commands/help_command.rb +199 -20
- data/lib/rubygems/commands/install_command.rb +40 -10
- data/lib/rubygems/commands/list_command.rb +2 -2
- data/lib/rubygems/commands/open_command.rb +81 -0
- data/lib/rubygems/commands/search_command.rb +5 -5
- data/lib/rubygems/commands/setup_command.rb +1 -1
- data/lib/rubygems/commands/update_command.rb +8 -5
- data/lib/rubygems/commands/yank_command.rb +8 -13
- data/lib/rubygems/config_file.rb +13 -2
- data/lib/rubygems/dependency.rb +29 -16
- data/lib/rubygems/dependency_installer.rb +44 -10
- data/lib/rubygems/doctor.rb +1 -1
- data/lib/rubygems/errors.rb +30 -0
- data/lib/rubygems/exceptions.rb +20 -0
- data/lib/rubygems/ext/builder.rb +1 -1
- data/lib/rubygems/gemcutter_utilities.rb +1 -1
- data/lib/rubygems/installer.rb +4 -4
- data/lib/rubygems/name_tuple.rb +3 -1
- data/lib/rubygems/package.rb +27 -14
- data/lib/rubygems/package/file_source.rb +33 -0
- data/lib/rubygems/package/io_source.rb +45 -0
- data/lib/rubygems/package/old.rb +5 -5
- data/lib/rubygems/package/source.rb +3 -0
- data/lib/rubygems/platform.rb +2 -1
- data/lib/rubygems/rdoc.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +59 -18
- data/lib/rubygems/request.rb +71 -101
- data/lib/rubygems/request/connection_pools.rb +77 -0
- data/lib/rubygems/request/http_pool.rb +38 -0
- data/lib/rubygems/request/https_pool.rb +10 -0
- data/lib/rubygems/request_set.rb +65 -20
- data/lib/rubygems/request_set/gem_dependency_api.rb +234 -14
- data/lib/rubygems/request_set/lockfile.rb +65 -22
- data/lib/rubygems/requirement.rb +3 -0
- data/lib/rubygems/resolver.rb +33 -16
- data/lib/rubygems/resolver/activation_request.rb +7 -0
- data/lib/rubygems/resolver/api_set.rb +12 -2
- data/lib/rubygems/resolver/api_specification.rb +6 -0
- data/lib/rubygems/resolver/composed_set.rb +4 -0
- data/lib/rubygems/resolver/dependency_request.rb +20 -1
- data/lib/rubygems/resolver/git_set.rb +1 -1
- data/lib/rubygems/resolver/git_specification.rb +1 -1
- data/lib/rubygems/resolver/index_set.rb +3 -1
- data/lib/rubygems/resolver/installed_specification.rb +19 -1
- data/lib/rubygems/resolver/installer_set.rb +84 -4
- data/lib/rubygems/resolver/local_specification.rb +25 -0
- data/lib/rubygems/resolver/lock_set.rb +13 -9
- data/lib/rubygems/resolver/lock_specification.rb +1 -1
- data/lib/rubygems/resolver/set.rb +6 -0
- data/lib/rubygems/resolver/spec_specification.rb +0 -2
- data/lib/rubygems/resolver/specification.rb +23 -2
- data/lib/rubygems/resolver/vendor_set.rb +1 -1
- data/lib/rubygems/resolver/vendor_specification.rb +1 -1
- data/lib/rubygems/security/policy.rb +1 -0
- data/lib/rubygems/server.rb +36 -1
- data/lib/rubygems/source.rb +6 -2
- data/lib/rubygems/source/git.rb +1 -1
- data/lib/rubygems/source/installed.rb +4 -0
- data/lib/rubygems/source/specific_file.rb +6 -1
- data/lib/rubygems/spec_fetcher.rb +6 -13
- data/lib/rubygems/specification.rb +91 -63
- data/lib/rubygems/stub_specification.rb +9 -0
- data/lib/rubygems/test_case.rb +4 -2
- data/lib/rubygems/text.rb +15 -5
- data/lib/rubygems/uninstaller.rb +4 -1
- data/lib/rubygems/user_interaction.rb +8 -0
- data/lib/rubygems/version.rb +5 -1
- data/test/rubygems/test_gem.rb +88 -2
- data/test/rubygems/test_gem_available_set.rb +11 -8
- data/test/rubygems/test_gem_command.rb +55 -0
- data/test/rubygems/test_gem_commands_cert_command.rb +1 -0
- data/test/rubygems/test_gem_commands_environment_command.rb +1 -0
- data/test/rubygems/test_gem_commands_help_command.rb +7 -0
- data/test/rubygems/test_gem_commands_install_command.rb +71 -4
- data/test/rubygems/test_gem_commands_open_command.rb +46 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +9 -0
- data/test/rubygems/test_gem_commands_update_command.rb +48 -0
- data/test/rubygems/test_gem_commands_yank_command.rb +2 -2
- data/test/rubygems/test_gem_config_file.rb +19 -7
- data/test/rubygems/test_gem_dependency.rb +86 -2
- data/test/rubygems/test_gem_dependency_installer.rb +36 -164
- data/test/rubygems/test_gem_gemcutter_utilities.rb +9 -0
- data/test/rubygems/test_gem_installer.rb +6 -1
- data/test/rubygems/test_gem_name_tuple.rb +7 -0
- data/test/rubygems/test_gem_package.rb +17 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +65 -46
- data/test/rubygems/test_gem_request.rb +75 -61
- data/test/rubygems/test_gem_request_connection_pools.rb +83 -0
- data/test/rubygems/test_gem_request_set.rb +156 -1
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +72 -27
- data/test/rubygems/test_gem_request_set_lockfile.rb +335 -0
- data/test/rubygems/test_gem_requirement.rb +5 -0
- data/test/rubygems/test_gem_resolver.rb +91 -2
- data/test/rubygems/test_gem_resolver_activation_request.rb +10 -0
- data/test/rubygems/test_gem_resolver_api_set.rb +2 -2
- data/test/rubygems/test_gem_resolver_api_specification.rb +40 -0
- data/test/rubygems/test_gem_resolver_composed_set.rb +14 -0
- data/test/rubygems/test_gem_resolver_dependency_request.rb +55 -0
- data/test/rubygems/test_gem_resolver_git_set.rb +26 -0
- data/test/rubygems/test_gem_resolver_index_set.rb +28 -2
- data/test/rubygems/test_gem_resolver_installer_set.rb +143 -0
- data/test/rubygems/test_gem_resolver_lock_set.rb +12 -6
- data/test/rubygems/test_gem_resolver_lock_specification.rb +1 -1
- data/test/rubygems/test_gem_resolver_specification.rb +32 -0
- data/test/rubygems/test_gem_resolver_vendor_set.rb +14 -0
- data/test/rubygems/test_gem_security_policy.rb +2 -2
- data/test/rubygems/test_gem_server.rb +69 -4
- data/test/rubygems/test_gem_source.rb +4 -1
- data/test/rubygems/test_gem_source_git.rb +15 -0
- data/test/rubygems/test_gem_source_specific_file.rb +4 -0
- data/test/rubygems/test_gem_specification.rb +82 -27
- data/test/rubygems/test_gem_stub_specification.rb +61 -23
- data/test/rubygems/test_gem_uninstaller.rb +23 -0
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +32 -0
- metadata +187 -33
- metadata.gz.sig +0 -0
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +0 -32
data/lib/rubygems/doctor.rb
CHANGED
@@ -105,7 +105,7 @@ class Gem::Doctor
|
|
105
105
|
next if ent == "." || ent == ".."
|
106
106
|
|
107
107
|
child = File.join(directory, ent)
|
108
|
-
next unless File.
|
108
|
+
next unless File.exist?(child)
|
109
109
|
|
110
110
|
basename = File.basename(child, extension)
|
111
111
|
next if installed_specs.include? basename
|
data/lib/rubygems/errors.rb
CHANGED
@@ -19,6 +19,36 @@ module Gem
|
|
19
19
|
attr_accessor :requirement
|
20
20
|
end
|
21
21
|
|
22
|
+
# Raised when there are conflicting gem specs loaded
|
23
|
+
|
24
|
+
class ConflictError < LoadError
|
25
|
+
|
26
|
+
##
|
27
|
+
# A Hash mapping conflicting specifications to the dependencies that
|
28
|
+
# caused the conflict
|
29
|
+
|
30
|
+
attr_reader :conflicts
|
31
|
+
|
32
|
+
##
|
33
|
+
# The specification that had the conflict
|
34
|
+
|
35
|
+
attr_reader :target
|
36
|
+
|
37
|
+
def initialize target, conflicts
|
38
|
+
@target = target
|
39
|
+
@conflicts = conflicts
|
40
|
+
@name = target.name
|
41
|
+
|
42
|
+
reason = conflicts.map { |act, dependencies|
|
43
|
+
"#{act.full_name} conflicts with #{dependencies.join(", ")}"
|
44
|
+
}.join ", "
|
45
|
+
|
46
|
+
# TODO: improve message by saying who activated `con`
|
47
|
+
|
48
|
+
super("Unable to activate #{target.full_name}, because #{reason}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
22
52
|
class ErrorReason; end
|
23
53
|
|
24
54
|
# Generated when trying to lookup a gem to indicate that the gem
|
data/lib/rubygems/exceptions.rb
CHANGED
@@ -222,6 +222,11 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception
|
|
222
222
|
|
223
223
|
attr_reader :dependency
|
224
224
|
|
225
|
+
##
|
226
|
+
# Errors encountered which may have contributed to this exception
|
227
|
+
|
228
|
+
attr_accessor :errors
|
229
|
+
|
225
230
|
##
|
226
231
|
# Creates a new UnsatisfiableDependencyError for the unsatisfiable
|
227
232
|
# Gem::Resolver::DependencyRequest +dep+
|
@@ -239,6 +244,21 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception
|
|
239
244
|
end
|
240
245
|
|
241
246
|
@dependency = dep
|
247
|
+
@errors = []
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# The name of the unresolved dependency
|
252
|
+
|
253
|
+
def name
|
254
|
+
@dependency.name
|
255
|
+
end
|
256
|
+
|
257
|
+
##
|
258
|
+
# The Requirement of the unresolved dependency (not Version).
|
259
|
+
|
260
|
+
def version
|
261
|
+
@dependency.requirement
|
242
262
|
end
|
243
263
|
|
244
264
|
end
|
data/lib/rubygems/ext/builder.rb
CHANGED
data/lib/rubygems/installer.rb
CHANGED
@@ -382,7 +382,7 @@ class Gem::Installer
|
|
382
382
|
file.puts windows_stub_script(bindir, filename)
|
383
383
|
end
|
384
384
|
|
385
|
-
|
385
|
+
verbose script_path
|
386
386
|
end
|
387
387
|
end
|
388
388
|
|
@@ -433,7 +433,7 @@ class Gem::Installer
|
|
433
433
|
file.print app_script_text(filename)
|
434
434
|
end
|
435
435
|
|
436
|
-
|
436
|
+
verbose bin_script_path
|
437
437
|
|
438
438
|
generate_windows_script filename, bindir
|
439
439
|
end
|
@@ -660,10 +660,10 @@ TEXT
|
|
660
660
|
return <<-TEXT
|
661
661
|
@ECHO OFF
|
662
662
|
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
663
|
-
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
663
|
+
@"#{bindir.tr(File::SEPARATOR, File::ALT_SEPARATOR)}\\#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
664
664
|
GOTO :EOF
|
665
665
|
:WinNT
|
666
|
-
@"#{ruby}" "%~dpn0" %*
|
666
|
+
@"%~dp0#{ruby}" "%~dpn0" %*
|
667
667
|
TEXT
|
668
668
|
end
|
669
669
|
|
data/lib/rubygems/name_tuple.rb
CHANGED
@@ -90,7 +90,9 @@ class Gem::NameTuple
|
|
90
90
|
alias to_s inspect # :nodoc:
|
91
91
|
|
92
92
|
def <=> other
|
93
|
-
|
93
|
+
[@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1] <=>
|
94
|
+
[other.name, other.version,
|
95
|
+
other.platform == Gem::Platform::RUBY ? -1 : 1]
|
94
96
|
end
|
95
97
|
|
96
98
|
include Comparable
|
data/lib/rubygems/package.rb
CHANGED
@@ -54,10 +54,12 @@ class Gem::Package
|
|
54
54
|
class FormatError < Error
|
55
55
|
attr_reader :path
|
56
56
|
|
57
|
-
def initialize message,
|
58
|
-
|
57
|
+
def initialize message, source = nil
|
58
|
+
if source
|
59
|
+
@path = source.path
|
59
60
|
|
60
|
-
|
61
|
+
message << " in #{path}" if path
|
62
|
+
end
|
61
63
|
|
62
64
|
super message
|
63
65
|
end
|
@@ -80,6 +82,7 @@ class Gem::Package
|
|
80
82
|
|
81
83
|
class TarInvalidError < Error; end
|
82
84
|
|
85
|
+
|
83
86
|
attr_accessor :build_time # :nodoc:
|
84
87
|
|
85
88
|
##
|
@@ -114,19 +117,26 @@ class Gem::Package
|
|
114
117
|
end
|
115
118
|
|
116
119
|
##
|
117
|
-
# Creates a new Gem::Package for the file at +gem+.
|
120
|
+
# Creates a new Gem::Package for the file at +gem+. +gem+ can also be
|
121
|
+
# provided as an IO object.
|
118
122
|
#
|
119
123
|
# If +gem+ is an existing file in the old format a Gem::Package::Old will be
|
120
124
|
# returned.
|
121
125
|
|
122
126
|
def self.new gem
|
123
|
-
|
124
|
-
|
127
|
+
gem = if gem.is_a?(Gem::Package::Source)
|
128
|
+
gem
|
129
|
+
elsif gem.respond_to? :read
|
130
|
+
Gem::Package::IOSource.new gem
|
131
|
+
else
|
132
|
+
Gem::Package::FileSource.new gem
|
133
|
+
end
|
125
134
|
|
126
|
-
|
135
|
+
return super(gem) unless Gem::Package == self
|
136
|
+
return super unless gem.present?
|
127
137
|
|
128
|
-
return super unless start
|
129
|
-
return super unless start.include? 'MD5SUM ='
|
138
|
+
return super unless gem.start
|
139
|
+
return super unless gem.start.include? 'MD5SUM ='
|
130
140
|
|
131
141
|
Gem::Package::Old.new gem
|
132
142
|
end
|
@@ -227,7 +237,7 @@ class Gem::Package
|
|
227
237
|
|
228
238
|
setup_signer
|
229
239
|
|
230
|
-
|
240
|
+
@gem.with_write_io do |gem_io|
|
231
241
|
Gem::Package::TarWriter.new gem_io do |gem|
|
232
242
|
add_metadata gem
|
233
243
|
add_contents gem
|
@@ -255,7 +265,7 @@ EOM
|
|
255
265
|
|
256
266
|
@contents = []
|
257
267
|
|
258
|
-
|
268
|
+
@gem.with_read_io do |io|
|
259
269
|
gem_tar = Gem::Package::TarReader.new io
|
260
270
|
|
261
271
|
gem_tar.each do |entry|
|
@@ -312,7 +322,7 @@ EOM
|
|
312
322
|
|
313
323
|
FileUtils.mkdir_p destination_dir
|
314
324
|
|
315
|
-
|
325
|
+
@gem.with_read_io do |io|
|
316
326
|
reader = Gem::Package::TarReader.new io
|
317
327
|
|
318
328
|
reader.each do |entry|
|
@@ -360,7 +370,7 @@ EOM
|
|
360
370
|
out.write entry.read
|
361
371
|
end if entry.file?
|
362
372
|
|
363
|
-
|
373
|
+
verbose destination
|
364
374
|
end
|
365
375
|
end
|
366
376
|
end
|
@@ -490,7 +500,7 @@ EOM
|
|
490
500
|
@files = []
|
491
501
|
@spec = nil
|
492
502
|
|
493
|
-
|
503
|
+
@gem.with_read_io do |io|
|
494
504
|
Gem::Package::TarReader.new io do |reader|
|
495
505
|
read_checksums reader
|
496
506
|
|
@@ -592,6 +602,9 @@ EOM
|
|
592
602
|
end
|
593
603
|
|
594
604
|
require 'rubygems/package/digest_io'
|
605
|
+
require 'rubygems/package/source'
|
606
|
+
require 'rubygems/package/file_source'
|
607
|
+
require 'rubygems/package/io_source'
|
595
608
|
require 'rubygems/package/old'
|
596
609
|
require 'rubygems/package/tar_header'
|
597
610
|
require 'rubygems/package/tar_reader'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
##
|
2
|
+
# The primary source of gems is a file on disk, including all usages
|
3
|
+
# internal to rubygems.
|
4
|
+
#
|
5
|
+
# This is a private class, do not depend on it directly. Instead, pass a path
|
6
|
+
# object to `Gem::Package.new`.
|
7
|
+
|
8
|
+
class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all
|
9
|
+
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
def initialize path
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
@start ||= File.read path, 20
|
18
|
+
end
|
19
|
+
|
20
|
+
def present?
|
21
|
+
File.exist? path
|
22
|
+
end
|
23
|
+
|
24
|
+
def with_write_io &block
|
25
|
+
open path, 'wb', &block
|
26
|
+
end
|
27
|
+
|
28
|
+
def with_read_io &block
|
29
|
+
open path, 'rb', &block
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
##
|
2
|
+
# Supports reading and writing gems from/to a generic IO object. This is
|
3
|
+
# useful for other applications built on top of rubygems, such as
|
4
|
+
# rubygems.org.
|
5
|
+
#
|
6
|
+
# This is a private class, do not depend on it directly. Instead, pass an IO
|
7
|
+
# object to `Gem::Package.new`.
|
8
|
+
|
9
|
+
class Gem::Package::IOSource < Gem::Package::Source # :nodoc: all
|
10
|
+
|
11
|
+
attr_reader :io
|
12
|
+
|
13
|
+
def initialize io
|
14
|
+
@io = io
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
@start ||= begin
|
19
|
+
if io.pos > 0
|
20
|
+
raise Gem::Package::Error, "Cannot read start unless IO is at start"
|
21
|
+
end
|
22
|
+
|
23
|
+
value = io.read 20
|
24
|
+
io.rewind
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def present?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_read_io
|
34
|
+
yield io
|
35
|
+
end
|
36
|
+
|
37
|
+
def with_write_io
|
38
|
+
yield io
|
39
|
+
end
|
40
|
+
|
41
|
+
def path
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
data/lib/rubygems/package/old.rb
CHANGED
@@ -37,7 +37,7 @@ class Gem::Package::Old < Gem::Package
|
|
37
37
|
|
38
38
|
return @contents if @contents
|
39
39
|
|
40
|
-
|
40
|
+
@gem.with_read_io do |io|
|
41
41
|
read_until_dashes io # spec
|
42
42
|
header = file_list io
|
43
43
|
|
@@ -53,7 +53,7 @@ class Gem::Package::Old < Gem::Package
|
|
53
53
|
|
54
54
|
errstr = "Error reading files from gem"
|
55
55
|
|
56
|
-
|
56
|
+
@gem.with_read_io do |io|
|
57
57
|
read_until_dashes io # spec
|
58
58
|
header = file_list io
|
59
59
|
raise Gem::Exception, errstr unless header
|
@@ -83,7 +83,7 @@ class Gem::Package::Old < Gem::Package
|
|
83
83
|
out.write file_data
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
verbose destination
|
87
87
|
end
|
88
88
|
end
|
89
89
|
rescue Zlib::DataError
|
@@ -136,7 +136,7 @@ class Gem::Package::Old < Gem::Package
|
|
136
136
|
|
137
137
|
yaml = ''
|
138
138
|
|
139
|
-
|
139
|
+
@gem.with_read_io do |io|
|
140
140
|
skip_ruby io
|
141
141
|
read_until_dashes io do |line|
|
142
142
|
yaml << line
|
@@ -145,7 +145,7 @@ class Gem::Package::Old < Gem::Package
|
|
145
145
|
|
146
146
|
yaml_error = if RUBY_VERSION < '1.9' then
|
147
147
|
YAML::ParseError
|
148
|
-
elsif YAML::ENGINE.yamler == 'syck' then
|
148
|
+
elsif YAML.const_defined?(:ENGINE) && YAML::ENGINE.yamler == 'syck' then
|
149
149
|
YAML::ParseError
|
150
150
|
else
|
151
151
|
YAML::SyntaxError
|
data/lib/rubygems/platform.rb
CHANGED
@@ -17,7 +17,7 @@ class Gem::Platform
|
|
17
17
|
|
18
18
|
def self.local
|
19
19
|
arch = RbConfig::CONFIG['arch']
|
20
|
-
arch = "#{arch}_60" if arch =~ /
|
20
|
+
arch = "#{arch}_60" if arch =~ /mswin(?:32|64)$/
|
21
21
|
@local ||= new(arch)
|
22
22
|
end
|
23
23
|
|
@@ -173,6 +173,7 @@ class Gem::Platform
|
|
173
173
|
when /^dalvik(\d+)?$/ then [nil, 'dalvik', $1 ]
|
174
174
|
when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ]
|
175
175
|
when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ]
|
176
|
+
when /mswin64(\_(\d+))?/ then ['x64', 'mswin64', $2 ]
|
176
177
|
when 'powerpc-darwin' then ['powerpc', 'darwin', nil ]
|
177
178
|
when /powerpc-darwin(\d)/ then ['powerpc', 'darwin', $1 ]
|
178
179
|
when /sparc-solaris2.8/ then ['sparc', 'solaris', '2.8' ]
|
data/lib/rubygems/rdoc.rb
CHANGED
@@ -263,7 +263,7 @@ class Gem::RDoc # :nodoc: all
|
|
263
263
|
Gem::Requirement.new('>= 2.4.0') =~ self.class.rdoc_version
|
264
264
|
|
265
265
|
r = new_rdoc
|
266
|
-
|
266
|
+
verbose { "rdoc #{args.join ' '}" }
|
267
267
|
|
268
268
|
Dir.chdir @spec.full_gem_path do
|
269
269
|
begin
|
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rubygems/request'
|
3
3
|
require 'rubygems/uri_formatter'
|
4
4
|
require 'rubygems/user_interaction'
|
5
|
+
require 'rubygems/request/connection_pools'
|
5
6
|
require 'resolv'
|
6
7
|
|
7
8
|
##
|
@@ -73,6 +74,9 @@ class Gem::RemoteFetcher
|
|
73
74
|
Socket.do_not_reverse_lookup = true
|
74
75
|
|
75
76
|
@proxy = proxy
|
77
|
+
@pools = {}
|
78
|
+
@pool_lock = Mutex.new
|
79
|
+
@cert_files = Gem::Request.get_cert_files
|
76
80
|
|
77
81
|
@dns = dns
|
78
82
|
end
|
@@ -90,13 +94,7 @@ class Gem::RemoteFetcher
|
|
90
94
|
rescue Resolv::ResolvError
|
91
95
|
uri
|
92
96
|
else
|
93
|
-
|
94
|
-
|
95
|
-
if /\.#{Regexp.quote(host)}\z/ =~ target
|
96
|
-
return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
|
97
|
-
end
|
98
|
-
|
99
|
-
uri
|
97
|
+
URI.parse "#{uri.scheme}://#{res.target}#{uri.path}"
|
100
98
|
end
|
101
99
|
end
|
102
100
|
|
@@ -160,11 +158,10 @@ class Gem::RemoteFetcher
|
|
160
158
|
# REFACTOR: split this up and dispatch on scheme (eg download_http)
|
161
159
|
# REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
|
162
160
|
case scheme
|
163
|
-
when 'http', 'https' then
|
161
|
+
when 'http', 'https', 's3' then
|
164
162
|
unless File.exist? local_gem_path then
|
165
163
|
begin
|
166
|
-
|
167
|
-
Gem.configuration.really_verbose
|
164
|
+
verbose "Downloading gem #{gem_file_name}"
|
168
165
|
|
169
166
|
remote_gem_path = source_uri + "gems/#{gem_file_name}"
|
170
167
|
|
@@ -174,8 +171,7 @@ class Gem::RemoteFetcher
|
|
174
171
|
|
175
172
|
alternate_name = "#{spec.original_name}.gem"
|
176
173
|
|
177
|
-
|
178
|
-
Gem.configuration.really_verbose
|
174
|
+
verbose "Failed, downloading gem #{alternate_name}"
|
179
175
|
|
180
176
|
remote_gem_path = source_uri + "gems/#{alternate_name}"
|
181
177
|
|
@@ -194,8 +190,7 @@ class Gem::RemoteFetcher
|
|
194
190
|
local_gem_path = source_uri.to_s
|
195
191
|
end
|
196
192
|
|
197
|
-
|
198
|
-
Gem.configuration.really_verbose
|
193
|
+
verbose "Using local gem #{local_gem_path}"
|
199
194
|
when nil then # TODO test for local overriding cache
|
200
195
|
source_path = if Gem.win_platform? && source_uri.scheme &&
|
201
196
|
!source_uri.path.include?(':') then
|
@@ -213,8 +208,7 @@ class Gem::RemoteFetcher
|
|
213
208
|
local_gem_path = source_uri.to_s
|
214
209
|
end
|
215
210
|
|
216
|
-
|
217
|
-
Gem.configuration.really_verbose
|
211
|
+
verbose "Using local gem #{local_gem_path}"
|
218
212
|
else
|
219
213
|
raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}"
|
220
214
|
end
|
@@ -238,6 +232,7 @@ class Gem::RemoteFetcher
|
|
238
232
|
|
239
233
|
case response
|
240
234
|
when Net::HTTPOK, Net::HTTPNotModified then
|
235
|
+
response.uri = uri if response.respond_to? :uri
|
241
236
|
head ? response : response.body
|
242
237
|
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
|
243
238
|
Net::HTTPTemporaryRedirect then
|
@@ -271,7 +266,7 @@ class Gem::RemoteFetcher
|
|
271
266
|
|
272
267
|
data = send "fetch_#{uri.scheme}", uri, mtime, head
|
273
268
|
|
274
|
-
if data and !head and uri.to_s =~
|
269
|
+
if data and !head and uri.to_s =~ /\.gz$/
|
275
270
|
begin
|
276
271
|
data = Gem.gunzip data
|
277
272
|
rescue Zlib::GzipFile::Error
|
@@ -292,6 +287,11 @@ class Gem::RemoteFetcher
|
|
292
287
|
end
|
293
288
|
end
|
294
289
|
|
290
|
+
def fetch_s3(uri, mtime = nil, head = false)
|
291
|
+
public_uri = sign_s3_url(uri)
|
292
|
+
fetch_https public_uri, mtime, head
|
293
|
+
end
|
294
|
+
|
295
295
|
##
|
296
296
|
# Downloads +uri+ to +path+ if necessary. If no path is given, it just
|
297
297
|
# passes the data.
|
@@ -338,7 +338,10 @@ class Gem::RemoteFetcher
|
|
338
338
|
# connections to reduce connect overhead.
|
339
339
|
|
340
340
|
def request(uri, request_class, last_modified = nil)
|
341
|
-
|
341
|
+
proxy = proxy_for @proxy, uri
|
342
|
+
pool = pools_for(proxy).pool_for uri
|
343
|
+
|
344
|
+
request = Gem::Request.new uri, request_class, last_modified, pool
|
342
345
|
|
343
346
|
request.fetch do |req|
|
344
347
|
yield req if block_given?
|
@@ -349,5 +352,43 @@ class Gem::RemoteFetcher
|
|
349
352
|
uri.scheme.downcase == 'https'
|
350
353
|
end
|
351
354
|
|
355
|
+
protected
|
356
|
+
|
357
|
+
# we have our own signing code here to avoid a dependency on the aws-sdk gem
|
358
|
+
# fortunately, a simple GET request isn't too complex to sign properly
|
359
|
+
def sign_s3_url(uri, expiration = nil)
|
360
|
+
require 'base64'
|
361
|
+
require 'openssl'
|
362
|
+
|
363
|
+
unless uri.user && uri.password
|
364
|
+
raise FetchError.new("credentials needed in s3 source, like s3://key:secret@bucket-name/", uri.to_s)
|
365
|
+
end
|
366
|
+
|
367
|
+
expiration ||= s3_expiration
|
368
|
+
canonical_path = "/#{uri.host}#{uri.path}"
|
369
|
+
payload = "GET\n\n\n#{expiration}\n#{canonical_path}"
|
370
|
+
digest = OpenSSL::HMAC.digest('sha1', uri.password, payload)
|
371
|
+
# URI.escape is deprecated, and there isn't yet a replacement that does quite what we want
|
372
|
+
signature = Base64.encode64(digest).gsub("\n", '').gsub(/[\+\/=]/) { |c| BASE64_URI_TRANSLATE[c] }
|
373
|
+
URI.parse("https://#{uri.host}.s3.amazonaws.com#{uri.path}?AWSAccessKeyId=#{uri.user}&Expires=#{expiration}&Signature=#{signature}")
|
374
|
+
end
|
375
|
+
|
376
|
+
def s3_expiration
|
377
|
+
(Time.now + 3600).to_i # one hour from now
|
378
|
+
end
|
379
|
+
|
380
|
+
BASE64_URI_TRANSLATE = { '+' => '%2B', '/' => '%2F', '=' => '%3D' }.freeze
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
def proxy_for proxy, uri
|
385
|
+
Gem::Request.proxy_uri(proxy || Gem::Request.get_proxy_from_env(uri.scheme))
|
386
|
+
end
|
387
|
+
|
388
|
+
def pools_for proxy
|
389
|
+
@pool_lock.synchronize do
|
390
|
+
@pools[proxy] ||= Gem::Request::ConnectionPools.new proxy, @cert_files
|
391
|
+
end
|
392
|
+
end
|
352
393
|
end
|
353
394
|
|