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/