1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/rubygems: Update to RubyGems master 3de7e0f. Changes:

Only attempt to build extensions for newly-installed gems.  This
  prevents compilation attempts at gem activation time for gems that
  already have extensions built.

  Fix crash in the dependency resolver for dependencies that cannot be
  resolved.

* test/rubygems:  ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43368 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
drbrain 2013-10-20 00:31:12 +00:00
parent 347e748bdd
commit 8552f7aa68
11 changed files with 134 additions and 16 deletions

View file

@ -1,3 +1,16 @@
Sun Oct 20 09:30:56 2013 Eric Hodel <drbrain@segment7.net>
* lib/rubygems: Update to RubyGems master 3de7e0f. Changes:
Only attempt to build extensions for newly-installed gems. This
prevents compilation attempts at gem activation time for gems that
already have extensions built.
Fix crash in the dependency resolver for dependencies that cannot be
resolved.
* test/rubygems: ditto.
Sun Oct 20 05:24:29 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> Sun Oct 20 05:24:29 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* variable.c (rb_class2name): should return real class name, not * variable.c (rb_class2name): should return real class name, not

View file

@ -125,7 +125,7 @@ class Gem::DependencyResolver
# If the existing activation indicates that there are other possibles for # If the existing activation indicates that there are other possibles for
# it, then issue the conflict on the dependency for the activation itself. # it, then issue the conflict on the dependency for the activation itself.
# Otherwise, issue it on the requester's request itself. # Otherwise, issue it on the requester's request itself.
if existing.others_possible? if existing.others_possible? or existing.request.requester.nil? then
conflict = conflict =
Gem::DependencyResolver::DependencyConflict.new dep, existing Gem::DependencyResolver::DependencyConflict.new dep, existing
else else

View file

@ -28,6 +28,9 @@ class Gem::DependencyResolver::VendorSet
spec = Gem::Specification.load gemspec spec = Gem::Specification.load gemspec
raise Gem::GemNotFoundException,
"unable to find #{gemspec} for gem #{name}" unless spec
key = "#{spec.name}-#{spec.version}-#{spec.platform}" key = "#{spec.name}-#{spec.version}-#{spec.platform}"
@specs[key] = spec @specs[key] = spec

View file

@ -346,7 +346,10 @@ class Gem::Installer
def write_spec def write_spec
open spec_file, 'w' do |file| open spec_file, 'w' do |file|
spec.installed_by_version = Gem.rubygems_version
file.puts spec.to_ruby_for_cache file.puts spec.to_ruby_for_cache
file.fsync rescue nil # for filesystems without fsync(2) file.fsync rescue nil # for filesystems without fsync(2)
end end
end end

View file

@ -505,6 +505,23 @@ class Gem::Specification < Gem::BasicSpecification
@extra_rdoc_files ||= [] @extra_rdoc_files ||= []
end end
##
# The version of RubyGems that installed this gem. Returns
# <code>Gem::Version.new(0)</code> for gems installed by versions earlier
# than RubyGems 2.2.0.
def installed_by_version # :nodoc:
@installed_by_version ||= Gem::Version.new(0)
end
##
# Sets the version of RubyGems that installed this gem. See also
# #installed_by_version.
def installed_by_version= version # :nodoc:
@installed_by_version = Gem::Version.new version
end
## ##
# The license for this gem. # The license for this gem.
# #
@ -1391,6 +1408,7 @@ class Gem::Specification < Gem::BasicSpecification
def build_extensions # :nodoc: def build_extensions # :nodoc:
return if default_gem? return if default_gem?
return if extensions.empty? return if extensions.empty?
return if installed_by_version < Gem::Version.new('2.2')
return if File.exist? gem_build_complete_path return if File.exist? gem_build_complete_path
return if !File.writable?(base_dir) && return if !File.writable?(base_dir) &&
!File.exist?(File.join(base_dir, 'extensions')) !File.exist?(File.join(base_dir, 'extensions'))
@ -1776,6 +1794,7 @@ class Gem::Specification < Gem::BasicSpecification
@activated = false @activated = false
self.loaded_from = nil self.loaded_from = nil
@original_platform = nil @original_platform = nil
@installed_by_version = nil
@@nil_attributes.each do |key| @@nil_attributes.each do |key|
instance_variable_set "@#{key}", nil instance_variable_set "@#{key}", nil
@ -1979,7 +1998,12 @@ class Gem::Specification < Gem::BasicSpecification
q.group 2, 'Gem::Specification.new do |s|', 'end' do q.group 2, 'Gem::Specification.new do |s|', 'end' do
q.breakable q.breakable
@@attributes.each do |attr_name| attributes = @@attributes - [:name, :version]
attributes.unshift :installed_by_version
attributes.unshift :version
attributes.unshift :name
attributes.each do |attr_name|
current_value = self.send attr_name current_value = self.send attr_name
if current_value != default_value(attr_name) or if current_value != default_value(attr_name) or
self.class.required_attribute? attr_name then self.class.required_attribute? attr_name then
@ -2262,6 +2286,11 @@ class Gem::Specification < Gem::BasicSpecification
end end
end end
if @installed_by_version then
result << nil
result << " s.installed_by_version = \"#{Gem::VERSION}\""
end
unless dependencies.empty? then unless dependencies.empty? then
result << nil result << nil
result << " if s.respond_to? :specification_version then" result << " if s.respond_to? :specification_version then"

View file

@ -36,6 +36,10 @@ module Gem
List.new value, self List.new value, self
end end
def pretty_print q # :nodoc:
q.pp to_a
end
def self.prepend(list, value) def self.prepend(list, value)
return List.new(value) unless list return List.new(value) unless list
List.new value, list List.new value, list

View file

@ -11,13 +11,17 @@ class TestGemDependencyResolver < Gem::TestCase
StaticSet.new(specs) StaticSet.new(specs)
end end
def assert_set(expected, actual) def assert_resolves_to expected, resolver
actual = resolver.resolve
exp = expected.sort_by { |s| s.full_name } exp = expected.sort_by { |s| s.full_name }
act = actual.map { |a| a.spec }.sort_by { |s| s.full_name } act = actual.map { |a| a.spec }.sort_by { |s| s.full_name }
msg = "Set of gems was not the same: #{exp.map { |x| x.full_name}.inspect} != #{act.map { |x| x.full_name}.inspect}" msg = "Set of gems was not the same: #{exp.map { |x| x.full_name}.inspect} != #{act.map { |x| x.full_name}.inspect}"
assert_equal exp, act, msg assert_equal exp, act, msg
rescue Gem::DependencyResolutionError => e
flunk "#{e.message}\n#{e.conflict.explanation}"
end end
def test_no_overlap_specificly def test_no_overlap_specificly
@ -33,7 +37,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new(deps, s) res = Gem::DependencyResolver.new(deps, s)
assert_set [a, b], res.resolve assert_resolves_to [a, b], res
end end
def test_pulls_in_dependencies def test_pulls_in_dependencies
@ -50,7 +54,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new(deps, s) res = Gem::DependencyResolver.new(deps, s)
assert_set [a, b, c], res.resolve assert_resolves_to [a, b, c], res
end end
def test_picks_highest_version def test_picks_highest_version
@ -63,7 +67,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new([ad], s) res = Gem::DependencyResolver.new([ad], s)
assert_set [a2], res.resolve assert_resolves_to [a2], res
end end
def test_picks_best_platform def test_picks_best_platform
@ -89,7 +93,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new([ad], s) res = Gem::DependencyResolver.new([ad], s)
assert_set [a2_p1], res.resolve assert_resolves_to [a2_p1], res
end end
def test_only_returns_spec_once def test_only_returns_spec_once
@ -105,7 +109,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::DependencyResolver.new([ad, bd], s)
assert_set [a1, b1, c1], res.resolve assert_resolves_to [a1, b1, c1], res
end end
def test_picks_lower_version_when_needed def test_picks_lower_version_when_needed
@ -122,7 +126,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::DependencyResolver.new([ad, bd], s)
assert_set [a1, b1, c1], res.resolve assert_resolves_to [a1, b1, c1], res
cons = res.conflicts cons = res.conflicts
@ -150,7 +154,7 @@ class TestGemDependencyResolver < Gem::TestCase
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::DependencyResolver.new([ad, bd], s)
assert_set [a1, b1, c1, d4], res.resolve assert_resolves_to [a1, b1, c1, d4], res
cons = res.conflicts cons = res.conflicts
@ -266,7 +270,7 @@ class TestGemDependencyResolver < Gem::TestCase
r = Gem::DependencyResolver.new([ad, bd], s) r = Gem::DependencyResolver.new([ad, bd], s)
assert_set [a1, b1, c1], r.resolve assert_resolves_to [a1, b1, c1], r
end end
def test_common_rack_activation_scenario def test_common_rack_activation_scenario
@ -285,13 +289,13 @@ class TestGemDependencyResolver < Gem::TestCase
r = Gem::DependencyResolver.new([d1, d2], s) r = Gem::DependencyResolver.new([d1, d2], s)
assert_set [rails, ap, rack101, lib1], r.resolve assert_resolves_to [rails, ap, rack101, lib1], r
# check it with the deps reverse too # check it with the deps reverse too
r = Gem::DependencyResolver.new([d2, d1], s) r = Gem::DependencyResolver.new([d2, d1], s)
assert_set [lib1, rack101, rails, ap], r.resolve assert_resolves_to [lib1, rack101, rails, ap], r
end end
def test_backtracks_to_the_first_conflict def test_backtracks_to_the_first_conflict
@ -313,6 +317,24 @@ class TestGemDependencyResolver < Gem::TestCase
end end
end end
def test_resolve_conflict
a1 = util_spec 'a', 1
a2 = util_spec 'a', 2
b2 = util_spec 'b', 2, 'a' => '~> 2.0'
s = set a1, a2, b2
a_dep = dep 'a', '~> 1.0'
b_dep = dep 'b'
r = Gem::DependencyResolver.new [a_dep, b_dep], s
assert_raises Gem::DependencyResolutionError do
r.resolve
end
end
# actionmailer 2.3.4 # actionmailer 2.3.4
# activemerchant 1.5.0 # activemerchant 1.5.0
# activesupport 2.3.5, 2.3.4 # activesupport 2.3.5, 2.3.4
@ -333,7 +355,7 @@ class TestGemDependencyResolver < Gem::TestCase
r = Gem::DependencyResolver.new([d1, d2], s) r = Gem::DependencyResolver.new([d1, d2], s)
assert_set [merch, mail, sup1], r.resolve assert_resolves_to [merch, mail, sup1], r
end end
def test_second_level_backout def test_second_level_backout
@ -351,7 +373,7 @@ class TestGemDependencyResolver < Gem::TestCase
r = Gem::DependencyResolver.new([p1, p2], s) r = Gem::DependencyResolver.new([p1, p2], s)
assert_set [b1, c1, d2], r.resolve assert_resolves_to [b1, c1, d2], r
end end
def test_select_local_platforms def test_select_local_platforms

View file

@ -19,6 +19,19 @@ class TestGemDependencyResolverVendorSet < Gem::TestCase
assert_equal "#{name}-#{version}", spec.full_name assert_equal "#{name}-#{version}", spec.full_name
end end
def test_add_vendor_gem_missing
name, version, directory = vendor_gem
FileUtils.rm_r directory
e = assert_raises Gem::GemNotFoundException do
@set.add_vendor_gem name, directory
end
assert_equal "unable to find #{directory}/#{name}.gemspec for gem #{name}",
e.message
end
def test_find_all def test_find_all
name, version, directory = vendor_gem name, version, directory = vendor_gem

View file

@ -1346,7 +1346,12 @@ gem 'other', version
@installer.write_spec @installer.write_spec
assert_path_exists @spec.spec_file assert_path_exists @spec.spec_file
assert_equal @spec, eval(File.read(@spec.spec_file))
loaded = Gem::Specification.load @spec.spec_file
assert_equal @spec, loaded
assert_equal Gem.rubygems_version, @spec.installed_by_version
end end
def test_write_spec_writes_cached_spec def test_write_spec_writes_cached_spec

View file

@ -67,6 +67,7 @@ end
s.mark_version s.mark_version
s.files = %w[lib/code.rb] s.files = %w[lib/code.rb]
s.installed_by_version = v('2.2')
end end
end end
@ -1221,6 +1222,19 @@ dependencies: []
refute_path_exists @a1.extension_install_dir refute_path_exists @a1.extension_install_dir
end end
def test_build_extensions_old
ext_spec
refute_empty @ext.extensions, 'sanity check'
@ext.installed_by_version = v(0)
@ext.build_extensions
gem_make_out = File.join @ext.extension_install_dir, 'gem_make.out'
refute_path_exists gem_make_out
end
def test_contains_requirable_file_eh def test_contains_requirable_file_eh
code_rb = File.join @a1.gem_dir, 'lib', 'code.rb' code_rb = File.join @a1.gem_dir, 'lib', 'code.rb'
FileUtils.mkdir_p File.dirname code_rb FileUtils.mkdir_p File.dirname code_rb
@ -1544,6 +1558,14 @@ dependencies: []
refute_equal @a1.hash, @a2.hash refute_equal @a1.hash, @a2.hash
end end
def test_installed_by_version
assert_equal v(0), @a1.installed_by_version
@a1.installed_by_version = Gem.rubygems_version
assert_equal Gem.rubygems_version, @a1.installed_by_version
end
def test_base_dir def test_base_dir
assert_equal @gemhome, @a1.base_dir assert_equal @gemhome, @a1.base_dir
end end
@ -1841,6 +1863,7 @@ end
@a2.add_runtime_dependency 'b', '1' @a2.add_runtime_dependency 'b', '1'
@a2.dependencies.first.instance_variable_set :@type, nil @a2.dependencies.first.instance_variable_set :@type, nil
@a2.required_rubygems_version = Gem::Requirement.new '> 0' @a2.required_rubygems_version = Gem::Requirement.new '> 0'
@a2.installed_by_version = Gem.rubygems_version
# cached specs do not have spec.files populated: # cached specs do not have spec.files populated:
ruby_code = @a2.to_ruby_for_cache ruby_code = @a2.to_ruby_for_cache
@ -1863,6 +1886,8 @@ Gem::Specification.new do |s|
s.rubygems_version = "#{Gem::VERSION}" s.rubygems_version = "#{Gem::VERSION}"
s.summary = "this is a summary" s.summary = "this is a summary"
s.installed_by_version = "#{Gem::VERSION}"
if s.respond_to? :specification_version then if s.respond_to? :specification_version then
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}

View file

@ -104,6 +104,7 @@ Gem::Specification.new do |s|
s.name = 'stub_e' s.name = 'stub_e'
s.version = Gem::Version.new '2' s.version = Gem::Version.new '2'
s.extensions = ['ext/stub_e/extconf.rb'] s.extensions = ['ext/stub_e/extconf.rb']
s.installed_by_version = '2.2'
end end
STUB STUB