From 372dcece3f69989d133f720468f1e24aa1133cda Mon Sep 17 00:00:00 2001 From: drbrain Date: Thu, 22 Apr 2010 08:24:42 +0000 Subject: Update to RubyGems 1.3.7.pre.1 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27441 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++ lib/rubygems.rb | 74 +++++++++++++++------- lib/rubygems/builder.rb | 2 + lib/rubygems/command.rb | 12 ++++ lib/rubygems/command_manager.rb | 24 ++++--- lib/rubygems/commands/contents_command.rb | 2 +- lib/rubygems/commands/dependency_command.rb | 4 +- lib/rubygems/commands/environment_command.rb | 5 +- lib/rubygems/commands/fetch_command.rb | 10 ++- lib/rubygems/commands/install_command.rb | 3 +- lib/rubygems/commands/query_command.rb | 19 +++++- lib/rubygems/commands/server_command.rb | 8 ++- lib/rubygems/commands/setup_command.rb | 2 +- lib/rubygems/commands/unpack_command.rb | 58 ++++++++++------- lib/rubygems/commands/update_command.rb | 2 +- lib/rubygems/defaults.rb | 5 +- lib/rubygems/dependency.rb | 38 +++++++++-- lib/rubygems/dependency_installer.rb | 13 +++- lib/rubygems/doc_manager.rb | 7 +- lib/rubygems/errors.rb | 35 ++++++++++ lib/rubygems/exceptions.rb | 11 +++- lib/rubygems/indexer.rb | 2 +- lib/rubygems/installer.rb | 11 ++-- lib/rubygems/package.rb | 10 +-- lib/rubygems/package/f_sync_dir.rb | 8 +-- lib/rubygems/package/tar_header.rb | 8 +-- lib/rubygems/package/tar_output.rb | 8 +-- lib/rubygems/package/tar_reader.rb | 8 +-- lib/rubygems/package/tar_writer.rb | 8 +-- lib/rubygems/package_task.rb | 3 +- lib/rubygems/platform.rb | 3 + lib/rubygems/remote_fetcher.rb | 12 +++- lib/rubygems/requirement.rb | 5 ++ lib/rubygems/server.rb | 51 +++++++++------ lib/rubygems/source_index.rb | 6 +- lib/rubygems/source_info_cache.rb | 8 ++- lib/rubygems/spec_fetcher.rb | 40 +++++++++--- lib/rubygems/specification.rb | 72 +++++++++++---------- lib/rubygems/validator.rb | 5 +- lib/rubygems/version.rb | 4 +- test/rubygems/gemutilities.rb | 21 +++--- test/rubygems/plugin/exception/rubygems_plugin.rb | 2 + test/rubygems/plugin/load/rubygems_plugin.rb | 1 + .../plugin/standarderror/rubygems_plugin.rb | 2 + test/rubygems/rubygems/commands/crash_command.rb | 5 ++ test/rubygems/rubygems_plugin.rb | 5 ++ test/rubygems/test_gem.rb | 45 ++++++++++++- test/rubygems/test_gem_command_manager.rb | 14 ++++ .../rubygems/test_gem_commands_contents_command.rb | 12 ++-- .../test_gem_commands_environment_command.rb | 4 +- test/rubygems/test_gem_commands_fetch_command.rb | 22 ++++++- test/rubygems/test_gem_commands_install_command.rb | 6 +- test/rubygems/test_gem_commands_query_command.rb | 39 ++++++++++-- test/rubygems/test_gem_commands_server_command.rb | 11 +++- .../test_gem_commands_uninstall_command.rb | 9 ++- test/rubygems/test_gem_commands_unpack_command.rb | 48 +++++++++++++- test/rubygems/test_gem_config_file.rb | 2 + test/rubygems/test_gem_dependency.rb | 11 ++++ test/rubygems/test_gem_indexer.rb | 3 +- test/rubygems/test_gem_platform.rb | 19 ++++++ test/rubygems/test_gem_server.rb | 11 ++++ test/rubygems/test_gem_source_index.rb | 2 +- test/rubygems/test_gem_spec_fetcher.rb | 42 ++++++++++++ test/rubygems/test_gem_specification.rb | 51 +++++++++++++-- 64 files changed, 758 insertions(+), 239 deletions(-) create mode 100644 lib/rubygems/errors.rb create mode 100644 test/rubygems/plugin/exception/rubygems_plugin.rb create mode 100644 test/rubygems/plugin/load/rubygems_plugin.rb create mode 100644 test/rubygems/plugin/standarderror/rubygems_plugin.rb create mode 100644 test/rubygems/rubygems/commands/crash_command.rb diff --git a/ChangeLog b/ChangeLog index 586c7a3ab1..419eed8d7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Apr 22 17:13:34 2010 Eric Hodel + + * lib/rubygems: Import RubyGems 1.3.7.pre.1 (as 1.3.6.1). + Thu Apr 22 16:43:31 2010 Nobuyoshi Nakada * parse.y (warn_balanced): removed false warning. diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 95cdee86c5..d2214f6e9f 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -5,6 +5,8 @@ # See LICENSE.txt for permissions. #++ +gem_disabled = !defined? Gem + require 'rubygems/defaults' require 'thread' require 'etc' @@ -98,7 +100,7 @@ require 'etc' # -The RubyGems Team module Gem - RubyGemsVersion = VERSION = '1.3.6' + RubyGemsVersion = VERSION = '1.3.6.1' ## # Raised when RubyGems is unable to load or activate a gem. Contains the @@ -127,9 +129,9 @@ module Gem :bindir => RbConfig::CONFIG["bindir"], :datadir => RbConfig::CONFIG["datadir"], :libdir => RbConfig::CONFIG["libdir"], - :rubylibprefix => RbConfig::CONFIG["rubylibprefix"], :ruby_install_name => RbConfig::CONFIG["ruby_install_name"], :ruby_version => RbConfig::CONFIG["ruby_version"], + :rubylibprefix => RbConfig::CONFIG["rubylibprefix"], :sitedir => RbConfig::CONFIG["sitedir"], :sitelibdir => RbConfig::CONFIG["sitelibdir"], :vendordir => RbConfig::CONFIG["vendordir"] , @@ -144,7 +146,7 @@ module Gem # :stopdoc: MUTEX = Mutex.new - RubyGemsPackageVersion = RubyGemsVersion + RubyGemsPackageVersion = VERSION # :startdoc: ## @@ -310,8 +312,8 @@ module Gem ## # Find the full path to the executable for gem +name+. If the +exec_name+ # is not given, the gem's default_executable is chosen, otherwise the - # specified executable's path is returned. +version_requirements+ allows you - # to specify specific gem versions. + # specified executable's path is returned. +version_requirements+ allows + # you to specify specific gem versions. def self.bin_path(name, exec_name = nil, *version_requirements) version_requirements = Gem::Requirement.default if @@ -568,9 +570,13 @@ module Gem ## # The index to insert activated gem paths into the $LOAD_PATH. + # + # Defaults to the site lib directory unless gem_prelude.rb has loaded paths, + # then it inserts the activated gem's paths before the gem_prelude.rb paths + # so you can override the gem_prelude.rb default $LOAD_PATH paths. def self.load_path_insert_index - $LOAD_PATH.index {|path| path.instance_variable_defined?(:@gem_prelude_index)} + $LOAD_PATH.index { |p| p.instance_variable_defined? :@gem_prelude_index } end ## @@ -667,7 +673,7 @@ module Gem def self.prefix dir = File.dirname File.expand_path(__FILE__) - prefix = File.dirname(dir) + prefix = File.dirname dir if prefix == File.expand_path(ConfigMap[:sitelibdir]) or prefix == File.expand_path(ConfigMap[:libdir]) or @@ -942,6 +948,28 @@ module Gem @@win_platform end + ## + # Find all 'rubygems_plugin' files and load them + + def self.load_plugins + plugins = Gem.find_files 'rubygems_plugin' + + plugins.each do |plugin| + + # Skip older versions of the GemCutter plugin: Its commands are in + # RubyGems proper now. + + next if plugin =~ /gemcutter-0\.[0-3]/ + + begin + load plugin + rescue ::Exception => e + details = "#{plugin.inspect}: #{e.message} (#{e.class})" + warn "Error loading RubyGems plugin #{details}" + end + end + end + class << self ## @@ -991,8 +1019,8 @@ module Gem end module Kernel - # defined in gem_prelude.rb - undef gem + + undef gem if respond_to? :gem # defined in gem_prelude.rb on 1.9 ## # Use Kernel#gem to activate a specific version of +gem_name+. @@ -1051,12 +1079,18 @@ require 'rubygems/platform' require 'rubygems/builder' # HACK: Needed for rake's package task. begin + ## + # Defaults the operating system (or packager) wants to provide for RubyGems. + require 'rubygems/defaults/operating_system' rescue LoadError end if defined?(RUBY_ENGINE) then begin + ## + # Defaults the ruby implementation wants to provide for RubyGems + require "rubygems/defaults/#{RUBY_ENGINE}" rescue LoadError end @@ -1064,21 +1098,15 @@ end require 'rubygems/config_file' -Gem.clear_paths - -plugins = Gem.find_files 'rubygems_plugin' - -plugins.each do |plugin| +## +# Enables the require hook for RubyGems. +# +# Ruby 1.9 allows --disable-gems, so we require it when we didn't detect a Gem +# constant at rubygems.rb load time. - # Skip older versions of the GemCutter plugin: Its commands are in - # RubyGems proper now. +require 'rubygems/custom_require' if gem_disabled or RUBY_VERSION < '1.9' - next if plugin =~ /gemcutter-0\.[0-3]/ +Gem.clear_paths - begin - load plugin - rescue => e - warn "error loading #{plugin.inspect}: #{e.message} (#{e.class})" - end -end +Gem.load_plugins diff --git a/lib/rubygems/builder.rb b/lib/rubygems/builder.rb index 9e7f262243..2bcd4b0bb3 100644 --- a/lib/rubygems/builder.rb +++ b/lib/rubygems/builder.rb @@ -4,6 +4,8 @@ # See LICENSE.txt for permissions. #++ +require 'rubygems/user_interaction' + ## # The Builder class processes RubyGem specification files # to produce a .gem file. diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb index 08692bdb70..3491937358 100644 --- a/lib/rubygems/command.rb +++ b/lib/rubygems/command.rb @@ -145,6 +145,18 @@ class Gem::Command raise Gem::Exception, "generic command has no actions" end + ## + # + # Display to the user that a gem couldn't be found and reasons why + def show_lookup_failure(gem_name, version, errors=nil) + if errors and !errors.empty? + alert_error "Could not find a valid gem '#{gem_name}' (#{version}), here is why:" + errors.each { |x| say " #{x.wordy}" } + else + alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository" + end + end + ## # Get all gem names from the command line. diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb index 11344f1fb6..176e6a0bb4 100644 --- a/lib/rubygems/command_manager.rb +++ b/lib/rubygems/command_manager.rb @@ -75,10 +75,10 @@ class Gem::CommandManager end ## - # Register the command object. + # Register the Symbol +command+ as a gem command. - def register_command(command_obj) - @commands[command_obj] = false + def register_command(command) + @commands[command] = false end ## @@ -123,7 +123,7 @@ class Gem::CommandManager say Gem::Command::HELP terminate_interaction(0) when '-v', '--version' - say Gem::RubyGemsVersion + say Gem::VERSION terminate_interaction(0) when /^-/ alert_error "Invalid option: #{args[0]}. See 'gem --help'." @@ -161,15 +161,19 @@ class Gem::CommandManager retried = false begin - commands.const_get(const_name) + commands.const_get const_name rescue NameError - if retried then - raise - else - retried = true + raise if retried + + retried = true + begin require "rubygems/commands/#{command_name}_command" - retry + rescue Exception => e + alert_error "Loading command: #{command_name} (#{e.class})\n #{e}" + ui.errs.puts "\t#{e.backtrace.join "\n\t"}" if + Gem.configuration.backtrace end + retry end.new end diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb index ce2c655240..a49918689c 100644 --- a/lib/rubygems/commands/contents_command.rb +++ b/lib/rubygems/commands/contents_command.rb @@ -7,7 +7,7 @@ class Gem::Commands::ContentsCommand < Gem::Command def initialize super 'contents', 'Display the contents of the installed gems', - :specdirs => [], :lib_only => false + :specdirs => [], :lib_only => false, :prefix => true add_version_option diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb index 35702fbc6e..649e3c2d2d 100644 --- a/lib/rubygems/commands/dependency_command.rb +++ b/lib/rubygems/commands/dependency_command.rb @@ -159,7 +159,9 @@ class Gem::Commands::DependencyCommand < Gem::Command response end - # Returns list of [specification, dep] that are satisfied by spec. + ## + # Returns an Array of [specification, dep] that are satisfied by +spec+. + def find_reverse_dependencies(spec) result = [] diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb index f3550cae28..a8284b4bf6 100644 --- a/lib/rubygems/commands/environment_command.rb +++ b/lib/rubygems/commands/environment_command.rb @@ -69,7 +69,7 @@ lib/rubygems/defaults/operating_system.rb when /^packageversion/ then out << Gem::RubyGemsPackageVersion when /^version/ then - out << Gem::RubyGemsVersion + out << Gem::VERSION when /^gemdir/, /^gemhome/, /^home/, /^GEM_HOME/ then out << Gem.dir when /^gempath/, /^path/, /^GEM_PATH/ then @@ -79,7 +79,7 @@ lib/rubygems/defaults/operating_system.rb when nil then out = "RubyGems Environment:\n" - out << " - RUBYGEMS VERSION: #{Gem::RubyGemsVersion}\n" + out << " - RUBYGEMS VERSION: #{Gem::VERSION}\n" out << " - RUBY VERSION: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}" out << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL @@ -109,6 +109,7 @@ lib/rubygems/defaults/operating_system.rb out << " - GEM CONFIGURATION:\n" Gem.configuration.each do |name, value| + value = value.gsub(/./, '*') if name == 'gemcutter_key' out << " - #{name.inspect} => #{value.inspect}\n" end diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb index b12e1b4a5d..43229c0512 100644 --- a/lib/rubygems/commands/fetch_command.rb +++ b/lib/rubygems/commands/fetch_command.rb @@ -34,7 +34,7 @@ class Gem::Commands::FetchCommand < Gem::Command def execute version = options[:version] || Gem::Requirement.default - all = Gem::Requirement.default + all = Gem::Requirement.default != version gem_names = get_all_gem_names @@ -42,13 +42,17 @@ class Gem::Commands::FetchCommand < Gem::Command dep = Gem::Dependency.new gem_name, version dep.prerelease = options[:prerelease] - specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, false, true, + specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, all, true, dep.prerelease?) + specs_and_sources, errors = + Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true, + dep.prerelease?) + spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last if spec.nil? then - alert_error "Could not find #{gem_name} in any repository" + show_lookup_failure gem_name, version, errors next end diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index df6b3e5f2c..06a89eeb0a 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -127,7 +127,8 @@ to write the specification by hand. For example: alert_error "Error installing #{gem_name}:\n\t#{e.message}" exit_code |= 1 rescue Gem::GemNotFoundException => e - alert_error e.message + show_lookup_failure e.name, e.version, e.errors + exit_code |= 2 end end diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb index 7dd0a4a0d6..93b417015c 100644 --- a/lib/rubygems/commands/query_command.rb +++ b/lib/rubygems/commands/query_command.rb @@ -21,7 +21,7 @@ class Gem::Commands::QueryCommand < Gem::Command options[:installed] = value end - add_version_option + add_version_option command, "for use with --installed" add_option('-n', '--name-matches REGEXP', 'Name of gem(s) to query on matches the', @@ -185,8 +185,21 @@ class Gem::Commands::QueryCommand < Gem::Command entry = gem_name.dup if options[:versions] then - versions = matching_tuples.map { |(name, version,_),_| version }.uniq - entry << " (#{versions.join ', '})" + list = if platforms.empty? or options[:details] then + matching_tuples.map { |(name, version,_),_| version }.uniq + else + platforms.sort.reverse.map do |version, pls| + if pls == [Gem::Platform::RUBY] then + version + else + ruby = pls.delete Gem::Platform::RUBY + platform_list = [ruby, *pls.sort].compact + "#{version} #{platform_list.join ' '}" + end + end + end.join ', ' + + entry << " (#{list})" end if options[:details] then diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb index 6bc58367e9..4277787035 100644 --- a/lib/rubygems/commands/server_command.rb +++ b/lib/rubygems/commands/server_command.rb @@ -5,7 +5,7 @@ class Gem::Commands::ServerCommand < Gem::Command def initialize super 'server', 'Documentation and gem repository HTTP server', - :port => 8808, :gemdir => Gem.dir, :daemon => false + :port => 8808, :gemdir => [], :daemon => false OptionParser.accept :Port do |port| if port =~ /\A\d+\z/ then @@ -29,8 +29,9 @@ class Gem::Commands::ServerCommand < Gem::Command end add_option '-d', '--dir=GEMDIR', - 'directory from which to serve gems' do |gemdir, options| - options[:gemdir] = File.expand_path gemdir + 'directories from which to serve gems', + 'multiple directories may be provided' do |gemdir, options| + options[:gemdir] << File.expand_path(gemdir) end add_option '--[no-]daemon', 'run as a daemon' do |daemon, options| @@ -69,6 +70,7 @@ You can set up a shortcut to gem server documentation using the URL: end def execute + options[:gemdir] << Gem.dir if options[:gemdir].empty? Gem::Server.run options end diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index f5f5185f86..4bc115eaf8 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -231,7 +231,7 @@ TEXT def install_rdoc gem_doc_dir = File.join Gem.dir, 'doc' - rubygems_name = "rubygems-#{Gem::RubyGemsVersion}" + rubygems_name = "rubygems-#{Gem::VERSION}" rubygems_doc_dir = File.join gem_doc_dir, rubygems_name if File.writable? gem_doc_dir and diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb index 84a53b107a..8ed99babbe 100644 --- a/lib/rubygems/commands/unpack_command.rb +++ b/lib/rubygems/commands/unpack_command.rb @@ -12,7 +12,8 @@ class Gem::Commands::UnpackCommand < Gem::Command :version => Gem::Requirement.default, :target => Dir.pwd - add_option('--target=DIR', 'target directory for unpacking') do |value, options| + add_option('--target=DIR', + 'target directory for unpacking') do |value, options| options[:target] = value end @@ -31,6 +32,16 @@ class Gem::Commands::UnpackCommand < Gem::Command "#{program_name} GEMNAME" end + def download dependency + found = Gem::SpecFetcher.fetcher.fetch dependency + + return if found.empty? + + spec, source_uri = found.first + + Gem::RemoteFetcher.fetcher.download spec, source_uri + end + #-- # TODO: allow, e.g., 'gem unpack rake-0.3.1'. Find a general solution for # this, so that it works for uninstall as well. (And check other commands @@ -38,11 +49,12 @@ class Gem::Commands::UnpackCommand < Gem::Command def execute get_all_gem_names.each do |name| - path = get_path name, options[:version] + dependency = Gem::Dependency.new name, options[:version] + path = get_path dependency if path then - basename = File.basename(path, '.gem') - target_dir = File.expand_path File.join(options[:target], basename) + basename = File.basename path, '.gem' + target_dir = File.expand_path basename, options[:target] FileUtils.mkdir_p target_dir Gem::Installer.new(path, :unpack => true).unpack target_dir say "Unpacked gem: '#{target_dir}'" @@ -52,14 +64,15 @@ class Gem::Commands::UnpackCommand < Gem::Command end end + ## # Return the full path to the cached gem file matching the given # name and version requirement. Returns 'nil' if no match. # # Example: # - # get_path('rake', '> 0.4') # -> '/usr/lib/ruby/gems/1.8/cache/rake-0.4.2.gem' - # get_path('rake', '< 0.1') # -> nil - # get_path('rak') # -> nil (exact name required) + # get_path 'rake', '> 0.4' # "/usr/lib/ruby/gems/1.8/cache/rake-0.4.2.gem" + # get_path 'rake', '< 0.1' # nil + # get_path 'rak' # nil (exact name required) #-- # TODO: This should be refactored so that it's a general service. I don't # think any of our existing classes are the right place though. Just maybe @@ -67,30 +80,29 @@ class Gem::Commands::UnpackCommand < Gem::Command # # TODO: It just uses Gem.dir for now. What's an easy way to get the list of # source directories? - def get_path(gemname, version_req) - return gemname if gemname =~ /\.gem$/i - specs = Gem::source_index.find_name gemname, version_req + def get_path dependency + return dependency.name if dependency.name =~ /\.gem$/i + + specs = Gem.source_index.search dependency selected = specs.sort_by { |s| s.version }.last - return nil if selected.nil? + return download(dependency) if selected.nil? - # We expect to find (basename).gem in the 'cache' directory. - # Furthermore, the name match must be exact (ignoring case). - if gemname =~ /^#{selected.name}$/i - filename = selected.file_name - path = nil + return unless dependency.name =~ /^#{selected.name}$/i - Gem.path.find do |gem_dir| - path = File.join gem_dir, 'cache', filename - File.exist? path - end + # We expect to find (basename).gem in the 'cache' directory. Furthermore, + # the name match must be exact (ignoring case). + filename = selected.file_name + path = nil - path - else - nil + Gem.path.find do |gem_dir| + path = File.join gem_dir, 'cache', filename + File.exist? path end + + path end end diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 4b0439df1f..45d82e9385 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -56,7 +56,7 @@ class Gem::Commands::UpdateCommand < Gem::Command rubygems_update = Gem::Specification.new rubygems_update.name = 'rubygems-update' - rubygems_update.version = Gem::Version.new Gem::RubyGemsVersion + rubygems_update.version = Gem::Version.new Gem::VERSION hig['rubygems-update'] = rubygems_update options[:user_install] = false diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index c3c4737892..8950d0f73d 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -33,15 +33,14 @@ module Gem # Path for gems in the user's home directory def self.user_dir - File.join(Gem.user_home, '.gem', ruby_engine, - ConfigMap[:ruby_version]) + File.join Gem.user_home, '.gem', ruby_engine, ConfigMap[:ruby_version] end ## # Default gem load path def self.default_path - if File.exist?(Gem.user_home) + if File.exist? Gem.user_home then [user_dir, default_dir] else [default_dir] diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb index 351991067d..ec5d88b607 100644 --- a/lib/rubygems/dependency.rb +++ b/lib/rubygems/dependency.rb @@ -68,9 +68,6 @@ class Gem::Dependency @version_requirements = @requirement end - ## - # What does this dependency require? - ## # A dependency's hash is the XOR of the hashes of +name+, +type+, # and +requirement+. @@ -106,6 +103,9 @@ class Gem::Dependency end end + ## + # What does this dependency require? + def requirement return @requirement if defined?(@requirement) and @requirement @@ -160,7 +160,16 @@ class Gem::Dependency __requirement end - alias_method :version_requirement, :version_requirements + alias version_requirement version_requirements # :nodoc: + + def version_requirements= requirements # :nodoc: + warn "#{Gem.location_of_caller.join ':'}:Warning: " \ + "Gem::Dependency#version_requirements= is deprecated " \ + "and will be removed on or after August 2010. " \ + "Use Gem::Dependency.new." + + @requirement = Gem::Requirement.create requirements + end def == other # :nodoc: Gem::Dependency === other && @@ -188,9 +197,12 @@ class Gem::Dependency end pattern = name - pattern = /\A#{Regexp.escape pattern}\Z/ unless Regexp === pattern - return false unless pattern =~ other.name + if Regexp === pattern then + return false unless pattern =~ other.name + else + return false unless pattern == other.name + end reqs = other.requirement.requirements @@ -202,5 +214,19 @@ class Gem::Dependency requirement.satisfied_by? version end + def match?(spec_name, spec_version) + pattern = name + + if Regexp === pattern + return false unless pattern =~ spec_name + else + return false unless pattern == spec_name + end + + return true if requirement.none? + + requirement.satisfied_by? Gem::Version.new(spec_version) + end + end diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index 9d9aaba400..099d223295 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -69,6 +69,10 @@ class Gem::DependencyInstaller @install_dir = options[:install_dir] || Gem.dir @cache_dir = options[:cache_dir] || @install_dir + + # Set with any errors that SpecFetcher finds while search through + # gemspecs for a dep + @errors = nil end ## @@ -78,6 +82,8 @@ class Gem::DependencyInstaller # local gems preferred over remote gems. def find_gems_with_sources(dep) + # Reset the errors + @errors = nil gems_and_sources = [] if @domain == :both or @domain == :local then @@ -99,7 +105,7 @@ class Gem::DependencyInstaller (requirements.length > 1 or (requirements.first != ">=" and requirements.first != ">")) - found = Gem::SpecFetcher.fetcher.fetch dep, all, true, dep.prerelease? + found, @errors = Gem::SpecFetcher.fetcher.fetch_with_errors dep, all, true, dep.prerelease? gems_and_sources.push(*found) @@ -204,8 +210,9 @@ class Gem::DependencyInstaller end if spec_and_source.nil? then - raise Gem::GemNotFoundException, - "could not find gem #{gem_name} locally or in a repository" + raise Gem::GemNotFoundException.new( + "Could not find a valid gem '#{gem_name}' (#{version}) locally or in a repository", + gem_name, version, @errors) end @specs_and_sources = [spec_and_source] diff --git a/lib/rubygems/doc_manager.rb b/lib/rubygems/doc_manager.rb index a4976ae10a..d26d87a26f 100644 --- a/lib/rubygems/doc_manager.rb +++ b/lib/rubygems/doc_manager.rb @@ -179,7 +179,10 @@ class Gem::DocManager r = RDoc::RDoc.new old_pwd = Dir.pwd - Dir.chdir(@spec.full_gem_path) + Dir.chdir @spec.full_gem_path + + say "rdoc #{args.join ' '}" if Gem.configuration.really_verbose + begin r.document args rescue Errno::EACCES => e @@ -193,7 +196,7 @@ class Gem::DocManager Gem.configuration.backtrace ui.errs.puts "(continuing with the rest of the installation)" ensure - Dir.chdir(old_pwd) + Dir.chdir old_pwd end end diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb new file mode 100644 index 0000000000..950b34d744 --- /dev/null +++ b/lib/rubygems/errors.rb @@ -0,0 +1,35 @@ +class Gem::ErrorReason; end + +# Generated when trying to lookup a gem to indicate that the gem +# was found, but that it isn't usable on the current platform. +# +# fetch and install read these and report them to the user to aid +# in figuring out why a gem couldn't be installed. +# +class Gem::PlatformMismatch < Gem::ErrorReason + + attr_reader :name + attr_reader :version + attr_reader :platforms + + def initialize(name, version) + @name = name + @version = version + @platforms = [] + end + + def add_platform(platform) + @platforms << platform + end + + def wordy + prefix = "Found #{@name} (#{@version})" + + if @platforms.size == 1 + "#{prefix}, but was for platform #{@platforms[0]}" + else + "#{prefix}, but was for platforms #{@platforms.join(' ,')}" + end + end + +end diff --git a/lib/rubygems/exceptions.rb b/lib/rubygems/exceptions.rb index d6c60c7a02..55d67f9125 100644 --- a/lib/rubygems/exceptions.rb +++ b/lib/rubygems/exceptions.rb @@ -37,7 +37,16 @@ class Gem::FormatException < Gem::Exception attr_accessor :file_path end -class Gem::GemNotFoundException < Gem::Exception; end +class Gem::GemNotFoundException < Gem::Exception + def initialize(msg, name=nil, version=nil, errors=nil) + super msg + @name = name + @version = version + @errors = errors + end + + attr_reader :name, :version, :errors +end class Gem::InstallError < Gem::Exception; end diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb index baa582447d..f85fe8467d 100644 --- a/lib/rubygems/indexer.rb +++ b/lib/rubygems/indexer.rb @@ -320,7 +320,7 @@ class Gem::Indexer #{rss_title} http://#{rss_host} Recently released gems from http://#{rss_host} - RubyGems v#{Gem::RubyGemsVersion} + RubyGems v#{Gem::VERSION} http://cyber.law.harvard.edu/rss/rss.html HEADER diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 50f8d20b33..f64696fe7a 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -133,7 +133,8 @@ class Gem::Installer end FileUtils.mkdir_p @gem_home - raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home + raise Gem::FilePermissionError, @gem_home unless + options[:unpack] or File.writable? @gem_home @spec = @format.spec @@ -165,7 +166,7 @@ class Gem::Installer end if rrgv = @spec.required_rubygems_version then - unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then + unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then raise Gem::InstallError, "#{@spec.name} requires RubyGems version #{rrgv}. " + "Try 'gem update --system' to update RubyGems itself." @@ -270,7 +271,7 @@ class Gem::Installer ## # Creates windows .bat files for easy running of commands - def generate_windows_script(bindir, filename) + def generate_windows_script(filename, bindir) if Gem.win_platform? then script_name = filename + ".bat" script_path = File.join bindir, File.basename(script_name) @@ -295,7 +296,7 @@ class Gem::Installer @spec.executables.each do |filename| filename.untaint - bin_path = File.expand_path("#{@spec.bindir}/#{filename}", @gem_dir) + bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir mode = File.stat(bin_path).mode | 0111 File.chmod mode, bin_path @@ -329,7 +330,7 @@ class Gem::Installer say bin_script_path if Gem.configuration.really_verbose - generate_windows_script bindir, filename + generate_windows_script filename, bindir #else # FileUtils.rm_f bin_script_path # FileUtils.cp exec_path, bin_script_path, diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 0fd64025ad..937da584cb 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ require 'fileutils' require 'find' @@ -13,8 +13,10 @@ require 'zlib' require 'rubygems/security' require 'rubygems/specification' +## # Wrapper for FileUtils meant to provide logging and additional operations if # needed. + class Gem::FileOperations def initialize(logger = nil) diff --git a/lib/rubygems/package/f_sync_dir.rb b/lib/rubygems/package/f_sync_dir.rb index e15035ec37..f7eb7f3ce3 100644 --- a/lib/rubygems/package/f_sync_dir.rb +++ b/lib/rubygems/package/f_sync_dir.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ module Gem::Package::FSyncDir diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb index 0689c319b9..4f923b9b5e 100644 --- a/lib/rubygems/package/tar_header.rb +++ b/lib/rubygems/package/tar_header.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ ## #-- diff --git a/lib/rubygems/package/tar_output.rb b/lib/rubygems/package/tar_output.rb index 98fa8b8fe1..7d99a51127 100644 --- a/lib/rubygems/package/tar_output.rb +++ b/lib/rubygems/package/tar_output.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ ## # TarOutput is a wrapper to TarWriter that builds gem-format tar file. diff --git a/lib/rubygems/package/tar_reader.rb b/lib/rubygems/package/tar_reader.rb index b28714d124..e6a71d386c 100644 --- a/lib/rubygems/package/tar_reader.rb +++ b/lib/rubygems/package/tar_reader.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ ## # TarReader reads tar files and allows iteration over their items diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb index b5fc89e55e..d115162a76 100644 --- a/lib/rubygems/package/tar_writer.rb +++ b/lib/rubygems/package/tar_writer.rb @@ -1,8 +1,8 @@ -# -*- coding: iso-8859-1 -*- -#++ -# Copyright (C) 2004 Mauricio Julio Fernández Pradier -# See LICENSE.txt for additional licensing information. +# -*- coding: utf-8 -*- #-- +# Copyright (C) 2004 Mauricio Julio Fernández Pradier +# See LICENSE.txt for additional licensing information. +#++ ## # Allows writing of tar files diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb index bb0a60464e..d43dfc8323 100644 --- a/lib/rubygems/package_task.rb +++ b/lib/rubygems/package_task.rb @@ -102,6 +102,7 @@ class Gem::PackageTask < Rake::PackageTask gem_file = gem_spec.file_name gem_path = File.join package_dir, gem_file + gem_dir = File.join package_dir, gem_spec.full_name desc "Build the gem file #{gem_file}" task :gem => [gem_path] @@ -109,7 +110,7 @@ class Gem::PackageTask < Rake::PackageTask trace = Rake.application.options.trace Gem.configuration.verbose = trace - file gem_path => [package_dir] + @gem_spec.files do + file gem_path => [package_dir, gem_dir] + @gem_spec.files do when_writing "Creating #{gem_spec.file_name}" do Gem::Builder.new(gem_spec).build verbose trace do diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index f5410cf4f7..c9a084707a 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -70,6 +70,8 @@ class Gem::Platform when /hpux(\d+)/ then [ 'hpux', $1 ] when /^java$/, /^jruby$/ then [ 'java', nil ] when /^java([\d.]*)/ then [ 'java', $1 ] + when /^dotnet$/ then [ 'dotnet', nil ] + when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] when /linux/ then [ 'linux', $1 ] when /mingw32/ then [ 'mingw32', nil ] when /(mswin\d+)(\_(\d+))?/ then @@ -148,6 +150,7 @@ class Gem::Platform when /^i686-darwin(\d)/ then ['x86', 'darwin', $1 ] when /^i\d86-linux/ then ['x86', 'linux', nil ] when 'java', 'jruby' then [nil, 'java', nil ] + when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ] when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ] when 'powerpc-darwin' then ['powerpc', 'darwin', nil ] when /powerpc-darwin(\d)/ then ['powerpc', 'darwin', $1 ] diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index dbd4cef816..07cd55b161 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -88,7 +88,9 @@ class Gem::RemoteFetcher # Always escape URI's to deal with potential spaces and such unless URI::Generic === source_uri - source_uri = URI.parse(URI.escape(source_uri)) + source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ? + URI::DEFAULT_PARSER.escape(source_uri) : + URI.escape(source_uri)) end scheme = source_uri.scheme @@ -252,6 +254,8 @@ class Gem::RemoteFetcher connection.start unless connection.started? connection + rescue Errno::EHOSTDOWN => e + raise FetchError.new(e.message, uri) end ## @@ -309,7 +313,7 @@ class Gem::RemoteFetcher request.basic_auth uri.user, uri.password end - ua = "RubyGems/#{Gem::RubyGemsVersion} #{Gem::Platform.local}" + ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}" ua << " Ruby/#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}" ua << " patchlevel #{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL ua << ")" @@ -351,7 +355,9 @@ class Gem::RemoteFetcher # HACK work around EOFError bug in Net::HTTP # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible # to install gems. - rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE + rescue EOFError, Timeout::Error, + Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE + requests = @requests[connection.object_id] say "connection reset after #{requests} requests, retrying" if Gem.configuration.really_verbose diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb index d9b510a76d..d51bf8ffa3 100644 --- a/lib/rubygems/requirement.rb +++ b/lib/rubygems/requirement.rb @@ -93,9 +93,14 @@ class Gem::Requirement requirements.uniq! requirements << ">= 0" if requirements.empty? + @none = (requirements == ">= 0") @requirements = requirements.map! { |r| self.class.parse r } end + def none? + @none ||= (to_s == ">= 0") + end + def as_list # :nodoc: requirements.map { |op, version| "#{op} #{version}" } end diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb index 24c9e044e1..c1a578920c 100644 --- a/lib/rubygems/server.rb +++ b/lib/rubygems/server.rb @@ -33,6 +33,8 @@ require 'rubygems/doc_manager' class Gem::Server + attr_reader :spec_dirs + include ERB::Util include Gem::UserInteraction @@ -430,29 +432,36 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } options[:addresses]).run end - def initialize(gem_dir, port, daemon, addresses = nil) + ## + # Only the first directory in gem_dirs is used for serving gems + + def initialize(gem_dirs, port, daemon, addresses = nil) Socket.do_not_reverse_lookup = true - @gem_dir = gem_dir + @gem_dirs = Array gem_dirs @port = port @daemon = daemon @addresses = addresses logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL @server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger - @spec_dir = File.join @gem_dir, 'specifications' + @spec_dirs = @gem_dirs.map do |gem_dir| + spec_dir = File.join gem_dir, 'specifications' - unless File.directory? @spec_dir then - raise ArgumentError, "#{@gem_dir} does not appear to be a gem repository" + unless File.directory? spec_dir then + raise ArgumentError, "#{gem_dir} does not appear to be a gem repository" + end + + spec_dir end - @source_index = Gem::SourceIndex.from_gems_in @spec_dir + @source_index = Gem::SourceIndex.from_gems_in(*@spec_dirs) end def Marshal(req, res) @source_index.refresh! - res['date'] = File.stat(@spec_dir).mtime + add_date res index = Marshal.dump @source_index @@ -471,12 +480,18 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } res.body << index end + def add_date res + res['date'] = @spec_dirs.map do |spec_dir| + File.stat(spec_dir).mtime + end.max + end + def latest_specs(req, res) @source_index.refresh! res['content-type'] = 'application/x-gzip' - res['date'] = File.stat(@spec_dir).mtime + add_date res specs = @source_index.latest_specs.sort.map do |spec| platform = spec.original_platform @@ -535,7 +550,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } @source_index.refresh! res['content-type'] = 'text/plain' - res['date'] = File.stat(@spec_dir).mtime + add_date res case req.request_uri.path when '/quick/index' then @@ -586,7 +601,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } def root(req, res) @source_index.refresh! - res['date'] = File.stat(@spec_dir).mtime + add_date res raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." unless req.path == '/' @@ -630,16 +645,16 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } specs << { "authors" => "Chad Fowler, Rich Kilmer, Jim Weirich, Eric Hodel and others", "dependencies" => [], - "doc_path" => "/doc_root/rubygems-#{Gem::RubyGemsVersion}/rdoc/index.html", + "doc_path" => "/doc_root/rubygems-#{Gem::VERSION}/rdoc/index.html", "executables" => [{"executable" => 'gem', "is_last" => true}], "only_one_executable" => true, - "full_name" => "rubygems-#{Gem::RubyGemsVersion}", + "full_name" => "rubygems-#{Gem::VERSION}", "has_deps" => false, "homepage" => "http://docs.rubygems.org/", "name" => 'rubygems', "rdoc_installed" => true, "summary" => "RubyGems itself", - "version" => Gem::RubyGemsVersion, + "version" => Gem::VERSION, } specs = specs.sort_by { |spec| [spec["name"].downcase, spec["version"]] } @@ -718,7 +733,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } # documentation - just put it underneath the main doc folder. def show_rdoc_for_pattern(pattern, res) - found_gems = Dir.glob("#{@gem_dir}/doc/#{pattern}").select {|path| + found_gems = Dir.glob("{#{@gem_dirs.join ','}}/doc/#{pattern}").select {|path| File.exist? File.join(path, 'rdoc/index.html') } case found_gems.length @@ -771,7 +786,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } @server.mount_proc("/gem-server-rdoc-style.css") do |req, res| res['content-type'] = 'text/css' - res['date'] = File.stat(@spec_dir).mtime + add_date res res.body << RDOC_CSS end @@ -782,7 +797,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } paths = { "/gems" => "/cache/", "/doc_root" => "/doc/" } paths.each do |mount_point, mount_dir| @server.mount(mount_point, WEBrick::HTTPServlet::FileHandler, - File.join(@gem_dir, mount_dir), true) + File.join(@gem_dir.first, mount_dir), true) end trap("INT") { @server.shutdown; exit! } @@ -794,7 +809,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } def specs(req, res) @source_index.refresh! - res['date'] = File.stat(@spec_dir).mtime + add_date res specs = @source_index.sort.map do |_, spec| platform = spec.original_platform @@ -821,7 +836,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } def yaml(req, res) @source_index.refresh! - res['date'] = File.stat(@spec_dir).mtime + add_date res index = @source_index.to_yaml diff --git a/lib/rubygems/source_index.rb b/lib/rubygems/source_index.rb index ac5d8add1e..f9b8ea0f81 100644 --- a/lib/rubygems/source_index.rb +++ b/lib/rubygems/source_index.rb @@ -85,10 +85,10 @@ class Gem::SourceIndex def load_specification(file_name) return nil unless file_name and File.exist? file_name - spec_code = if !defined?(Encoding) then - File.read file_name - else + spec_code = if defined? Encoding then File.read file_name, :encoding => 'UTF-8' + else + File.read file_name end.untaint begin diff --git a/lib/rubygems/source_info_cache.rb b/lib/rubygems/source_info_cache.rb index 4289cdb52a..36615d82a1 100644 --- a/lib/rubygems/source_info_cache.rb +++ b/lib/rubygems/source_info_cache.rb @@ -285,17 +285,19 @@ class Gem::SourceInfoCache cache_data.map do |source_uri, sic_entry| next unless Gem.sources.include? source_uri # TODO - Remove this gunk after 2008/11 - unless pattern.kind_of?(Gem::Dependency) - pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) + unless pattern.kind_of? Gem::Dependency then + pattern = Gem::Dependency.new pattern, Gem::Requirement.default end sic_entry.source_index.search pattern, platform_only end.flatten.compact end + ## # Searches all source indexes for +pattern+. If +only_platform+ is true, # only gems matching Gem.platforms will be selected. Returns an Array of # pairs containing the Gem::Specification found and the source_uri it was # found at. + def search_with_source(pattern, only_platform = false, all = false) read_all_cache_data if all @@ -306,7 +308,7 @@ class Gem::SourceInfoCache # TODO - Remove this gunk after 2008/11 unless pattern.kind_of?(Gem::Dependency) - pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) + pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) end sic_entry.source_index.search(pattern, only_platform).each do |spec| diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb index 027970c342..dac35d85d0 100644 --- a/lib/rubygems/spec_fetcher.rb +++ b/lib/rubygems/spec_fetcher.rb @@ -3,6 +3,7 @@ require 'fileutils' require 'rubygems/remote_fetcher' require 'rubygems/user_interaction' +require 'rubygems/errors' ## # SpecFetcher handles metadata updates from remote gem repositories. @@ -65,22 +66,28 @@ class Gem::SpecFetcher # false, all platforms are returned. If +prerelease+ is true, # prerelease versions are included. - def fetch(dependency, all = false, matching_platform = true, prerelease = false) - specs_and_sources = find_matching dependency, all, matching_platform, prerelease + def fetch_with_errors(dependency, all = false, matching_platform = true, prerelease = false) + specs_and_sources, errors = find_matching_with_errors dependency, all, matching_platform, prerelease - specs_and_sources.map do |spec_tuple, source_uri| + ss = specs_and_sources.map do |spec_tuple, source_uri| [fetch_spec(spec_tuple, URI.parse(source_uri)), source_uri] end + return [ss, errors] + rescue Gem::RemoteFetcher::FetchError => e raise unless warn_legacy e do require 'rubygems/source_info_cache' - return Gem::SourceInfoCache.search_with_source(dependency, - matching_platform, all) + return [Gem::SourceInfoCache.search_with_source(dependency, + matching_platform, all), nil] end end + def fetch(*args) + fetch_with_errors(*args).first + end + def fetch_spec(spec, source_uri) spec = spec - [nil, 'ruby', ''] spec_file_name = "#{spec.join '-'}.gemspec" @@ -117,16 +124,27 @@ class Gem::SpecFetcher # matching released versions are returned. If +matching_platform+ # is false, gems for all platforms are returned. - def find_matching(dependency, all = false, matching_platform = true, prerelease = false) + def find_matching_with_errors(dependency, all = false, matching_platform = true, prerelease = false) found = {} + rejected_specs = {} + list(all, prerelease).each do |source_uri, specs| found[source_uri] = specs.select do |spec_name, version, spec_platform| - dependency =~ Gem::Dependency.new(spec_name, version) and - (not matching_platform or Gem::Platform.match(spec_platform)) + if dependency.match?(spec_name, version) + if matching_platform and !Gem::Platform.match(spec_platform) + pm = (rejected_specs[dependency] ||= Gem::PlatformMismatch.new(spec_name, version)) + pm.add_platform spec_platform + false + else + true + end + end end end + errors = rejected_specs.values + specs_and_sources = [] found.each do |source_uri, specs| @@ -134,7 +152,11 @@ class Gem::SpecFetcher specs_and_sources.push(*specs.map { |spec| [spec, uri_str] }) end - specs_and_sources + [specs_and_sources, errors] + end + + def find_matching(*args) + find_matching_with_errors(*args).first end ## diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 472d60817b..4c5a02d39c 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -504,8 +504,8 @@ class Gem::Specification gemspec = nil raise "NESTED Specification.load calls not allowed!" if @@gather @@gather = proc { |gs| gemspec = gs } - data = File.read(filename) - eval(data) + data = File.read filename + eval data, nil, filename gemspec ensure @@gather = nil @@ -524,7 +524,7 @@ class Gem::Specification # Sets the rubygems_version to the current RubyGems version def mark_version - @rubygems_version = Gem::RubyGemsVersion + @rubygems_version = Gem::VERSION end ## @@ -677,33 +677,43 @@ class Gem::Specification } end - def to_yaml(opts = {}) # :nodoc: + def encode_with coder # :nodoc: mark_version attributes = @@attributes.map { |name,| name.to_s }.sort attributes = attributes - %w[name version platform] + coder.add 'name', @name + coder.add 'version', @version + platform = case @original_platform + when nil, '' then + 'ruby' + when String then + @original_platform + else + @original_platform.to_s + end + coder.add 'platform', platform + + attributes.each do |name| + coder.add name, instance_variable_get("@#{name}") + end + end + + def to_yaml(opts = {}) # :nodoc: + return super if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? + yaml = YAML.quick_emit object_id, opts do |out| out.map taguri, to_yaml_style do |map| - map.add 'name', @name - map.add 'version', @version - platform = case @original_platform - when nil, '' then - 'ruby' - when String then - @original_platform - else - @original_platform.to_s - end - map.add 'platform', platform - - attributes.each do |name| - map.add name, instance_variable_get("@#{name}") - end + encode_with map end end end + def init_with coder # :nodoc: + yaml_initialize coder.tag, coder.map + end + def yaml_initialize(tag, vals) # :nodoc: vals.each do |ivar, val| instance_variable_set "@#{ivar}", val @@ -759,7 +769,7 @@ class Gem::Specification result << " s.specification_version = #{specification_version}" result << nil - result << " if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then" + result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then" unless dependencies.empty? then dependencies.each do |dep| @@ -804,9 +814,9 @@ class Gem::Specification extend Gem::UserInteraction normalize - if rubygems_version != Gem::RubyGemsVersion then + if rubygems_version != Gem::VERSION then raise Gem::InvalidSpecificationException, - "expected RubyGems version #{Gem::RubyGemsVersion}, was #{rubygems_version}" + "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" end @@required_attributes.each do |symbol| @@ -1052,7 +1062,7 @@ class Gem::Specification # # Do not set this, it is set automatically when the gem is packaged. - required_attribute :rubygems_version, Gem::RubyGemsVersion + required_attribute :rubygems_version, Gem::VERSION ## # :attr_accessor: specification_version @@ -1481,14 +1491,12 @@ class Gem::Specification end overwrite_accessor :files do - result = [] - result.push(*@files) if defined?(@files) - result.push(*@test_files) if defined?(@test_files) - result.push(*(add_bindir(@executables))) - result.push(*@extra_rdoc_files) if defined?(@extra_rdoc_files) - result.push(*@extensions) if defined?(@extensions) - result.uniq.compact + # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) + @files = [@files, + @test_files, + add_bindir(@executables), + @extra_rdoc_files, + @extensions, + ].flatten.uniq.compact end - end - diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb index 38ee62fd6d..16e12ef02e 100644 --- a/lib/rubygems/validator.rb +++ b/lib/rubygems/validator.rb @@ -10,11 +10,10 @@ require 'digest' require 'rubygems/format' require 'rubygems/installer' -# Load test-unit 2.x if it's a gem begin - Gem.activate('test-unit') + gem 'test-unit' rescue Gem::LoadError - # Ignore - use the test-unit library that's part of the standard library + # Ignore - use the test-unit library that's part of the standard library end ## diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index 77403ff32b..50d8204a5d 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -212,7 +212,7 @@ class Gem::Version end def hash # :nodoc: - segments.hash + @hash ||= segments.hash end def inspect # :nodoc: @@ -234,6 +234,7 @@ class Gem::Version def marshal_load array initialize array[0] end + ## # A version is considered a prerelease if it contains a letter. @@ -244,6 +245,7 @@ class Gem::Version def pretty_print q # :nodoc: q.text "Gem::Version.new(#{version.inspect})" end + ## # The release for this version (e.g. 1.2.0.a -> 1.2.0). # Non-prerelease versions return themselves. diff --git a/test/rubygems/gemutilities.rb b/test/rubygems/gemutilities.rb index cea1dbeb2a..f1b0f75f51 100644 --- a/test/rubygems/gemutilities.rb +++ b/test/rubygems/gemutilities.rb @@ -8,13 +8,17 @@ else require 'rubygems' end require 'fileutils' -require 'minitest/unit' +require 'minitest/autorun' require 'tmpdir' require 'uri' require 'rubygems/package' require 'rubygems/test_utilities' require 'pp' require 'yaml' +begin + YAML::ENGINE.yamler = 'psych' +rescue LoadError +end if YAML.const_defined? :ENGINE begin gem 'rdoc' @@ -66,10 +70,10 @@ class RubyGemTestCase < MiniTest::Unit::TestCase Gem.ensure_gem_subdirectories @gemhome - if ruby = ENV['RUBY'] - Gem.class_eval {ruby, @ruby = @ruby, ruby} - @orig_ruby = ruby - end + @orig_ruby = if ruby = ENV['RUBY'] then + Gem.class_eval { ruby, @ruby = @ruby, ruby } + ruby + end Gem.ensure_gem_subdirectories @gemhome @@ -131,7 +135,6 @@ class RubyGemTestCase < MiniTest::Unit::TestCase Gem.pre_uninstall do |uninstaller| @pre_uninstall_hook_arg = uninstaller end - end def teardown @@ -150,9 +153,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase Gem.clear_paths - if ruby = @orig_ruby - Gem.class_eval {@ruby = ruby} - end + Gem.class_eval { @ruby = ruby } if ruby = @orig_ruby if @orig_ENV_HOME then ENV['HOME'] = @orig_ENV_HOME @@ -585,5 +586,3 @@ Also, a list: end -MiniTest::Unit.autorun - diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/exception/rubygems_plugin.rb new file mode 100644 index 0000000000..affa72f09c --- /dev/null +++ b/test/rubygems/plugin/exception/rubygems_plugin.rb @@ -0,0 +1,2 @@ +TestGem::TEST_PLUGIN_EXCEPTION = :loaded +raise Exception.new('boom') \ No newline at end of file diff --git a/test/rubygems/plugin/load/rubygems_plugin.rb b/test/rubygems/plugin/load/rubygems_plugin.rb new file mode 100644 index 0000000000..bf020b0f6a --- /dev/null +++ b/test/rubygems/plugin/load/rubygems_plugin.rb @@ -0,0 +1 @@ +TestGem::TEST_PLUGIN_LOAD = :loaded \ No newline at end of file diff --git a/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/test/rubygems/plugin/standarderror/rubygems_plugin.rb new file mode 100644 index 0000000000..d36849f144 --- /dev/null +++ b/test/rubygems/plugin/standarderror/rubygems_plugin.rb @@ -0,0 +1,2 @@ +TestGem::TEST_PLUGIN_STANDARDERROR = :loaded +raise StandardError.new('boom') \ No newline at end of file diff --git a/test/rubygems/rubygems/commands/crash_command.rb b/test/rubygems/rubygems/commands/crash_command.rb new file mode 100644 index 0000000000..e77b3fcd72 --- /dev/null +++ b/test/rubygems/rubygems/commands/crash_command.rb @@ -0,0 +1,5 @@ +class Gem::Commands::CrashCommand < Gem::Command + + raise "crash" + +end \ No newline at end of file diff --git a/test/rubygems/rubygems_plugin.rb b/test/rubygems/rubygems_plugin.rb index 269c3f10db..6c08f97c6d 100644 --- a/test/rubygems/rubygems_plugin.rb +++ b/test/rubygems/rubygems_plugin.rb @@ -1,5 +1,10 @@ require 'rubygems/command_manager' +## +# This is an example of exactly what NOT to do. +# +# DO NOT include code like this in your rubygems_plugin.rb + class Gem::Commands::InterruptCommand < Gem::Command def initialize diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 72074916b2..eacb11a290 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -16,6 +16,8 @@ class TestGem < RubyGemTestCase else %r|/[Rr]uby/[Gg]ems/[0-9.]+| end + + util_remove_interrupt_command end def test_self_all_load_paths @@ -258,8 +260,8 @@ class TestGem < RubyGemTestCase def test_self_find_files discover_path = File.join 'lib', 'foo', 'discover.rb' - cwd = File.expand_path('..', __FILE__) - $LOAD_PATH.unshift(cwd.dup) + cwd = File.expand_path '..', __FILE__ + $LOAD_PATH.unshift cwd.dup foo1 = quick_gem 'foo', '1' do |s| s.files << discover_path @@ -290,7 +292,7 @@ class TestGem < RubyGemTestCase assert_equal expected, Gem.find_files('foo/discover') ensure - assert_equal(cwd, $LOAD_PATH.shift) + assert_equal cwd, $LOAD_PATH.shift end def test_self_latest_load_paths @@ -617,6 +619,38 @@ class TestGem < RubyGemTestCase ENV['USERPATH'] = orig_user_path end if '1.9' > RUBY_VERSION + def test_load_plugins + with_plugin('load') { Gem.load_plugins } + assert_equal :loaded, TEST_PLUGIN_LOAD + + util_remove_interrupt_command + + # Should attempt to cause a StandardError + with_plugin('standarderror') { Gem.load_plugins } + assert_equal :loaded, TEST_PLUGIN_STANDARDERROR + + util_remove_interrupt_command + + # Should attempt to cause an Exception + with_plugin('exception') { Gem.load_plugins } + assert_equal :loaded, TEST_PLUGIN_EXCEPTION + end + + def with_plugin(path) + test_plugin_path = File.expand_path "../plugin/#{path}", __FILE__ + + # A single test plugin should get loaded once only, in order to preserve + # sane test semantics. + refute_includes $LOAD_PATH, test_plugin_path + $LOAD_PATH.unshift test_plugin_path + + capture_io do + yield + end + ensure + $LOAD_PATH.delete test_plugin_path + end + def util_ensure_gem_dirs Gem.ensure_gem_subdirectories @gemhome @additional.each do |dir| @@ -665,5 +699,10 @@ class TestGem < RubyGemTestCase defined?(@RUBY_REVISION) end + def util_remove_interrupt_command + Gem::Commands.send :remove_const, :InterruptCommand if + Gem::Commands.const_defined? :InterruptCommand + end + end diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 143ea692bc..c81cc59abf 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -10,6 +10,8 @@ class TestGemCommandManager < RubyGemTestCase end def test_run_interrupt + Gem.load_plugins + use_ui @ui do assert_raises MockGemUi::TermError do @command_manager.run 'interrupt' @@ -19,6 +21,18 @@ class TestGemCommandManager < RubyGemTestCase end end + def test_run_crash_command + @command_manager.register_command :crash + use_ui @ui do + assert_raises MockGemUi::TermError do + @command_manager.run 'crash' + end + assert_equal '', ui.output + err = ui.error.split("\n").first + assert_equal "ERROR: Loading command: crash (RuntimeError)", err + end + end + def test_process_args_bad_arg use_ui @ui do assert_raises(MockGemUi::TermError) { diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb index e0284c8d5c..2085947afa 100644 --- a/test/rubygems/test_gem_commands_contents_command.rb +++ b/test/rubygems/test_gem_commands_contents_command.rb @@ -139,13 +139,15 @@ Rakefile end def test_handle_options - assert_equal false, @cmd.options[:lib_only] - assert_equal [], @cmd.options[:specdirs] - assert_equal nil, @cmd.options[:version] + refute @cmd.options[:lib_only] + assert @cmd.options[:prefix] + assert_empty @cmd.options[:specdirs] + assert_nil @cmd.options[:version] - @cmd.send :handle_options, %w[-l -s foo --version 0.0.2] + @cmd.send :handle_options, %w[-l -s foo --version 0.0.2 --no-prefix] - assert_equal true, @cmd.options[:lib_only] + assert @cmd.options[:lib_only] + refute @cmd.options[:prefix] assert_equal %w[foo], @cmd.options[:specdirs] assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version] end diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb index 21bacb11af..6d694c3372 100644 --- a/test/rubygems/test_gem_commands_environment_command.rb +++ b/test/rubygems/test_gem_commands_environment_command.rb @@ -12,6 +12,7 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase def test_execute orig_sources = Gem.sources.dup Gem.sources.replace %w[http://gems.example.com] + Gem.configuration['gemcutter_key'] = 'blah' @cmd.send :handle_options, %w[] @@ -32,6 +33,7 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase assert_match %r|GEM PATHS:|, @ui.output assert_match %r|- #{Regexp.escape @gemhome}|, @ui.output assert_match %r|GEM CONFIGURATION:|, @ui.output + assert_match %r|"gemcutter_key" => "\*\*\*\*"|, @ui.output assert_match %r|:verbose => |, @ui.output assert_match %r|REMOTE SOURCES:|, @ui.output assert_equal '', @ui.error @@ -125,7 +127,7 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase @cmd.execute end - assert_equal "#{Gem::RubyGemsVersion}\n", @ui.output + assert_equal "#{Gem::VERSION}\n", @ui.output assert_equal '', @ui.error end diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb index 07e38b4b99..909bcf89de 100644 --- a/test/rubygems/test_gem_commands_fetch_command.rb +++ b/test/rubygems/test_gem_commands_fetch_command.rb @@ -27,7 +27,7 @@ class TestGemCommandsFetchCommand < RubyGemTestCase end assert File.exist?(File.join(@tempdir, @a2.file_name)), - "#{@a2.full_name} fetched" + "#{@a2.full_name} not fetched" end def test_execute_prerelease @@ -52,5 +52,25 @@ class TestGemCommandsFetchCommand < RubyGemTestCase "#{@a2_pre.full_name} not fetched" end + def test_execute_version + util_setup_fake_fetcher + util_setup_spec_fetcher @a1, @a2 + + @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = + File.read(File.join(@gemhome, 'cache', @a1.file_name)) + + @cmd.options[:args] = [@a2.name] + @cmd.options[:version] = Gem::Requirement.new '1' + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + assert File.exist?(File.join(@tempdir, @a1.file_name)), + "#{@a1.full_name} not fetched" + end + end diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 0a3071b719..ccdce787af 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -145,8 +145,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase end # HACK no repository was checked - assert_equal "ERROR: could not find gem no_such_gem locally or in a repository\n", - @ui.error + assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error) end def test_execute_no_gem @@ -170,8 +169,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase assert_equal 2, e.exit_code end - assert_equal "ERROR: could not find gem nonexistent locally or in a repository\n", - @ui.error + assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error) end def test_execute_prerelease diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index b56b33b639..aa54e9f545 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -29,7 +29,34 @@ class TestGemCommandsQueryCommand < RubyGemTestCase *** REMOTE GEMS *** a (2) -pl (1) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + + def test_execute_platform + @a1r = @a1.dup + + @a1.platform = 'x86-linux' + @a2.platform = 'universal-darwin' + + @si = util_setup_spec_fetcher @a1, @a1r, @a2, @b2, @pl1 + + @cmd.handle_options %w[-r -a] + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF + +*** REMOTE GEMS *** + +a (2 universal-darwin, 1 ruby x86-linux) +b (2) +pl (1 i386-linux) EOF assert_equal expected, @ui.output @@ -51,7 +78,7 @@ pl (1) *** REMOTE GEMS *** a (2, 1) -pl (1) +pl (1 i386-linux) EOF assert_equal expected, @ui.output @@ -73,7 +100,7 @@ pl (1) *** REMOTE GEMS *** a (3.a, 2, 1) -pl (1) +pl (1 i386-linux) EOF assert_equal expected, @ui.output @@ -311,7 +338,7 @@ a (3.a, 2, 1) a_evil (9) b (2) c (1.2) -pl (1) +pl (1 i386-linux) EOF assert_equal expected, @ui.output @@ -348,7 +375,7 @@ pl expected = <<-EOF a (2) -pl (1) +pl (1 i386-linux) EOF assert_equal expected, @ui.output @@ -388,7 +415,7 @@ a (3.a, 2, 1) a_evil (9) b (2) c (1.2) -pl (1) +pl (1 i386-linux) EOF assert_equal expected, @ui.output diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb index 5b4faae06e..780e542036 100644 --- a/test/rubygems/test_gem_commands_server_command.rb +++ b/test/rubygems/test_gem_commands_server_command.rb @@ -13,16 +13,23 @@ class TestGemCommandsServerCommand < RubyGemTestCase @cmd.send :handle_options, %w[-p 8808 --no-daemon] assert_equal false, @cmd.options[:daemon] - assert_equal @gemhome, @cmd.options[:gemdir] + assert_equal [], @cmd.options[:gemdir] assert_equal 8808, @cmd.options[:port] @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon] assert_equal true, @cmd.options[:daemon] - assert_equal File.expand_path('/nonexistent'), @cmd.options[:gemdir] + assert_equal [File.expand_path('/nonexistent')], @cmd.options[:gemdir] assert_equal 9999, @cmd.options[:port] end + def test_handle_options_gemdir + @cmd.send :handle_options, %w[--dir a --dir b] + + assert_equal [File.expand_path('a'), File.expand_path('b')], + @cmd.options[:gemdir] + end + def test_handle_options_port @cmd.send :handle_options, %w[-p 0] assert_equal 0, @cmd.options[:port] diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index c9feb31ccb..6113ed61b2 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -64,11 +64,10 @@ class TestGemCommandsUninstallCommand < GemInstallerTestCase util_setup_gem - use_ui @ui do - tmp_rake = ENV['rake'] - ENV['rake'] = @@rake - @installer.install - ENV['rake'] = tmp_rake + build_rake_in do + use_ui @ui do + @installer.install + end end @cmd.options[:args] = ["pre"] diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb index 821ff576ba..f81a84e3ac 100644 --- a/test/rubygems/test_gem_commands_unpack_command.rb +++ b/test/rubygems/test_gem_commands_unpack_command.rb @@ -22,8 +22,8 @@ class TestGemCommandsUnpackCommand < RubyGemTestCase end end - assert File.exist?(File.join(@tempdir, 'a-3.a')), 'a should be installed' - assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be installed' + assert File.exist?(File.join(@tempdir, 'a-3.a')), 'a should be unpacked' + assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked' end def test_execute_gem_path @@ -49,6 +49,7 @@ class TestGemCommandsUnpackCommand < RubyGemTestCase def test_execute_gem_path_missing util_make_gems + util_setup_spec_fetcher Gem.clear_paths @@ -68,6 +69,49 @@ class TestGemCommandsUnpackCommand < RubyGemTestCase assert_equal '', @ui.output end + def test_execute_remote + util_setup_fake_fetcher + util_setup_spec_fetcher @a1, @a2 + util_clear_gems + + a2_data = nil + open File.join(@gemhome, 'cache', @a2.file_name), 'rb' do |fp| + a2_data = fp.read + end + + Gem::RemoteFetcher.fetcher.data['http://gems.example.com/gems/a-2.gem'] = + a2_data + + Gem.configuration.verbose = :really + @cmd.options[:args] = %w[a] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked' + end + + def test_execute_sudo + util_make_gems + + File.chmod 0555, @gemhome + + @cmd.options[:args] = %w[b] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked' + ensure + File.chmod 0755, @gemhome + end + def test_execute_with_target_option util_make_gems diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 4cd0790b92..b76ff7b180 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -46,6 +46,7 @@ class TestGemConfigFile < RubyGemTestCase fp.puts ":benchmark: true" fp.puts ":bulk_threshold: 10" fp.puts ":verbose: false" + fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97" fp.puts ":sources:" fp.puts " - http://more-gems.example.com" fp.puts "install: --wrappers" @@ -61,6 +62,7 @@ class TestGemConfigFile < RubyGemTestCase assert_equal 10, @cfg.bulk_threshold assert_equal false, @cfg.verbose assert_equal false, @cfg.update_sources + assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key assert_equal %w[http://more-gems.example.com], Gem.sources assert_equal '--wrappers', @cfg[:install] assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'], diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index 1f361229a4..fb88735a03 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -134,5 +134,16 @@ class TestGemDependency < RubyGemTestCase assert d.prerelease? end + def test_version_requirements_equals_deprecated + d = dep "pkg", "1.0" + + out, err = capture_io do + d.version_requirements = '2.0' + assert_equal Gem::Requirement.new(%w[2.0]), d.requirement + end + + assert_match %r%deprecated%, err + end + end diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb index 7bc4862d7b..9474f3fd36 100644 --- a/test/rubygems/test_gem_indexer.rb +++ b/test/rubygems/test_gem_indexer.rb @@ -1,5 +1,4 @@ require_relative 'gemutilities' - require 'rubygems/indexer' unless ''.respond_to? :to_xs then @@ -166,7 +165,7 @@ pl-1-i386-linux ExampleForge gems http://example.com Recently released gems from http://example.com - RubyGems v#{Gem::RubyGemsVersion} + RubyGems v#{Gem::VERSION} http://cyber.law.harvard.edu/rss/rss.html a-2 diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index 60ceb3141b..686493511f 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -30,6 +30,9 @@ class TestGemPlatform < RubyGemTestCase 'hppa2.0w-hpux11.31' => ['hppa2.0w', 'hpux', '11'], 'java' => [nil, 'java', nil], 'jruby' => [nil, 'java', nil], + 'universal-dotnet' => ['universal', 'dotnet', nil], + 'universal-dotnet2.0' => ['universal', 'dotnet', '2.0'], + 'universal-dotnet4.0' => ['universal', 'dotnet', '4.0'], 'powerpc-aix5.3.0.0' => ['powerpc', 'aix', '5'], 'powerpc-darwin7' => ['powerpc', 'darwin', '7'], 'powerpc-darwin8' => ['powerpc', 'darwin', '8'], @@ -227,6 +230,22 @@ class TestGemPlatform < RubyGemTestCase util_set_arch 'java' assert_match 'java', Gem::Platform.local assert_match 'jruby', Gem::Platform.local + + util_set_arch 'universal-dotnet2.0' + assert_match 'universal-dotnet', Gem::Platform.local + assert_match 'universal-dotnet-2.0', Gem::Platform.local + refute_match 'universal-dotnet-4.0', Gem::Platform.local + assert_match 'dotnet', Gem::Platform.local + assert_match 'dotnet-2.0', Gem::Platform.local + refute_match 'dotnet-4.0', Gem::Platform.local + + util_set_arch 'universal-dotnet4.0' + assert_match 'universal-dotnet', Gem::Platform.local + refute_match 'universal-dotnet-2.0', Gem::Platform.local + assert_match 'universal-dotnet-4.0', Gem::Platform.local + assert_match 'dotnet', Gem::Platform.local + refute_match 'dotnet-2.0', Gem::Platform.local + assert_match 'dotnet-4.0', Gem::Platform.local util_set_arch 'powerpc-darwin' assert_match 'powerpc-darwin', Gem::Platform.local diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb index 41c25fe7d9..8f8a9cae05 100644 --- a/test/rubygems/test_gem_server.rb +++ b/test/rubygems/test_gem_server.rb @@ -20,6 +20,17 @@ class TestGemServer < RubyGemTestCase @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' end + def test_spec_dirs + s = Gem::Server.new Gem.dir, process_based_port, false + + assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs + + s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false + + assert_equal [File.join(Gem.dir, 'specifications'), + File.join(Gem.dir, 'specifications')], s.spec_dirs + end + def test_Marshal data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" @req.parse data diff --git a/test/rubygems/test_gem_source_index.rb b/test/rubygems/test_gem_source_index.rb index acace09da9..40dfeb95c1 100644 --- a/test/rubygems/test_gem_source_index.rb +++ b/test/rubygems/test_gem_source_index.rb @@ -85,7 +85,7 @@ Gem::Specification.new do |s| current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 2 - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then else end else diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb index 6864fd3beb..95b74d9bfe 100644 --- a/test/rubygems/test_gem_spec_fetcher.rb +++ b/test/rubygems/test_gem_spec_fetcher.rb @@ -115,6 +115,21 @@ class TestGemSpecFetcher < RubyGemTestCase assert_equal [[@pl1.full_name, @gem_repo]], spec_names end + def test_fetch_with_errors_mismatched_platform + util_set_arch 'hrpa-989' + + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] = + util_zip(Marshal.dump(@pl1)) + + dep = Gem::Dependency.new 'pl', 1 + specs_and_sources, errors = @sf.fetch_with_errors dep + + assert_equal 0, specs_and_sources.size + assert_equal 1, errors.size + + assert_equal "i386-linux", errors[0].platforms.first + end + def test_fetch_spec spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" @fetcher.data["#{spec_uri}.rz"] = util_zip(Marshal.dump(@a1)) @@ -220,6 +235,33 @@ class TestGemSpecFetcher < RubyGemTestCase assert_equal [], specs end + def test_find_matching_with_errors_matched_platform + util_set_arch 'i386-linux' + + dep = Gem::Dependency.new 'pl', 1 + specs, errors = @sf.find_matching_with_errors dep + + expected = [ + [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo], + ] + + assert_equal expected, specs + assert_equal 0, errors.size + end + + def test_find_matching_with_errors_invalid_platform + util_set_arch 'hrpa-899' + + dep = Gem::Dependency.new 'pl', 1 + specs, errors = @sf.find_matching_with_errors dep + + assert_equal 0, specs.size + + assert_equal 1, errors.size + + assert_equal "i386-linux", errors[0].platforms.first + end + def test_find_all_platforms util_set_arch 'i386-freebsd6' diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 5979890aeb..97e2615fe2 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -473,6 +473,31 @@ end assert_equal expected, @a1.files.sort end + def test_files_append + @a1.files = %w(files bin/common) + @a1.test_files = %w(test_files bin/common) + @a1.executables = %w(executables common) + @a1.extra_rdoc_files = %w(extra_rdoc_files bin/common) + @a1.extensions = %w(extensions bin/common) + + expected = %w[ + bin/common + bin/executables + extensions + extra_rdoc_files + files + test_files + ] + assert_equal expected, @a1.files.sort + + @a1.files << "generated_file.c" + + expected << "generated_file.c" + expected.sort! + + assert_equal expected, @a1.files.sort + end + def test_files_duplicate @a2.files = %w[a b c d b] @a2.extra_rdoc_files = %w[x y z x] @@ -748,14 +773,14 @@ Gem::Specification.new do |s| s.files = [\"lib/code.rb\"] s.homepage = %q{http://example.com} s.require_paths = [\"lib\"] - s.rubygems_version = %q{#{Gem::RubyGemsVersion}} + s.rubygems_version = %q{#{Gem::VERSION}} s.summary = %q{this is a summary} if s.respond_to? :specification_version then current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [\"= 1\"]) else s.add_dependency(%q, [\"= 1\"]) @@ -802,7 +827,7 @@ Gem::Specification.new do |s| s.require_paths = [\"lib\"] s.requirements = [\"A working computer\"] s.rubyforge_project = %q{example} - s.rubygems_version = %q{#{Gem::RubyGemsVersion}} + s.rubygems_version = %q{#{Gem::VERSION}} s.summary = %q{this is a summary} s.test_files = [\"test/suite.rb\"] @@ -810,7 +835,7 @@ Gem::Specification.new do |s| current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION s.specification_version = 3 - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [\"> 0.4\"]) s.add_runtime_dependency(%q, [\"> 0.0.0\"]) s.add_runtime_dependency(%q, [\"> 0.4\", \"<= 0.6\"]) @@ -883,7 +908,7 @@ end yaml_str = @a1.to_yaml - same_spec = YAML.load(yaml_str) + same_spec = YAML.load yaml_str assert_equal Gem::Platform.new('powerpc-darwin7'), same_spec.platform assert_equal 'powerpc-darwin7.9.0', same_spec.original_platform @@ -1173,7 +1198,7 @@ end @a1.validate end - assert_equal "expected RubyGems version #{Gem::RubyGemsVersion}, was 3", + assert_equal "expected RubyGems version #{Gem::VERSION}, was 3", e.message end @@ -1228,6 +1253,20 @@ end assert_equal Gem::Version.new('1'), @a1.version end + def test_load_errors_contain_filename + specfile = Tempfile.new(self.class.name.downcase) + specfile.write "raise 'boom'" + specfile.close + begin + Gem::Specification.load(specfile.path) + rescue => e + name_rexp = Regexp.new(Regexp.escape(specfile.path)) + assert e.backtrace.grep(name_rexp).any? + end + ensure + specfile.delete + end + def util_setup_validate Dir.chdir @tempdir do FileUtils.mkdir_p File.join('ext', 'a') -- cgit v1.2.3