[前][次][番号順一覧][スレッド一覧]

ruby-changes:42234

From: hsbt <ko1@a...>
Date: Mon, 28 Mar 2016 11:26:45 +0900 (JST)
Subject: [ruby-changes:42234] hsbt:r54308 (trunk): * lib/rubygems.rb, lib/rubygems/*, test/rubygems/*: Update rubygems-2.6.2.

hsbt	2016-03-28 11:26:39 +0900 (Mon, 28 Mar 2016)

  New Revision: 54308

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54308

  Log:
    * lib/rubygems.rb, lib/rubygems/*, test/rubygems/*: Update rubygems-2.6.2.
      Please see entries of 2.6.2 on
      https://github.com/rubygems/rubygems/blob/master/History.txt

  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/core_ext/kernel_require.rb
    trunk/lib/rubygems/dependency.rb
    trunk/lib/rubygems/installer.rb
    trunk/lib/rubygems/installer_test_case.rb
    trunk/lib/rubygems/resolver.rb
    trunk/lib/rubygems/test_case.rb
    trunk/lib/rubygems.rb
    trunk/test/rubygems/test_gem.rb
    trunk/test/rubygems/test_gem_installer.rb
    trunk/test/rubygems/test_gem_resolver.rb
    trunk/test/rubygems/test_kernel.rb
    trunk/test/rubygems/test_require.rb
Index: lib/rubygems.rb
===================================================================
--- lib/rubygems.rb	(revision 54307)
+++ lib/rubygems.rb	(revision 54308)
@@ -10,7 +10,7 @@ require 'rbconfig' https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L10
 require 'thread'
 
 module Gem
-  VERSION = '2.6.1'
+  VERSION = '2.6.2'
 end
 
 # Must be first since it unloads the prelude from 1.9.2
@@ -174,14 +174,6 @@ module Gem https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L174
   @pre_reset_hooks      ||= []
   @post_reset_hooks     ||= []
 
-  def self.env_requirement(gem_name)
-    @env_requirements_by_name ||= {}
-    @env_requirements_by_name[gem_name] ||= begin
-      req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || '>= 0'.freeze
-      Gem::Requirement.create(req)
-    end
-  end
-
   ##
   # Try to activate a gem containing +path+. Returns true if
   # activation succeeded or wasn't needed because it was already
@@ -243,11 +235,15 @@ module Gem https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L235
     requirements = Gem::Requirement.default if
       requirements.empty?
 
+    find_spec_for_exe(name, exec_name, requirements).bin_file exec_name
+  end
+
+  def self.find_spec_for_exe name, exec_name, requirements
     dep = Gem::Dependency.new name, requirements
 
     loaded = Gem.loaded_specs[name]
 
-    return loaded.bin_file exec_name if loaded && dep.matches_spec?(loaded)
+    return loaded if loaded && dep.matches_spec?(loaded)
 
     specs = dep.matching_specs(true)
 
@@ -263,6 +259,24 @@ module Gem https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L259
       raise Gem::GemNotFoundException, msg
     end
 
+    spec
+  end
+  private_class_method :find_spec_for_exe
+
+  ##
+  # 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.  +requirements+ allows
+  # you to specify specific gem versions.
+  #
+  # A side effect of this method is that it will activate the gem that
+  # contains the executable.
+  #
+  # This method should *only* be used in bin stub files.
+
+  def self.activate_bin_path name, exec_name, requirement # :nodoc:
+    spec = find_spec_for_exe name, exec_name, [requirement]
+    Gem::LOADED_SPECS_MUTEX.synchronize { spec.activate }
     spec.bin_file exec_name
   end
 
@@ -849,6 +863,15 @@ An Array was passed in from #{caller[3]} https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L863
     @ruby_api_version ||= RbConfig::CONFIG['ruby_version'].dup
   end
 
+  def self.env_requirement(gem_name)
+    @env_requirements_by_name ||= {}
+    @env_requirements_by_name[gem_name] ||= begin
+      req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || '>= 0'.freeze
+      Gem::Requirement.create(req)
+    end
+  end
+  post_reset { @env_requirements_by_name = {} }
+
   ##
   # Returns the latest release-version specification for the gem +name+.
 
Index: lib/rubygems/test_case.rb
===================================================================
--- lib/rubygems/test_case.rb	(revision 54307)
+++ lib/rubygems/test_case.rb	(revision 54308)
@@ -223,6 +223,10 @@ class Gem::TestCase < MiniTest::Unit::Te https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L223
     @orig_gem_spec_cache = ENV['GEM_SPEC_CACHE']
     @orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
     @orig_rubygems_host = ENV['RUBYGEMS_HOST']
+    ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
+      ENV.delete k
+    end
+    @orig_gem_env_requirements = ENV.to_hash
 
     ENV['GEM_VENDOR'] = nil
 
@@ -288,6 +292,7 @@ class Gem::TestCase < MiniTest::Unit::Te https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L292
     ENV['HOME'] = @userhome
     Gem.instance_variable_set :@user_home, nil
     Gem.instance_variable_set :@gemdeps, nil
+    Gem.instance_variable_set :@env_requirements_by_name, nil
     Gem.send :remove_instance_variable, :@ruby_version if
       Gem.instance_variables.include? :@ruby_version
 
@@ -379,6 +384,11 @@ class Gem::TestCase < MiniTest::Unit::Te https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L384
 
     FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES']
 
+    ENV.clear
+    @orig_gem_env_requirements.each do |k,v|
+      ENV[k] = v
+    end
+
     ENV['GEM_HOME']   = @orig_gem_home
     ENV['GEM_PATH']   = @orig_gem_path
     ENV['GEM_VENDOR'] = @orig_gem_vendor
@@ -1504,4 +1514,3 @@ tmpdirs << (ENV['GEM_PATH'] = Dir.mktmpd https://github.com/ruby/ruby/blob/trunk/lib/rubygems/test_case.rb#L1514
 pid = $$
 END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
 Gem.clear_paths
-
Index: lib/rubygems/resolver.rb
===================================================================
--- lib/rubygems/resolver.rb	(revision 54307)
+++ lib/rubygems/resolver.rb	(revision 54308)
@@ -193,7 +193,7 @@ class Gem::Resolver https://github.com/ruby/ruby/blob/trunk/lib/rubygems/resolver.rb#L193
     conflict = e.conflicts.values.first
     raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
   ensure
-    @output.close if @output and !debug?
+    @output.close if defined?(@output) and !debug?
   end
 
   ##
@@ -233,7 +233,7 @@ class Gem::Resolver https://github.com/ruby/ruby/blob/trunk/lib/rubygems/resolver.rb#L233
       exc.errors = @set.errors
       raise exc
     end
-    possibles.sort_by { |s| [s.source, s.version, s.platform.to_s == Gem::Platform.local.to_s ? 1 : 0] }.
+    possibles.sort_by { |s| [s.source, s.version, Gem::Platform.local =~ s.platform ? 1 : 0] }.
       map { |s| ActivationRequest.new s, dependency, [] }
   end
 
Index: lib/rubygems/dependency.rb
===================================================================
--- lib/rubygems/dependency.rb	(revision 54307)
+++ lib/rubygems/dependency.rb	(revision 54308)
@@ -286,7 +286,9 @@ class Gem::Dependency https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency.rb#L286
       }
     end
 
-    matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
+    # `stubs_for` returns oldest first, but `matching_specs` is supposed to
+    # return newest first, so just reverse the list
+    matches.reverse
   end
 
   ##
@@ -302,14 +304,13 @@ class Gem::Dependency https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency.rb#L304
     # TODO: check Gem.activated_spec[self.name] in case matches falls outside
 
     if matches.empty? then
-      specs = Gem::Specification.find_all { |s|
-                s.name == name
-              }.map { |x| x.full_name }
+      specs = Gem::Specification.stubs_for name
 
       if specs.empty?
-        total = Gem::Specification.to_a.size
+        total = Gem::Specification.stubs.size
         msg   = "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)\n".dup
       else
+        specs = specs.map(&:full_name)
         msg   = "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]\n".dup
       end
       msg << "Checked in 'GEM_PATH=#{Gem.path.join(File::PATH_SEPARATOR)}', execute `gem env` for more information"
@@ -334,6 +335,6 @@ class Gem::Dependency https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency.rb#L335
 
     matches.delete_if { |spec| spec.nil? || spec.version.prerelease? } unless prerelease?
 
-    matches.last
+    matches.first
   end
 end
Index: lib/rubygems/installer_test_case.rb
===================================================================
--- lib/rubygems/installer_test_case.rb	(revision 54307)
+++ lib/rubygems/installer_test_case.rb	(revision 54308)
@@ -170,6 +170,8 @@ class Gem::InstallerTestCase < Gem::Test https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer_test_case.rb#L170
         EOF
       end
 
+      yield @spec if block_given?
+
       use_ui ui do
         FileUtils.rm_f @gem
 
Index: lib/rubygems/core_ext/kernel_require.rb
===================================================================
--- lib/rubygems/core_ext/kernel_require.rb	(revision 54307)
+++ lib/rubygems/core_ext/kernel_require.rb	(revision 54308)
@@ -121,14 +121,17 @@ module Kernel https://github.com/ruby/ruby/blob/trunk/lib/rubygems/core_ext/kernel_require.rb#L121
   rescue LoadError => load_error
     RUBYGEMS_ACTIVATION_MONITOR.enter
 
-    if load_error.message.start_with?("Could not find") or
-        (load_error.message.end_with?(path) and Gem.try_activate(path)) then
-      RUBYGEMS_ACTIVATION_MONITOR.exit
-      return gem_original_require(path)
-    else
+    begin
+      if load_error.message.start_with?("Could not find") or
+          (load_error.message.end_with?(path) and Gem.try_activate(path)) then
+        require_again = true
+      end
+    ensure
       RUBYGEMS_ACTIVATION_MONITOR.exit
     end
 
+    return gem_original_require(path) if require_again
+
     raise load_error
   end
 
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb	(revision 54307)
+++ lib/rubygems/installer.rb	(revision 54308)
@@ -216,7 +216,8 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L216
       existing = io.read.slice(%r{
           ^(
             gem \s |
-            load \s Gem\.bin_path\(
+            load \s Gem\.bin_path\( |
+            load \s Gem\.activate_bin_path\(
           )
           (['"])(.*?)(\2),
         }x, 3)
@@ -719,7 +720,7 @@ if ARGV.first https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L720
   end
 end
 
-load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
+load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version)
 TEXT
   end
 
Index: test/rubygems/test_gem_resolver.rb
===================================================================
--- test/rubygems/test_gem_resolver.rb	(revision 54307)
+++ test/rubygems/test_gem_resolver.rb	(revision 54308)
@@ -695,6 +695,18 @@ class TestGemResolver < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_resolver.rb#L695
     assert_equal [a1, a1_p1], selected
   end
 
+  def test_search_for_local_platform_partial_string_match
+    a1    = util_spec 'a', 1
+    a1_p1 = util_spec 'a', 1 do |s| s.platform = Gem::Platform.local.os end
+    a1_p2 = util_spec 'a', 1 do |s| s.platform = 'unknown'              end
+
+    s = set(a1_p1, a1_p2, a1)
+    d = [make_dep('a')]
+    r = Gem::Resolver.new(d, s)
+
+    assert_resolves_to [a1_p1], r
+  end
+
   def test_raises_and_explains_when_platform_prevents_install
     a1 = util_spec "a", "1" do |s|
       s.platform = Gem::Platform.new %w[c p 1]
Index: test/rubygems/test_kernel.rb
===================================================================
--- test/rubygems/test_kernel.rb	(revision 54307)
+++ test/rubygems/test_kernel.rb	(revision 54308)
@@ -64,6 +64,13 @@ class TestKernel < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_kernel.rb#L64
     assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease'
   end
 
+  def test_gem_env_req
+    ENV["GEM_REQUIREMENT_A"] = '~> 2.0'
+    assert_raises(Gem::LoadError) { gem('a', '= 1') }
+    assert gem('a', '> 1')
+    assert_equal @a2, Gem.loaded_specs['a']
+  end
+
   def test_gem_conflicting
     assert gem('a', '= 1'), "Should load"
 
Index: test/rubygems/test_gem_installer.rb
===================================================================
--- test/rubygems/test_gem_installer.rb	(revision 54307)
+++ test/rubygems/test_gem_installer.rb	(revision 54308)
@@ -48,7 +48,7 @@ if ARGV.first https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L48
   end
 end
 
-load Gem.bin_path('a', 'executable', version)
+load Gem.activate_bin_path('a', 'executable', version)
     EOF
 
     wrapper = @installer.app_script_text 'executable'
@@ -781,6 +781,55 @@ gem 'other', version https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L781
     assert_match(/ran executable/, e.message)
   end
 
+  def test_conflicting_binstubs
+    Dir.mkdir util_inst_bindir
+    util_clear_gems
+
+    # build old version that has a bin file
+    util_setup_gem do |spec|
+      File.open File.join('bin', 'executable'), 'w' do |f|
+        f.puts "require 'code'"
+      end
+      File.open File.join('lib', 'code.rb'), 'w' do |f|
+        f.puts 'raise "I have an executable"'
+      end
+    end
+
+    @installer.wrappers = true
+    build_rake_in do
+      use_ui @ui do
+        @newspec = @installer.install
+      end
+    end
+
+    old_bin_file = File.join @installer.bin_dir, 'executable'
+
+    # build new version that doesn't have a bin file
+    util_setup_gem do |spec|
+      FileUtils.rm File.join('bin', 'executable')
+      spec.files.delete File.join('bin', 'executable')
+      spec.executables.delete 'executable'
+      spec.version = @spec.version.bump
+      File.open File.join('lib', 'code.rb'), 'w' do |f|
+        f.puts 'raise "I do not have an executable"'
+      end
+    end
+
+    build_rake_in do
+      use_ui @ui do
+        @newspec = @installer.install
+      end
+    end
+
+    e = assert_raises RuntimeError do
+      instance_eval File.read(old_bin_file)
+    end
+
+    # We expect the bin stub to activate the version that actually contains
+    # the binstub.
+    assert_match('I have an executable', e.message)
+  end
+
   def test_install_creates_binstub_that_understand_version
     Dir.mkdir util_inst_bindir
     util_setup_gem
Index: test/rubygems/test_require.rb
===================================================================
--- test/rubygems/test_require.rb	(revision 54307)
+++ test/rubygems/test_require.rb	(revision 54308)
@@ -319,4 +319,32 @@ class TestGemRequire < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_require.rb#L319
   def unresolved_names
     Gem::Specification.unresolved_deps.values.map(&:to_s).sort
   end
+
+  def test_try_activate_error_unlocks_require_monitor
+    silence_warnings do
+      class << ::Gem
+        alias old_try_activate try_activate
+        def try_activate(*); raise 'raised from try_activate'; end
+      end
+    end
+
+    require 'does_not_exist_for_try_activate_test'
+  rescue RuntimeError => e
+    assert_match(/raised from try_activate/, e.message)
+    assert Kernel::RUBYGEMS_ACTIVATION_MONITOR.try_enter, "require monitor was not unlocked when try_activate raised"
+  ensure
+    silence_warnings do
+      class << ::Gem
+        alias try_activate old_try_activate
+      end
+    end
+    Kernel::RUBYGEMS_ACTIVATION_MONITOR.exit
+  end
+
+  def silence_warnings
+    old_verbose, $VERBOSE = $VERBOSE, false
+    yield
+  ensure
+    $VERBOSE = old_verbose
+  end
 end
Index: test/rubygems/test_gem.rb
===================================================================
--- test/rubygems/test_gem.rb	(revision 54307)
+++ test/rubygems/test_gem.rb	(revision 54308)
@@ -816,6 +816,17 @@ class TestGem < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem.rb#L816
     RbConfig::CONFIG['ruby_version'] = orig_ruby_version
   end
 
+  def test_self_env_requirement
+    ENV["GEM_REQUIREMENT_FOO"] = '>= 1.2.3'
+    ENV["GEM_REQUIREMENT_BAR"] = '1.2.3'
+    ENV["GEM_REQUIREMENT_BAZ"] = 'abcd'
+
+    assert_equal Gem::Requirement.create('>= 1.2.3'), Gem.env_requirement('foo')
+    assert_equal Gem::Requirement.create('1.2.3'), Gem.env_requirement('bAr')
+    assert_raises(Gem::Requirement::BadRequirementError) { Gem.env_requirement('baz') }
+    assert_equal Gem::Requirement.default, Gem.env_requirement('qux')
+  end
+
   def test_self_ruby_version_1_8_5
     util_set_RUBY_VERSION '1.8.5'
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54307)
+++ ChangeLog	(revision 54308)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Mar 28 11:26:31 2016  SHIBATA Hiroshi  <hsbt@r...>
+
+	* lib/rubygems.rb, lib/rubygems/*, test/rubygems/*: Update rubygems-2.6.2.
+	  Please see entries of 2.6.2 on
+	  https://github.com/rubygems/rubygems/blob/master/History.txt
+
 Mon Mar 28 11:02:31 2016  Hiroshi Shirosaki  <h.shirosaki@g...>
 
 	* lib/rubygems/test_case.rb: Fix test on Windows for inconsistent temp path.

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]