diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index f25756f92c57..0eee52492f08 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -98,6 +98,20 @@ def default_gem? File.dirname(loaded_from) == Gem.default_specifications_dir end + ## + # Regular gems take precedence over default gems + + def default_gem_priority + default_gem? ? 1 : -1 + end + + ## + # Gems higher up in +gem_path+ take precedence + + def base_dir_priority(gem_path) + gem_path.index(base_dir) || gem_path.size + end + ## # Returns full path to the directory where gem's extensions are installed. diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index da55a2e6d3b9..e50f83385203 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -771,6 +771,11 @@ def self.clear_load_cache # :nodoc: end private_class_method :clear_load_cache + def self.gem_path # :nodoc: + Gem.path + end + private_class_method :gem_path + def self.each_gemspec(dirs) # :nodoc: dirs.each do |dir| Gem::Util.glob_files_in_dir("*.gemspec", dir).each do |path| @@ -832,7 +837,9 @@ def self._resort!(specs) # :nodoc: next versions if versions.nonzero? platforms = Gem::Platform.sort_priority(b.platform) <=> Gem::Platform.sort_priority(a.platform) next platforms if platforms.nonzero? - b.base_dir == Gem.path.first ? 1 : -1 + default_gem = a.default_gem_priority <=> b.default_gem_priority + next default_gem if default_gem.nonzero? + a.base_dir_priority(gem_path) <=> b.base_dir_priority(gem_path) end end @@ -908,7 +915,7 @@ def self.attribute_names # Return the directories that Specification uses to find specs. def self.dirs - @@dirs ||= Gem::SpecificationRecord.dirs_from(Gem.path) + @@dirs ||= Gem::SpecificationRecord.dirs_from(gem_path) end ## diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index 30a4a477f9df..42a31452ae55 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -489,6 +489,22 @@ def test_default_gem_and_normal_gem assert_equal %w[default-3.0], loaded_spec_names end + def test_default_gem_and_normal_gem_same_version + default_gem_spec = new_default_spec("default", "3.0", + nil, "default/gem.rb") + install_default_gems(default_gem_spec) + normal_gem_spec = util_spec("default", "3.0", nil, + "lib/default/gem.rb") + install_specs(normal_gem_spec) + + # Load default ruby gems fresh as if we've just started a ruby script. + Gem::Specification.reset + + assert_require "default/gem" + assert_equal %w[default-3.0], loaded_spec_names + refute Gem.loaded_specs["default"].default_gem? + end + def test_normal_gem_does_not_shadow_default_gem default_gem_spec = new_default_spec("foo", "2.0", nil, "foo.rb") install_default_gems(default_gem_spec)