diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml index a95c7005c41054..7f52dc08b62cc6 100644 --- a/.github/workflows/dependabot_automerge.yml +++ b/.github/workflows/dependabot_automerge.yml @@ -17,7 +17,7 @@ jobs: id: metadata - name: Wait for status checks - uses: lewagon/wait-on-check-action@3603e826ee561ea102b58accb5ea55a1a7482343 # v1.4.1 + uses: lewagon/wait-on-check-action@74049309dfeff245fe8009a0137eacf28136cb3c # v1.5.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} ref: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/doc/syntax/literals.rdoc b/doc/syntax/literals.rdoc index 87a891bf2d3c05..c876558d4e07b9 100644 --- a/doc/syntax/literals.rdoc +++ b/doc/syntax/literals.rdoc @@ -547,6 +547,13 @@ with %w (non-interpolable) or %W (interpolable): # (not nested array). %w[foo[bar baz]qux] # => ["foo[bar", "baz]qux"] +The interpolated string is treated as a single word even if it contains +whitespace. + + s = "bar baz" + %W[foo #{s} zot] #=> ["foo", "bar baz", "zot"] + %W[foo #{"bar baz zot"} qux] # => ["foo", "bar baz zot", "qux"] + The following characters are considered as white spaces to separate words: * space, ASCII 20h (SPC) diff --git a/lib/rubygems.rb b/lib/rubygems.rb index b52dd1b9d3e99a..31abb7e56987ea 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -193,11 +193,12 @@ def self.try_activate(path) begin spec.activate rescue Gem::LoadError => e # this could fail due to gem dep collisions, go lax - spec_by_name = Gem::Specification.find_by_name(spec.name) - if spec_by_name.nil? + spec = Gem::Specification.find_unloaded_by_path(path) + spec ||= Gem::Specification.find_by_name(spec.name) + if spec.nil? raise e else - spec_by_name.activate + spec.activate end end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 3d1f2dad910485..aa495696adce3c 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -958,6 +958,15 @@ def self.find_by_path(path) specification_record.find_by_path(path) end + ## + # Return the best specification that contains the file matching +path+ + # amongst the specs that are not loaded. This method is different than + # +find_inactive_by_path+ as it will filter out loaded specs by their name. + + def self.find_unloaded_by_path(path) + specification_record.find_unloaded_by_path(path) + end + ## # Return the best specification that contains the file matching +path+ # amongst the specs that are not activated. diff --git a/lib/rubygems/specification_record.rb b/lib/rubygems/specification_record.rb index d08410096facdd..c7e5cbedb58ce6 100644 --- a/lib/rubygems/specification_record.rb +++ b/lib/rubygems/specification_record.rb @@ -154,6 +154,19 @@ def find_by_path(path) spec.to_spec end + ## + # Return the best specification that contains the file matching +path+ + # amongst the specs that are not loaded. This method is different than + # +find_inactive_by_path+ as it will filter out loaded specs by their name. + + def find_unloaded_by_path(path) + stub = stubs.find do |s| + next if Gem.loaded_specs[s.name] + s.contains_requirable_file? path + end + stub&.to_spec + end + ## # Return the best specification in the record that contains the file # matching +path+ amongst the specs that are not activated. diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index f63c23c3159db5..e5f9d7bed2c901 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -431,6 +431,22 @@ def test_default_gem_only assert_equal %w[default-2.0.0.0], loaded_spec_names end + def test_multiple_gems_with_the_same_path_the_non_activated_spec_is_chosen + a1 = util_spec "a", "1", nil, "lib/ib.rb" + a2 = util_spec "a", "2", nil, "lib/foo.rb" + b1 = util_spec "b", "1", nil, "lib/ib.rb" + + install_specs a1, a2, b1 + + a2.activate + + assert_equal %w[a-2], loaded_spec_names + assert_empty unresolved_names + + assert_require "ib" + assert_equal %w[a-2 b-1], loaded_spec_names + end + def test_default_gem_require_activates_just_once default_gem_spec = new_default_spec("default", "2.0.0.0", nil, "default/gem.rb")