diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-02-06 02:59:36 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-02-06 02:59:36 +0000 |
commit | 9b9d3bac4d5fb0d0287b898885a2e6f1125f807c (patch) | |
tree | aad6503711a1179f86564e8303a34af258e8c975 /lib | |
parent | 39cb7840950e87a4a77f066fd07dac6bb2e0b41c (diff) |
* lib/rubygems: RubyGems 2.2.2 which contains the following bug fixes:
http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.2.2+%2F+2014-02-05
https://bugs.ruby-lang.org/issues/9489
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@44858 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
37 files changed, 302 insertions, 170 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 73c4846f82..456273ed19 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.2.0' + VERSION = '2.2.2' end # Must be first since it unloads the prelude from 1.9.2 @@ -572,7 +572,7 @@ module Gem # gem's paths are inserted before site lib directory by default. def self.load_path_insert_index - index = $LOAD_PATH.index ConfigMap[:sitelibdir] + index = $LOAD_PATH.index RbConfig::CONFIG['sitelibdir'] index end @@ -743,8 +743,8 @@ module Gem def self.prefix prefix = File.dirname RUBYGEMS_DIR - if prefix != File.expand_path(ConfigMap[:sitelibdir]) and - prefix != File.expand_path(ConfigMap[:libdir]) and + if prefix != File.expand_path(RbConfig::CONFIG['sitelibdir']) and + prefix != File.expand_path(RbConfig::CONFIG['libdir']) and 'lib' == File.basename(RUBYGEMS_DIR) then prefix end @@ -765,6 +765,10 @@ module Gem f.flock(File::LOCK_EX) f.read end + rescue Errno::EACCES + open path, 'rb' do |f| + f.read + end end ## @@ -772,8 +776,8 @@ module Gem def self.ruby if @ruby.nil? then - @ruby = File.join(ConfigMap[:bindir], - "#{ConfigMap[:ruby_install_name]}#{ConfigMap[:EXEEXT]}") + @ruby = File.join(RbConfig::CONFIG['bindir'], + "#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}") @ruby = "\"#{@ruby}\"" if @ruby =~ /\s/ end @@ -785,8 +789,7 @@ module Gem # Returns a String containing the API compatibility version of Ruby def self.ruby_api_version - @ruby_api_version ||= - "#{ConfigMap[:MAJOR]}.#{ConfigMap[:MINOR]}.#{ConfigMap[:TEENY]}" + @ruby_api_version ||= RbConfig::CONFIG['ruby_version'].dup end ## diff --git a/lib/rubygems/available_set.rb b/lib/rubygems/available_set.rb index d8655afc34..fabdd6e79d 100644 --- a/lib/rubygems/available_set.rb +++ b/lib/rubygems/available_set.rb @@ -4,9 +4,12 @@ class Gem::AvailableSet Tuple = Struct.new(:spec, :source) + attr_accessor :remote # :nodoc: + def initialize @set = [] @sorted = nil + @remote = true end attr_reader :set diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index a52377ff22..470a6ebc8b 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -207,6 +207,24 @@ class Gem::BasicSpecification end ## + # Returns the paths to the source files for use with analysis and + # documentation tools. These paths are relative to full_gem_path. + + def source_paths + paths = raw_require_paths.dup + + if @extensions then + ext_dirs = @extensions.map do |extension| + extension.split(File::SEPARATOR, 2).first + end.uniq + + paths.concat ext_dirs + end + + paths.uniq + end + + ## # Return a Gem::Specification from this gem def to_spec diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb index 97218848ed..603f1d072a 100644 --- a/lib/rubygems/commands/contents_command.rb +++ b/lib/rubygems/commands/contents_command.rb @@ -94,11 +94,11 @@ prefix or only the files that are requireable. spec.files.sort.map do |file| case file when /\A#{spec.bindir}\// - [Gem::ConfigMap[:bindir], $POSTMATCH] + [RbConfig::CONFIG['bindir'], $POSTMATCH] when /\.so\z/ - [Gem::ConfigMap[:archdir], file] + [RbConfig::CONFIG['archdir'], file] else - [Gem::ConfigMap[:rubylibdir], file] + [RbConfig::CONFIG['rubylibdir'], file] end end end diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb index a7db013caf..ca6f694bc5 100644 --- a/lib/rubygems/commands/generate_index_command.rb +++ b/lib/rubygems/commands/generate_index_command.rb @@ -62,7 +62,7 @@ Marshal::MINOR_VERSION constants. It is used to ensure compatibility. end def execute - # This is always true becasue it's the only way now. + # This is always true because it's the only way now. options[:build_modern] = true if not File.exist?(options[:directory]) or diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index 4485eb12e8..8219eef6ea 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -228,7 +228,18 @@ to write the specification by hand. For example: def install_gem_without_dependencies name, req # :nodoc: gem = nil - if remote? then + if local? then + if name =~ /\.gem$/ and File.file? name then + source = Gem::Source::SpecificFile.new name + spec = source.spec + else + source = Gem::Source::Local.new + spec = source.find_gem name, req + end + gem = source.download spec if spec + end + + if remote? and not gem then dependency = Gem::Dependency.new name, req dependency.prerelease = options[:prerelease] @@ -236,13 +247,6 @@ to write the specification by hand. For example: gem = fetcher.download_to_cache dependency end - if local? and not gem then - source = Gem::Source::Local.new - spec = source.find_gem name, req - - gem = source.download spec - end - inst = Gem::Installer.new gem, options inst.install diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index face77fae9..681db0dc1d 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -13,7 +13,7 @@ class Gem::Commands::SetupCommand < Gem::Command super 'setup', 'Install RubyGems', :format_executable => true, :document => %w[ri], - :site_or_vendor => :sitelibdir, + :site_or_vendor => 'sitelibdir', :destdir => '', :prefix => '', :previous_version => '' add_option '--previous-version=VERSION', @@ -36,7 +36,7 @@ class Gem::Commands::SetupCommand < Gem::Command add_option '--[no-]vendor', 'Install into vendorlibdir not sitelibdir' do |vendor, options| - options[:site_or_vendor] = vendor ? :vendorlibdir : :sitelibdir + options[:site_or_vendor] = vendor ? 'vendorlibdir' : 'sitelibdir' end add_option '--[no-]format-executable', @@ -343,19 +343,19 @@ TEXT site_or_vendor = options[:site_or_vendor] if prefix.empty? then - lib_dir = Gem::ConfigMap[site_or_vendor] - bin_dir = Gem::ConfigMap[:bindir] + lib_dir = RbConfig::CONFIG[site_or_vendor] + bin_dir = RbConfig::CONFIG['bindir'] else # Apple installed RubyGems into libdir, and RubyGems <= 1.1.0 gets # confused about installation location, so switch back to # sitelibdir/vendorlibdir. if defined?(APPLE_GEM_HOME) and # just in case Apple and RubyGems don't get this patched up proper. - (prefix == Gem::ConfigMap[:libdir] or + (prefix == RbConfig::CONFIG['libdir'] or # this one is important - prefix == File.join(Gem::ConfigMap[:libdir], 'ruby')) then - lib_dir = Gem::ConfigMap[site_or_vendor] - bin_dir = Gem::ConfigMap[:bindir] + prefix == File.join(RbConfig::CONFIG['libdir'], 'ruby')) then + lib_dir = RbConfig::CONFIG[site_or_vendor] + bin_dir = RbConfig::CONFIG['bindir'] else lib_dir = File.join prefix, 'lib' bin_dir = File.join prefix, 'bin' diff --git a/lib/rubygems/compatibility.rb b/lib/rubygems/compatibility.rb index 5e8618fe39..d06ade1fa6 100644 --- a/lib/rubygems/compatibility.rb +++ b/lib/rubygems/compatibility.rb @@ -33,6 +33,8 @@ end module Gem RubyGemsVersion = VERSION + # TODO remove at RubyGems 3 + RbConfigPriorities = %w[ MAJOR MINOR @@ -45,7 +47,7 @@ module Gem unless defined?(ConfigMap) ## # Configuration settings from ::RbConfig - ConfigMap = Hash.new do |cm, key| + ConfigMap = Hash.new do |cm, key| # TODO remove at RubyGems 3 cm[key] = RbConfig::CONFIG[key.to_s] end else diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 1acae9b529..cf14017ea2 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -137,9 +137,10 @@ class Gem::ConfigFile attr_reader :ssl_verify_mode ## - # Path name of directory or file of openssl CA certificate, used for remote https connection + # Path name of directory or file of openssl CA certificate, used for remote + # https connection - attr_reader :ssl_ca_cert + attr_accessor :ssl_ca_cert ## # Path name of directory or file of openssl client certificate, used for remote https connection with client authentication diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 715c0b71b3..6924f48e5a 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -29,22 +29,22 @@ module Gem def self.default_dir path = if defined? RUBY_FRAMEWORK_VERSION then [ - File.dirname(ConfigMap[:sitedir]), + File.dirname(RbConfig::CONFIG['sitedir']), 'Gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] - elsif ConfigMap[:rubylibprefix] then + elsif RbConfig::CONFIG['rubylibprefix'] then [ - ConfigMap[:rubylibprefix], + RbConfig::CONFIG['rubylibprefix'], 'gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] else [ - ConfigMap[:libdir], + RbConfig::CONFIG['libdir'], ruby_engine, 'gems', - ConfigMap[:ruby_version] + RbConfig::CONFIG['ruby_version'] ] end @@ -74,7 +74,7 @@ module Gem def self.user_dir parts = [Gem.user_home, '.gem', ruby_engine] - parts << ConfigMap[:ruby_version] unless ConfigMap[:ruby_version].empty? + parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? File.join parts end @@ -100,7 +100,7 @@ module Gem # Deduce Ruby's --program-prefix and --program-suffix from its install name def self.default_exec_format - exec_format = ConfigMap[:ruby_install_name].sub('ruby', '%s') rescue '%s' + exec_format = RbConfig::CONFIG['ruby_install_name'].sub('ruby', '%s') rescue '%s' unless exec_format =~ /%s/ then raise Gem::Exception, @@ -117,7 +117,7 @@ module Gem if defined? RUBY_FRAMEWORK_VERSION then # mac framework support '/usr/bin' else # generic install - ConfigMap[:bindir] + RbConfig::CONFIG['bindir'] end end diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index b7babf6d38..da6994a9be 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -419,6 +419,7 @@ class Gem::DependencyInstaller request_set = as.to_request_set install_development_deps request_set.soft_missing = @force + request_set.remote = false unless consider_remote? installer_set = Gem::Resolver::InstallerSet.new @domain installer_set.always_install.concat request_set.always_install diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb index 274d6a5c12..e19360da13 100644 --- a/lib/rubygems/deprecate.rb +++ b/lib/rubygems/deprecate.rb @@ -50,7 +50,7 @@ module Gem::Deprecate class_eval { old = "_deprecated_#{name}" alias_method old, name - define_method name do |*args, &block| # TODO: really works on 1.8.7? + define_method name do |*args, &block| klass = self.kind_of? Module target = klass ? "#{self}." : "#{self.class}#" msg = [ "NOTE: #{target}#{name} is deprecated", diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index 402aa966c0..990fd18524 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -34,7 +34,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder ENV["RUBYOPT"] = ["-r#{siteconf_path}", rubyopt].compact.join(' ') cmd = [Gem.ruby, File.basename(extension), *args].join ' ' - run cmd, results + begin + run cmd, results + ensure + FileUtils.mv 'mkmf.log', dest_path if File.exist? 'mkmf.log' + end ENV["DESTDIR"] = nil ENV["RUBYOPT"] = rubyopt diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index f8eb2c2145..c80981682f 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -480,7 +480,7 @@ class Gem::Installer # def shebang(bin_file_name) - ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang + ruby_name = RbConfig::CONFIG['ruby_install_name'] if @env_shebang path = File.join gem_dir, spec.bindir, bin_file_name first_line = File.open(path, "rb") {|file| file.gets} @@ -493,7 +493,7 @@ class Gem::Installer if which = Gem.configuration[:custom_shebang] # replace bin_file_name with "ruby" to avoid endless loops - which = which.gsub(/ #{bin_file_name}$/," #{Gem::ConfigMap[:ruby_install_name]}") + which = which.gsub(/ #{bin_file_name}$/," #{RbConfig::CONFIG['ruby_install_name']}") which = which.gsub(/\$(\w+)/) do case $1 @@ -641,7 +641,7 @@ version = "#{Gem::Requirement.default}" if ARGV.first str = ARGV.first str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding - if str =~ /\\A_(.*)_\\z/ + if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then version = $1 ARGV.shift end diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb index 28da1db0b5..f9ab13aca7 100644 --- a/lib/rubygems/package/tar_header.rb +++ b/lib/rubygems/package/tar_header.rb @@ -134,7 +134,7 @@ class Gem::Package::TarHeader vals[:gid] ||= 0 vals[:mtime] ||= 0 vals[:checksum] ||= "" - vals[:typeflag] ||= "0" + vals[:typeflag] = "0" if vals[:typeflag].nil? || vals[:typeflag].empty? vals[:magic] ||= "ustar" vals[:version] ||= "00" vals[:uname] ||= "wheel" diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index e050959dc6..1bcd7549ad 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -16,7 +16,7 @@ class Gem::Platform attr_accessor :version def self.local - arch = Gem::ConfigMap[:arch] + arch = RbConfig::CONFIG['arch'] arch = "#{arch}_60" if arch =~ /mswin32$/ @local ||= new(arch) end diff --git a/lib/rubygems/rdoc.rb b/lib/rubygems/rdoc.rb index 52249dc267..633bd893a5 100644 --- a/lib/rubygems/rdoc.rb +++ b/lib/rubygems/rdoc.rb @@ -193,7 +193,7 @@ class Gem::RDoc # :nodoc: all ::RDoc::Parser::C.reset args = @spec.rdoc_options - args.concat @spec.require_paths + args.concat @spec.source_paths args.concat @spec.extra_rdoc_files case config_args = Gem.configuration[:rdoc] diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index e32c024989..58991caeda 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -131,11 +131,19 @@ class Gem::RemoteFetcher FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir - # Always escape URI's to deal with potential spaces and such - unless URI::Generic === source_uri - source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? - URI::DEFAULT_PARSER.escape(source_uri.to_s) : - URI.escape(source_uri.to_s)) + # Always escape URI's to deal with potential spaces and such + # It should also be considered that source_uri may already be + # a valid URI with escaped characters. e.g. "{DESede}" is encoded + # as "%7BDESede%7D". If this is escaped again the percentage + # symbols will be escaped. + unless source_uri.is_a?(URI::Generic) + begin + source_uri = URI.parse(source_uri) + rescue + source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? + URI::DEFAULT_PARSER.escape(source_uri.to_s) : + URI.escape(source_uri.to_s)) + end end scheme = source_uri.scheme @@ -285,20 +293,20 @@ class Gem::RemoteFetcher def cache_update_path uri, path = nil, update = true mtime = path && File.stat(path).mtime rescue nil - if mtime && Net::HTTPNotModified === fetch_path(uri, mtime, true) - Gem.read_binary(path) - else - data = fetch_path(uri) + data = fetch_path(uri, mtime) - if update and path then - open(path, 'wb') do |io| - io.flock(File::LOCK_EX) - io.write data - end - end + if data == nil # indicates the server returned 304 Not Modified + return Gem.read_binary(path) + end - data + if update and path + open(path, 'wb') do |io| + io.flock(File::LOCK_EX) + io.write data + end end + + data end ## diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index e8707630c5..d2f076f581 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -48,15 +48,14 @@ class Gem::Request connection.key = OpenSSL::PKey::RSA.new pem end + store.set_default_paths + add_rubygems_trusted_certs(store) if Gem.configuration.ssl_ca_cert if File.directory? Gem.configuration.ssl_ca_cert store.add_path Gem.configuration.ssl_ca_cert else store.add_file Gem.configuration.ssl_ca_cert end - else - store.set_default_paths - add_rubygems_trusted_certs(store) end connection.cert_store = store rescue LoadError => e @@ -106,7 +105,8 @@ class Gem::Request request = @request_class.new @uri.request_uri unless @uri.nil? || @uri.user.nil? || @uri.user.empty? then - request.basic_auth @uri.user, @uri.password + request.basic_auth Gem::UriFormatter.new(@uri.user).unescape, + Gem::UriFormatter.new(@uri.password).unescape end request.add_field 'User-Agent', @user_agent diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb index aa3f27c9c1..fb54e344bd 100644 --- a/lib/rubygems/request_set.rb +++ b/lib/rubygems/request_set.rb @@ -39,6 +39,11 @@ class Gem::RequestSet attr_accessor :ignore_dependencies ## + # When false no remote sets are used for resolving gems. + + attr_accessor :remote + + ## # Sets used for resolution attr_reader :sets # :nodoc: @@ -71,6 +76,7 @@ class Gem::RequestSet @git_set = nil @ignore_dependencies = false @install_dir = Gem.dir + @remote = true @requests = [] @sets = [] @soft_missing = false @@ -150,6 +156,7 @@ class Gem::RequestSet gemdeps = options[:gemdeps] @install_dir = options[:install_dir] || Gem.dir + @remote = options[:domain] != :local load_gemdeps gemdeps, options[:without_groups] @@ -235,6 +242,7 @@ class Gem::RequestSet @sets << @vendor_set set = Gem::Resolver.compose_sets(*@sets) + set.remote = @remote resolver = Gem::Resolver.new @dependencies, set resolver.development = @development diff --git a/lib/rubygems/request_set/lockfile.rb b/lib/rubygems/request_set/lockfile.rb index 522caf1502..0433d2a7fc 100644 --- a/lib/rubygems/request_set/lockfile.rb +++ b/lib/rubygems/request_set/lockfile.rb @@ -303,7 +303,12 @@ class Gem::RequestSet::Lockfile type, data, = get [:text, :requirement] if type == :text and column == 4 then - last_spec = set.add name, data, Gem::Platform::RUBY + version, platform = data.split '-', 2 + + platform = + platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY + + last_spec = set.add name, version, platform else dependency = parse_dependency name, data diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb index d455e03c05..65e92bbf29 100644 --- a/lib/rubygems/resolver.rb +++ b/lib/rubygems/resolver.rb @@ -59,6 +59,8 @@ class Gem::Resolver sets = sets.map do |set| case set + when Gem::Resolver::BestSet then + set when Gem::Resolver::ComposedSet then set.sets else @@ -179,27 +181,6 @@ class Gem::Resolver end ## - # Finds the State in +states+ that matches the +conflict+ so that we can try - # other possible sets. - # - # If no good candidate is found, the first state is tried. - - def find_conflict_state conflict, states # :nodoc: - until states.empty? do - state = states.pop - - explain :consider, state.dep, conflict.failed_dep - - if conflict.for_spec? state.spec - state.conflicts << [state.spec, conflict] - return state - end - end - - nil - end - - ## # Extracts the specifications that may be able to fulfill +dependency+ and # returns those that match the local platform and all those that match. diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb index 89ee3c9b15..5475e626e6 100644 --- a/lib/rubygems/resolver/api_set.rb +++ b/lib/rubygems/resolver/api_set.rb @@ -25,10 +25,12 @@ class Gem::Resolver::APISet < Gem::Resolver::Set # http://guides.rubygems.org/rubygems-org-api def initialize dep_uri = 'https://rubygems.org/api/v1/dependencies' + super() + dep_uri = URI dep_uri unless URI === dep_uri # for ruby 1.8 @dep_uri = dep_uri - @uri = dep_uri + '../../..' + @uri = dep_uri + '../..' @data = Hash.new { |h,k| h[k] = [] } @source = Gem::Source.new @uri @@ -41,6 +43,8 @@ class Gem::Resolver::APISet < Gem::Resolver::Set def find_all req res = [] + return res unless @remote + versions(req.name).each do |ver| if req.dependency.match? req.name, ver[:number] res << Gem::Resolver::APISpecification.new(self, ver) @@ -55,6 +59,7 @@ class Gem::Resolver::APISet < Gem::Resolver::Set # data for DependencyRequests +reqs+. def prefetch reqs + return unless @remote names = reqs.map { |r| r.dependency.name } needed = names - @data.keys diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb index fa6c9f84c0..20bb94827b 100644 --- a/lib/rubygems/resolver/best_set.rb +++ b/lib/rubygems/resolver/best_set.rb @@ -12,11 +12,30 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet def initialize sources = Gem.sources super() - sources.each_source do |source| + @sources = sources + end + + ## + # Picks which sets to use for the configured sources. + + def pick_sets # :nodoc: + @sources.each_source do |source| @sets << source.dependency_resolver_set end end + def find_all req # :nodoc: + pick_sets if @remote and @sets.empty? + + super + end + + def prefetch reqs # :nodoc: + pick_sets if @remote and @sets.empty? + + super + end + def pretty_print q # :nodoc: q.group 2, '[BestSet', ']' do q.breakable diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb index 19227e095b..6f912b0afe 100644 --- a/lib/rubygems/resolver/composed_set.rb +++ b/lib/rubygems/resolver/composed_set.rb @@ -16,10 +16,21 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set # Gem::Resolver::compose_sets instead. def initialize *sets + super() + @sets = sets end ## + # Sets the remote network access for all composed sets. + + def remote= remote + super + + @sets.each { |set| set.remote = remote } + end + + ## # Finds all specs matching +req+ in all sets. def find_all req diff --git a/lib/rubygems/resolver/git_set.rb b/lib/rubygems/resolver/git_set.rb index 1a2b230b80..d32710e3d6 100644 --- a/lib/rubygems/resolver/git_set.rb +++ b/lib/rubygems/resolver/git_set.rb @@ -33,6 +33,8 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set attr_reader :specs # :nodoc: def initialize # :nodoc: + super() + @git = ENV['git'] || 'git' @need_submodules = {} @repositories = {} @@ -91,6 +93,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set @repositories.each do |name, (repository, reference)| source = Gem::Source::Git.new name, repository, reference source.root_dir = @root_dir + source.remote = @remote source.specs.each do |spec| git_spec = Gem::Resolver::GitSpecification.new self, spec, source diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb index a6ef56bb7f..ef01f0f0ad 100644 --- a/lib/rubygems/resolver/index_set.rb +++ b/lib/rubygems/resolver/index_set.rb @@ -5,6 +5,8 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set def initialize source = nil # :nodoc: + super() + @f = if source then sources = Gem::SourceList.from [source] @@ -34,6 +36,8 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set def find_all req res = [] + return res unless @remote + name = req.dependency.name @all[name].each do |uri, n| diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb index e35e0aabec..045c893fdc 100644 --- a/lib/rubygems/resolver/installer_set.rb +++ b/lib/rubygems/resolver/installer_set.rb @@ -24,15 +24,17 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set # Creates a new InstallerSet that will look for gems in +domain+. def initialize domain + super() + @domain = domain + @remote = consider_remote? @f = Gem::SpecFetcher.fetcher - @all = Hash.new { |h,k| h[k] = [] } @always_install = [] @ignore_dependencies = false @ignore_installed = false - @loaded_remote_specs = [] + @remote_set = Gem::Resolver::BestSet.new @specs = {} end @@ -79,16 +81,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end end - if consider_remote? then - load_remote_specs dep - - @all[name].each do |remote_source, n| - if dep.match? n then - res << Gem::Resolver::IndexSpecification.new( - self, n.name, n.version, remote_source, n.platform) - end - end - end + res.concat @remote_set.find_all req if consider_remote? res end @@ -102,27 +95,6 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end ## - # Loads remote prerelease specs if +dep+ is a prerelease dependency - - def load_remote_specs dep # :nodoc: - types = [:released] - types << :prerelease if dep.prerelease? - - types.each do |type| - next if @loaded_remote_specs.include? type - @loaded_remote_specs << type - - list, = @f.available_specs type - - list.each do |uri, specs| - specs.each do |n| - @all[n.name] << [uri, n] - end - end - end - end - - ## # Called from IndexSpecification to get a true Specification # object. @@ -151,5 +123,16 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end end + def remote= remote # :nodoc: + case @domain + when :local then + @domain = :both if remote + when :remote then + @domain = nil unless remote + when :both then + @domain = :local unless remote + end + end + end diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb index cdb41b22bf..f4987576ec 100644 --- a/lib/rubygems/resolver/lock_set.rb +++ b/lib/rubygems/resolver/lock_set.rb @@ -9,6 +9,8 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set # Creates a new LockSet from the given +source+ def initialize source + super() + @source = Gem::Source::Lock.new source @specs = [] end diff --git a/lib/rubygems/resolver/set.rb b/lib/rubygems/resolver/set.rb index 32c137ef6b..f053b65e15 100644 --- a/lib/rubygems/resolver/set.rb +++ b/lib/rubygems/resolver/set.rb @@ -5,6 +5,15 @@ class Gem::Resolver::Set ## + # Set to true to disable network access for this set + + attr_accessor :remote + + def initialize # :nodoc: + @remote = true + end + + ## # The find_all method must be implemented. It returns all Resolver # Specification objects matching the given DependencyRequest +req+. @@ -23,5 +32,13 @@ class Gem::Resolver::Set def prefetch reqs end + ## + # When true, this set is allowed to access the network when looking up + # specifications or dependencies. + + def remote? # :nodoc: + @remote + end + end diff --git a/lib/rubygems/resolver/vendor_set.rb b/lib/rubygems/resolver/vendor_set.rb index 3db637f4a3..6e867073be 100644 --- a/lib/rubygems/resolver/vendor_set.rb +++ b/lib/rubygems/resolver/vendor_set.rb @@ -21,6 +21,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set attr_reader :specs # :nodoc: def initialize # :nodoc: + super() + @directories = {} @specs = {} end diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb index bfd6fd225b..8c5fb7d9f2 100644 --- a/lib/rubygems/security.rb +++ b/lib/rubygems/security.rb @@ -120,11 +120,11 @@ end # * HighSecurity - Here's the bugger that got us into this mess. # The HighSecurity policy is identical to the MediumSecurity policy, # except that it does not allow unsigned gems. A malicious user -# doesn't have a whole lot of options here; he can't modify the -# package contents without invalidating the signature, and he can't +# doesn't have a whole lot of options here; they can't modify the +# package contents without invalidating the signature, and they can't # modify or remove signature or the signing certificate chain, or # RubyGems will simply refuse to install the package. Oh well, maybe -# he'll have better luck causing problems for CPAN users instead :). +# they'll have better luck causing problems for CPAN users instead :). # # The reason RubyGems refused to install your shiny new signed gem was because # it was from an untrusted source. Well, your code is infallible (naturally), diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index 28178a5f4f..2e3fa03730 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -24,6 +24,11 @@ class Gem::Source::Git < Gem::Source attr_reader :reference ## + # When false the cache for this repository will not be updated. + + attr_accessor :remote + + ## # The git repository this gem is sourced from. attr_reader :repository @@ -53,6 +58,7 @@ class Gem::Source::Git < Gem::Source @reference = reference @need_submodules = submodules + @remote = true @root_dir = Gem.dir @git = ENV['git'] || 'git' end @@ -85,6 +91,8 @@ class Gem::Source::Git < Gem::Source def checkout # :nodoc: cache + return false unless File.exist? repo_cache_dir + unless File.exist? install_dir then system @git, 'clone', '--quiet', '--no-checkout', repo_cache_dir, install_dir @@ -107,6 +115,8 @@ class Gem::Source::Git < Gem::Source # Creates a local cache repository for the git gem. def cache # :nodoc: + return unless @remote + if File.exist? repo_cache_dir then Dir.chdir repo_cache_dir do system @git, 'fetch', '--quiet', '--force', '--tags', @@ -142,6 +152,8 @@ class Gem::Source::Git < Gem::Source # The directory where the git gem will be installed. def install_dir # :nodoc: + return unless File.exist? repo_cache_dir + File.join base_dir, 'gems', "#{@name}-#{dir_shortref}" end @@ -177,6 +189,8 @@ class Gem::Source::Git < Gem::Source def specs checkout + return [] unless install_dir + Dir.chdir install_dir do Dir['{,*,*/*}.gemspec'].map do |spec_file| directory = File.dirname spec_file diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 59d71d378b..f4e609a5eb 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -241,6 +241,28 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :summary ## + # Singular writer for #authors + # + # Usage: + # + # spec.author = 'John Jones' + + def author= o + self.authors = [o] + end + + ## + # Sets the list of authors, ensuring it is an array. + # + # Usage: + # + # spec.authors = ['John Jones', 'Mary Smith'] + + def authors= value + @authors = Array(value).flatten.grep(String) + end + + ## # The platform this gem runs on. # # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT. @@ -327,7 +349,7 @@ class Gem::Specification < Gem::BasicSpecification add_bindir(@executables), @extra_rdoc_files, @extensions, - ].flatten.sort.uniq.compact + ].flatten.uniq.compact.sort end ###################################################################### @@ -443,28 +465,6 @@ class Gem::Specification < Gem::BasicSpecification end ## - # Singular writer for #authors - # - # Usage: - # - # spec.author = 'John Jones' - - def author= o - self.authors = [o] - end - - ## - # Sets the list of authors, ensuring it is an array. - # - # Usage: - # - # spec.authors = ['John Jones', 'Mary Smith'] - - def authors= value - @authors = Array(value).flatten.grep(String) - end - - ## # Executables included in the gem. # # For example, the rake gem has rake as an executable. You don’t specify the diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb index 8dc37d6720..328731d4ea 100644 --- a/lib/rubygems/test_case.rb +++ b/lib/rubygems/test_case.rb @@ -115,6 +115,23 @@ class Gem::TestCase < MiniTest::Unit::TestCase assert File.exist?(path), msg end + ## + # Sets the ENABLE_SHARED entry in RbConfig::CONFIG to +value+ and restores + # the original value when the block ends + + def enable_shared value + enable_shared = RbConfig::CONFIG['ENABLE_SHARED'] + RbConfig::CONFIG['ENABLE_SHARED'] = value + + yield + ensure + if enable_shared then + RbConfig::CONFIG['enable_shared'] = enable_shared + else + RbConfig::CONFIG.delete 'enable_shared' + end + end + # TODO: move to minitest def refute_path_exists path, msg = nil msg = message(msg) { "Expected path '#{path}' to not exist" } @@ -294,10 +311,10 @@ class Gem::TestCase < MiniTest::Unit::TestCase Gem.searcher = nil Gem::SpecFetcher.fetcher = nil - @orig_BASERUBY = Gem::ConfigMap[:BASERUBY] - Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:ruby_install_name] + @orig_BASERUBY = RbConfig::CONFIG['BASERUBY'] + RbConfig::CONFIG['BASERUBY'] = RbConfig::CONFIG['ruby_install_name'] - @orig_arch = Gem::ConfigMap[:arch] + @orig_arch = RbConfig::CONFIG['arch'] if win_platform? util_set_arch 'i386-mswin32' @@ -315,8 +332,12 @@ class Gem::TestCase < MiniTest::Unit::TestCase def teardown $LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH - Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY - Gem::ConfigMap[:arch] = @orig_arch + if @orig_BASERUBY + RbConfig::CONFIG['BASERUBY'] = @orig_BASERUBY + else + RbConfig::CONFIG.delete('BASERUBY') + end + RbConfig::CONFIG['arch'] = @orig_arch if defined? Gem::RemoteFetcher then Gem::RemoteFetcher.fetcher = nil @@ -898,7 +919,7 @@ Also, a list: # Set the platform to +arch+ def util_set_arch(arch) - Gem::ConfigMap[:arch] = arch + RbConfig::CONFIG['arch'] = arch platform = Gem::Platform.new arch Gem.instance_variable_set :@platforms, nil @@ -1245,10 +1266,17 @@ Also, a list: class StaticSet ## + # A StaticSet ignores remote because it has a fixed set of gems. + + attr_accessor :remote + + ## # Creates a new StaticSet for the given +specs+ def initialize(specs) @specs = specs + + @remote = true end ## diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb index 4cb2a1d333..fa838333cd 100644 --- a/lib/rubygems/uninstaller.rb +++ b/lib/rubygems/uninstaller.rb @@ -237,7 +237,7 @@ class Gem::Uninstaller unless path_ok?(@gem_home, spec) or (@user_install and path_ok?(Gem.user_dir, spec)) then e = Gem::GemNotInHomeException.new \ - "Gem is not installed in directory #{@gem_home}" + "Gem '#{spec.full_name}' is not installed in directory #{@gem_home}" e.spec = spec raise e diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index fda8b0b5d4..20663326ef 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -22,6 +22,11 @@ # 3. 1.0.a.2 # 4. 0.9 # +# If you want to specify a version restriction that includes both prereleases +# and regular releases of the 1.x series this is the best way: +# +# s.add_dependency 'example', '>= 1.0.0.a', '< 2.0.0' +# # == How Software Changes # # Users expect to be able to specify a version constraint that gives them @@ -81,8 +86,8 @@ # # * Any "public" release of a gem should have a different version. Normally # that means incrementing the build number. This means a developer can -# generate builds all day long for himself, but as soon as he/she makes a -# public release, the version must be updated. +# generate builds all day long, but as soon as they make a public release, +# the version must be updated. # # === Examples # @@ -99,26 +104,25 @@ # Version 1.1.1:: Fixed a bug in the linked list implementation. # Version 1.1.2:: Fixed a bug introduced in the last fix. # -# Client A needs a stack with basic push/pop capability. He writes to the -# original interface (no <tt>top</tt>), so his version constraint looks -# like: +# Client A needs a stack with basic push/pop capability. They write to the +# original interface (no <tt>top</tt>), so their version constraint looks like: # # gem 'stack', '~> 0.0' # # Essentially, any version is OK with Client A. An incompatible change to -# the library will cause him grief, but he is willing to take the chance (we -# call Client A optimistic). +# the library will cause them grief, but they are willing to take the chance +# (we call Client A optimistic). # -# Client B is just like Client A except for two things: (1) He uses the -# <tt>depth</tt> method and (2) he is worried about future -# incompatibilities, so he writes his version constraint like this: +# Client B is just like Client A except for two things: (1) They use the +# <tt>depth</tt> method and (2) they are worried about future +# incompatibilities, so they write their version constraint like this: # # gem 'stack', '~> 0.1' # # The <tt>depth</tt> method was introduced in version 0.1.0, so that version # or anything later is fine, as long as the version stays below version 1.0 # where incompatibilities are introduced. We call Client B pessimistic -# because he is worried about incompatible future changes (it is OK to be +# because they are worried about incompatible future changes (it is OK to be # pessimistic!). # # == Preventing Version Catastrophe: @@ -185,6 +189,8 @@ class Gem::Version @@all = {} def self.new version # :nodoc: + return super unless Gem::VERSION == self.class + @@all[version] ||= super end |