summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-11 20:57:02 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-11 20:57:02 +0000
commite72b71d56a1f369cb7eb3892c61715460bac8109 (patch)
tree6f55131cbd153845e71dadc91f08636aa6707423 /lib
parent0ae6c7f816cbc3ba0cdd97f609b9ffcbf49bf9bb (diff)
Update to RubyGems 1.1.1 r1701.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15980 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/rubygems.rb34
-rw-r--r--lib/rubygems/command_manager.rb2
-rw-r--r--lib/rubygems/commands/environment_command.rb2
-rw-r--r--lib/rubygems/commands/pristine_command.rb1
-rw-r--r--lib/rubygems/commands/query_command.rb6
-rw-r--r--lib/rubygems/commands/sources_command.rb2
-rw-r--r--lib/rubygems/commands/update_command.rb11
-rw-r--r--lib/rubygems/dependency_installer.rb10
-rw-r--r--lib/rubygems/doc_manager.rb6
-rw-r--r--lib/rubygems/gem_open_uri.rb7
-rw-r--r--lib/rubygems/indexer.rb2
-rw-r--r--lib/rubygems/open-uri.rb773
-rw-r--r--lib/rubygems/remote_fetcher.rb4
-rw-r--r--lib/rubygems/rubygems_version.rb2
-rw-r--r--lib/rubygems/server.rb10
-rw-r--r--lib/rubygems/source_index.rb32
-rw-r--r--lib/rubygems/source_info_cache.rb74
-rw-r--r--lib/rubygems/version_option.rb3
18 files changed, 137 insertions, 844 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 3f9657ac1e..1cb205cbc9 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -97,7 +97,7 @@ module Gem
@configuration = nil
@loaded_specs = {}
- @platforms = nil
+ @platforms = []
@ruby = nil
@sources = []
@@ -215,7 +215,7 @@ module Gem
def self.bindir(install_dir=Gem.dir)
return File.join(install_dir, 'bin') unless
- install_dir.to_s == Gem.default_dir
+ install_dir.to_s == Gem.default_dir
Gem.default_bindir
end
@@ -451,10 +451,21 @@ module Gem
end
##
- # Array of platforms this RubyGems supports.
+ # Set array of platforms this RubyGems supports (primarily for testing).
+
+ def self.platforms=(platforms)
+ @platforms = platforms
+ end
+ ##
+ # Array of platforms this RubyGems supports.
+
def self.platforms
- @platforms ||= [Gem::Platform::RUBY, Gem::Platform.local]
+ @platforms ||= []
+ if @platforms.empty?
+ @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
+ end
+ @platforms
end
##
@@ -463,7 +474,9 @@ module Gem
def self.prefix
prefix = File.dirname File.expand_path(__FILE__)
- if prefix == File.expand_path(ConfigMap[:sitelibdir]) then
+ if File.dirname(prefix) == File.expand_path(ConfigMap[:sitelibdir]) or
+ File.dirname(prefix) == File.expand_path(ConfigMap[:libdir]) or
+ 'lib' != File.basename(prefix) then
nil
else
File.dirname prefix
@@ -471,6 +484,17 @@ module Gem
end
##
+ # Refresh source_index from disk and clear searcher.
+
+ def self.refresh
+ source_index.refresh!
+
+ MUTEX.synchronize do
+ @searcher = nil
+ end
+ end
+
+ ##
# Safely read a file in binary mode on all platforms.
def self.read_binary(path)
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index b8aa651f56..299b5213cc 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -93,7 +93,7 @@ module Gem
say Gem::Command::HELP
terminate_interaction(0)
when '-v', '--version'
- say Gem::RubyGemsPackageVersion
+ say Gem::RubyGemsVersion
terminate_interaction(0)
when /^-/
alert_error "Invalid option: #{args[0]}. See 'gem --help'."
diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb
index 56b373cfbe..342f93ca54 100644
--- a/lib/rubygems/commands/environment_command.rb
+++ b/lib/rubygems/commands/environment_command.rb
@@ -39,7 +39,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
when nil then
out = "RubyGems Environment:\n"
- out << " - RUBYGEMS VERSION: #{Gem::RubyGemsVersion} (#{Gem::RubyGemsPackageVersion})\n"
+ out << " - RUBYGEMS VERSION: #{Gem::RubyGemsVersion}\n"
out << " - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}"
out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index 2900e7e739..bbea835133 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -126,6 +126,7 @@ revert the gem.
end
installer.generate_bin
+ installer.build_extensions
end
end
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index fdc5a6a4ea..ea83b93bbb 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -82,13 +82,15 @@ class Gem::Commands::QueryCommand < Gem::Command
say "*** REMOTE GEMS ***"
say
+ all = options[:all]
+
begin
- Gem::SourceInfoCache.cache.refresh options[:all]
+ Gem::SourceInfoCache.cache all
rescue Gem::RemoteFetcher::FetchError
# no network
end
- output_query_results Gem::SourceInfoCache.search(name, false, true)
+ output_query_results Gem::SourceInfoCache.search(name, false, all)
end
end
diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb
index 6d9d5b5b90..1558d79b8b 100644
--- a/lib/rubygems/commands/sources_command.rb
+++ b/lib/rubygems/commands/sources_command.rb
@@ -69,7 +69,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
end
if options[:update] then
- Gem::SourceInfoCache.cache.refresh true
+ Gem::SourceInfoCache.cache true
Gem::SourceInfoCache.cache.flush
say "source cache successfully updated"
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index b8de911e20..31a97c4844 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -58,7 +58,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
say "Updating installed gems"
end
- hig = {}
+ hig = {} # highest installed gems
Gem::SourceIndex.from_installed_gems.each do |name, spec|
if hig[spec.name].nil? or hig[spec.name].version < spec.version then
@@ -67,7 +67,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
pattern = if options[:args].empty? then
- //
+ //
else
Regexp.union(*options[:args])
end
@@ -78,12 +78,14 @@ class Gem::Commands::UpdateCommand < Gem::Command
updated = []
- # HACK use the real API
+ installer = Gem::DependencyInstaller.new options
+
gems_to_update.uniq.sort.each do |name|
next if updated.any? { |spec| spec.name == name }
+
say "Updating #{name}"
- installer = Gem::DependencyInstaller.new options
installer.install name
+
installer.installed_gems.each do |spec|
updated << spec
say "Successfully installed #{spec.full_name}"
@@ -115,6 +117,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
args.push '--prefix', Gem.prefix unless Gem.prefix.nil?
args << '--no-rdoc' unless options[:generate_rdoc]
args << '--no-ri' unless options[:generate_ri]
+ args << '--no-format-executable' if options[:no_format_executable]
update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"
diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb
index 26ef41b2f1..57ac631031 100644
--- a/lib/rubygems/dependency_installer.rb
+++ b/lib/rubygems/dependency_installer.rb
@@ -72,7 +72,7 @@ class Gem::DependencyInstaller
end
all = requirements.length > 1 ||
- requirements.first != ">=" || requirements.first != ">"
+ (requirements.first != ">=" and requirements.first != ">")
found = Gem::SourceInfoCache.search_with_source dep, true, all
@@ -189,7 +189,13 @@ class Gem::DependencyInstaller
say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
_, source_uri = @specs_and_sources.assoc spec
- local_gem_path = Gem::RemoteFetcher.fetcher.download spec, source_uri
+ begin
+ local_gem_path = Gem::RemoteFetcher.fetcher.download spec, source_uri,
+ @install_dir
+ rescue Gem::RemoteFetcher::FetchError
+ next if @force
+ raise
+ end
inst = Gem::Installer.new local_gem_path,
:env_shebang => @env_shebang,
diff --git a/lib/rubygems/doc_manager.rb b/lib/rubygems/doc_manager.rb
index 8d9b4a7b23..f214269ab3 100644
--- a/lib/rubygems/doc_manager.rb
+++ b/lib/rubygems/doc_manager.rb
@@ -65,6 +65,12 @@ module Gem
FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
begin
+ gem 'rdoc'
+ rescue Gem::LoadError
+ # use built-in RDoc
+ end
+
+ begin
require 'rdoc/rdoc'
rescue LoadError => e
raise Gem::DocumentError,
diff --git a/lib/rubygems/gem_open_uri.rb b/lib/rubygems/gem_open_uri.rb
deleted file mode 100644
index 597930dc50..0000000000
--- a/lib/rubygems/gem_open_uri.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env ruby
-
-if RUBY_VERSION > '1.9' then
- require 'open-uri'
-else
- require 'rubygems/open-uri'
-end
diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb
index 5496e452cc..9f6c0a2fc9 100644
--- a/lib/rubygems/indexer.rb
+++ b/lib/rubygems/indexer.rb
@@ -85,7 +85,7 @@ class Gem::Indexer
progress.updated spec.original_name
rescue SignalException => e
- alert_error "Recieved signal, exiting"
+ alert_error "Received signal, exiting"
raise
rescue Exception => e
alert_error "Unable to process #{gemfile}\n#{e.message} (#{e.class})\n\t#{e.backtrace.join "\n\t"}"
diff --git a/lib/rubygems/open-uri.rb b/lib/rubygems/open-uri.rb
deleted file mode 100644
index 50fa94374c..0000000000
--- a/lib/rubygems/open-uri.rb
+++ /dev/null
@@ -1,773 +0,0 @@
-require 'uri'
-require 'stringio'
-require 'time'
-
-# :stopdoc:
-module Kernel
- private
- alias rubygems_open_uri_original_open open # :nodoc:
-
- # makes possible to open various resources including URIs.
- # If the first argument respond to `open' method,
- # the method is called with the rest arguments.
- #
- # If the first argument is a string which begins with xxx://,
- # it is parsed by URI.parse. If the parsed object respond to `open' method,
- # the method is called with the rest arguments.
- #
- # Otherwise original open is called.
- #
- # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and
- # URI::FTP#open,
- # Kernel[#.]open can accepts such URIs and strings which begins with
- # http://, https:// and ftp://.
- # In these case, the opened file object is extended by OpenURI::Meta.
- def open(name, *rest, &block) # :doc:
- if name.respond_to?(:open)
- name.open(*rest, &block)
- elsif name.respond_to?(:to_str) &&
- %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ name &&
- (uri = URI.parse(name)).respond_to?(:open)
- uri.open(*rest, &block)
- else
- rubygems_open_uri_original_open(name, *rest, &block)
- end
- end
- module_function :open
-end
-
-# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.
-#
-#== Example
-#
-# It is possible to open http/https/ftp URL as usual like opening a file:
-#
-# open("http://www.ruby-lang.org/") {|f|
-# f.each_line {|line| p line}
-# }
-#
-# The opened file has several methods for meta information as follows since
-# it is extended by OpenURI::Meta.
-#
-# open("http://www.ruby-lang.org/en") {|f|
-# f.each_line {|line| p line}
-# p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
-# p f.content_type # "text/html"
-# p f.charset # "iso-8859-1"
-# p f.content_encoding # []
-# p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
-# }
-#
-# Additional header fields can be specified by an optional hash argument.
-#
-# open("http://www.ruby-lang.org/en/",
-# "User-Agent" => "Ruby/#{RUBY_VERSION}",
-# "From" => "foo@bar.invalid",
-# "Referer" => "http://www.ruby-lang.org/") {|f|
-# # ...
-# }
-#
-# The environment variables such as http_proxy, https_proxy and ftp_proxy
-# are in effect by default. :proxy => nil disables proxy.
-#
-# open("http://www.ruby-lang.org/en/raa.html", :proxy => nil) {|f|
-# # ...
-# }
-#
-# URI objects can be opened in a similar way.
-#
-# uri = URI.parse("http://www.ruby-lang.org/en/")
-# uri.open {|f|
-# # ...
-# }
-#
-# URI objects can be read directly. The returned string is also extended by
-# OpenURI::Meta.
-#
-# str = uri.read
-# p str.base_uri
-#
-# Author:: Tanaka Akira <akr@m17n.org>
-
-module OpenURI
- Options = {
- :proxy => true,
- :proxy_http_basic_authentication => true,
- :progress_proc => true,
- :content_length_proc => true,
- :http_basic_authentication => true,
- :read_timeout => true,
- :ssl_ca_cert => nil,
- :ssl_verify_mode => nil,
- }
-
- def OpenURI.check_options(options) # :nodoc:
- options.each {|k, v|
- next unless Symbol === k
- unless Options.include? k
- raise ArgumentError, "unrecognized option: #{k}"
- end
- }
- end
-
- def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:
- if !rest.empty? && (String === rest.first || Integer === rest.first)
- mode = rest.shift
- if !rest.empty? && Integer === rest.first
- perm = rest.shift
- end
- end
- return mode, perm, rest
- end
-
- def OpenURI.open_uri(name, *rest) # :nodoc:
- uri = URI::Generic === name ? name : URI.parse(name)
- mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)
- options = rest.shift if !rest.empty? && Hash === rest.first
- raise ArgumentError.new("extra arguments") if !rest.empty?
- options ||= {}
- OpenURI.check_options(options)
-
- unless mode == nil ||
- mode == 'r' || mode == 'rb' ||
- mode == File::RDONLY
- raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
- end
-
- io = open_loop(uri, options)
- if block_given?
- begin
- yield io
- ensure
- io.close
- end
- else
- io
- end
- end
-
- def OpenURI.open_loop(uri, options) # :nodoc:
- proxy_opts = []
- proxy_opts << :proxy_http_basic_authentication if options.include? :proxy_http_basic_authentication
- proxy_opts << :proxy if options.include? :proxy
- proxy_opts.compact!
- if 1 < proxy_opts.length
- raise ArgumentError, "multiple proxy options specified"
- end
- case proxy_opts.first
- when :proxy_http_basic_authentication
- opt_proxy, proxy_user, proxy_pass = options.fetch(:proxy_http_basic_authentication)
- proxy_user = proxy_user.to_str
- proxy_pass = proxy_pass.to_str
- if opt_proxy == true
- raise ArgumentError.new("Invalid authenticated proxy option: #{options[:proxy_http_basic_authentication].inspect}")
- end
- when :proxy
- opt_proxy = options.fetch(:proxy)
- proxy_user = nil
- proxy_pass = nil
- when nil
- opt_proxy = true
- proxy_user = nil
- proxy_pass = nil
- end
- case opt_proxy
- when true
- find_proxy = lambda {|u| pxy = u.find_proxy; pxy ? [pxy, nil, nil] : nil}
- when nil, false
- find_proxy = lambda {|u| nil}
- when String
- opt_proxy = URI.parse(opt_proxy)
- find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
- when URI::Generic
- find_proxy = lambda {|u| [opt_proxy, proxy_user, proxy_pass]}
- else
- raise ArgumentError.new("Invalid proxy option: #{opt_proxy}")
- end
-
- uri_set = {}
- buf = nil
- while true
- redirect = catch(:open_uri_redirect) {
- buf = Buffer.new
- uri.buffer_open(buf, find_proxy.call(uri), options)
- nil
- }
- if redirect
- if redirect.relative?
- # Although it violates RFC2616, Location: field may have relative
- # URI. It is converted to absolute URI using uri as a base URI.
- redirect = uri + redirect
- end
- unless OpenURI.redirectable?(uri, redirect)
- raise "redirection forbidden: #{uri} -> #{redirect}"
- end
- if options.include? :http_basic_authentication
- # send authentication only for the URI directly specified.
- options = options.dup
- options.delete :http_basic_authentication
- end
- uri = redirect
- raise "HTTP redirection loop: #{uri}" if uri_set.include? uri.to_s
- uri_set[uri.to_s] = true
- else
- break
- end
- end
- io = buf.io
- io.base_uri = uri
- io
- end
-
- def OpenURI.redirectable?(uri1, uri2) # :nodoc:
- # This test is intended to forbid a redirection from http://... to
- # file:///etc/passwd.
- # However this is ad hoc. It should be extensible/configurable.
- uri1.scheme.downcase == uri2.scheme.downcase ||
- (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp)\z/i =~ uri2.scheme)
- end
-
- def OpenURI.open_http(buf, target, proxy, options) # :nodoc:
- if proxy
- proxy_uri, proxy_user, proxy_pass = proxy
- raise "Non-HTTP proxy URI: #{proxy_uri}" if proxy_uri.class != URI::HTTP
- end
-
- if target.userinfo && "1.9.0" <= RUBY_VERSION
- # don't raise for 1.8 because compatibility.
- raise ArgumentError, "userinfo not supported. [RFC3986]"
- end
-
- header = {}
- options.each {|k, v| header[k] = v if String === k }
-
- require 'net/http'
- klass = Net::HTTP
- if URI::HTTP === target
- # HTTP or HTTPS
- if proxy
- if proxy_user && proxy_pass
- klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_user, proxy_pass)
- else
- klass = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
- end
- end
- target_host = target.host
- target_port = target.port
- request_uri = target.request_uri
- else
- # FTP over HTTP proxy
- target_host = proxy_uri.host
- target_port = proxy_uri.port
- request_uri = target.to_s
- if proxy_user && proxy_pass
- header["Proxy-Authorization"] = 'Basic ' + ["#{proxy_user}:#{proxy_pass}"].pack('m').delete("\r\n")
- end
- end
-
- http = klass.new(target_host, target_port)
- if target.class == URI::HTTPS
- require 'net/https'
- http.use_ssl = true
- http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
- store = OpenSSL::X509::Store.new
- if options[:ssl_ca_cert]
- if File.directory? options[:ssl_ca_cert]
- store.add_path options[:ssl_ca_cert]
- else
- store.add_file options[:ssl_ca_cert]
- end
- else
- store.set_default_paths
- end
- store.set_default_paths
- http.cert_store = store
- end
- if options.include? :read_timeout
- http.read_timeout = options[:read_timeout]
- end
-
- resp = nil
- http.start {
- if target.class == URI::HTTPS
- # xxx: information hiding violation
- sock = http.instance_variable_get(:@socket)
- if sock.respond_to?(:io)
- sock = sock.io # 1.9
- else
- sock = sock.instance_variable_get(:@socket) # 1.8
- end
- sock.post_connection_check(target_host)
- end
- req = Net::HTTP::Get.new(request_uri, header)
- if options.include? :http_basic_authentication
- user, pass = options[:http_basic_authentication]
- req.basic_auth user, pass
- end
- http.request(req) {|response|
- resp = response
- if options[:content_length_proc] && Net::HTTPSuccess === resp
- if resp.key?('Content-Length')
- options[:content_length_proc].call(resp['Content-Length'].to_i)
- else
- options[:content_length_proc].call(nil)
- end
- end
- resp.read_body {|str|
- buf << str
- if options[:progress_proc] && Net::HTTPSuccess === resp
- options[:progress_proc].call(buf.size)
- end
- }
- }
- }
- io = buf.io
- io.rewind
- io.status = [resp.code, resp.message]
- resp.each {|name,value| buf.io.meta_add_field name, value }
- case resp
- when Net::HTTPSuccess
- when Net::HTTPMovedPermanently, # 301
- Net::HTTPFound, # 302
- Net::HTTPSeeOther, # 303
- Net::HTTPTemporaryRedirect # 307
- throw :open_uri_redirect, URI.parse(resp['location'])
- else
- raise OpenURI::HTTPError.new(io.status.join(' '), io)
- end
- end
-
- class HTTPError < StandardError
- def initialize(message, io)
- super(message)
- @io = io
- end
- attr_reader :io
- end
-
- class Buffer # :nodoc:
- def initialize
- @io = StringIO.new
- @size = 0
- end
- attr_reader :size
-
- StringMax = 10240
- def <<(str)
- @io << str
- @size += str.length
- if StringIO === @io && StringMax < @size
- require 'tempfile'
- io = Tempfile.new('open-uri')
- io.binmode
- Meta.init io, @io if @io.respond_to? :meta
- io << @io.string
- @io = io
- end
- end
-
- def io
- Meta.init @io unless @io.respond_to? :meta
- @io
- end
- end
-
- # Mixin for holding meta-information.
- module Meta
- def Meta.init(obj, src=nil) # :nodoc:
- obj.extend Meta
- obj.instance_eval {
- @base_uri = nil
- @meta = {}
- }
- if src
- obj.status = src.status
- obj.base_uri = src.base_uri
- src.meta.each {|name, value|
- obj.meta_add_field(name, value)
- }
- end
- end
-
- # returns an Array which consists status code and message.
- attr_accessor :status
-
- # returns a URI which is base of relative URIs in the data.
- # It may differ from the URI supplied by a user because redirection.
- attr_accessor :base_uri
-
- # returns a Hash which represents header fields.
- # The Hash keys are downcased for canonicalization.
- attr_reader :meta
-
- def meta_add_field(name, value) # :nodoc:
- @meta[name.downcase] = value
- end
-
- # returns a Time which represents Last-Modified field.
- def last_modified
- if v = @meta['last-modified']
- Time.httpdate(v)
- else
- nil
- end
- end
-
- RE_LWS = /[\r\n\t ]+/n
- RE_TOKEN = %r{[^\x00- ()<>@,;:\\"/\[\]?={}\x7f]+}n
- RE_QUOTED_STRING = %r{"(?:[\r\n\t !#-\[\]-~\x80-\xff]|\\[\x00-\x7f])*"}n
- RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n
-
- def content_type_parse # :nodoc:
- v = @meta['content-type']
- # The last (?:;#{RE_LWS}?)? matches extra ";" which violates RFC2045.
- if v && %r{\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\z}no =~ v
- type = $1.downcase
- subtype = $2.downcase
- parameters = []
- $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|
- val = qval.gsub(/[\r\n\t !#-\[\]-~\x80-\xff]+|(\\[\x00-\x7f])/n) { $1 ? $1[1,1] : $& } if qval
- parameters << [att.downcase, val]
- }
- ["#{type}/#{subtype}", *parameters]
- else
- nil
- end
- end
-
- # returns "type/subtype" which is MIME Content-Type.
- # It is downcased for canonicalization.
- # Content-Type parameters are stripped.
- def content_type
- type, *parameters = content_type_parse
- type || 'application/octet-stream'
- end
-
- # returns a charset parameter in Content-Type field.
- # It is downcased for canonicalization.
- #
- # If charset parameter is not given but a block is given,
- # the block is called and its result is returned.
- # It can be used to guess charset.
- #
- # If charset parameter and block is not given,
- # nil is returned except text type in HTTP.
- # In that case, "iso-8859-1" is returned as defined by RFC2616 3.7.1.
- def charset
- type, *parameters = content_type_parse
- if pair = parameters.assoc('charset')
- pair.last.downcase
- elsif block_given?
- yield
- elsif type && %r{\Atext/} =~ type &&
- @base_uri && /\Ahttp\z/i =~ @base_uri.scheme
- "iso-8859-1" # RFC2616 3.7.1
- else
- nil
- end
- end
-
- # returns a list of encodings in Content-Encoding field
- # as an Array of String.
- # The encodings are downcased for canonicalization.
- def content_encoding
- v = @meta['content-encoding']
- if v && %r{\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v
- v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}
- else
- []
- end
- end
- end
-
- # Mixin for HTTP and FTP URIs.
- module OpenRead
- # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.
- #
- # OpenURI::OpenRead#open takes optional 3 arguments as:
- # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]
- #
- # `mode', `perm' is same as Kernel#open.
- #
- # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't
- # support write mode (yet).
- # Also `perm' is just ignored because it is meaningful only for file
- # creation.
- #
- # `options' must be a hash.
- #
- # Each pairs which key is a string in the hash specify a extra header
- # field for HTTP.
- # I.e. it is ignored for FTP without HTTP proxy.
- #
- # The hash may include other options which key is a symbol:
- #
- # [:proxy]
- # Synopsis:
- # :proxy => "http://proxy.foo.com:8000/"
- # :proxy => URI.parse("http://proxy.foo.com:8000/")
- # :proxy => true
- # :proxy => false
- # :proxy => nil
- #
- # If :proxy option is specified, the value should be String, URI,
- # boolean or nil.
- # When String or URI is given, it is treated as proxy URI.
- # When true is given or the option itself is not specified,
- # environment variable `scheme_proxy' is examined.
- # `scheme' is replaced by `http', `https' or `ftp'.
- # When false or nil is given, the environment variables are ignored and
- # connection will be made to a server directly.
- #
- # [:proxy_http_basic_authentication]
- # Synopsis:
- # :proxy_http_basic_authentication => ["http://proxy.foo.com:8000/", "proxy-user", "proxy-password"]
- # :proxy_http_basic_authentication => [URI.parse("http://proxy.foo.com:8000/"), "proxy-user", "proxy-password"]
- #
- # If :proxy option is specified, the value should be an Array with 3 elements.
- # It should contain a proxy URI, a proxy user name and a proxy password.
- # The proxy URI should be a String, an URI or nil.
- # The proxy user name and password should be a String.
- #
- # If nil is given for the proxy URI, this option is just ignored.
- #
- # If :proxy and :proxy_http_basic_authentication is specified,
- # ArgumentError is raised.
- #
- # [:http_basic_authentication]
- # Synopsis:
- # :http_basic_authentication=>[user, password]
- #
- # If :http_basic_authentication is specified,
- # the value should be an array which contains 2 strings:
- # username and password.
- # It is used for HTTP Basic authentication defined by RFC 2617.
- #
- # [:content_length_proc]
- # Synopsis:
- # :content_length_proc => lambda {|content_length| ... }
- #
- # If :content_length_proc option is specified, the option value procedure
- # is called before actual transfer is started.
- # It takes one argument which is expected content length in bytes.
- #
- # If two or more transfer is done by HTTP redirection, the procedure
- # is called only one for a last transfer.
- #
- # When expected content length is unknown, the procedure is called with
- # nil.
- # It is happen when HTTP response has no Content-Length header.
- #
- # [:progress_proc]
- # Synopsis:
- # :progress_proc => lambda {|size| ...}
- #
- # If :progress_proc option is specified, the proc is called with one
- # argument each time when `open' gets content fragment from network.
- # The argument `size' `size' is a accumulated transfered size in bytes.
- #
- # If two or more transfer is done by HTTP redirection, the procedure
- # is called only one for a last transfer.
- #
- # :progress_proc and :content_length_proc are intended to be used for
- # progress bar.
- # For example, it can be implemented as follows using Ruby/ProgressBar.
- #
- # pbar = nil
- # open("http://...",
- # :content_length_proc => lambda {|t|
- # if t && 0 < t
- # pbar = ProgressBar.new("...", t)
- # pbar.file_transfer_mode
- # end
- # },
- # :progress_proc => lambda {|s|
- # pbar.set s if pbar
- # }) {|f| ... }
- #
- # [:read_timeout]
- # Synopsis:
- # :read_timeout=>nil (no timeout)
- # :read_timeout=>10 (10 second)
- #
- # :read_timeout option specifies a timeout of read for http connections.
- #
- # [:ssl_ca_cert]
- # Synopsis:
- # :ssl_ca_cert=>filename
- #
- # :ssl_ca_cert is used to specify CA certificate for SSL.
- # If it is given, default certificates are not used.
- #
- # [:ssl_verify_mode]
- # Synopsis:
- # :ssl_verify_mode=>mode
- #
- # :ssl_verify_mode is used to specify openssl verify mode.
- #
- # OpenURI::OpenRead#open returns an IO like object if block is not given.
- # Otherwise it yields the IO object and return the value of the block.
- # The IO object is extended with OpenURI::Meta.
- def open(*rest, &block)
- OpenURI.open_uri(self, *rest, &block)
- end
-
- # OpenURI::OpenRead#read([options]) reads a content referenced by self and
- # returns the content as string.
- # The string is extended with OpenURI::Meta.
- # The argument `options' is same as OpenURI::OpenRead#open.
- def read(options={})
- self.open(options) {|f|
- str = f.read
- Meta.init str, f
- str
- }
- end
- end
-end
-
-module URI
- class Generic
- # returns a proxy URI.
- # The proxy URI is obtained from environment variables such as http_proxy,
- # ftp_proxy, no_proxy, etc.
- # If there is no proper proxy, nil is returned.
- #
- # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)
- # are examined too.
- #
- # But http_proxy and HTTP_PROXY is treated specially under CGI environment.
- # It's because HTTP_PROXY may be set by Proxy: header.
- # So HTTP_PROXY is not used.
- # http_proxy is not used too if the variable is case insensitive.
- # CGI_HTTP_PROXY can be used instead.
- def find_proxy
- name = self.scheme.downcase + '_proxy'
- proxy_uri = nil
- if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
- # HTTP_PROXY conflicts with *_proxy for proxy settings and
- # HTTP_* for header information in CGI.
- # So it should be careful to use it.
- pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
- case pairs.length
- when 0 # no proxy setting anyway.
- proxy_uri = nil
- when 1
- k, v = pairs.shift
- if k == 'http_proxy' && ENV[k.upcase] == nil
- # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = ENV[name]
- else
- proxy_uri = nil
- end
- else # http_proxy is safe to use because ENV is case sensitive.
- proxy_uri = ENV[name]
- end
- if !proxy_uri
- # Use CGI_HTTP_PROXY. cf. libwww-perl.
- proxy_uri = ENV["CGI_#{name.upcase}"]
- end
- elsif name == 'http_proxy'
- unless proxy_uri = ENV[name]
- if proxy_uri = ENV[name.upcase]
- warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
- end
- end
- else
- proxy_uri = ENV[name] || ENV[name.upcase]
- end
-
- if proxy_uri && self.host
- require 'socket'
- begin
- addr = IPSocket.getaddress(self.host)
- proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
- rescue SocketError
- end
- end
-
- if proxy_uri
- proxy_uri = URI.parse(proxy_uri)
- name = 'no_proxy'
- if no_proxy = ENV[name] || ENV[name.upcase]
- no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
- if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
- (!port || self.port == port.to_i)
- proxy_uri = nil
- break
- end
- }
- end
- proxy_uri
- else
- nil
- end
- end
- end
-
- class HTTP
- def buffer_open(buf, proxy, options) # :nodoc:
- OpenURI.open_http(buf, self, proxy, options)
- end
-
- include OpenURI::OpenRead
- end
-
- class FTP
- def buffer_open(buf, proxy, options) # :nodoc:
- if proxy
- OpenURI.open_http(buf, self, proxy, options)
- return
- end
- require 'net/ftp'
-
- directories = self.path.split(%r{/}, -1)
- directories.shift if directories[0] == '' # strip a field before leading slash
- directories.each {|d|
- d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
- }
- unless filename = directories.pop
- raise ArgumentError, "no filename: #{self.inspect}"
- end
- directories.each {|d|
- if /[\r\n]/ =~ d
- raise ArgumentError, "invalid directory: #{d.inspect}"
- end
- }
- if /[\r\n]/ =~ filename
- raise ArgumentError, "invalid filename: #{filename.inspect}"
- end
- typecode = self.typecode
- if typecode && /\A[aid]\z/ !~ typecode
- raise ArgumentError, "invalid typecode: #{typecode.inspect}"
- end
-
- # The access sequence is defined by RFC 1738
- ftp = Net::FTP.open(self.host)
- # todo: extract user/passwd from .netrc.
- user = 'anonymous'
- passwd = nil
- user, passwd = self.userinfo.split(/:/) if self.userinfo
- ftp.login(user, passwd)
- directories.each {|cwd|
- ftp.voidcmd("CWD #{cwd}")
- }
- if typecode
- # xxx: typecode D is not handled.
- ftp.voidcmd("TYPE #{typecode.upcase}")
- end
- if options[:content_length_proc]
- options[:content_length_proc].call(ftp.size(filename))
- end
- ftp.retrbinary("RETR #{filename}", 4096) { |str|
- buf << str
- options[:progress_proc].call(buf.size) if options[:progress_proc]
- }
- ftp.close
- buf.io.rewind
- end
-
- include OpenURI::OpenRead
- end
-end
-# :startdoc:
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index f49ee2f4a1..96775c4d00 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -236,11 +236,13 @@ class Gem::RemoteFetcher
request.add_field 'Keep-Alive', '30'
# HACK work around EOFError bug in Net::HTTP
+ # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
+ # to install gems.
retried = false
begin
@requests[connection_id] += 1
response = connection.request(request)
- rescue EOFError
+ rescue EOFError, Errno::ECONNABORTED
requests = @requests[connection_id]
say "connection reset after #{requests} requests, retrying" if
Gem.configuration.really_verbose
diff --git a/lib/rubygems/rubygems_version.rb b/lib/rubygems/rubygems_version.rb
index cc7269d622..453f9b57b6 100644
--- a/lib/rubygems/rubygems_version.rb
+++ b/lib/rubygems/rubygems_version.rb
@@ -2,5 +2,5 @@
# This file is auto-generated by build scripts.
# See: rake update_version
module Gem
- RubyGemsVersion = '1.1.0'
+ RubyGemsVersion = '1.1.1'
end
diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb
index dab449894f..e2e10a0ad9 100644
--- a/lib/rubygems/server.rb
+++ b/lib/rubygems/server.rb
@@ -29,7 +29,7 @@ class Gem::Server
DOC_TEMPLATE = <<-'WEBPAGE'
<?xml version="1.0" encoding="iso-8859-1"?>
- <!DOCTYPE html
+ <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -51,7 +51,7 @@ class Gem::Server
<h1>Summary</h1>
<p>There are <%=values["gem_count"]%> gems installed:</p>
<p>
- <%= values["specs"].map { |v| "<a href=\"#{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
+ <%= values["specs"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
<h1>Gems</h1>
<dl>
@@ -77,7 +77,7 @@ class Gem::Server
<% if spec["has_deps"] then %>
- depends on
- <%= spec["dependencies"].map { |v| "<a href=\"#{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
+ <%= spec["dependencies"].map { |v| "<a href=\"##{v["name"]}\">#{v["name"]}</a>" }.join ', ' %>.
<% end %>
</dt>
<dd>
@@ -91,8 +91,8 @@ class Gem::Server
Executables are
<%end%>
- <%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
-
+ <%= spec["executables"].map { |v| "<span class=\"context-item-name\">#{v["executable"]}</span>"}.join ', ' %>.
+
<%end%>
<br/>
<br/>
diff --git a/lib/rubygems/source_index.rb b/lib/rubygems/source_index.rb
index 61f5324a95..8057fd1d0f 100644
--- a/lib/rubygems/source_index.rb
+++ b/lib/rubygems/source_index.rb
@@ -25,6 +25,8 @@ class Gem::SourceIndex
include Gem::UserInteraction
+ attr_reader :gems # :nodoc:
+
class << self
include Gem::UserInteraction
@@ -50,14 +52,10 @@ class Gem::SourceIndex
end
##
- # Return a list of directories in the current gem path that
- # contain specifications.
- #
- # return::
- # List of directory paths (all ending in "../specifications").
+ # Returns a list of directories from Gem.path that contain specifications.
def installed_spec_directories
- Gem.path.collect { |dir| File.join(dir, "specifications") }
+ Gem.path.collect { |dir| File.join(dir, "specifications") }
end
##
@@ -272,12 +270,11 @@ class Gem::SourceIndex
end
##
- # Refresh the source index from the local file system.
- #
- # return:: Returns a pointer to itself.
+ # Replaces the gems in the source index from specifications in the
+ # installed_spec_directories,
def refresh!
- load_gems_in(self.class.installed_spec_directories)
+ load_gems_in(*self.class.installed_spec_directories)
end
##
@@ -347,10 +344,6 @@ class Gem::SourceIndex
Marshal.dump(self)
end
- protected
-
- attr_reader :gems
-
private
def fetcher
@@ -430,15 +423,22 @@ class Gem::SourceIndex
# Make a list of full names for all the missing gemspecs.
def find_missing(spec_names)
+ unless defined? @originals then
+ @originals = {}
+ each do |full_name, spec|
+ @originals[spec.original_name] = spec
+ end
+ end
+
spec_names.find_all { |full_name|
- specification(full_name).nil?
+ @originals[full_name].nil?
}
end
def remove_extra(spec_names)
dictionary = spec_names.inject({}) { |h, k| h[k] = true; h }
each do |name, spec|
- remove_spec name unless dictionary.include? name
+ remove_spec name unless dictionary.include? spec.original_name
end
end
diff --git a/lib/rubygems/source_info_cache.rb b/lib/rubygems/source_info_cache.rb
index 9383f6362e..4d69d88c89 100644
--- a/lib/rubygems/source_info_cache.rb
+++ b/lib/rubygems/source_info_cache.rb
@@ -22,8 +22,8 @@ require 'rubygems/user_interaction'
# Gem::SourceInfoCache
# @cache_data = {
# source_uri => Gem::SourceInfoCacheEntry
-# @size => source index size
-# @source_index => Gem::SourceIndex
+# @size = source index size
+# @source_index = Gem::SourceIndex
# ...
# }
@@ -31,14 +31,14 @@ class Gem::SourceInfoCache
include Gem::UserInteraction
- @cache = nil
- @system_cache_file = nil
- @user_cache_file = nil
+ ##
+ # The singleton Gem::SourceInfoCache. If +all+ is true, a full refresh will
+ # be performed if the singleton instance is being initialized.
- def self.cache
+ def self.cache(all = false)
return @cache if @cache
@cache = new
- @cache.refresh false if Gem.configuration.update_sources
+ @cache.refresh all if Gem.configuration.update_sources
@cache
end
@@ -63,6 +63,15 @@ class Gem::SourceInfoCache
end
##
+ # Reset all singletons, discarding any changes.
+
+ def self.reset
+ @cache = nil
+ @system_cache_file = nil
+ @user_cache_file = nil
+ end
+
+ ##
# Search all source indexes. See Gem::SourceInfoCache#search.
def self.search(*args)
@@ -122,13 +131,6 @@ class Gem::SourceInfoCache
try_file(user_cache_file) or
raise "unable to locate a writable cache file")
end
-
- ##
- # Force cache file to be reset, useful for integration testing of rubygems
-
- def reset_cache_file
- @cache_file = nil
- end
##
# Write the cache to a local file (if it is dirty).
@@ -175,13 +177,30 @@ class Gem::SourceInfoCache
self.class.latest_user_cache_file
end
+ ##
+ # Merges the complete cache file into this Gem::SourceInfoCache.
+
def read_all_cache_data
if @only_latest then
@only_latest = false
- @cache_data = read_cache_data cache_file
+ all_data = read_cache_data cache_file
+
+ cache_data.update all_data do |source_uri, latest_sice, all_sice|
+ all_sice.source_index.gems.update latest_sice.source_index.gems
+
+ Gem::SourceInfoCacheEntry.new all_sice.source_index, latest_sice.size
+ end
+
+ begin
+ refresh true
+ rescue Gem::RemoteFetcher::FetchError
+ end
end
end
+ ##
+ # Reads cached data from +file+.
+
def read_cache_data(file)
# Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
data = open file, 'rb' do |fp| fp.read end
@@ -203,6 +222,8 @@ class Gem::SourceInfoCache
end
cache_data
+ rescue Errno::ENOENT
+ {}
rescue => e
if Gem.configuration.really_verbose then
say "Exception during cache_data handling: #{e.class} - #{e}"
@@ -243,6 +264,14 @@ class Gem::SourceInfoCache
def reset_cache_data
@cache_data = nil
+ @only_latest = true
+ end
+
+ ##
+ # Force cache file to be reset, useful for integration testing of rubygems
+
+ def reset_cache_file
+ @cache_file = nil
end
##
@@ -315,10 +344,7 @@ class Gem::SourceInfoCache
end
end
- if File.writable? dir then
- open path, "wb" do |io| io.write Marshal.dump({}) end
- return path
- end
+ return path if File.writable? dir
nil
end
@@ -338,11 +364,13 @@ class Gem::SourceInfoCache
end
##
- # Write data to the proper cache.
+ # Write data to the proper cache files.
def write_cache
- open cache_file, 'wb' do |io|
- io.write Marshal.dump(cache_data)
+ if not File.exist?(cache_file) or not @only_latest then
+ open cache_file, 'wb' do |io|
+ io.write Marshal.dump(cache_data)
+ end
end
open latest_cache_file, 'wb' do |io|
@@ -350,5 +378,7 @@ class Gem::SourceInfoCache
end
end
+ reset
+
end
diff --git a/lib/rubygems/version_option.rb b/lib/rubygems/version_option.rb
index 54f85188df..1374018913 100644
--- a/lib/rubygems/version_option.rb
+++ b/lib/rubygems/version_option.rb
@@ -23,8 +23,7 @@ module Gem::VersionOption
"Specify the platform of gem to #{task}", *wrap) do
|value, options|
unless options[:added_platform] then
- Gem.platforms.clear
- Gem.platforms << Gem::Platform::RUBY
+ Gem.platforms = [Gem::Platform::RUBY]
options[:added_platform] = true
end