Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bundler/lib/bundler/stub_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def manually_installed?

# This is defined directly to avoid having to loading the full spec
def missing_extensions?
return false if RUBY_ENGINE == "jruby"
return false if default_gem?
return false if extensions.empty?
return false if File.exist? gem_build_complete_path
Expand Down
5 changes: 5 additions & 0 deletions lib/rubygems/commands/pristine_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ def execute
specs = specs.select {|spec| spec.platform == RUBY_ENGINE || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }

if specs.to_a.empty?
if options[:only_missing_extensions]
say "No gems with missing extensions to restore"
return
end

raise Gem::Exception,
"Failed to find gems #{options[:args]} #{options[:version]}"
end
Expand Down
1 change: 1 addition & 0 deletions lib/rubygems/specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2070,6 +2070,7 @@ def method_missing(sym, *a, &b) # :nodoc:
# probably want to build_extensions

def missing_extensions?
return false if RUBY_ENGINE == "jruby"

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing_extensions? returning false unconditionally on JRuby changes behavior beyond silencing warnings: specs with unbuilt extensions will no longer be marked ignored, so they can be selected for activation/resolution even though their native bits are unavailable for the current platform/ABI (and commands like gem pristine --only-missing-extensions will stop working). Instead of short-circuiting missing_extensions? by engine, keep the missing-extension detection intact and suppress the warning in the caller(s) when the spec is for a different platform (or when running on non-CRuby engines).

Suggested change
return false if RUBY_ENGINE == "jruby"

Copilot uses AI. Check for mistakes.
return false if extensions.empty?
return false if default_gem?
return false if File.exist? gem_build_complete_path
Expand Down
1 change: 1 addition & 0 deletions lib/rubygems/stub_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ def raw_require_paths # :nodoc:
end

def missing_extensions?
return false if RUBY_ENGINE == "jruby"

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JRuby early return in missing_extensions? prevents Gem::StubSpecification#ignored? from filtering out specs whose extensions are not built for the current platform, which can lead to incompatible gems being considered activatable under a shared GEM_HOME. This method should continue to report missing extensions based on gem_build_complete_path; if the goal is to avoid noisy output, adjust the warning site(s) instead (e.g., only warn when Gem::Platform.local === platform).

Suggested change
return false if RUBY_ENGINE == "jruby"

Copilot uses AI. Check for mistakes.
return false if default_gem?
return false if extensions.empty?
return false if File.exist? gem_build_complete_path
Expand Down
8 changes: 6 additions & 2 deletions spec/bundler/stub_specification_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@
expect(stub.missing_extensions?).to be false
end

it "returns true if not manually_installed?" do
it "returns #{RUBY_ENGINE == "jruby" ? "false" : "true"} if not manually_installed?" do
stub = described_class.from_stub(with_bundler_stub_spec)
stub.installed_by_version = Gem::Version.new(1)
expect(stub.missing_extensions?).to be true
if RUBY_ENGINE == "jruby"
expect(stub.missing_extensions?).to be false
else
expect(stub.missing_extensions?).to be true
end
end
end

Expand Down
10 changes: 7 additions & 3 deletions test/rubygems/test_gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1304,10 +1304,14 @@ def test_self_try_activate_missing_extensions
refute Gem.try_activate "nonexistent"
end

expected = "Ignoring ext-1 because its extensions are not built. " \
"Try: gem pristine ext --version 1\n"
if RUBY_ENGINE == "jruby"
assert_equal "", err
else
expected = "Ignoring ext-1 because its extensions are not built. " \
"Try: gem pristine ext --version 1\n"

assert_equal expected, err
assert_equal expected, err
end
Comment on lines +1307 to +1314

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test now expects no warning on JRuby, but the implementation change achieves that by disabling missing-extension detection entirely on JRuby (which can allow incompatible specs into activation). Once warning suppression is implemented at the warning site, update this test to verify that missing extensions are still detected/ignored while stderr remains quiet, instead of changing missing_extensions? semantics by engine.

Copilot uses AI. Check for mistakes.
end

def test_self_use_paths_with_nils
Expand Down
8 changes: 7 additions & 1 deletion test/rubygems/test_gem_commands_pristine_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,13 @@ def test_execute_extensions_only_missing_extensions
end

refute_includes @ui.output, "Restored #{a.full_name}"
assert_includes @ui.output, "Restored #{b.full_name}"

if Gem.java_platform?
refute_includes @ui.output, "Restored #{b.full_name}"
assert_includes @ui.output, "No gems with missing extensions to restore"
else
assert_includes @ui.output, "Restored #{b.full_name}"
end
end

def test_execute_no_extension
Expand Down
22 changes: 17 additions & 5 deletions test/rubygems/test_gem_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1578,13 +1578,21 @@ def test_contains_requirable_file_eh_extension
ext_spec

_, err = capture_output do
refute @ext.contains_requirable_file? "nonexistent"
if RUBY_ENGINE == "jruby"
refute @ext.ignored?
else
refute @ext.contains_requirable_file? "nonexistent"
end
Comment on lines +1581 to +1585

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the stub-spec test, the JRuby branch no longer tests contains_requirable_file? and therefore doesn't validate the warning/no-warning behavior at the call site. Consider keeping the contains_requirable_file? assertion for JRuby as well, and only adjust the stderr expectation.

Suggested change
if RUBY_ENGINE == "jruby"
refute @ext.ignored?
else
refute @ext.contains_requirable_file? "nonexistent"
end
refute @ext.contains_requirable_file? "nonexistent"

Copilot uses AI. Check for mistakes.
end

expected = "Ignoring ext-1 because its extensions are not built. " \
"Try: gem pristine ext --version 1\n"
if RUBY_ENGINE == "jruby"
assert_equal "", err
else
expected = "Ignoring ext-1 because its extensions are not built. " \
"Try: gem pristine ext --version 1\n"

assert_equal expected, err
assert_equal expected, err
end
end

def test_contains_requirable_file_eh_extension_java_platform
Expand Down Expand Up @@ -4007,7 +4015,11 @@ def test_metadata_specs
def test_missing_extensions_eh
ext_spec

assert @ext.missing_extensions?
if RUBY_ENGINE == "jruby"
refute @ext.missing_extensions?
else
assert @ext.missing_extensions?
end
Comment on lines +4018 to +4022

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making missing_extensions? return false on JRuby changes core behavior and this test now codifies that change. If the desired behavior is “still ignore specs missing extensions, but don’t warn when those specs are effectively for another platform/engine”, adjust the warning logic and keep missing_extensions? consistent across engines; then this test should continue to expect @ext.missing_extensions? to be true before build_extensions.

Suggested change
if RUBY_ENGINE == "jruby"
refute @ext.missing_extensions?
else
assert @ext.missing_extensions?
end
assert @ext.missing_extensions?

Copilot uses AI. Check for mistakes.

extconf_rb = File.join @ext.gem_dir, @ext.extensions.first
FileUtils.mkdir_p File.dirname extconf_rb
Expand Down
22 changes: 17 additions & 5 deletions test/rubygems/test_gem_stub_specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,21 @@ def test_contains_requirable_file_eh
def test_contains_requirable_file_eh_extension
stub_with_extension do |stub|
_, err = capture_output do
refute stub.contains_requirable_file? "nonexistent"
if RUBY_ENGINE == "jruby"
refute stub.ignored?
else
refute stub.contains_requirable_file? "nonexistent"
end
Comment on lines 69 to +75

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JRuby branch stops exercising contains_requirable_file? entirely (it only checks ignored?), which weakens coverage of the behavior this test is named after. Prefer asserting refute stub.contains_requirable_file?("nonexistent") on all engines, and only vary the stderr expectation (empty vs warning) to verify the warning-suppression behavior.

Copilot uses AI. Check for mistakes.
end

expected = "Ignoring stub_e-2 because its extensions are not built. " \
"Try: gem pristine stub_e --version 2\n"
if RUBY_ENGINE == "jruby"
assert_equal "", err
else
expected = "Ignoring stub_e-2 because its extensions are not built. " \
"Try: gem pristine stub_e --version 2\n"

assert_equal expected, err
assert_equal expected, err
end
end
end

Expand Down Expand Up @@ -137,7 +145,11 @@ def test_missing_extensions_eh
end
end

assert stub.missing_extensions?
if RUBY_ENGINE == "jruby"
refute stub.missing_extensions?
else
assert stub.missing_extensions?
end
Comment on lines +148 to +152

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions now make missing_extensions? engine-dependent, but missing_extensions? is also used for correctness (filtering/pristine --only-missing-extensions), not just warnings. If the intent is only to silence warnings under cross-platform shared GEM_HOME, keep missing_extensions? reporting true when the current platform's gem.build_complete is absent and suppress the warning output separately.

Suggested change
if RUBY_ENGINE == "jruby"
refute stub.missing_extensions?
else
assert stub.missing_extensions?
end
assert stub.missing_extensions?

Copilot uses AI. Check for mistakes.

stub.build_extensions

Expand Down
Loading