mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[rubygems/rubygems] Fix incorrect bundler version being required
In ruby 2.7.0, there's a slight change in bundler's default gemspec file where the executable folder of the bundler gem is `libexec` instead of `exe`. I made that change in https://github.com/ruby/ruby/pull/2380 to try to simplify the integration of the `bundler` gem with upstream, minimizing the number of changes that need to be made to the gemspec to adapt to the structure of ruby-core. That worked ok, expected for this issue. The new name of the folder including the executable files uncovered a bug in rubygems, which is the following: * In order to be able to use newer versions of default gems, `rubygems` ships with a customized `require` that has knowledge about which files belong to which default gem. If one of these files is required, `rubygems` will detect that and activate its gem mechanism to choose the newest version of the corresponding default gem present in the system (unless a different version has already been activated). It's this part of the custom require:ea3e6f194d/lib/rubygems/core_ext/kernel_require.rb (L77-L85)
* In order to do that, `rubygems` registers a map of default gems and their files when it is first required:ea3e6f194d/lib/rubygems.rb (L1247-L1276)
As explained in the method's header, two types of default gem specifications are supported. One of the formats is the style used by some ruby-core gemspec files, where paths inside the `spec.files` array don't include the `spec.require_paths` part. So in this "old style", if a gem ships with a `lib/bundler.rb` file, it will be registered in this array as `spec.files = ["bundler.rb"]`, not as `spec.files = ["lib/bundler.rb"]`. The `Gem.register_default_spec` method "detects" this style by making sure that none of the files in the `spec.files` array start with any of the `spec.require_paths`. * Since in ruby 2.7 the default specification file of the `bundler` gem includes a `libexec/bundle` file, this check would no longer work correctly, because even though the specification file is still "old style", it has one registered file which starts with "lib", one of the "require paths" of the gem. * This means that the gem is incorrectly detected as "new style", but since none of the paths start with "lib/", no files are actually registered, so the gem is not being considered a default gem, and thus the default version is always used with no possibility of being "upgraded". The fix of the problem is simple: check that no files start with `lib/` (or any other require paths), instead of with "lib" which doesn't exclude other potential "non requirable folder" starting with lib, like in the `bundler` case. https://github.com/rubygems/rubygems/commit/94df740c2b
This commit is contained in:
parent
8250000187
commit
4a417b08ae
Notes:
git
2020-05-08 14:14:15 +09:00
2 changed files with 13 additions and 1 deletions
|
@ -1217,7 +1217,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
|||
|
||||
def register_default_spec(spec)
|
||||
extended_require_paths = spec.require_paths.map {|f| f + "/"}
|
||||
new_format = spec.require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
|
||||
new_format = extended_require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } }
|
||||
|
||||
if new_format
|
||||
prefix_group = extended_require_paths.join("|")
|
||||
|
|
|
@ -1750,6 +1750,18 @@ class TestGem < Gem::TestCase
|
|||
assert_nil Gem.find_unresolved_default_spec("README")
|
||||
end
|
||||
|
||||
def test_register_default_spec_old_style_with_folder_starting_with_lib
|
||||
Gem.clear_default_specs
|
||||
|
||||
old_style = Gem::Specification.new do |spec|
|
||||
spec.files = ["libexec/bundle", "foo.rb", "bar.rb"]
|
||||
end
|
||||
|
||||
Gem.register_default_spec old_style
|
||||
|
||||
assert_equal old_style, Gem.find_unresolved_default_spec("foo.rb")
|
||||
end
|
||||
|
||||
def test_use_gemdeps
|
||||
gem_deps_file = 'gem.deps.rb'.tap(&Gem::UNTAINT)
|
||||
spec = util_spec 'a', 1
|
||||
|
|
Loading…
Reference in a new issue