From 79f3167e0b601656f651b247d6ca09e4cadfadcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Wed, 26 Mar 2025 22:26:16 +0100 Subject: [PATCH] [rubygems/rubygems] Let compact index response parser consistently return a mutable dependencies array That restores support for compact index dummy implementations that only lists versions, without checksums or dependencies. This format is undocumented, so we may want to get rid of it in the future. However, some of our tests rely on it, and some implementations did use it (gems.mutant.dev at least). And the way the code was written suggest that support was intentional. So for now, we should restore it. https://github.com/rubygems/rubygems/commit/0427d8c983 --- lib/bundler/rubygems_ext.rb | 11 +++++++++++ lib/rubygems/resolver/api_set/gem_parser.rb | 7 ++----- spec/bundler/install/gems/compact_index_spec.rb | 7 +++++++ .../artifice/compact_index_no_checksums.rb | 16 ++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 spec/bundler/support/artifice/compact_index_no_checksums.rb diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index c684c6023a..1f3fb0fdde 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -447,6 +447,17 @@ module Gem end end + unless Gem.rubygems_version >= Gem::Version.new("3.6.7") + module UnfreezeCompactIndexParsedResponse + def parse(line) + version, platform, dependencies, requirements = super + [version, platform, dependencies.frozen? ? dependencies.dup : dependencies, requirements.frozen? ? requirements.dup : requirements] + end + end + + Resolver::APISet::GemParser.prepend(UnfreezeCompactIndexParsedResponse) + end + if Gem.rubygems_version < Gem::Version.new("3.6.0") class Package; end require "rubygems/package/tar_reader" diff --git a/lib/rubygems/resolver/api_set/gem_parser.rb b/lib/rubygems/resolver/api_set/gem_parser.rb index 643b857107..7dd9a89ebc 100644 --- a/lib/rubygems/resolver/api_set/gem_parser.rb +++ b/lib/rubygems/resolver/api_set/gem_parser.rb @@ -1,15 +1,12 @@ # frozen_string_literal: true class Gem::Resolver::APISet::GemParser - EMPTY_ARRAY = [].freeze - private_constant :EMPTY_ARRAY - def parse(line) version_and_platform, rest = line.split(" ", 2) version, platform = version_and_platform.split("-", 2) dependencies, requirements = rest.split("|", 2).map! {|s| s.split(",") } if rest - dependencies = dependencies ? dependencies.map! {|d| parse_dependency(d) } : EMPTY_ARRAY - requirements = requirements ? requirements.map! {|d| parse_dependency(d) } : EMPTY_ARRAY + dependencies = dependencies ? dependencies.map! {|d| parse_dependency(d) } : [] + requirements = requirements ? requirements.map! {|d| parse_dependency(d) } : [] [version, platform, dependencies, requirements] end diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 6f34cbbe85..2cf9b19e41 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -1089,4 +1089,11 @@ Running `bundle update rails` should fix the problem. count = lockfile.match?("CHECKSUMS") ? 2 : 1 # Once in the specs, and once in CHECKSUMS expect(lockfile.scan(/activemerchant \(/).size).to eq(count) end + + it "handles an API that does not provide checksums info (undocumented, support may get removed)" do + install_gemfile <<-G, artifice: "compact_index_no_checksums" + source "https://gem.repo1" + gem "rake" + G + end end diff --git a/spec/bundler/support/artifice/compact_index_no_checksums.rb b/spec/bundler/support/artifice/compact_index_no_checksums.rb new file mode 100644 index 0000000000..ecb7fc7d7c --- /dev/null +++ b/spec/bundler/support/artifice/compact_index_no_checksums.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require_relative "helpers/compact_index" + +class CompactIndexNoChecksums < CompactIndexAPI + get "/info/:name" do + etag_response do + gem = gems.find {|g| g.name == params[:name] } + gem.versions.map(&:number).join("\n") + end + end +end + +require_relative "helpers/artifice" + +Artifice.activate_with(CompactIndexNoChecksums)