rubygems-update 0.9.1 → 0.9.2

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/ChangeLog CHANGED
@@ -1,3 +1,52 @@
1
+ 2007-02-05 Jim Weirich <jim@weirichhouse.org>
2
+
3
+ * lib/rubygems/rubygems_version.rb (Gem): Bumped to version 0.9.2
4
+ and made a release.
5
+
6
+ 2007-02-04 Chad Fowler <chad@chadfowler.com>
7
+
8
+ * Fixed failing tests (changed from assert_equal to assert_match to
9
+ deal with ARGV inconsistencies in test vs. production).
10
+
11
+ 2007-02-03 Jim Weirich <jim@weirichhouse.org>
12
+
13
+ * Bumped version to 0.9.1.1.
14
+
15
+ * lib/rubygems/gem_open_uri.rb: Added the patched open-uri back
16
+ into the gems software. Evidently, the 1.8 version of open-uri
17
+ does not handle authenticating proxies with username and password.
18
+
19
+ * lib/rubygems/source_info_cache.rb (Gem::cache_data): Added
20
+ rescue block to capture bad file loads. The original rescue was
21
+ only around the marshal load (bug was probably introduced when the
22
+ file data was preloaded into a string).
23
+ (Gem::set_cache_data): Added set_cache_data to be used during
24
+ testing to avoid reload the cache file over and over.
25
+
26
+ * lib/rubygems/gem_commands.rb: Added require for command class so
27
+ that this file can be loaded independently.
28
+
29
+ * lib/rubygems/source_index.rb (Gem::SourceIndex::outdated): Minor
30
+ cleanup.
31
+
32
+ * test/gemutilities.rb
33
+ (RubyGemTestCase::util_setup_source_info_cache): Minor cleanup
34
+
35
+ * test/test_gem_source_info_cache.rb
36
+ (TestGemSourceInfoCache::test_write_cache_user): Switched to using
37
+ set_cache_data here and several other places to avoid rereading
38
+ the cache data over and over again.
39
+
40
+ 2007-02-02 Chad Fowler <chad@chadfowler.com>
41
+
42
+ * lib/rubygems/gem_commands.rb:
43
+ Fixed gem unpack (broken since 0.9.1)
44
+
45
+ 2007-01-20 Eric Hodel <drbrain@segment7.net>
46
+
47
+ * lib/rubygems/source_info_cache.rb (Gem::SourceInfoCache#cache_data):
48
+ Read the source_cache in binary mode for mswin.
49
+
1
50
  2007-01-16 Eric Hodel <drbrain@segment7.net>
2
51
 
3
52
  * lib/rubygems/rubygems_version.rb (Gem): Released 0.9.1.
@@ -5,6 +5,9 @@
5
5
  # See LICENSE.txt for permissions.
6
6
  #++
7
7
 
8
+ require 'rubygems'
9
+ require 'rubygems/command'
10
+
8
11
  module Gem
9
12
 
10
13
  class CommandLineError < Gem::Exception; end
@@ -1409,7 +1412,7 @@ module Gem
1409
1412
  require 'fileutils'
1410
1413
  target_dir = File.basename(path).sub(/\.gem$/, '')
1411
1414
  FileUtils.mkdir_p target_dir
1412
- Installer.new(path).unpack(target_dir)
1415
+ Installer.new(path).unpack(File.expand_path(target_dir))
1413
1416
  say "Unpacked gem: '#{target_dir}'"
1414
1417
  else
1415
1418
  alert_error "Gem '#{gemname}' not installed."
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if RUBY_VERSION < "1.9"
4
+ require 'rubygems/open-uri'
5
+ else
6
+ require 'open-uri'
7
+ end
@@ -0,0 +1,771 @@
1
+ require 'uri'
2
+ require 'stringio'
3
+ require 'time'
4
+
5
+ module Kernel
6
+ private
7
+ alias open_uri_original_open open # :nodoc:
8
+
9
+ # makes possible to open various resources including URIs.
10
+ # If the first argument respond to `open' method,
11
+ # the method is called with the rest arguments.
12
+ #
13
+ # If the first argument is a string which begins with xxx://,
14
+ # it is parsed by URI.parse. If the parsed object respond to `open' method,
15
+ # the method is called with the rest arguments.
16
+ #
17
+ # Otherwise original open is called.
18
+ #
19
+ # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
20
+ # URI::FTP#open,
21
+ # Kernel[#.]open can accepts such URIs and strings which begins with
22
+ # http://, https:// and ftp://.
23
+ # In these case, the opened file object is extended by OpenURI::Meta.
24
+ def open(name, *rest, &block) # :doc:
25
+ if name.respond_to?(:open)
26
+ name.open(*rest, &block)
27
+ elsif name.respond_to?(:to_str) &&
28
+ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
29
+ (uri = URI.parse(name)).respond_to?(:open)
30
+ uri.open(*rest, &block)
31
+ else
32
+ open_uri_original_open(name, *rest, &block)
33
+ end
34
+ end
35
+ module_function :open
36
+ end
37
+
38
+ # OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
39
+ #
40
+ #== Example
41
+ #
42
+ # It is possible to open http/https/ftp URL as usual like opening a file:
43
+ #
44
+ # open("http://www.ruby-lang.org/") {|f|
45
+ # f.each_line {|line| p line}
46
+ # }
47
+ #
48
+ # The opened file has several methods for meta information as follows since
49
+ # it is extended by OpenURI::Meta.
50
+ #
51
+ # open("http://www.ruby-lang.org/en") {|f|
52
+ # f.each_line {|line| p line}
53
+ # p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
54
+ # p f.content_type # "text/html"
55
+ # p f.charset # "iso-8859-1"
56
+ # p f.content_encoding # []
57
+ # p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
58
+ # }
59
+ #
60
+ # Additional header fields can be specified by an optional hash argument.
61
+ #
62
+ # open("http://www.ruby-lang.org/en/",
63
+ # "User-Agent" => "Ruby/#{RUBY_VERSION}",
64
+ # "From" => "foo@bar.invalid",
65
+ # "Referer" => "http://www.ruby-lang.org/") {|f|
66
+ # # ...
67
+ # }
68
+ #
69
+ # The environment variables such as http_proxy, https_proxy and ftp_proxy
70
+ # are in effect by default. :proxy => nil disables proxy.
71
+ #
72
+ # open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
73
+ # # ...
74
+ # }
75
+ #
76
+ # URI objects can be opened in a similar way.
77
+ #
78
+ # uri = URI.parse("http://www.ruby-lang.org/en/")
79
+ # uri.open {|f|
80
+ # # ...
81
+ # }
82
+ #
83
+ # URI objects can be read directly. The returned string is also extended by
84
+ # OpenURI::Meta.
85
+ #
86
+ # str = uri.read
87
+ # p str.base_uri
88
+ #
89
+ # Author:: Tanaka Akira <akr@m17n.org>
90
+
91
+ module OpenURI
92
+ Options = {
93
+ :proxy => true,
94
+ :proxy_http_basic_authentication => true,
95
+ :progress_proc => true,
96
+ :content_length_proc => true,
97
+ :http_basic_authentication => true,
98
+ :read_timeout => true,
99
+ :ssl_ca_cert => nil,
100
+ :ssl_verify_mode => nil,
101
+ }
102
+
103
+ def OpenURI.check_options(options) # :nodoc:
104
+ options.each {|k, v|
105
+ next unless Symbol === k
106
+ unless Options.include? k
107
+ raise ArgumentError, "unrecognized option: #{k}"
108
+ end
109
+ }
110
+ end
111
+
112
+ def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
113
+ if !rest.empty? && (String === rest.first || Integer === rest.first)
114
+ mode = rest.shift
115
+ if !rest.empty? && Integer === rest.first
116
+ perm = rest.shift
117
+ end
118
+ end
119
+ return mode, perm, rest
120
+ end
121
+
122
+ def OpenURI.open_uri(name, *rest) # :nodoc:
123
+ uri = URI::Generic === name ? name : URI.parse(name)
124
+ mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
125
+ options = rest.shift if !rest.empty? && Hash === rest.first
126
+ raise ArgumentError.new("extra arguments") if !rest.empty?
127
+ options ||= {}
128
+ OpenURI.check_options(options)
129
+
130
+ unless mode == nil ||
131
+ mode == 'r' || mode == 'rb' ||
132
+ mode == File::RDONLY
133
+ raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
134
+ end
135
+
136
+ io = open_loop(uri, options)
137
+ if block_given?
138
+ begin
139
+ yield io
140
+ ensure
141
+ io.close
142
+ end
143
+ else
144
+ io
145
+ end
146
+ end
147
+
148
+ def OpenURI.open_loop(uri, options) # :nodoc:
149
+ proxy_opts = []
150
+ proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
151
+ proxy_opts << :proxy if options.include? :proxy
152
+ proxy_opts.compact!
153
+ if 1 < proxy_opts.length
154
+ raise ArgumentError, "multiple proxy options specified"
155
+ end
156
+ case proxy_opts.first
157
+ when :proxy_http_basic_authentication
158
+ opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
159
+ proxy_user = proxy_user.to_str
160
+ proxy_pass = proxy_pass.to_str
161
+ if opt_proxy == true
162
+ raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
163
+ end
164
+ when :proxy
165
+ opt_proxy = options.fetch(:proxy)
166
+ proxy_user = nil
167
+ proxy_pass = nil
168
+ when nil
169
+ opt_proxy = true
170
+ proxy_user = nil
171
+ proxy_pass = nil
172
+ end
173
+ case opt_proxy
174
+ when true
175
+ find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
176
+ when nil, false
177
+ find_proxy = lambda {|u| nil}
178
+ when String
179
+ opt_proxy = URI.parse(opt_proxy)
180
+ find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
181
+ when URI::Generic
182
+ find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
183
+ else
184
+ raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
185
+ end
186
+
187
+ uri_set = {}
188
+ buf = nil
189
+ while true
190
+ redirect = catch(:open_uri_redirect) {
191
+ buf = Buffer.new
192
+ uri.buffer_open(buf, find_proxy.call(uri), options)
193
+ nil
194
+ }
195
+ if redirect
196
+ if redirect.relative?
197
+ # Although it violates RFC2616, Location: field may have relative
198
+ # URI. It is converted to absolute URI using uri as a base URI.
199
+ redirect = uri + redirect
200
+ end
201
+ unless OpenURI.redirectable?(uri, redirect)
202
+ raise "redirection forbidden: #{uri} -> #{redirect}"
203
+ end
204
+ if options.include? :http_basic_authentication
205
+ # send authentication only for the URI directly specified.
206
+ options = options.dup
207
+ options.delete :http_basic_authentication
208
+ end
209
+ uri = redirect
210
+ raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
211
+ uri_set[uri.to_s] = true
212
+ else
213
+ break
214
+ end
215
+ end
216
+ io = buf.io
217
+ io.base_uri = uri
218
+ io
219
+ end
220
+
221
+ def OpenURI.redirectable?(uri1, uri2) # :nodoc:
222
+ # This test is intended to forbid a redirection from http://... to
223
+ # file:///etc/passwd.
224
+ # However this is ad hoc. It should be extensible/configurable.
225
+ uri1.scheme.downcase == uri2.scheme.downcase ||
226
+ (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
227
+ end
228
+
229
+ def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
230
+ if proxy
231
+ proxy_uri, proxy_user, proxy_pass = proxy
232
+ raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
233
+ end
234
+
235
+ if target.userinfo && "1.9.0" <= RUBY_VERSION
236
+ # don't raise for 1.8 because compatibility.
237
+ raise ArgumentError, "userinfo not supported. [RFC3986]"
238
+ end
239
+
240
+ header = {}
241
+ options.each {|k, v| header[k] = v if String === k }
242
+
243
+ require 'net/http'
244
+ klass = Net::HTTP
245
+ if URI::HTTP === target
246
+ # HTTP or HTTPS
247
+ if proxy
248
+ if proxy_user && proxy_pass
249
+ klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass)
250
+ else
251
+ klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
252
+ end
253
+ end
254
+ target_host = target.host
255
+ target_port = target.port
256
+ request_uri = target.request_uri
257
+ else
258
+ # FTP over HTTP proxy
259
+ target_host = proxy_uri.host
260
+ target_port = proxy_uri.port
261
+ request_uri = target.to_s
262
+ if proxy_user && proxy_pass
263
+ header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
264
+ end
265
+ end
266
+
267
+ http = klass.new(target_host, target_port)
268
+ if target.class == URI::HTTPS
269
+ require 'net/https'
270
+ http.use_ssl = true
271
+ http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
272
+ store = OpenSSL::X509::Store.new
273
+ if options[:ssl_ca_cert]
274
+ if File.directory? options[:ssl_ca_cert]
275
+ store.add_path options[:ssl_ca_cert]
276
+ else
277
+ store.add_file options[:ssl_ca_cert]
278
+ end
279
+ else
280
+ store.set_default_paths
281
+ end
282
+ store.set_default_paths
283
+ http.cert_store = store
284
+ end
285
+ if options.include? :read_timeout
286
+ http.read_timeout = options[:read_timeout]
287
+ end
288
+
289
+ resp = nil
290
+ http.start {
291
+ if target.class == URI::HTTPS
292
+ # xxx: information hiding violation
293
+ sock = http.instance_variable_get(:@socket)
294
+ if sock.respond_to?(:io)
295
+ sock = sock.io # 1.9
296
+ else
297
+ sock = sock.instance_variable_get(:@socket) # 1.8
298
+ end
299
+ sock.post_connection_check(target_host)
300
+ end
301
+ req = Net::HTTP::Get.new(request_uri, header)
302
+ if options.include? :http_basic_authentication
303
+ user, pass = options[:http_basic_authentication]
304
+ req.basic_auth user, pass
305
+ end
306
+ http.request(req) {|response|
307
+ resp = response
308
+ if options[:content_length_proc] && Net::HTTPSuccess === resp
309
+ if resp.key?('Content-Length')
310
+ options[:content_length_proc].call(resp['Content-Length'].to_i)
311
+ else
312
+ options[:content_length_proc].call(nil)
313
+ end
314
+ end
315
+ resp.read_body {|str|
316
+ buf << str
317
+ if options[:progress_proc] && Net::HTTPSuccess === resp
318
+ options[:progress_proc].call(buf.size)
319
+ end
320
+ }
321
+ }
322
+ }
323
+ io = buf.io
324
+ io.rewind
325
+ io.status = [resp.code, resp.message]
326
+ resp.each {|name,value| buf.io.meta_add_field name, value }
327
+ case resp
328
+ when Net::HTTPSuccess
329
+ when Net::HTTPMovedPermanently, # 301
330
+ Net::HTTPFound, # 302
331
+ Net::HTTPSeeOther, # 303
332
+ Net::HTTPTemporaryRedirect # 307
333
+ throw :open_uri_redirect, URI.parse(resp['location'])
334
+ else
335
+ raise OpenURI::HTTPError.new(io.status.join(' '), io)
336
+ end
337
+ end
338
+
339
+ class HTTPError < StandardError
340
+ def initialize(message, io)
341
+ super(message)
342
+ @io = io
343
+ end
344
+ attr_reader :io
345
+ end
346
+
347
+ class Buffer # :nodoc:
348
+ def initialize
349
+ @io = StringIO.new
350
+ @size = 0
351
+ end
352
+ attr_reader :size
353
+
354
+ StringMax = 10240
355
+ def <<(str)
356
+ @io << str
357
+ @size += str.length
358
+ if StringIO === @io && StringMax < @size
359
+ require 'tempfile'
360
+ io = Tempfile.new('open-uri')
361
+ io.binmode
362
+ Meta.init io, @io if @io.respond_to? :meta
363
+ io << @io.string
364
+ @io = io
365
+ end
366
+ end
367
+
368
+ def io
369
+ Meta.init @io unless @io.respond_to? :meta
370
+ @io
371
+ end
372
+ end
373
+
374
+ # Mixin for holding meta-information.
375
+ module Meta
376
+ def Meta.init(obj, src=nil) # :nodoc:
377
+ obj.extend Meta
378
+ obj.instance_eval {
379
+ @base_uri = nil
380
+ @meta = {}
381
+ }
382
+ if src
383
+ obj.status = src.status
384
+ obj.base_uri = src.base_uri
385
+ src.meta.each {|name, value|
386
+ obj.meta_add_field(name, value)
387
+ }
388
+ end
389
+ end
390
+
391
+ # returns an Array which consists status code and message.
392
+ attr_accessor :status
393
+
394
+ # returns a URI which is base of relative URIs in the data.
395
+ # It may differ from the URI supplied by a user because redirection.
396
+ attr_accessor :base_uri
397
+
398
+ # returns a Hash which represents header fields.
399
+ # The Hash keys are downcased for canonicalization.
400
+ attr_reader :meta
401
+
402
+ def meta_add_field(name, value) # :nodoc:
403
+ @meta[name.downcase] = value
404
+ end
405
+
406
+ # returns a Time which represents Last-Modified field.
407
+ def last_modified
408
+ if v = @meta['last-modified']
409
+ Time.httpdate(v)
410
+ else
411
+ nil
412
+ end
413
+ end
414
+
415
+ RE_LWS = /[\r\n\t ]+/n
416
+ RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
417
+ RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
418
+ RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
419
+
420
+ def content_type_parse # :nodoc:
421
+ v = @meta['content-type']
422
+ # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
423
+ if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
424
+ type = $1.downcase
425
+ subtype = $2.downcase
426
+ parameters = []
427
+ $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
428
+ val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/) { $1 ? $1[1,1] : $& } if qval
429
+ parameters << [att.downcase, val]
430
+ }
431
+ ["#{type}/#{subtype}", *parameters]
432
+ else
433
+ nil
434
+ end
435
+ end
436
+
437
+ # returns "type/subtype" which is MIME Content-Type.
438
+ # It is downcased for canonicalization.
439
+ # Content-Type parameters are stripped.
440
+ def content_type
441
+ type, *parameters = content_type_parse
442
+ type || 'application/octet-stream'
443
+ end
444
+
445
+ # returns a charset parameter in Content-Type field.
446
+ # It is downcased for canonicalization.
447
+ #
448
+ # If charset parameter is not given but a block is given,
449
+ # the block is called and its result is returned.
450
+ # It can be used to guess charset.
451
+ #
452
+ # If charset parameter and block is not given,
453
+ # nil is returned except text type in HTTP.
454
+ # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
455
+ def charset
456
+ type, *parameters = content_type_parse
457
+ if pair = parameters.assoc('charset')
458
+ pair.last.downcase
459
+ elsif block_given?
460
+ yield
461
+ elsif type && %r{\Atext/} =~ type &&
462
+ @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
463
+ "iso-8859-1" # RFC2616 3.7.1
464
+ else
465
+ nil
466
+ end
467
+ end
468
+
469
+ # returns a list of encodings in Content-Encoding field
470
+ # as an Array of String.
471
+ # The encodings are downcased for canonicalization.
472
+ def content_encoding
473
+ v = @meta['content-encoding']
474
+ if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
475
+ v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
476
+ else
477
+ []
478
+ end
479
+ end
480
+ end
481
+
482
+ # Mixin for HTTP and FTP URIs.
483
+ module OpenRead
484
+ # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
485
+ #
486
+ # OpenURI::OpenRead#open takes optional 3 arguments as:
487
+ # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
488
+ #
489
+ # `mode', `perm' is same as Kernel#open.
490
+ #
491
+ # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
492
+ # support write mode (yet).
493
+ # Also `perm' is just ignored because it is meaningful only for file
494
+ # creation.
495
+ #
496
+ # `options' must be a hash.
497
+ #
498
+ # Each pairs which key is a string in the hash specify a extra header
499
+ # field for HTTP.
500
+ # I.e. it is ignored for FTP without HTTP proxy.
501
+ #
502
+ # The hash may include other options which key is a symbol:
503
+ #
504
+ # [:proxy]
505
+ # Synopsis:
506
+ # :proxy => "http://proxy.foo.com:8000/"
507
+ # :proxy => URI.parse("http://proxy.foo.com:8000/")
508
+ # :proxy => true
509
+ # :proxy => false
510
+ # :proxy => nil
511
+ #
512
+ # If :proxy option is specified, the value should be String, URI,
513
+ # boolean or nil.
514
+ # When String or URI is given, it is treated as proxy URI.
515
+ # When true is given or the option itself is not specified,
516
+ # environment variable `scheme_proxy' is examined.
517
+ # `scheme' is replaced by `http', `https' or `ftp'.
518
+ # When false or nil is given, the environment variables are ignored and
519
+ # connection will be made to a server directly.
520
+ #
521
+ # [:proxy_http_basic_authentication]
522
+ # Synopsis:
523
+ # :proxy_http_basic_authentication => ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
524
+ # :proxy_http_basic_authentication => [URI.parse("http://proxy.foo.com:8000/"), "proxy-user", "proxy-password"]
525
+ #
526
+ # If :proxy option is specified, the value should be an Array with 3 elements.
527
+ # It should contain a proxy URI, a proxy user name and a proxy password.
528
+ # The proxy URI should be a String, an URI or nil.
529
+ # The proxy user name and password should be a String.
530
+ #
531
+ # If nil is given for the proxy URI, this option is just ignored.
532
+ #
533
+ # If :proxy and :proxy_http_basic_authentication is specified,
534
+ # ArgumentError is raised.
535
+ #
536
+ # [:http_basic_authentication]
537
+ # Synopsis:
538
+ # :http_basic_authentication=>[user, password]
539
+ #
540
+ # If :http_basic_authentication is specified,
541
+ # the value should be an array which contains 2 strings:
542
+ # username and password.
543
+ # It is used for HTTP Basic authentication defined by RFC 2617.
544
+ #
545
+ # [:content_length_proc]
546
+ # Synopsis:
547
+ # :content_length_proc => lambda {|content_length| ... }
548
+ #
549
+ # If :content_length_proc option is specified, the option value procedure
550
+ # is called before actual transfer is started.
551
+ # It takes one argument which is expected content length in bytes.
552
+ #
553
+ # If two or more transfer is done by HTTP redirection, the procedure
554
+ # is called only one for a last transfer.
555
+ #
556
+ # When expected content length is unknown, the procedure is called with
557
+ # nil.
558
+ # It is happen when HTTP response has no Content-Length header.
559
+ #
560
+ # [:progress_proc]
561
+ # Synopsis:
562
+ # :progress_proc => lambda {|size| ...}
563
+ #
564
+ # If :progress_proc option is specified, the proc is called with one
565
+ # argument each time when `open' gets content fragment from network.
566
+ # The argument `size' `size' is a accumulated transfered size in bytes.
567
+ #
568
+ # If two or more transfer is done by HTTP redirection, the procedure
569
+ # is called only one for a last transfer.
570
+ #
571
+ # :progress_proc and :content_length_proc are intended to be used for
572
+ # progress bar.
573
+ # For example, it can be implemented as follows using Ruby/ProgressBar.
574
+ #
575
+ # pbar = nil
576
+ # open("http://...",
577
+ # :content_length_proc => lambda {|t|
578
+ # if t && 0 < t
579
+ # pbar = ProgressBar.new("...", t)
580
+ # pbar.file_transfer_mode
581
+ # end
582
+ # },
583
+ # :progress_proc => lambda {|s|
584
+ # pbar.set s if pbar
585
+ # }) {|f| ... }
586
+ #
587
+ # [:read_timeout]
588
+ # Synopsis:
589
+ # :read_timeout=>nil (no timeout)
590
+ # :read_timeout=>10 (10 second)
591
+ #
592
+ # :read_timeout option specifies a timeout of read for http connections.
593
+ #
594
+ # [:ssl_ca_cert]
595
+ # Synopsis:
596
+ # :ssl_ca_cert=>filename
597
+ #
598
+ # :ssl_ca_cert is used to specify CA certificate for SSL.
599
+ # If it is given, default certificates are not used.
600
+ #
601
+ # [:ssl_verify_mode]
602
+ # Synopsis:
603
+ # :ssl_verify_mode=>mode
604
+ #
605
+ # :ssl_verify_mode is used to specify openssl verify mode.
606
+ #
607
+ # OpenURI::OpenRead#open returns an IO like object if block is not given.
608
+ # Otherwise it yields the IO object and return the value of the block.
609
+ # The IO object is extended with OpenURI::Meta.
610
+ def open(*rest, &block)
611
+ OpenURI.open_uri(self, *rest, &block)
612
+ end
613
+
614
+ # OpenURI::OpenRead#read([options]) reads a content referenced by self and
615
+ # returns the content as string.
616
+ # The string is extended with OpenURI::Meta.
617
+ # The argument `options' is same as OpenURI::OpenRead#open.
618
+ def read(options={})
619
+ self.open(options) {|f|
620
+ str = f.read
621
+ Meta.init str, f
622
+ str
623
+ }
624
+ end
625
+ end
626
+ end
627
+
628
+ module URI
629
+ class Generic
630
+ # returns a proxy URI.
631
+ # The proxy URI is obtained from environment variables such as http_proxy,
632
+ # ftp_proxy, no_proxy, etc.
633
+ # If there is no proper proxy, nil is returned.
634
+ #
635
+ # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
636
+ # are examined too.
637
+ #
638
+ # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
639
+ # It's because HTTP_PROXY may be set by Proxy: header.
640
+ # So HTTP_PROXY is not used.
641
+ # http_proxy is not used too if the variable is case insensitive.
642
+ # CGI_HTTP_PROXY can be used instead.
643
+ def find_proxy
644
+ name = self.scheme.downcase + '_proxy'
645
+ proxy_uri = nil
646
+ if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
647
+ # HTTP_PROXY conflicts with *_proxy for proxy settings and
648
+ # HTTP_* for header information in CGI.
649
+ # So it should be careful to use it.
650
+ pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
651
+ case pairs.length
652
+ when 0 # no proxy setting anyway.
653
+ proxy_uri = nil
654
+ when 1
655
+ k, v = pairs.shift
656
+ if k == 'http_proxy' && ENV[k.upcase] == nil
657
+ # http_proxy is safe to use because ENV is case sensitive.
658
+ proxy_uri = ENV[name]
659
+ else
660
+ proxy_uri = nil
661
+ end
662
+ else # http_proxy is safe to use because ENV is case sensitive.
663
+ proxy_uri = ENV[name]
664
+ end
665
+ if !proxy_uri
666
+ # Use CGI_HTTP_PROXY. cf. libwww-perl.
667
+ proxy_uri = ENV["CGI_#{name.upcase}"]
668
+ end
669
+ elsif name == 'http_proxy'
670
+ unless proxy_uri = ENV[name]
671
+ if proxy_uri = ENV[name.upcase]
672
+ warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
673
+ end
674
+ end
675
+ else
676
+ proxy_uri = ENV[name] || ENV[name.upcase]
677
+ end
678
+
679
+ if proxy_uri && self.host
680
+ require 'socket'
681
+ begin
682
+ addr = IPSocket.getaddress(self.host)
683
+ proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
684
+ rescue SocketError
685
+ end
686
+ end
687
+
688
+ if proxy_uri
689
+ proxy_uri = URI.parse(proxy_uri)
690
+ name = 'no_proxy'
691
+ if no_proxy = ENV[name] || ENV[name.upcase]
692
+ no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
693
+ if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
694
+ (!port || self.port == port.to_i)
695
+ proxy_uri = nil
696
+ break
697
+ end
698
+ }
699
+ end
700
+ proxy_uri
701
+ else
702
+ nil
703
+ end
704
+ end
705
+ end
706
+
707
+ class HTTP
708
+ def buffer_open(buf, proxy, options) # :nodoc:
709
+ OpenURI.open_http(buf, self, proxy, options)
710
+ end
711
+
712
+ include OpenURI::OpenRead
713
+ end
714
+
715
+ class FTP
716
+ def buffer_open(buf, proxy, options) # :nodoc:
717
+ if proxy
718
+ OpenURI.open_http(buf, self, proxy, options)
719
+ return
720
+ end
721
+ require 'net/ftp'
722
+
723
+ directories = self.path.split(%r{/}, -1)
724
+ directories.shift if directories[0] == '' # strip a field before leading slash
725
+ directories.each {|d|
726
+ d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
727
+ }
728
+ unless filename = directories.pop
729
+ raise ArgumentError, "no filename: #{self.inspect}"
730
+ end
731
+ directories.each {|d|
732
+ if /[\r\n]/ =~ d
733
+ raise ArgumentError, "invalid directory: #{d.inspect}"
734
+ end
735
+ }
736
+ if /[\r\n]/ =~ filename
737
+ raise ArgumentError, "invalid filename: #{filename.inspect}"
738
+ end
739
+ typecode = self.typecode
740
+ if typecode && /\A[aid]\z/ !~ typecode
741
+ raise ArgumentError, "invalid typecode: #{typecode.inspect}"
742
+ end
743
+
744
+ # The access sequence is defined by RFC 1738
745
+ ftp = Net::FTP.open(self.host)
746
+ # todo: extract user/passwd from .netrc.
747
+ user = 'anonymous'
748
+ passwd = nil
749
+ user, passwd = self.userinfo.split(/:/) if self.userinfo
750
+ ftp.login(user, passwd)
751
+ directories.each {|cwd|
752
+ ftp.voidcmd("CWD #{cwd}")
753
+ }
754
+ if typecode
755
+ # xxx: typecode D is not handled.
756
+ ftp.voidcmd("TYPE #{typecode.upcase}")
757
+ end
758
+ if options[:content_length_proc]
759
+ options[:content_length_proc].call(ftp.size(filename))
760
+ end
761
+ ftp.retrbinary("RETR #{filename}", 4096) { |str|
762
+ buf << str
763
+ options[:progress_proc].call(buf.size) if options[:progress_proc]
764
+ }
765
+ ftp.close
766
+ buf.io.rewind
767
+ end
768
+
769
+ include OpenURI::OpenRead
770
+ end
771
+ end
@@ -116,14 +116,19 @@ class Gem::RemoteFetcher
116
116
  # Read the data from the (source based) URI, but if it is a file:// URI,
117
117
  # read from the filesystem instead.
118
118
  def open_uri_or_path(uri, &block)
119
- require 'open-uri'
119
+ require 'rubygems/gem_open_uri'
120
120
  if file_uri?(uri)
121
121
  open(get_file_uri_path(uri), &block)
122
122
  else
123
123
  connection_options = {
124
- "User-Agent" => "RubyGems/#{Gem::RubyGemsVersion}",
125
- :proxy => @proxy_uri,
124
+ "User-Agent" => "RubyGems/#{Gem::RubyGemsVersion}"
126
125
  }
126
+
127
+ if @proxy_uri
128
+ http_proxy_url = "#{@proxy_uri.scheme}://#{@proxy_uri.host}:#{@proxy_uri.port}"
129
+ connection_options[:proxy_http_basic_authentication] = [http_proxy_url, unescape(@proxy_uri.user)||'', unescape(@proxy_uri.password)||'']
130
+ end
131
+
127
132
  open(uri, connection_options, &block)
128
133
  end
129
134
  end
@@ -2,5 +2,5 @@
2
2
  # This file is auto-generated by build scripts.
3
3
  # See: rake update_version
4
4
  module Gem
5
- RubyGemsVersion = '0.9.1'
5
+ RubyGemsVersion = '0.9.2'
6
6
  end
@@ -226,7 +226,6 @@ module Gem
226
226
  def outdated
227
227
  remotes = Gem::SourceInfoCache.search(//)
228
228
  outdateds = []
229
-
230
229
  latest_specs.each do |_, local|
231
230
  name = local.name
232
231
  remote = remotes.select { |spec| spec.name == name }.
@@ -234,7 +233,6 @@ module Gem
234
233
  last
235
234
  outdateds << name if remote and local.version < remote.version
236
235
  end
237
-
238
236
  outdateds
239
237
  end
240
238
 
@@ -5,7 +5,6 @@ require 'rubygems/source_info_cache_entry'
5
5
 
6
6
  require 'sources'
7
7
 
8
- ##
9
8
  # SourceInfoCache stores a copy of the gem index for each gem source.
10
9
  #
11
10
  # There are two possible cache locations, the system cache and the user cache:
@@ -65,15 +64,22 @@ class Gem::SourceInfoCache
65
64
  @dirty = false
66
65
  cache_file # HACK writable check
67
66
  # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
68
- @cache_data = Marshal.load(File.read(cache_file)) rescue {}
67
+ begin
68
+ data = File.open cache_file, 'rb' do |fp|
69
+ fp.read
70
+ end
71
+ @cache_data = Marshal.load data
72
+ rescue
73
+ {}
74
+ end
69
75
  end
70
76
 
71
77
  # The name of the cache file to be read
72
78
  def cache_file
73
79
  return @cache_file if @cache_file
74
80
  @cache_file = (try_file(system_cache_file) or
75
- try_file(user_cache_file) or
76
- raise "unable to locate a writable cache file")
81
+ try_file(user_cache_file) or
82
+ raise "unable to locate a writable cache file")
77
83
  end
78
84
 
79
85
  # Write the cache to a local file (if it is dirty).
@@ -127,6 +133,15 @@ class Gem::SourceInfoCache
127
133
  end
128
134
  end
129
135
 
136
+ # Set the source info cache data directly. This is mainly used for unit
137
+ # testing when we don't want to read a file system for to grab the cached
138
+ # source index information. The +hash+ should map a source URL into a
139
+ # SourceIndexCacheEntry.
140
+ def set_cache_data(hash)
141
+ @cache_data = hash
142
+ @dirty = false
143
+ end
144
+
130
145
  private
131
146
 
132
147
  # Determine if +fn+ is a candidate for a cache file. Return fn if
@@ -22,8 +22,8 @@ class Gem::SourceInfoCacheEntry
22
22
 
23
23
  def refresh(source_uri)
24
24
  remote_size = Gem::RemoteFetcher.fetcher.fetch_size source_uri + '/yaml'
25
- return if @size == remote_size
26
- @source_index.update source_uri
25
+ return if @size == remote_size # HACK bad check, local cache not YAML
26
+ @source_index.update source_uri
27
27
  @size = remote_size
28
28
  end
29
29
 
@@ -9,7 +9,7 @@ require 'fileutils'
9
9
  require 'test/unit/testcase'
10
10
  require 'tmpdir'
11
11
  require 'uri'
12
- require 'open-uri'
12
+ require 'rubygems/gem_open_uri'
13
13
 
14
14
  require 'test/yaml_data'
15
15
  require 'test/mockgemui'
@@ -158,16 +158,12 @@ class RubyGemTestCase < Test::Unit::TestCase
158
158
 
159
159
  def util_setup_source_info_cache(*specs)
160
160
  specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
161
-
162
161
  si = Gem::SourceIndex.new specs
163
162
 
164
163
  sice = Gem::SourceInfoCacheEntry.new si, 0
165
-
166
164
  sic = Gem::SourceInfoCache.new
167
- sic.cache_data['http://gems.example.com'] = sice
168
-
165
+ sic.set_cache_data( { 'http://gems.example.com' => sice } )
169
166
  Gem::SourceInfoCache.instance_variable_set :@cache, sic
170
-
171
167
  si
172
168
  end
173
169
 
@@ -34,7 +34,7 @@ class TestGemExtExtConfBuilder < RubyGemTestCase
34
34
  "make: Nothing to be done for `install'.\n"
35
35
  ]
36
36
 
37
- assert_equal "ruby extconf.rb", output[0]
37
+ assert_match(/^ruby extconf.rb/, output[0])
38
38
  assert_equal "creating Makefile\n", output[1]
39
39
  case RUBY_PLATFORM
40
40
  when /mswin/ then
@@ -63,10 +63,10 @@ class TestGemExtExtConfBuilder < RubyGemTestCase
63
63
 
64
64
  assert_match(/\Aextconf failed:
65
65
 
66
- ruby extconf.rb
67
- checking for main\(\) in .*?nonexistent/, error.message)
66
+ ruby extconf.rb.*
67
+ checking for main\(\) in .*?nonexistent/m, error.message)
68
68
 
69
- assert_equal 'ruby extconf.rb', output[0]
69
+ assert_match(/^ruby extconf.rb/, output[0])
70
70
  end
71
71
 
72
72
  def test_class_make
@@ -163,7 +163,8 @@ class TestGemSourceInfoCache < RubyGemTestCase
163
163
 
164
164
  def test_write_cache_user
165
165
  FileUtils.chmod 0444, @sic.system_cache_file
166
- @sic.cache_data['key'] = 'new'
166
+ @sic.set_cache_data({'key' => 'new'})
167
+ @sic.update
167
168
  @sic.write_cache
168
169
 
169
170
  assert_equal [['key', 'sys']], read_cache(@sic.system_cache_file).to_a.sort
@@ -173,8 +174,8 @@ class TestGemSourceInfoCache < RubyGemTestCase
173
174
  def test_write_cache_user_from_scratch
174
175
  FileUtils.rm_rf @sic.user_cache_file
175
176
  FileUtils.chmod 0444, @sic.system_cache_file
176
-
177
- @sic.cache_data['key'] = 'new'
177
+ @sic.set_cache_data({'key' => 'new'})
178
+ @sic.update
178
179
  @sic.write_cache
179
180
 
180
181
  assert_equal [['key', 'sys']], read_cache(@sic.system_cache_file).to_a.sort
@@ -184,8 +185,8 @@ class TestGemSourceInfoCache < RubyGemTestCase
184
185
  def test_write_cache_user_no_directory
185
186
  FileUtils.rm_rf File.dirname(@sic.user_cache_file)
186
187
  FileUtils.chmod 0444, @sic.system_cache_file
187
-
188
- @sic.cache_data['key'] = 'new'
188
+ @sic.set_cache_data({'key' => 'new'})
189
+ @sic.update
189
190
  @sic.write_cache
190
191
 
191
192
  assert_equal [['key','sys']], read_cache(@sic.system_cache_file).to_a.sort
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0.10
3
3
  specification_version: 1
4
4
  name: rubygems-update
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.1
7
- date: 2007-01-16 00:00:00 -08:00
6
+ version: 0.9.2
7
+ date: 2007-02-05 00:00:00 -05:00
8
8
  summary: RubyGems Update GEM
9
9
  require_paths:
10
10
  - lib
@@ -83,10 +83,12 @@ files:
83
83
  - lib/rubygems/doc_manager.rb
84
84
  - lib/rubygems/format.rb
85
85
  - lib/rubygems/gem_commands.rb
86
+ - lib/rubygems/gem_open_uri.rb
86
87
  - lib/rubygems/gem_openssl.rb
87
88
  - lib/rubygems/gem_runner.rb
88
89
  - lib/rubygems/installer.rb
89
90
  - lib/rubygems/old_format.rb
91
+ - lib/rubygems/open-uri.rb
90
92
  - lib/rubygems/package.rb
91
93
  - lib/rubygems/remote_fetcher.rb
92
94
  - lib/rubygems/remote_installer.rb
@@ -103,7 +105,6 @@ files:
103
105
  - lib/rubygems/version.rb
104
106
  - pkgs/sources
105
107
  - pkgs/sources/lib
106
- - pkgs/sources/sources-0.0.1.gem
107
108
  - pkgs/sources/sources.gemspec
108
109
  - pkgs/sources/lib/sources.rb
109
110
  - redist/session.gem
@@ -162,13 +163,8 @@ files:
162
163
  - test/testgem.rc
163
164
  - test/user_capture.rb
164
165
  - test/yaml_data.rb
165
- - test/data/a-0.0.1.gem
166
- - test/data/a-0.0.2.gem
167
- - test/data/b-0.0.2.gem
168
166
  - test/data/broken-1.0.0.gem
169
167
  - test/data/broken_build
170
- - test/data/c-1.2.gem
171
- - test/data/gemhome
172
168
  - test/data/legacy
173
169
  - test/data/lib
174
170
  - test/data/one
@@ -178,35 +174,10 @@ files:
178
174
  - test/data/broken_build/ext
179
175
  - test/data/broken_build/ext/extconf.rb
180
176
  - test/data/broken_build/ext/foo.c
181
- - test/data/gemhome/cache
182
- - test/data/gemhome/doc
183
- - test/data/gemhome/gems
184
- - test/data/gemhome/specifications
185
- - test/data/gemhome/cache/a-0.0.1.gem
186
- - test/data/gemhome/cache/a-0.0.2.gem
187
- - test/data/gemhome/cache/b-0.0.2.gem
188
- - test/data/gemhome/cache/c-1.2.gem
189
- - test/data/gemhome/gems/a-0.0.1
190
- - test/data/gemhome/gems/a-0.0.2
191
- - test/data/gemhome/gems/b-0.0.2
192
- - test/data/gemhome/gems/c-1.2
193
- - test/data/gemhome/gems/a-0.0.1/lib
194
- - test/data/gemhome/gems/a-0.0.1/lib/code.rb
195
- - test/data/gemhome/gems/a-0.0.2/lib
196
- - test/data/gemhome/gems/a-0.0.2/lib/code.rb
197
- - test/data/gemhome/gems/b-0.0.2/lib
198
- - test/data/gemhome/gems/b-0.0.2/lib/code.rb
199
- - test/data/gemhome/gems/c-1.2/lib
200
- - test/data/gemhome/gems/c-1.2/lib/code.rb
201
- - test/data/gemhome/specifications/a-0.0.1.gemspec
202
- - test/data/gemhome/specifications/a-0.0.2.gemspec
203
- - test/data/gemhome/specifications/b-0.0.2.gemspec
204
- - test/data/gemhome/specifications/c-1.2.gemspec
205
177
  - test/data/legacy/keyedlist-0.4.0.ruby
206
178
  - test/data/legacy/keyedlist-0.4.0.yaml
207
179
  - test/data/lib/code.rb
208
180
  - test/data/one/lib
209
- - test/data/one/one-0.0.1.gem
210
181
  - test/data/one/one.gemspec
211
182
  - test/data/one/one.yaml
212
183
  - test/data/one/README.one
Binary file
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- CODE = 1
@@ -1 +0,0 @@
1
- CODE = 1
@@ -1 +0,0 @@
1
- CODE = 1
@@ -1 +0,0 @@
1
- CODE = 1
@@ -1,8 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = %q{a}
3
- s.version = "0.0.1"
4
- s.date = %q{2007-01-16}
5
- s.summary = %q{summary}
6
- s.description = %q{desc}
7
- s.files = ["lib/code.rb"]
8
- end
@@ -1,8 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = %q{a}
3
- s.version = "0.0.2"
4
- s.date = %q{2007-01-16}
5
- s.summary = %q{summary}
6
- s.description = %q{desc}
7
- s.files = ["lib/code.rb"]
8
- end
@@ -1,8 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = %q{b}
3
- s.version = "0.0.2"
4
- s.date = %q{2007-01-16}
5
- s.summary = %q{summary}
6
- s.description = %q{desc}
7
- s.files = ["lib/code.rb"]
8
- end
@@ -1,8 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = %q{c}
3
- s.version = "1.2"
4
- s.date = %q{2007-01-16}
5
- s.summary = %q{summary}
6
- s.description = %q{desc}
7
- s.files = ["lib/code.rb"]
8
- end
Binary file