Index: NEWS =================================================================== --- NEWS (revision 41878) +++ NEWS (working copy) @@ -461,8 +461,8 @@ with all sufficient information, see the XML declaration is used for XML document encoding. * RubyGems - * Updated to 2.0.3. See - http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.0.3+%2F+2012-03-1 + * Updated to 2.0.4. See + http://rubygems.rubyforge.org/rubygems-update/History_txt.html#label-2.0.4+%2F+2013-07-09 for release notes. * Updated to 2.0.0 Index: lib/resolv.rb =================================================================== --- lib/resolv.rb (revision 41878) +++ lib/resolv.rb (working copy) @@ -659,7 +659,12 @@ class Resolv def request(sender, tout) start = Time.now timelimit = start + tout - sender.send + begin + sender.send + rescue Errno::EHOSTUNREACH + # multi-homed IPv6 may generate this + raise ResolvTimeout + end while true before_select = Time.now timeout = timelimit - before_select @@ -685,7 +690,7 @@ class Resolv rescue DecodeError next # broken DNS message ignored end - if s = @senders[[from,msg.id]] + if s = sender_for(from, msg) break else # unexpected DNS message ignored @@ -694,6 +699,10 @@ class Resolv return msg, s.data end + def sender_for(addr, msg) + @senders[[addr,msg.id]] + end + def close socks = @socks @socks = nil @@ -814,6 +823,22 @@ class Resolv end end + class MDNSOneShot < UnconnectedUDP # :nodoc: + def sender(msg, data, host, port=Port) + service = [host, port] + id = DNS.allocate_request_id(host, port) + request = msg.encode + request[0,2] = [id].pack('n') + sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] + return @senders[id] = + UnconnectedUDP::Sender.new(request, data, sock, host, port) + end + + def sender_for(addr, msg) + @senders[msg.id] + end + end + class TCP < Requester # :nodoc: def initialize(host, port=Port) super() @@ -2382,11 +2407,96 @@ class Resolv end ## + # Resolv::MDNS is a one-shot Multicast DNS (mDNS) resolver. It blindly + # makes queries to the mDNS addresses without understanding anything about + # multicast ports. + # + # Information taken form the following places: + # + # * RFC 6762 + + class MDNS < DNS + + ## + # Default mDNS Port + + Port = 5353 + + ## + # Default IPv4 mDNS address + + AddressV4 = '224.0.0.251' + + ## + # Default IPv6 mDNS address + + AddressV6 = 'ff02::fb' + + ## + # Default mDNS addresses + + Addresses = [ + [AddressV4, Port], + [AddressV6, Port], + ] + + ## + # Creates a new one-shot Multicast DNS (mDNS) resolver. + # + # +config_info+ can be: + # + # nil:: + # Uses the default mDNS addresses + # + # Hash:: + # Must contain :nameserver or :nameserver_port like + # Resolv::DNS#initialize. + + def initialize(config_info=nil) + if config_info then + super({ nameserver_port: Addresses }.merge(config_info)) + else + super(nameserver_port: Addresses) + end + end + + ## + # Iterates over all IP addresses for +name+ retrieved from the mDNS + # resolver, provided name ends with "local". If the name does not end in + # "local" no records will be returned. + # + # +name+ can be a Resolv::DNS::Name or a String. Retrieved addresses will + # be a Resolv::IPv4 or Resolv::IPv6 + + def each_address(name) + name = Resolv::DNS::Name.create(name) + + return unless name.to_a.last == 'local' + + super(name) + end + + def make_udp_requester # :nodoc: + nameserver_port = @config.nameserver_port + Requester::MDNSOneShot.new(*nameserver_port) + end + + end + + ## # Default resolver to use for Resolv class methods. DefaultResolver = self.new ## + # Replaces the resolvers in the default resolver with +new_resolvers+. This + # allows resolvers to be changed for resolv-replace. + + def DefaultResolver.replace_resolvers new_resolvers + @resolvers = new_resolvers + end + + ## # Address Regexp to use for matching IP addresses. AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/ Index: lib/rubygems/commands/help_command.rb =================================================================== --- lib/rubygems/commands/help_command.rb (revision 41878) +++ lib/rubygems/commands/help_command.rb (working copy) @@ -113,7 +113,15 @@ platform. format = "#{' ' * margin_width}%-#{desc_width}s%s" command_manager.command_names.each do |cmd_name| - summary = command_manager[cmd_name].summary + command = command_manager[cmd_name] + + summary = + if command then + command.summary + else + "[No command found for #{cmd_name}, bug?]" + end + summary = wrap(summary, summary_width).split "\n" out << sprintf(format, cmd_name, summary.shift) until summary.empty? do Index: lib/rubygems/commands/list_command.rb =================================================================== --- lib/rubygems/commands/list_command.rb (revision 41878) +++ lib/rubygems/commands/list_command.rb (working copy) @@ -7,9 +7,8 @@ require 'rubygems/commands/query_command class Gem::Commands::ListCommand < Gem::Commands::QueryCommand - def initialize(name = 'list', - summary = 'Display gems whose name starts with STRING') - super name, summary + def initialize + super 'list', 'Display gems whose name starts with STRING' remove_option('--name-matches') end @@ -27,9 +26,8 @@ class Gem::Commands::ListCommand < Gem:: end def execute - name = get_one_optional_argument || '' - options[:name] = /^#{name}/i - + string = get_one_optional_argument || '' + options[:name] = /^#{string}/i super end Index: lib/rubygems/commands/owner_command.rb =================================================================== --- lib/rubygems/commands/owner_command.rb (revision 41878) +++ lib/rubygems/commands/owner_command.rb (working copy) @@ -73,7 +73,7 @@ class Gem::Commands::OwnerCommand < Gem: request.add_field "Authorization", api_key end - with_response response + with_response response, "Removing #{owner}" rescue # ignore end Index: lib/rubygems/commands/pristine_command.rb =================================================================== --- lib/rubygems/commands/pristine_command.rb (revision 41878) +++ lib/rubygems/commands/pristine_command.rb (working copy) @@ -10,7 +10,8 @@ class Gem::Commands::PristineCommand < G def initialize super 'pristine', 'Restores installed gems to pristine condition from files located in the gem cache', - :version => Gem::Requirement.default, :extensions => true, + :version => Gem::Requirement.default, + :extensions => true, :all => false add_option('--all', @@ -37,7 +38,7 @@ class Gem::Commands::PristineCommand < G end def defaults_str # :nodoc: - "--all --extensions" + '--extensions' end def description # :nodoc: @@ -52,8 +53,8 @@ for the gem are regenerated. If the cached gem cannot be found, you will need to use `gem install` to revert the gem. -If --no-extensions is provided pristine will not attempt to restore gems with -extensions. +If --no-extensions is provided pristine will not attempt to restore gems +with extensions. EOF end Index: lib/rubygems/commands/push_command.rb =================================================================== --- lib/rubygems/commands/push_command.rb (revision 41878) +++ lib/rubygems/commands/push_command.rb (working copy) @@ -20,7 +20,8 @@ class Gem::Commands::PushCommand < Gem:: end def initialize - super 'push', description + super 'push', description, :host => self.host + add_proxy_option add_key_option Index: lib/rubygems/commands/search_command.rb =================================================================== --- lib/rubygems/commands/search_command.rb (revision 41878) +++ lib/rubygems/commands/search_command.rb (working copy) @@ -1,17 +1,31 @@ require 'rubygems/command' -require 'rubygems/commands/list_command' +require 'rubygems/commands/query_command' -class Gem::Commands::SearchCommand < Gem::Commands::ListCommand +class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand def initialize super 'search', 'Display all gems whose name contains STRING' - @defaults[:domain] = :remote + remove_option '--name-matches' + end + + def arguments # :nodoc: + "STRING fragment of gem name to search for" end def defaults_str # :nodoc: "--remote --no-details" end + def usage # :nodoc: + "#{program_name} [STRING]" + end + + def execute + string = get_one_optional_argument + options[:name] = /#{string}/i + super + end + end Index: lib/rubygems/commands/setup_command.rb =================================================================== --- lib/rubygems/commands/setup_command.rb (revision 41878) +++ lib/rubygems/commands/setup_command.rb (working copy) @@ -159,29 +159,7 @@ By default, this RubyGems will install g options[:previous_version] = Gem::Version.new(options[:previous_version]) - release_notes = File.join Dir.pwd, 'History.txt' - - release_notes = if File.exist? release_notes then - history = File.read release_notes - history = history.sub(/^# coding:.*?^=/m, '') - - text = history.split(HISTORY_HEADER) - text.shift # correct an off-by-one generated by split - version_lines = history.scan(HISTORY_HEADER) - versions = history.scan(VERSION_MATCHER).flatten.map { |x| Gem::Version.new(x) } - - history_string = "" - - until versions.length == 0 or versions.shift < options[:previous_version] - history_string += version_lines.shift + text.shift - end - - history_string - else - "Oh-no! Unable to find release notes!" - end - - say release_notes + show_release_notes say say "-" * 78 @@ -458,6 +436,40 @@ abort "#{deprecation_message}" end end + def show_release_notes + release_notes = File.join Dir.pwd, 'History.txt' + + release_notes = + if File.exist? release_notes then + history = File.read release_notes + + history.force_encoding Encoding::UTF_8 if + Object.const_defined? :Encoding + + history = history.sub(/^# coding:.*?^=/m, '') + + text = history.split(HISTORY_HEADER) + text.shift # correct an off-by-one generated by split + version_lines = history.scan(HISTORY_HEADER) + versions = history.scan(VERSION_MATCHER).flatten.map do |x| + Gem::Version.new(x) + end + + history_string = "" + + until versions.length == 0 or + versions.shift < options[:previous_version] do + history_string += version_lines.shift + text.shift + end + + history_string + else + "Oh-no! Unable to find release notes!" + end + + say release_notes + end + def uninstall_old_gemcutter require 'rubygems/uninstaller' Index: lib/rubygems/commands/specification_command.rb =================================================================== --- lib/rubygems/commands/specification_command.rb (revision 41878) +++ lib/rubygems/commands/specification_command.rb (working copy) @@ -28,7 +28,7 @@ class Gem::Commands::SpecificationComman options[:format] = :ruby end - add_option('--yaml', 'Output RUBY format') do |value, options| + add_option('--yaml', 'Output YAML format') do |value, options| options[:format] = :yaml end Index: lib/rubygems/commands/update_command.rb =================================================================== --- lib/rubygems/commands/update_command.rb (revision 41878) +++ lib/rubygems/commands/update_command.rb (working copy) @@ -94,7 +94,7 @@ class Gem::Commands::UpdateCommand < Gem say "Updating #{name}" begin - @installer.install name, version + @installer.install name, Gem::Requirement.new(version) success = true rescue Gem::InstallError => e alert_error "Error installing #{name}:\n\t#{e.message}" Index: lib/rubygems/core_ext/kernel_require.rb =================================================================== --- lib/rubygems/core_ext/kernel_require.rb (revision 41878) +++ lib/rubygems/core_ext/kernel_require.rb (working copy) @@ -4,6 +4,8 @@ # See LICENSE.txt for permissions. #++ +require 'monitor' + module Kernel if defined?(gem_original_require) then @@ -31,7 +33,11 @@ module Kernel # The normal require functionality of returning false if # that file has already been loaded is preserved. + ACTIVATION_MONITOR = Monitor.new + def require path + ACTIVATION_MONITOR.enter + spec = Gem.find_unresolved_default_spec(path) if spec Gem.remove_unresolved_default_spec(spec) @@ -111,6 +117,8 @@ module Kernel end raise load_error + ensure + ACTIVATION_MONITOR.exit end private :require Index: lib/rubygems/defaults.rb =================================================================== --- lib/rubygems/defaults.rb (revision 41878) +++ lib/rubygems/defaults.rb (working copy) @@ -54,7 +54,9 @@ 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] + parts = [Gem.user_home, '.gem', ruby_engine] + parts << ConfigMap[:ruby_version] unless ConfigMap[:ruby_version].empty? + File.join parts end ## Index: lib/rubygems/dependency_installer.rb =================================================================== --- lib/rubygems/dependency_installer.rb (revision 41878) +++ lib/rubygems/dependency_installer.rb (working copy) @@ -63,7 +63,6 @@ class Gem::DependencyInstaller # HACK shouldn't change the global settings, needed for -i behavior # maybe move to the install command? See also github #442 Gem::Specification.dirs = @install_dir - Gem.ensure_gem_subdirectories @install_dir end options = DEFAULT_OPTIONS.merge options Index: lib/rubygems/dependency_resolver.rb =================================================================== --- lib/rubygems/dependency_resolver.rb (revision 41878) +++ lib/rubygems/dependency_resolver.rb (working copy) @@ -349,7 +349,7 @@ module Gem when Dependency @dependency == other when DependencyRequest - @dependency == other.dep && @requester == other.requester + @dependency == other.dependency && @requester == other.requester else false end Index: lib/rubygems/errors.rb =================================================================== --- lib/rubygems/errors.rb (revision 41878) +++ lib/rubygems/errors.rb (working copy) @@ -62,10 +62,10 @@ module Gem ## # A wordy description of the error. def wordy - "Found %s (%), but was for platform%s %s" % + "Found %s (%s), but was for platform%s %s" % [@name, @version, - @platforms.size == 1 ? 's' : '', + @platforms.size == 1 ? '' : 's', @platforms.join(' ,')] end end Index: lib/rubygems/ext/ext_conf_builder.rb =================================================================== --- lib/rubygems/ext/ext_conf_builder.rb (revision 41878) +++ lib/rubygems/ext/ext_conf_builder.rb (working copy) @@ -37,6 +37,7 @@ class Gem::Ext::ExtConfBuilder < Gem::Ex run cmd, results ENV["DESTDIR"] = nil + siteconf.unlink make dest_path, results Index: lib/rubygems/gemcutter_utilities.rb =================================================================== --- lib/rubygems/gemcutter_utilities.rb (revision 41878) +++ lib/rubygems/gemcutter_utilities.rb (working copy) @@ -38,7 +38,7 @@ module Gem::GemcutterUtilities say "Enter your #{pretty_host} credentials." say "Don't have an account yet? " + - "Create one at https://#{sign_in_host}/sign_up" + "Create one at #{sign_in_host}/sign_up" email = ask " Email: " password = ask_for_password "Password: " @@ -60,7 +60,14 @@ module Gem::GemcutterUtilities configured_host = Gem.host unless Gem.configuration.disable_default_gem_server - @host ||= ENV['RUBYGEMS_HOST'] || configured_host + @host ||= + begin + env_rubygems_host = ENV['RUBYGEMS_HOST'] + env_rubygems_host = nil if + env_rubygems_host and env_rubygems_host.empty? + + env_rubygems_host|| configured_host + end end def rubygems_api_request(method, path, host = nil, &block) @@ -79,7 +86,7 @@ module Gem::GemcutterUtilities Gem::RemoteFetcher.fetcher.request(uri, request_method, &block) end - def with_response(resp) + def with_response resp, error_prefix = nil case resp when Net::HTTPSuccess then if block_given? then @@ -88,7 +95,10 @@ module Gem::GemcutterUtilities say resp.body end else - say resp.body + message = resp.body + message = "#{error_prefix}: #{message}" if error_prefix + + say message terminate_interaction 1 # TODO: question this end end Index: lib/rubygems/installer.rb =================================================================== --- lib/rubygems/installer.rb (revision 41878) +++ lib/rubygems/installer.rb (working copy) @@ -331,8 +331,9 @@ class Gem::Installer # specifications directory. def write_spec - File.open(spec_file, "w") do |file| + open spec_file, 'w' do |file| file.puts spec.to_ruby_for_cache + file.fsync rescue nil # for filesystems without fsync(2) end end @@ -773,7 +774,13 @@ EOF def write_build_info_file return if @build_args.empty? - open spec.build_info_file, 'w' do |io| + build_info_dir = File.join gem_home, 'build_info' + + FileUtils.mkdir_p build_info_dir + + build_info_file = File.join build_info_dir, "#{spec.full_name}.info" + + open build_info_file, 'w' do |io| @build_args.each do |arg| io.puts arg end Index: lib/rubygems/package/old.rb =================================================================== --- lib/rubygems/package/old.rb (revision 41878) +++ lib/rubygems/package/old.rb (working copy) @@ -23,9 +23,10 @@ class Gem::Package::Old < Gem::Package require 'zlib' Gem.load_yaml - @gem = gem - @contents = nil - @spec = nil + @contents = nil + @gem = gem + @security_policy = nil + @spec = nil end ## @@ -142,7 +143,7 @@ class Gem::Package::Old < Gem::Package end end - yaml_error = if RUBY_VERSION < '1.8' then + yaml_error = if RUBY_VERSION < '1.9' then YAML::ParseError elsif YAML::ENGINE.yamler == 'syck' then YAML::ParseError Index: lib/rubygems/package.rb =================================================================== --- lib/rubygems/package.rb (revision 41878) +++ lib/rubygems/package.rb (working copy) @@ -336,7 +336,6 @@ EOM open destination, 'wb', entry.header.mode do |out| out.write entry.read - out.fsync rescue nil # for filesystems without fsync(2) end say destination if Gem.configuration.really_verbose Index: lib/rubygems/platform.rb =================================================================== --- lib/rubygems/platform.rb (revision 41878) +++ lib/rubygems/platform.rb (working copy) @@ -74,6 +74,7 @@ class Gem::Platform when /hpux(\d+)?/ then [ 'hpux', $1 ] when /^java$/, /^jruby$/ then [ 'java', nil ] when /^java([\d.]*)/ then [ 'java', $1 ] + when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ] when /^dotnet$/ then [ 'dotnet', nil ] when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] when /linux/ then [ 'linux', $1 ] @@ -155,6 +156,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 /^dalvik(\d+)?$/ then [nil, 'dalvik', $1 ] when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ] when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ] when 'powerpc-darwin' then ['powerpc', 'darwin', nil ] Index: lib/rubygems/psych_tree.rb =================================================================== --- lib/rubygems/psych_tree.rb (revision 41878) +++ lib/rubygems/psych_tree.rb (working copy) @@ -1,6 +1,10 @@ module Gem if defined? ::Psych::Visitors class NoAliasYAMLTree < Psych::Visitors::YAMLTree + def self.create + new({}) + end unless respond_to? :create + def visit_String(str) return super unless str == '=' # or whatever you want Index: lib/rubygems/specification.rb =================================================================== --- lib/rubygems/specification.rb (revision 41878) +++ lib/rubygems/specification.rb (working copy) @@ -5,6 +5,17 @@ # See LICENSE.txt for permissions. #++ +require 'rubygems/version' +require 'rubygems/requirement' +require 'rubygems/platform' +require 'rubygems/deprecate' + +# :stopdoc: +# date.rb can't be loaded for `make install` due to miniruby +# Date is needed for old gems that stored #date as Date instead of Time. +class Date; end +# :startdoc: + ## # The Specification class contains the information for a Gem. Typically # defined in a .gemspec file or a Rakefile, and looks like this: @@ -20,32 +31,19 @@ # s.homepage = 'https://rubygems.org/gems/example' # end # -# Starting in RubyGems 1.9.0, a Specification can hold arbitrary -# metadata. This metadata is accessed via Specification#metadata -# and has the following restrictions: +# Starting in RubyGems 1.9.0, a Specification can hold arbitrary +# metadata. This metadata is accessed via Specification#metadata +# and has the following restrictions: # -# * Must be a Hash object -# * All keys and values must be Strings -# * Keys can be a maximum of 128 bytes and values can be a -# maximum of 1024 bytes -# * All strings must be UTF8, no binary data is allowed +# * Must be a Hash object +# * All keys and values must be Strings +# * Keys can be a maximum of 128 bytes and values can be a +# maximum of 1024 bytes +# * All strings must be UTF8, no binary data is allowed # -# For example, to add metadata for the location of a bugtracker: +# For example, to add metadata for the location of a bugtracker: # # s.metadata = { "bugtracker" => "http://somewhere.com/blah" } -# - - -require 'rubygems/version' -require 'rubygems/requirement' -require 'rubygems/platform' -require 'rubygems/deprecate' - -# :stopdoc: -# date.rb can't be loaded for `make install` due to miniruby -# Date is needed for old gems that stored #date as Date instead of Time. -class Date; end -# :startdoc: class Gem::Specification @@ -918,7 +916,7 @@ class Gem::Specification result = Hash.new { |h,k| h[k] = {} } native = {} - Gem::Specification._all.reverse_each do |spec| + Gem::Specification.reverse_each do |spec| next if spec.version.prerelease? unless prerelease native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY @@ -995,7 +993,7 @@ class Gem::Specification # TODO: maybe we should switch to rubygems' version service? fetcher = Gem::SpecFetcher.fetcher - latest_specs.each do |local| + latest_specs(true).each do |local| dependency = Gem::Dependency.new local.name, ">= #{local.version}" remotes, _ = fetcher.search_for_dependency dependency remotes = remotes.map { |n, _| n.version } @@ -1236,7 +1234,7 @@ class Gem::Specification unless dependency.respond_to?(:name) && dependency.respond_to?(:version_requirements) - dependency = Gem::Dependency.new(dependency, requirements, type) + dependency = Gem::Dependency.new(dependency.to_s, requirements, type) end dependencies << dependency @@ -2270,7 +2268,7 @@ class Gem::Specification require 'rubygems/psych_tree' end - builder = Gem::NoAliasYAMLTree.new({}) + builder = Gem::NoAliasYAMLTree.create builder << self ast = builder.tree Index: lib/rubygems.rb =================================================================== --- lib/rubygems.rb (revision 41878) +++ lib/rubygems.rb (working copy) @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.0.3' + VERSION = '2.0.4' end # Must be first since it unloads the prelude from 1.9.2 @@ -173,7 +173,12 @@ module Gem # require will try to activate the more specific version. spec = Gem::Specification.find_inactive_by_path path - return false unless spec + + unless spec + spec = Gem::Specification.find_by_path path + return true if spec && spec.activated? + return false + end begin spec.activate Index: test/rubygems/test_gem.rb =================================================================== --- test/rubygems/test_gem.rb (revision 41878) +++ test/rubygems/test_gem.rb (working copy) @@ -1198,8 +1198,10 @@ class TestGem < Gem::TestCase end def test_self_user_dir - assert_equal File.join(@userhome, '.gem', Gem.ruby_engine, - Gem::ConfigMap[:ruby_version]), Gem.user_dir + parts = [@userhome, '.gem', Gem.ruby_engine] + parts << Gem::ConfigMap[:ruby_version] unless Gem::ConfigMap[:ruby_version].empty? + + assert_equal File.join(parts), Gem.user_dir end def test_self_user_home Index: test/rubygems/test_gem_commands_help_command.rb =================================================================== --- test/rubygems/test_gem_commands_help_command.rb (revision 41878) +++ test/rubygems/test_gem_commands_help_command.rb (working copy) @@ -10,6 +10,9 @@ class TestGemCommandsHelpCommand < Gem:: super @cmd = Gem::Commands::HelpCommand.new + + load File.expand_path('../rubygems_plugin.rb', __FILE__) unless + Gem::Commands.const_defined? :InterruptCommand end def test_gem_help_bad @@ -34,6 +37,8 @@ class TestGemCommandsHelpCommand < Gem:: assert_match(/\s+#{cmd}\s+\S+/, out) end assert_equal '', err + + refute_match 'No command found for ', out end end Index: test/rubygems/test_gem_commands_owner_command.rb =================================================================== --- test/rubygems/test_gem_commands_owner_command.rb (revision 41878) +++ test/rubygems/test_gem_commands_owner_command.rb (working copy) @@ -140,4 +140,16 @@ EOF assert_equal '701229f217cdf23b1344c7b4b54ca97', @fetcher.last_request['Authorization'] end + + def test_remove_owners_missing + response = 'Owner could not be found.' + @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 404, 'Not Found'] + + use_ui @ui do + @cmd.remove_owners("freewill", ["missing@example"]) + end + + assert_equal "Removing missing@example: #{response}\n", @ui.output + end + end Index: test/rubygems/test_gem_commands_push_command.rb =================================================================== --- test/rubygems/test_gem_commands_push_command.rb (revision 41878) +++ test/rubygems/test_gem_commands_push_command.rb (working copy) @@ -61,6 +61,22 @@ class TestGemCommandsPushCommand < Gem:: assert_match @response, @ui.output end + def test_execute + open 'example', 'w' do |io| io.write 'hello' end + + @response = "Successfully registered gem: freewill (1.0.0)" + @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] + + @cmd.options[:args] = %w[example] + + @cmd.execute + + assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal 'hello', @fetcher.last_request.body + assert_equal "application/octet-stream", + @fetcher.last_request["Content-Type"] + end + def test_execute_host host = 'https://other.example' Index: test/rubygems/test_gem_commands_search_command.rb =================================================================== --- test/rubygems/test_gem_commands_search_command.rb (revision 41878) +++ test/rubygems/test_gem_commands_search_command.rb (working copy) @@ -1,25 +0,0 @@ -require 'rubygems/test_case' -require 'rubygems/commands/search_command' - -class TestGemCommandsSearchCommand < Gem::TestCase - - def setup - super - - @cmd = Gem::Commands::SearchCommand.new - end - - def test_execute - @cmd.handle_options %w[a] - - use_ui @ui do - @cmd.execute - end - - assert_match %r%REMOTE GEMS%, @ui.output - - assert_empty @ui.error - end - -end - Index: test/rubygems/test_gem_commands_setup_command.rb =================================================================== --- test/rubygems/test_gem_commands_setup_command.rb (revision 41878) +++ test/rubygems/test_gem_commands_setup_command.rb (working copy) @@ -1,3 +1,5 @@ +# coding: UTF-8 + require 'rubygems/test_case' require 'rubygems/commands/setup_command' @@ -73,5 +75,55 @@ class TestGemCommandsSetupCommand < Gem: assert_path_exists os_defaults_rb end + def test_show_release_notes + @default_external = nil + capture_io do + @default_external, Encoding.default_external = + Encoding.default_external, Encoding::US_ASCII + end if Object.const_defined? :Encoding + + @cmd.options[:previous_version] = Gem::Version.new '2.0.2' + + open 'History.txt', 'w' do |io| + io.puts <<-History_txt +# coding: UTF-8 + +=== #{Gem::VERSION} / 2013-03-26 + +* Bug fixes: + * Fixed release note display for LANG=C when installing rubygems + * π is tasty + +=== 2.0.2 / 2013-03-06 + +* Bug fixes: + * Other bugs fixed + +=== 2.0.1 / 2013-03-05 + +* Bug fixes: + * Yet more bugs fixed + History_txt + end + + use_ui @ui do + @cmd.show_release_notes + end + + expected = <<-EXPECTED +=== 2.0.2 / 2013-03-06 + +* Bug fixes: + * Other bugs fixed + + EXPECTED + + assert_equal expected, @ui.output + ensure + capture_io do + Encoding.default_external = @default_external + end if @default_external + end + end Index: test/rubygems/test_gem_ext_ext_conf_builder.rb =================================================================== --- test/rubygems/test_gem_ext_ext_conf_builder.rb (revision 41878) +++ test/rubygems/test_gem_ext_ext_conf_builder.rb (working copy) @@ -34,6 +34,7 @@ class TestGemExtExtConfBuilder < Gem::Te assert_equal "creating Makefile\n", output[1] assert_contains_make_command '', output[2] assert_contains_make_command 'install', output[4] + assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb')) end def test_class_build_rbconfig_make_prog Index: test/rubygems/test_gem_gemcutter_utilities.rb =================================================================== --- test/rubygems/test_gem_gemcutter_utilities.rb (revision 41878) +++ test/rubygems/test_gem_gemcutter_utilities.rb (working copy) @@ -15,6 +15,13 @@ class TestGemGemcutterUtilities < Gem::T @cmd.extend Gem::GemcutterUtilities end + def teardown + ENV['RUBYGEMS_HOST'] = nil + Gem.configuration.rubygems_api_key = nil + + super + end + def test_alternate_key_alternate_host keys = { :rubygems_api_key => 'KEY', @@ -63,6 +70,22 @@ class TestGemGemcutterUtilities < Gem::T assert_equal 'OTHER', @cmd.api_key end + def test_host + assert_equal 'https://rubygems.org', @cmd.host + end + + def test_host_RUBYGEMS_HOST + ENV['RUBYGEMS_HOST'] = 'https://other.example' + + assert_equal 'https://other.example', @cmd.host + end + + def test_host_RUBYGEMS_HOST_empty + ENV['RUBYGEMS_HOST'] = '' + + assert_equal 'https://rubygems.org', @cmd.host + end + def test_sign_in api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' util_sign_in [api_key, 200, 'OK'] Index: test/rubygems/test_gem_installer.rb =================================================================== --- test/rubygems/test_gem_installer.rb (revision 41878) +++ test/rubygems/test_gem_installer.rb (working copy) @@ -1365,6 +1365,20 @@ gem 'other', version refute_path_exists @spec.build_info_file end + def test_write_build_info_file_install_dir + installer = Gem::Installer.new @gem, :install_dir => "#{@gemhome}2" + + installer.build_args = %w[ + --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4 + ] + + installer.write_build_info_file + + refute_path_exists @spec.build_info_file + assert_path_exists \ + File.join("#{@gemhome}2", 'build_info', "#{@spec.full_name}.info") + end + def test_write_cache_file cache_file = File.join @gemhome, 'cache', @spec.file_name gem = File.join @gemhome, @spec.file_name Index: test/rubygems/test_gem_package.rb =================================================================== --- test/rubygems/test_gem_package.rb (revision 41878) +++ test/rubygems/test_gem_package.rb (working copy) @@ -335,6 +335,7 @@ class TestGemPackage < Gem::Package::Tar end def test_install_location_extra_slash + skip 'no File.realpath on 1.8' if RUBY_VERSION < '1.9' package = Gem::Package.new @gem file = 'foo//file.rb' @@ -511,7 +512,8 @@ class TestGemPackage < Gem::Package::Tar package.verify end - assert_match ' - nonexistent.gem', e.message + assert_match %r%^No such file or directory%, e.message + assert_match %r%nonexistent.gem$%, e.message end def test_verify_security_policy Index: test/rubygems/test_gem_spec_fetcher.rb =================================================================== --- test/rubygems/test_gem_spec_fetcher.rb (revision 41878) +++ test/rubygems/test_gem_spec_fetcher.rb (working copy) @@ -132,8 +132,10 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal 0, specs_and_sources.size assert_equal 1, errors.size + pmm = errors.first - assert_equal "i386-linux", errors[0].platforms.first + assert_equal "i386-linux", pmm.platforms.first + assert_equal "Found pl (1), but was for platform i386-linux", pmm.wordy end def test_spec_for_dependency_bad_fetch_spec Index: test/rubygems/test_gem_specification.rb =================================================================== --- test/rubygems/test_gem_specification.rb (revision 41878) +++ test/rubygems/test_gem_specification.rb (working copy) @@ -434,6 +434,21 @@ dependencies: [] assert_equal expected, Gem::Specification.normalize_yaml_input(input) end + def test_self_outdated + util_clear_gems + util_setup_fake_fetcher true + + a4 = quick_gem @a1.name, '4' + util_build_gem a4 + util_setup_spec_fetcher @a1, @a2, @a3a, a4 + + Gem::Specification.remove_spec @a1 + Gem::Specification.remove_spec @a2 + Gem::Specification.remove_spec a4 + + assert_equal %w[a], Gem::Specification.outdated + end + DATA_PATH = File.expand_path "../data", __FILE__ def test_handles_private_null_type @@ -597,7 +612,16 @@ dependencies: [] assert @a2.activated? end - def test_add_dependency_with_explicit_type + def test_add_dependency_with_type + gem = quick_spec "awesome", "1.0" do |awesome| + awesome.add_dependency true + awesome.add_dependency :gem_name + end + + assert_equal %w[true gem_name], gem.dependencies.map { |dep| dep.name } + end + + def test_add_dependency_with_type_explicit gem = quick_spec "awesome", "1.0" do |awesome| awesome.add_development_dependency "monkey" end