Skip to content

Refactor Bundler tests to invoke RubyGems API directly#9195

Merged
hsbt merged 4 commits intomasterfrom
colby/remove-test-subshelling
Mar 18, 2026
Merged

Refactor Bundler tests to invoke RubyGems API directly#9195
hsbt merged 4 commits intomasterfrom
colby/remove-test-subshelling

Conversation

@colby-swandale
Copy link
Member

Some Bundler tests currently spawn a subshell to invoke RubyGems. We're moving away from this pattern to speed up the test suite.

This PR refactors those tests to call the RubyGems API directly instead.

The ultimate prize is replacing the bundler and bundle helpers in the test suite entirely, but this serves as a good stepping stone towards that.

Copilot AI review requested due to automatic review settings December 15, 2025 11:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors Bundler tests to invoke the RubyGems API directly instead of spawning subshells, improving test suite performance. The primary change removes the gem_command helper method and replaces all its usages with direct API calls to RubyGems classes.

  • Removes the gem_command helper that spawned subshells for gem operations
  • Refactors install_gem to use Gem::Installer.at API directly
  • Adds uninstall_gem and installed_gems_list helper methods that call RubyGems APIs

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
bundler/spec/support/helpers.rb Removes gem_command method; refactors install_gem to use Gem::Installer.at; adds new uninstall_gem and installed_gems_list helper methods for direct API calls
bundler/spec/support/builders.rb Replaces gem build subshell command with direct Gem::Package.build API call
bundler/spec/install/gems/compact_index_spec.rb Updates test to use new uninstall_gem helper instead of gem_command
bundler/spec/commands/clean_spec.rb Updates tests to use new installed_gems_list helper instead of gem_command :list
bundler/spec/commands/check_spec.rb Updates test to use new uninstall_gem helper instead of gem_command
bundler/spec/bundler/gem_helper_spec.rb Updates test to use new installed_gems_list helper instead of gem_command :list

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +359 to +376
# Temporarily set GEM_HOME for the command
old_gem_home = ENV["GEM_HOME"]
ENV["GEM_HOME"] = gem_home
Gem.clear_paths

begin
require "rubygems/commands/list_command"

# Capture output from the list command
output_io = StringIO.new
cmd = Gem::Commands::ListCommand.new
cmd.ui = Gem::StreamUI.new(StringIO.new, output_io, StringIO.new, false)
cmd.invoke
output = output_io.string.strip
ensure
ENV["GEM_HOME"] = old_gem_home
Gem.clear_paths
end
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The installed_gems_list method manually saves and restores ENV["GEM_HOME"], but this codebase has an established pattern for temporary environment variable modifications using the without_env_side_effects helper (see lines 393-415). Using this helper would be more consistent with the codebase's patterns and provide better safety guarantees, as it ensures all ENV changes are properly restored even if an exception occurs during the begin block.

Copilot uses AI. Check for mistakes.
@Edouard-chin Edouard-chin mentioned this pull request Dec 19, 2025
4 tasks
@hsbt hsbt force-pushed the colby/remove-test-subshelling branch from eb62a3c to 185964f Compare March 18, 2026 02:31
@hsbt hsbt force-pushed the colby/remove-test-subshelling branch from 0f048fc to 65f6b69 Compare March 18, 2026 05:13
When install_gem runs Gem::Installer in-process, BUNDLER_SPEC_PLATFORM
is not applied because hax.rb only runs in subprocesses. Add
with_simulated_platform helper that mirrors hax.rb's platform override
for in-process operations, and restore psych in standalone extension
test's base_system_gems.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hsbt hsbt force-pushed the colby/remove-test-subshelling branch 2 times, most recently from 007aebf to b9c831a Compare March 18, 2026 06:41
hsbt and others added 2 commits March 18, 2026 16:03
With load_relative enabled (ruby-core CI), Gem::Installer generates
wrapper scripts with a bash prolog (#!/bin/sh) when wrappers: true is
set. Bundler's directly_loadable? only recognizes Ruby shebangs, so
these shell wrappers cause "command not found" errors in nested
bundle exec scenarios.

Adding env_shebang: true forces #!/usr/bin/env ruby shebang, which
directly_loadable? recognizes, fixing 6 test failures in ruby-core CI
while keeping wrappers to avoid double-loading issues with symlinks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gem::Uninstaller with install_dir uses File.realpath for @gem_home but
not for the specification_record path lookup, causing path mismatches
on some CI environments. Instead, temporarily set GEM_HOME and call
Gem.clear_paths to mimic the old subprocess-based gem_command behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hsbt
Copy link
Member

hsbt commented Mar 18, 2026

@colby-swandale Finally, I fixed CI failures with your changes. I prefer your proposal over shell spawn. I'm going to merge this.

@hsbt hsbt merged commit 9d755be into master Mar 18, 2026
96 checks passed
@hsbt hsbt deleted the colby/remove-test-subshelling branch March 18, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants