[rubygems/rubygems] Fix specs with missing extensions getting activated

https://github.com/rubygems/rubygems/commit/c80998a22a
This commit is contained in:
David Rodríguez 2024-10-04 18:21:41 +02:00 committed by git
parent f63873e7a2
commit 3fdf0e7e6d
7 changed files with 88 additions and 37 deletions

View File

@ -269,6 +269,16 @@ module Gem
end
out
end
if Gem.rubygems_version < Gem::Version.new("3.5.22")
module FilterIgnoredSpecs
def matching_specs(platform_only = false)
super.reject(&:ignored?)
end
end
prepend FilterIgnoredSpecs
end
end
require "rubygems/platform"
@ -374,6 +384,15 @@ module Gem
end
end
end
remove_method :ignored? if new.respond_to?(:ignored?)
# Same as RubyGems, but without warnings, because Bundler prints its own warnings
def ignored?
return @ignored unless @ignored.nil?
@ignored = missing_extensions?
end
end
require "rubygems/name_tuple"

View File

@ -357,10 +357,7 @@ module Bundler
@installed_specs ||= Index.build do |idx|
Bundler.rubygems.installed_specs.reverse_each do |spec|
spec.source = self
if spec.missing_extensions?
Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
next
end
next if spec.ignored?
idx << spec
end
end

View File

@ -28,6 +28,17 @@ module Bundler
# @!group Stub Delegates
def ignored?
return @ignored unless @ignored.nil?
@ignored = missing_extensions?
return false unless @ignored
warn "Source #{source} is ignoring #{self} because it is missing extensions"
true
end
def manually_installed?
# This is for manually installed gems which are gems that were fixed in place after a
# failed installation. Once the issue was resolved, the user then manually created

View File

@ -71,18 +71,7 @@ class Gem::BasicSpecification
# Return true if this spec can require +file+.
def contains_requirable_file?(file)
if @ignored
return false
elsif missing_extensions?
@ignored = true
if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
warn "Ignoring #{full_name} because its extensions are not built. " \
"Try: gem pristine #{name} --version #{version}"
end
return false
end
return false if ignored?
is_soext = file.end_with?(".so", ".o")
@ -93,6 +82,23 @@ class Gem::BasicSpecification
end
end
##
# Return true if this spec should be ignored because it's missing extensions.
def ignored?
return @ignored unless @ignored.nil?
@ignored = missing_extensions?
return false unless @ignored
if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
warn "Ignoring #{full_name} because its extensions are not built. " \
"Try: gem pristine #{name} --version #{version}"
end
true
end
def default_gem?
loaded_from &&
File.dirname(loaded_from) == Gem.default_specifications_dir

View File

@ -279,7 +279,7 @@ class Gem::Dependency
end
end
matches
matches.reject(&:ignored?)
end
##

View File

@ -142,7 +142,6 @@ RSpec.shared_examples "bundle install --standalone" do
describe "with default gems and a lockfile", :ruby_repo do
before do
necessary_system_gems = ["tsort --version 0.1.0"]
necessary_system_gems += ["etc --version 1.4.3"]
realworld_system_gems(*necessary_system_gems)
end
@ -173,7 +172,16 @@ RSpec.shared_examples "bundle install --standalone" do
bundle "lock", dir: cwd
bundle "config set --local path #{bundled_app("bundle")}"
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
# Make sure rubyinstaller2 does not activate the etc gem in its
# `operating_system.rb` file, but completely disable that since it's not
# really needed here
if Gem.win_platform?
FileUtils.mkdir_p bundled_app("rubygems/defaults")
FileUtils.touch bundled_app("rubygems/defaults/operating_system.rb")
end
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }, load_path: bundled_app
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }
@ -184,27 +192,35 @@ RSpec.shared_examples "bundle install --standalone" do
end
it "works for gems with extensions and points to the vendored copies, not to the default copies" do
necessary_gems_in_bundle_path = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.4.3", "stringio --version 3.1.0", "shellwords --version 0.2.0", "open3 --version 0.2.1"]
necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a")
realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle")))
build_gem "baz", "1.0.0", to_system: true, default: true, &:add_c_extension
build_repo4 do
build_gem "baz", "1.0.0", &:add_c_extension
end
gemfile <<-G
source "https://gem.repo4"
gem "baz"
G
bundle "config set --local path #{bundled_app("bundle")}"
simulate_platform "arm64-darwin-23" do
necessary_gems_in_bundle_path = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.4.3", "stringio --version 3.1.0", "shellwords --version 0.2.0", "open3 --version 0.2.1"]
necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a")
realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle")))
build_gem "baz", "1.0.0", to_system: true, default: true, &:add_c_extension
build_repo4 do
build_gem "baz", "1.0.0", &:add_c_extension
end
gemfile <<-G
source "https://gem.repo4"
gem "baz"
G
bundle "config set --local path #{bundled_app("bundle")}"
bundle "lock", dir: cwd
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
# Make sure rubyinstaller2 does not activate the etc gem in its
# `operating_system.rb` file, but completely disable that since it's not
# really needed here
if Gem.win_platform?
FileUtils.mkdir_p bundled_app("rubygems/defaults")
FileUtils.touch bundled_app("rubygems/defaults/operating_system.rb")
end
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }, load_path: bundled_app
end
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }

View File

@ -76,9 +76,11 @@ module Spec
requires = options.delete(:requires) || []
dir = options.delete(:dir) || bundled_app
custom_load_path = options.delete(:load_path)
load_path = []
load_path << spec_dir
load_path << custom_load_path if custom_load_path
build_ruby_options = { load_path: load_path, requires: requires, env: env }
build_ruby_options.merge!(artifice: options.delete(:artifice)) if options.key?(:artifice)