rubygems-update 1.2.0 → 1.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.
- data.tar.gz.sig +2 -4
- data/ChangeLog +155 -0
- data/Rakefile +20 -5
- data/doc/release_notes/rel_1_3_0.rdoc +125 -0
- data/lib/rubygems.rb +107 -15
- data/lib/rubygems/commands/contents_command.rb +1 -1
- data/lib/rubygems/commands/environment_command.rb +40 -0
- data/lib/rubygems/commands/help_command.rb +2 -2
- data/lib/rubygems/commands/install_command.rb +15 -0
- data/lib/rubygems/commands/lock_command.rb +15 -6
- data/lib/rubygems/commands/outdated_command.rb +1 -1
- data/lib/rubygems/commands/pristine_command.rb +1 -1
- data/lib/rubygems/commands/query_command.rb +14 -9
- data/lib/rubygems/commands/rdoc_command.rb +5 -1
- data/lib/rubygems/commands/specification_command.rb +2 -2
- data/lib/rubygems/commands/unpack_command.rb +1 -1
- data/lib/rubygems/commands/update_command.rb +23 -14
- data/lib/rubygems/commands/which_command.rb +4 -3
- data/lib/rubygems/config_file.rb +25 -3
- data/lib/rubygems/defaults.rb +42 -11
- data/lib/rubygems/dependency_installer.rb +19 -15
- data/lib/rubygems/doc_manager.rb +162 -115
- data/lib/rubygems/ext/builder.rb +2 -2
- data/lib/rubygems/ext/rake_builder.rb +1 -1
- data/lib/rubygems/gem_path_searcher.rb +35 -19
- data/lib/rubygems/indexer.rb +15 -6
- data/lib/rubygems/install_update_options.rb +7 -0
- data/lib/rubygems/installer.rb +85 -9
- data/lib/rubygems/local_remote_options.rb +7 -0
- data/lib/rubygems/package/tar_reader.rb +7 -7
- data/lib/rubygems/platform.rb +1 -18
- data/lib/rubygems/remote_fetcher.rb +45 -54
- data/lib/rubygems/rubygems_version.rb +1 -1
- data/lib/rubygems/source_index.rb +22 -7
- data/lib/rubygems/source_info_cache.rb +9 -0
- data/lib/rubygems/spec_fetcher.rb +18 -20
- data/lib/rubygems/specification.rb +502 -293
- data/lib/rubygems/test_utilities.rb +19 -8
- data/lib/rubygems/uninstaller.rb +60 -26
- data/setup.rb +15 -7
- data/test/gemutilities.rb +84 -0
- data/test/mockgemui.rb +22 -2
- data/test/test_gem.rb +118 -13
- data/test/test_gem_commands_dependency_command.rb +1 -1
- data/test/test_gem_commands_list_command.rb +37 -0
- data/test/test_gem_commands_lock_command.rb +69 -0
- data/test/test_gem_commands_query_command.rb +40 -1
- data/test/test_gem_commands_uninstall_command.rb +60 -0
- data/test/test_gem_config_file.rb +51 -17
- data/test/test_gem_ext_configure_builder.rb +9 -9
- data/test/test_gem_ext_rake_builder.rb +21 -12
- data/test/test_gem_gem_path_searcher.rb +15 -7
- data/test/test_gem_indexer.rb +35 -1
- data/test/test_gem_install_update_options.rb +26 -5
- data/test/test_gem_installer.rb +93 -21
- data/test/test_gem_local_remote_options.rb +12 -0
- data/test/test_gem_platform.rb +6 -13
- data/test/test_gem_remote_fetcher.rb +121 -31
- data/test/test_gem_source_index.rb +74 -21
- data/test/test_gem_source_info_cache.rb +2 -1
- data/test/test_gem_spec_fetcher.rb +13 -3
- data/test/test_gem_specification.rb +13 -7
- data/test/test_gem_uninstaller.rb +25 -2
- metadata +6 -2
- metadata.gz.sig +0 -0
data/lib/rubygems/indexer.rb
CHANGED
@@ -116,7 +116,7 @@ class Gem::Indexer
|
|
116
116
|
open @specs_index, 'wb' do |io|
|
117
117
|
specs = index.sort.map do |_, spec|
|
118
118
|
platform = spec.original_platform
|
119
|
-
platform = Gem::Platform::RUBY if platform.nil?
|
119
|
+
platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
|
120
120
|
[spec.name, spec.version, platform]
|
121
121
|
end
|
122
122
|
|
@@ -129,7 +129,9 @@ class Gem::Indexer
|
|
129
129
|
|
130
130
|
open @latest_specs_index, 'wb' do |io|
|
131
131
|
specs = index.latest_specs.sort.map do |spec|
|
132
|
-
|
132
|
+
platform = spec.original_platform
|
133
|
+
platform = Gem::Platform::RUBY if platform.nil? or platform.empty?
|
134
|
+
[spec.name, spec.version, platform]
|
133
135
|
end
|
134
136
|
|
135
137
|
specs = compact_specs specs
|
@@ -283,10 +285,7 @@ class Gem::Indexer
|
|
283
285
|
# Builds and installs indexicies.
|
284
286
|
|
285
287
|
def generate_index
|
286
|
-
|
287
|
-
FileUtils.mkdir_p @directory, :mode => 0700
|
288
|
-
FileUtils.mkdir_p @quick_marshal_dir
|
289
|
-
|
288
|
+
make_temp_directories
|
290
289
|
index = collect_specs
|
291
290
|
build_indicies index
|
292
291
|
install_indicies
|
@@ -322,6 +321,15 @@ class Gem::Indexer
|
|
322
321
|
end
|
323
322
|
end
|
324
323
|
|
324
|
+
##
|
325
|
+
# Make directories for index generation
|
326
|
+
|
327
|
+
def make_temp_directories
|
328
|
+
FileUtils.rm_rf @directory
|
329
|
+
FileUtils.mkdir_p @directory, :mode => 0700
|
330
|
+
FileUtils.mkdir_p @quick_marshal_dir
|
331
|
+
end
|
332
|
+
|
325
333
|
##
|
326
334
|
# Ensure +path+ and path with +extension+ are identical.
|
327
335
|
|
@@ -344,6 +352,7 @@ class Gem::Indexer
|
|
344
352
|
spec.description = sanitize_string(spec.description)
|
345
353
|
spec.post_install_message = sanitize_string(spec.post_install_message)
|
346
354
|
spec.authors = spec.authors.collect { |a| sanitize_string(a) }
|
355
|
+
|
347
356
|
spec
|
348
357
|
end
|
349
358
|
|
@@ -90,6 +90,13 @@ module Gem::InstallUpdateOptions
|
|
90
90
|
options[:format_executable] = value
|
91
91
|
end
|
92
92
|
|
93
|
+
add_option(:"Install/Update", '--[no-]user-install',
|
94
|
+
'Install in user\'s home directory instead',
|
95
|
+
'of GEM_HOME. Defaults to using home directory',
|
96
|
+
'only if GEM_HOME is not writable.') do |value, options|
|
97
|
+
options[:user_install] = value
|
98
|
+
end
|
99
|
+
|
93
100
|
add_option(:"Install/Update", "--development",
|
94
101
|
"Install any additional development",
|
95
102
|
"dependencies") do |value, options|
|
data/lib/rubygems/installer.rb
CHANGED
@@ -20,6 +20,7 @@ require 'rubygems/require_paths_builder'
|
|
20
20
|
# filesystem including unpacking the gem into its gem dir, installing the
|
21
21
|
# gemspec in the specifications dir, storing the cached gem in the cache dir,
|
22
22
|
# and installing either wrappers or symlinks for executables.
|
23
|
+
|
23
24
|
class Gem::Installer
|
24
25
|
|
25
26
|
##
|
@@ -31,8 +32,36 @@ class Gem::Installer
|
|
31
32
|
|
32
33
|
include Gem::RequirePathsBuilder
|
33
34
|
|
35
|
+
##
|
36
|
+
# The directory a gem's executables will be installed into
|
37
|
+
|
38
|
+
attr_reader :bin_dir
|
39
|
+
|
40
|
+
##
|
41
|
+
# The gem repository the gem will be installed into
|
42
|
+
|
43
|
+
attr_reader :gem_home
|
44
|
+
|
45
|
+
##
|
46
|
+
# The Gem::Specification for the gem being installed
|
47
|
+
|
48
|
+
attr_reader :spec
|
49
|
+
|
50
|
+
@home_install_warning = false
|
51
|
+
@path_warning = false
|
52
|
+
|
34
53
|
class << self
|
35
54
|
|
55
|
+
##
|
56
|
+
# True if we've warned about ~/.gems install
|
57
|
+
|
58
|
+
attr_accessor :home_install_warning
|
59
|
+
|
60
|
+
##
|
61
|
+
# True if we've warned about PATH not including Gem.bindir
|
62
|
+
|
63
|
+
attr_accessor :path_warning
|
64
|
+
|
36
65
|
attr_writer :exec_format
|
37
66
|
|
38
67
|
# Defaults to use Ruby's program prefix and suffix.
|
@@ -61,11 +90,12 @@ class Gem::Installer
|
|
61
90
|
@gem = gem
|
62
91
|
|
63
92
|
options = {
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:exec_format
|
67
|
-
:
|
68
|
-
:
|
93
|
+
:bin_dir => nil,
|
94
|
+
:env_shebang => false,
|
95
|
+
:exec_format => false,
|
96
|
+
:force => false,
|
97
|
+
:install_dir => Gem.dir,
|
98
|
+
:source_index => Gem.source_index,
|
69
99
|
}.merge options
|
70
100
|
|
71
101
|
@env_shebang = options[:env_shebang]
|
@@ -78,6 +108,7 @@ class Gem::Installer
|
|
78
108
|
@wrappers = options[:wrappers]
|
79
109
|
@bin_dir = options[:bin_dir]
|
80
110
|
@development = options[:development]
|
111
|
+
@source_index = options[:source_index]
|
81
112
|
|
82
113
|
begin
|
83
114
|
@format = Gem::Format.from_file_by_path @gem, @security_policy
|
@@ -85,6 +116,43 @@ class Gem::Installer
|
|
85
116
|
raise Gem::InstallError, "invalid gem format for #{@gem}"
|
86
117
|
end
|
87
118
|
|
119
|
+
begin
|
120
|
+
FileUtils.mkdir_p @gem_home
|
121
|
+
rescue Errno::EACCESS, Errno::ENOTDIR
|
122
|
+
# We'll divert to ~/.gems below
|
123
|
+
end
|
124
|
+
|
125
|
+
if not File.writable? @gem_home or
|
126
|
+
# TODO: Shouldn't have to test for existence of bindir; tests need it.
|
127
|
+
(@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and
|
128
|
+
not File.writable? Gem.bindir) then
|
129
|
+
if options[:user_install] == false then # You don't want to use ~
|
130
|
+
raise Gem::FilePermissionError, @gem_home
|
131
|
+
elsif options[:user_install].nil? then
|
132
|
+
unless self.class.home_install_warning then
|
133
|
+
alert_warning "Installing to ~/.gem since #{@gem_home} and\n\t #{Gem.bindir} aren't both writable."
|
134
|
+
self.class.home_install_warning = true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
options[:user_install] = true
|
138
|
+
end
|
139
|
+
|
140
|
+
if options[:user_install] then
|
141
|
+
@gem_home = Gem.user_dir
|
142
|
+
|
143
|
+
user_bin_dir = File.join(@gem_home, 'bin')
|
144
|
+
unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
|
145
|
+
unless self.class.path_warning then
|
146
|
+
alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
|
147
|
+
self.class.path_warning = true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
|
152
|
+
# If it's still not writable, you've got issues.
|
153
|
+
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
|
154
|
+
end
|
155
|
+
|
88
156
|
@spec = @format.spec
|
89
157
|
|
90
158
|
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
|
@@ -131,8 +199,11 @@ class Gem::Installer
|
|
131
199
|
end
|
132
200
|
end
|
133
201
|
|
202
|
+
Gem.pre_install_hooks.each do |hook|
|
203
|
+
hook.call self
|
204
|
+
end
|
205
|
+
|
134
206
|
FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
|
135
|
-
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
|
136
207
|
|
137
208
|
Gem.ensure_gem_subdirectories @gem_home
|
138
209
|
|
@@ -156,7 +227,11 @@ class Gem::Installer
|
|
156
227
|
@spec.loaded_from = File.join(@gem_home, 'specifications',
|
157
228
|
"#{@spec.full_name}.gemspec")
|
158
229
|
|
159
|
-
|
230
|
+
@source_index.add_spec @spec
|
231
|
+
|
232
|
+
Gem.post_install_hooks.each do |hook|
|
233
|
+
hook.call self
|
234
|
+
end
|
160
235
|
|
161
236
|
return @spec
|
162
237
|
rescue Zlib::GzipFile::Error
|
@@ -179,10 +254,10 @@ class Gem::Installer
|
|
179
254
|
end
|
180
255
|
|
181
256
|
##
|
182
|
-
# True if the gems in
|
257
|
+
# True if the gems in the source_index satisfy +dependency+.
|
183
258
|
|
184
259
|
def installation_satisfies_dependency?(dependency)
|
185
|
-
|
260
|
+
@source_index.find_name(dependency.name, dependency.version_requirements).size > 0
|
186
261
|
end
|
187
262
|
|
188
263
|
##
|
@@ -206,6 +281,7 @@ class Gem::Installer
|
|
206
281
|
|
207
282
|
file_name = File.join @gem_home, 'specifications',
|
208
283
|
"#{@spec.full_name}.gemspec"
|
284
|
+
|
209
285
|
file_name.untaint
|
210
286
|
|
211
287
|
File.open(file_name, "w") do |file|
|
@@ -46,17 +46,17 @@ class Gem::Package::TarReader
|
|
46
46
|
yield entry
|
47
47
|
|
48
48
|
skip = (512 - (size % 512)) % 512
|
49
|
+
pending = size - entry.bytes_read
|
49
50
|
|
50
|
-
|
51
|
+
begin
|
51
52
|
# avoid reading...
|
52
|
-
@io.seek
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
@io.seek pending, IO::SEEK_CUR
|
54
|
+
pending = 0
|
55
|
+
rescue Errno::EINVAL, NameError
|
56
56
|
while pending > 0 do
|
57
|
-
|
57
|
+
bytes_read = @io.read([pending, 4096].min).size
|
58
58
|
raise UnexpectedEOF if @io.eof?
|
59
|
-
pending -=
|
59
|
+
pending -= bytes_read
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/lib/rubygems/platform.rb
CHANGED
@@ -13,23 +13,6 @@ class Gem::Platform
|
|
13
13
|
|
14
14
|
attr_accessor :version
|
15
15
|
|
16
|
-
DEPRECATED_CONSTS = [
|
17
|
-
:DARWIN,
|
18
|
-
:LINUX_586,
|
19
|
-
:MSWIN32,
|
20
|
-
:PPC_DARWIN,
|
21
|
-
:WIN32,
|
22
|
-
:X86_LINUX
|
23
|
-
]
|
24
|
-
|
25
|
-
def self.const_missing(name) # TODO remove six months from 2007/12
|
26
|
-
if DEPRECATED_CONSTS.include? name then
|
27
|
-
raise NameError, "#{name} has been removed, use CURRENT instead"
|
28
|
-
else
|
29
|
-
super
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
16
|
def self.local
|
34
17
|
arch = Gem::ConfigMap[:arch]
|
35
18
|
arch = "#{arch}_60" if arch =~ /mswin32$/
|
@@ -73,7 +56,7 @@ class Gem::Platform
|
|
73
56
|
else cpu
|
74
57
|
end
|
75
58
|
|
76
|
-
if arch.length == 2 and arch.last =~ /^\d
|
59
|
+
if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ then # for command-line
|
77
60
|
@os, @version = arch
|
78
61
|
return
|
79
62
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'stringio'
|
3
|
+
require 'time'
|
3
4
|
require 'uri'
|
4
5
|
|
5
6
|
require 'rubygems'
|
@@ -74,7 +75,12 @@ class Gem::RemoteFetcher
|
|
74
75
|
# always replaced.
|
75
76
|
|
76
77
|
def download(spec, source_uri, install_dir = Gem.dir)
|
77
|
-
|
78
|
+
if File.writable?(install_dir)
|
79
|
+
cache_dir = File.join install_dir, 'cache'
|
80
|
+
else
|
81
|
+
cache_dir = File.join(Gem.user_dir, 'cache')
|
82
|
+
end
|
83
|
+
|
78
84
|
gem_file_name = "#{spec.full_name}.gem"
|
79
85
|
local_gem_path = File.join cache_dir, gem_file_name
|
80
86
|
|
@@ -87,7 +93,7 @@ class Gem::RemoteFetcher
|
|
87
93
|
scheme = nil if scheme =~ /^[a-z]$/i
|
88
94
|
|
89
95
|
case scheme
|
90
|
-
when 'http' then
|
96
|
+
when 'http', 'https' then
|
91
97
|
unless File.exist? local_gem_path then
|
92
98
|
begin
|
93
99
|
say "Downloading gem #{gem_file_name}" if
|
@@ -132,51 +138,27 @@ class Gem::RemoteFetcher
|
|
132
138
|
##
|
133
139
|
# Downloads +uri+ and returns it as a String.
|
134
140
|
|
135
|
-
def fetch_path(uri)
|
136
|
-
open_uri_or_path
|
137
|
-
|
138
|
-
|
141
|
+
def fetch_path(uri, mtime = nil, head = false)
|
142
|
+
data = open_uri_or_path uri, mtime, head
|
143
|
+
data = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
|
144
|
+
data
|
139
145
|
rescue FetchError
|
140
146
|
raise
|
141
147
|
rescue Timeout::Error
|
142
148
|
raise FetchError.new('timed out', uri)
|
143
149
|
rescue IOError, SocketError, SystemCallError => e
|
144
150
|
raise FetchError.new("#{e.class}: #{e}", uri)
|
145
|
-
rescue => e
|
146
|
-
raise FetchError.new("#{e.class}: #{e}", uri)
|
147
151
|
end
|
148
152
|
|
149
153
|
##
|
150
154
|
# Returns the size of +uri+ in bytes.
|
151
155
|
|
152
|
-
def fetch_size(uri)
|
153
|
-
|
154
|
-
|
155
|
-
uri = URI.parse uri unless URI::Generic === uri
|
156
|
-
|
157
|
-
raise ArgumentError, 'uri is not an HTTP URI' unless URI::HTTP === uri
|
158
|
-
|
159
|
-
response = request uri, Net::HTTP::Head
|
160
|
-
|
161
|
-
case response
|
162
|
-
when Net::HTTPOK then
|
163
|
-
else
|
164
|
-
raise FetchError.new("bad response #{response.message} #{response.code}", uri)
|
165
|
-
end
|
166
|
-
|
167
|
-
if response['content-length'] then
|
168
|
-
return response['content-length'].to_i
|
169
|
-
else
|
170
|
-
response = http.get uri.request_uri
|
171
|
-
return response.body.size
|
172
|
-
end
|
156
|
+
def fetch_size(uri) # TODO: phase this out
|
157
|
+
response = fetch_path(uri, nil, true)
|
173
158
|
|
174
|
-
|
175
|
-
raise FetchError.new("#{e.message} (#{e.class})\n\tfetching size", uri)
|
159
|
+
response['content-length'].to_i
|
176
160
|
end
|
177
161
|
|
178
|
-
private
|
179
|
-
|
180
162
|
def escape(str)
|
181
163
|
return unless str
|
182
164
|
URI.escape(str)
|
@@ -234,8 +216,9 @@ class Gem::RemoteFetcher
|
|
234
216
|
connection = @connections[connection_id]
|
235
217
|
|
236
218
|
if uri.scheme == 'https' and not connection.started? then
|
237
|
-
|
238
|
-
|
219
|
+
require 'net/https'
|
220
|
+
connection.use_ssl = true
|
221
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
239
222
|
end
|
240
223
|
|
241
224
|
connection.start unless connection.started?
|
@@ -247,24 +230,27 @@ class Gem::RemoteFetcher
|
|
247
230
|
# Read the data from the (source based) URI, but if it is a file:// URI,
|
248
231
|
# read from the filesystem instead.
|
249
232
|
|
250
|
-
def open_uri_or_path(uri, depth = 0
|
251
|
-
if
|
252
|
-
open(get_file_uri_path(uri), &block)
|
253
|
-
else
|
254
|
-
uri = URI.parse uri unless URI::Generic === uri
|
233
|
+
def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
|
234
|
+
raise "block is dead" if block_given?
|
255
235
|
|
256
|
-
|
236
|
+
return open(get_file_uri_path(uri)) if file_uri? uri
|
257
237
|
|
258
|
-
|
259
|
-
|
260
|
-
block.call(StringIO.new(response.body)) if block
|
261
|
-
when Net::HTTPRedirection then
|
262
|
-
raise FetchError.new('too many redirects', uri) if depth > 10
|
238
|
+
uri = URI.parse uri unless URI::Generic === uri
|
239
|
+
raise ArgumentError, 'uri is not an HTTP URI' unless URI::HTTP === uri
|
263
240
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
241
|
+
fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
|
242
|
+
response = request uri, fetch_type, last_modified
|
243
|
+
|
244
|
+
case response
|
245
|
+
when Net::HTTPOK, Net::HTTPNotModified then
|
246
|
+
head ? response : response.body
|
247
|
+
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
|
248
|
+
Net::HTTPTemporaryRedirect then
|
249
|
+
raise FetchError.new('too many redirects', uri) if depth > 10
|
250
|
+
|
251
|
+
open_uri_or_path(response['Location'], last_modified, head, depth + 1)
|
252
|
+
else
|
253
|
+
raise FetchError.new("bad response #{response.message} #{response.code}", uri)
|
268
254
|
end
|
269
255
|
end
|
270
256
|
|
@@ -273,7 +259,7 @@ class Gem::RemoteFetcher
|
|
273
259
|
# a Net::HTTP response object. request maintains a table of persistent
|
274
260
|
# connections to reduce connect overhead.
|
275
261
|
|
276
|
-
def request(uri, request_class =
|
262
|
+
def request(uri, request_class, last_modified = nil)
|
277
263
|
request = request_class.new uri.request_uri
|
278
264
|
|
279
265
|
unless uri.nil? || uri.user.nil? || uri.user.empty? then
|
@@ -289,14 +275,16 @@ class Gem::RemoteFetcher
|
|
289
275
|
request.add_field 'Connection', 'keep-alive'
|
290
276
|
request.add_field 'Keep-Alive', '30'
|
291
277
|
|
278
|
+
if last_modified then
|
279
|
+
last_modified = last_modified.utc
|
280
|
+
request.add_field 'If-Modified-Since', last_modified.rfc2822
|
281
|
+
end
|
282
|
+
|
292
283
|
connection = connection_for uri
|
293
284
|
|
294
285
|
retried = false
|
295
286
|
bad_response = false
|
296
287
|
|
297
|
-
# HACK work around EOFError bug in Net::HTTP
|
298
|
-
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
299
|
-
# to install gems.
|
300
288
|
begin
|
301
289
|
@requests[connection.object_id] += 1
|
302
290
|
response = connection.request request
|
@@ -309,6 +297,9 @@ class Gem::RemoteFetcher
|
|
309
297
|
|
310
298
|
bad_response = true
|
311
299
|
retry
|
300
|
+
# HACK work around EOFError bug in Net::HTTP
|
301
|
+
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
302
|
+
# to install gems.
|
312
303
|
rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET
|
313
304
|
requests = @requests[connection.object_id]
|
314
305
|
say "connection reset after #{requests} requests, retrying" if
|