[rubygems/rubygems] Make sure empty gems are not reinstalled every time

Unfortunately this requires reverting a previous enhancement of
reinstalling gems if they incorrectly ship with an empty installation
dir.

However, there's no way to distinguish this kind of bad state from a gem
that's empty for real, for example, sorbet-static-and-runtime.

This reverts commit https://github.com/rubygems/rubygems/commit/9720a9b980d2, and adds a
spec to make sure empty gems are not reinstalled every time.

https://github.com/rubygems/rubygems/commit/7c102394af
This commit is contained in:
David Rodríguez 2025-02-18 13:13:14 +01:00 committed by Hiroshi SHIBATA
parent da97662996
commit 5d8fe7a595
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
4 changed files with 28 additions and 15 deletions

View File

@ -259,7 +259,7 @@ module Gem
end
def installation_missing?
!default_gem? && (!Dir.exist?(full_gem_path) || Dir.empty?(full_gem_path))
!default_gem? && !File.directory?(full_gem_path)
end
unless VALIDATES_FOR_RESOLUTION

View File

@ -100,24 +100,30 @@ RSpec.describe "bundle install with gem sources" do
gem 'myrack'
G
gem_dir = default_bundle_path("gems/myrack-1.0.0")
FileUtils.rm_rf(gem_dir)
FileUtils.rm_rf(default_bundle_path("gems/myrack-1.0.0"))
bundle "install --verbose"
expect(out).to include("Installing myrack 1.0.0")
expect(gem_dir).to exist
expect(default_bundle_path("gems/myrack-1.0.0")).to exist
expect(the_bundle).to include_gems("myrack 1.0.0")
end
FileUtils.rm_rf(gem_dir)
Dir.mkdir(gem_dir)
it "does not state that it's constantly reinstalling empty gems" do
build_repo4 do
build_gem "empty", "1.0.0", no_default: true, allowed_warning: "no files specified"
end
install_gemfile <<~G
source "https://gem.repo4"
gem "empty"
G
gem_dir = default_bundle_path("gems/empty-1.0.0")
expect(gem_dir).to be_empty
bundle "install --verbose"
expect(out).to include("Installing myrack 1.0.0")
expect(gem_dir).to exist
expect(the_bundle).to include_gems("myrack 1.0.0")
expect(out).not_to include("Installing empty")
end
it "fetches gems when multiple versions are specified" do

View File

@ -639,7 +639,7 @@ module Spec
elsif opts[:skip_validation]
@context.gem_command "build --force #{@spec.name}", dir: lib_path
else
@context.gem_command "build #{@spec.name}", dir: lib_path
@context.gem_command "build #{@spec.name}", dir: lib_path, allowed_warning: opts[:allowed_warning]
end
gem_path = File.expand_path("#{@spec.full_name}.gem", lib_path)

View File

@ -194,9 +194,12 @@ module Spec
# command is expired too. So give `gem install` commands a bit more time.
options[:timeout] = 120
allowed_warning = options.delete(:allowed_warning)
output = sys_exec("#{Path.gem_bin} #{command}", options)
stderr = last_command.stderr
raise stderr if stderr.include?("WARNING") && !allowed_rubygems_warning?(stderr)
raise stderr if stderr.include?("WARNING") && !allowed_rubygems_warning?(stderr, allowed_warning)
output
end
@ -548,8 +551,12 @@ module Spec
private
def allowed_rubygems_warning?(text)
text.include?("open-ended") || text.include?("is a symlink") || text.include?("rake based") || text.include?("expected RubyGems version")
def allowed_rubygems_warning?(text, extra_allowed_warning)
allowed_warnings = ["open-ended", "is a symlink", "rake based", "expected RubyGems version"]
allowed_warnings << extra_allowed_warning if extra_allowed_warning
allowed_warnings.any? do |warning|
text.include?(warning)
end
end
def match_source(contents)