Skip to content

Commit 3fdf0e7

Browse files
deivid-rodriguezmatzbot
authored andcommitted
[rubygems/rubygems] Fix specs with missing extensions getting activated
rubygems/rubygems@c80998a22a
1 parent f63873e commit 3fdf0e7

File tree

7 files changed

+84
-33
lines changed

7 files changed

+84
-33
lines changed

lib/bundler/rubygems_ext.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,16 @@ def to_lock
269269
end
270270
out
271271
end
272+
273+
if Gem.rubygems_version < Gem::Version.new("3.5.22")
274+
module FilterIgnoredSpecs
275+
def matching_specs(platform_only = false)
276+
super.reject(&:ignored?)
277+
end
278+
end
279+
280+
prepend FilterIgnoredSpecs
281+
end
272282
end
273283

274284
require "rubygems/platform"
@@ -374,6 +384,15 @@ def extensions_dir
374384
end
375385
end
376386
end
387+
388+
remove_method :ignored? if new.respond_to?(:ignored?)
389+
390+
# Same as RubyGems, but without warnings, because Bundler prints its own warnings
391+
def ignored?
392+
return @ignored unless @ignored.nil?
393+
394+
@ignored = missing_extensions?
395+
end
377396
end
378397

379398
require "rubygems/name_tuple"

lib/bundler/source/rubygems.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,7 @@ def installed_specs
357357
@installed_specs ||= Index.build do |idx|
358358
Bundler.rubygems.installed_specs.reverse_each do |spec|
359359
spec.source = self
360-
if spec.missing_extensions?
361-
Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
362-
next
363-
end
360+
next if spec.ignored?
364361
idx << spec
365362
end
366363
end

lib/bundler/stub_specification.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ def to_yaml
2828

2929
# @!group Stub Delegates
3030

31+
def ignored?
32+
return @ignored unless @ignored.nil?
33+
34+
@ignored = missing_extensions?
35+
return false unless @ignored
36+
37+
warn "Source #{source} is ignoring #{self} because it is missing extensions"
38+
39+
true
40+
end
41+
3142
def manually_installed?
3243
# This is for manually installed gems which are gems that were fixed in place after a
3344
# failed installation. Once the issue was resolved, the user then manually created

lib/rubygems/basic_specification.rb

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,7 @@ def base_dir
7171
# Return true if this spec can require +file+.
7272

7373
def contains_requirable_file?(file)
74-
if @ignored
75-
return false
76-
elsif missing_extensions?
77-
@ignored = true
78-
79-
if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
80-
warn "Ignoring #{full_name} because its extensions are not built. " \
81-
"Try: gem pristine #{name} --version #{version}"
82-
end
83-
84-
return false
85-
end
74+
return false if ignored?
8675

8776
is_soext = file.end_with?(".so", ".o")
8877

@@ -93,6 +82,23 @@ def contains_requirable_file?(file)
9382
end
9483
end
9584

85+
##
86+
# Return true if this spec should be ignored because it's missing extensions.
87+
88+
def ignored?
89+
return @ignored unless @ignored.nil?
90+
91+
@ignored = missing_extensions?
92+
return false unless @ignored
93+
94+
if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
95+
warn "Ignoring #{full_name} because its extensions are not built. " \
96+
"Try: gem pristine #{name} --version #{version}"
97+
end
98+
99+
true
100+
end
101+
96102
def default_gem?
97103
loaded_from &&
98104
File.dirname(loaded_from) == Gem.default_specifications_dir

lib/rubygems/dependency.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def matching_specs(platform_only = false)
279279
end
280280
end
281281

282-
matches
282+
matches.reject(&:ignored?)
283283
end
284284

285285
##

spec/bundler/install/gems/standalone_spec.rb

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@
142142
describe "with default gems and a lockfile", :ruby_repo do
143143
before do
144144
necessary_system_gems = ["tsort --version 0.1.0"]
145-
necessary_system_gems += ["etc --version 1.4.3"]
146145
realworld_system_gems(*necessary_system_gems)
147146
end
148147

@@ -173,7 +172,16 @@
173172
bundle "lock", dir: cwd
174173

175174
bundle "config set --local path #{bundled_app("bundle")}"
176-
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
175+
176+
# Make sure rubyinstaller2 does not activate the etc gem in its
177+
# `operating_system.rb` file, but completely disable that since it's not
178+
# really needed here
179+
if Gem.win_platform?
180+
FileUtils.mkdir_p bundled_app("rubygems/defaults")
181+
FileUtils.touch bundled_app("rubygems/defaults/operating_system.rb")
182+
end
183+
184+
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }, load_path: bundled_app
177185

178186
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }
179187

@@ -184,27 +192,35 @@
184192
end
185193

186194
it "works for gems with extensions and points to the vendored copies, not to the default copies" do
187-
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"]
188-
necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a")
189-
realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle")))
195+
simulate_platform "arm64-darwin-23" do
196+
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"]
197+
necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a")
198+
realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle")))
190199

191-
build_gem "baz", "1.0.0", to_system: true, default: true, &:add_c_extension
200+
build_gem "baz", "1.0.0", to_system: true, default: true, &:add_c_extension
192201

193-
build_repo4 do
194-
build_gem "baz", "1.0.0", &:add_c_extension
195-
end
202+
build_repo4 do
203+
build_gem "baz", "1.0.0", &:add_c_extension
204+
end
196205

197-
gemfile <<-G
198-
source "https://gem.repo4"
199-
gem "baz"
200-
G
206+
gemfile <<-G
207+
source "https://gem.repo4"
208+
gem "baz"
209+
G
201210

202-
bundle "config set --local path #{bundled_app("bundle")}"
211+
bundle "config set --local path #{bundled_app("bundle")}"
203212

204-
simulate_platform "arm64-darwin-23" do
205213
bundle "lock", dir: cwd
206214

207-
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
215+
# Make sure rubyinstaller2 does not activate the etc gem in its
216+
# `operating_system.rb` file, but completely disable that since it's not
217+
# really needed here
218+
if Gem.win_platform?
219+
FileUtils.mkdir_p bundled_app("rubygems/defaults")
220+
FileUtils.touch bundled_app("rubygems/defaults/operating_system.rb")
221+
end
222+
223+
bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }, load_path: bundled_app
208224
end
209225

210226
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }

spec/bundler/support/helpers.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@ def bundle(cmd, options = {}, &block)
7676
requires = options.delete(:requires) || []
7777

7878
dir = options.delete(:dir) || bundled_app
79+
custom_load_path = options.delete(:load_path)
7980

8081
load_path = []
8182
load_path << spec_dir
83+
load_path << custom_load_path if custom_load_path
8284

8385
build_ruby_options = { load_path: load_path, requires: requires, env: env }
8486
build_ruby_options.merge!(artifice: options.delete(:artifice)) if options.key?(:artifice)

0 commit comments

Comments
 (0)