rubygems-update 0.9.1 → 0.9.2

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 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