[rubygems/rubygems] Fix `bundle exec rake install` failing when local gem has extensions and `gemspec` DSL is being used

In a `bundle exec` context, the local specification will actually be
part of the known specifications, so RubyGems will assume it has already
been installed, which is not actually true.

This will cause `RequestSet` to rebuild extensions for a gem that's not
actually installed, causing errors.

The fix is to make sure detection of installed activation requests
considers not only that there's a known spec with the same full name as
the one being installed, but also that this spec is installed in the
same gem_home were pretend to install the new gem.

https://github.com/rubygems/rubygems/commit/a8ef1286a6
This commit is contained in:
David Rodríguez 2024-08-29 14:24:00 +02:00 коммит произвёл git
Родитель 89eba5074e
Коммит e52d4d462f
3 изменённых файлов: 78 добавлений и 2 удалений

Просмотреть файл

@ -407,4 +407,23 @@ module Gem
end
end
end
unless Gem.rubygems_version >= Gem::Version.new("3.5.19")
class Resolver::ActivationRequest
remove_method :installed?
def installed?
case @spec
when Gem::Resolver::VendorSpecification then
true
else
this_spec = full_spec
Gem::Specification.any? do |s|
s == this_spec && s.base_dir == this_spec.base_dir
end
end
end
end
end
end

Просмотреть файл

@ -106,7 +106,7 @@ class Gem::Resolver::ActivationRequest
this_spec = full_spec
Gem::Specification.any? do |s|
s == this_spec
s == this_spec && s.base_dir == this_spec.base_dir
end
end
end

Просмотреть файл

@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe "require 'bundler/gem_tasks'" do
before :each do
let(:define_local_gem_using_gem_tasks) do
bundled_app("foo.gemspec").open("w") do |f|
f.write <<-GEMSPEC
Gem::Specification.new do |s|
@ -26,7 +26,46 @@ RSpec.describe "require 'bundler/gem_tasks'" do
G
end
let(:define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl) do
bundled_app("foo.gemspec").open("w") do |f|
f.write <<-GEMSPEC
Gem::Specification.new do |s|
s.name = "foo"
s.version = "1.0"
s.summary = "dummy"
s.author = "Perry Mason"
s.extensions = "ext/extconf.rb"
end
GEMSPEC
end
bundled_app("Rakefile").open("w") do |f|
f.write <<-RAKEFILE
require "bundler/gem_tasks"
RAKEFILE
end
Dir.mkdir bundled_app("ext")
bundled_app("ext/extconf.rb").open("w") do |f|
f.write <<-EXTCONF
require "mkmf"
File.write("Makefile", dummy_makefile($srcdir).join)
EXTCONF
end
install_gemfile <<-G
source "https://gem.repo1"
gemspec
gem "rake"
G
end
it "includes the relevant tasks" do
define_local_gem_using_gem_tasks
with_gem_path_as(base_system_gem_path.to_s) do
sys_exec "#{rake} -T", env: { "GEM_HOME" => system_gem_path.to_s }
end
@ -44,6 +83,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
end
it "defines a working `rake install` task", :ruby_repo do
define_local_gem_using_gem_tasks
with_gem_path_as(base_system_gem_path.to_s) do
sys_exec "#{rake} install", env: { "GEM_HOME" => system_gem_path.to_s }
end
@ -55,8 +96,18 @@ RSpec.describe "require 'bundler/gem_tasks'" do
expect(err).to be_empty
end
it "defines a working `rake install` task for local gems with extensions", :ruby_repo do
define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl
bundle "exec rake install"
expect(err).to be_empty
end
context "rake build when path has spaces", :ruby_repo do
before do
define_local_gem_using_gem_tasks
spaced_bundled_app = tmp("bundled app")
FileUtils.cp_r bundled_app, spaced_bundled_app
bundle "exec rake build", dir: spaced_bundled_app
@ -69,6 +120,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
context "rake build when path has brackets", :ruby_repo do
before do
define_local_gem_using_gem_tasks
bracketed_bundled_app = tmp("bundled[app")
FileUtils.cp_r bundled_app, bracketed_bundled_app
bundle "exec rake build", dir: bracketed_bundled_app
@ -81,6 +134,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
context "bundle path configured locally" do
before do
define_local_gem_using_gem_tasks
bundle "config set path vendor/bundle"
end
@ -98,6 +153,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do
end
it "adds 'pkg' to rake/clean's CLOBBER" do
define_local_gem_using_gem_tasks
with_gem_path_as(base_system_gem_path.to_s) do
sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), env: { "GEM_HOME" => system_gem_path.to_s }
end