[rubygems/rubygems] Backwards compatibility for 2.5.17-2.5.23 caches

https://github.com/rubygems/rubygems/commit/9dbfce76cf
This commit is contained in:
David Rodríguez 2024-11-26 19:46:26 +01:00 committed by git
parent 9a4d91fa95
commit ee7ff4a12b
3 changed files with 131 additions and 11 deletions

View File

@ -136,7 +136,11 @@ module Bundler
specs_to_cache.each do |spec|
next if spec.name == "bundler"
next if spec.source.is_a?(Source::Gemspec)
spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
if spec.source.respond_to?(:migrate_cache)
spec.source.migrate_cache(custom_path, local: local)
elsif spec.source.respond_to?(:cache)
spec.source.cache(spec, custom_path)
end
end
Dir[cache_path.join("*/.git")].each do |git_dir|

View File

@ -214,16 +214,16 @@ module Bundler
requires_checkout? ? spec.post_install_message : nil
end
def migrate_cache(custom_path = nil, local: false)
if local
cache_to(custom_path, try_migrate: false)
else
cache_to(custom_path, try_migrate: true)
end
end
def cache(spec, custom_path = nil)
return unless Bundler.feature_flag.cache_all?
app_cache_path = app_cache_path(custom_path)
return if cache_path == app_cache_path
cached!
FileUtils.rm_rf(app_cache_path)
git_proxy.checkout if requires_checkout?
git_proxy.copy_to(app_cache_path, @submodules)
cache_to(custom_path, try_migrate: false)
end
def load_spec_files
@ -267,14 +267,36 @@ module Bundler
private
def cache_to(custom_path, try_migrate: false)
return unless Bundler.feature_flag.cache_all?
app_cache_path = app_cache_path(custom_path)
migrate = try_migrate ? bare_repo?(app_cache_path) : false
set_cache_path!(nil) if migrate
return if cache_path == app_cache_path
cached!
FileUtils.rm_rf(app_cache_path)
git_proxy.checkout if migrate || requires_checkout?
git_proxy.copy_to(app_cache_path, @submodules)
end
def checkout
Bundler.ui.debug " * Checking out revision: #{ref}"
if use_app_cache?
if use_app_cache? && !bare_repo?(app_cache_path)
SharedHelpers.filesystem_access(install_path.dirname) do |p|
FileUtils.mkdir_p(p)
end
FileUtils.cp_r("#{app_cache_path}/.", install_path)
else
if use_app_cache? && bare_repo?(app_cache_path)
Bundler.ui.warn "Installing from cache in old \"bare repository\" format for compatibility. " \
"Please run `bundle cache` and commit the updated cache to migrate to the new format and get rid of this warning."
end
git_proxy.copy_to(install_path, submodules)
end
serialize_gemspecs_in(install_path)
@ -416,6 +438,10 @@ module Bundler
def override_for(path)
Bundler.settings.local_overrides.key(path)
end
def bare_repo?(path)
File.exist?(path.join("objects")) && File.exist?(path.join("HEAD"))
end
end
end
end

View File

@ -239,6 +239,96 @@ RSpec.describe "bundle cache with git" do
expect(the_bundle).to include_gem "foo 1.0"
end
it "installs properly a bundler 2.5.17-2.5.23 cache as a bare repository without cloning remote repositories" do
git = build_git "foo"
short_ref = git.ref_for("main", 11)
cache_dir = bundled_app("vendor/cache/foo-1.0-#{short_ref}")
gemfile <<-G
source "https://gem.repo1"
gem "foo", :git => '#{lib_path("foo-1.0")}'
G
bundle "config set global_gem_cache false"
bundle "config set cache_all true"
bundle "config path vendor/bundle"
bundle :install
# Simulate old cache by copying the real cache folder to vendor/cache
FileUtils.mkdir_p bundled_app("vendor/cache")
FileUtils.cp_r "#{Dir.glob(vendored_gems("cache/bundler/git/foo-1.0-*")).first}/.", cache_dir
FileUtils.rm_rf bundled_app("vendor/bundle")
bundle "install --local --verbose"
expect(err).to include("Installing from cache in old \"bare repository\" format for compatibility")
expect(out).to_not include("Fetching")
# leaves old cache alone
expect(cache_dir.join("lib/foo.rb")).not_to exist
expect(cache_dir.join("HEAD")).to exist
expect(the_bundle).to include_gem "foo 1.0"
end
it "migrates a bundler 2.5.17-2.5.23 cache as a bare repository when not running with --local" do
git = build_git "foo"
short_ref = git.ref_for("main", 11)
cache_dir = bundled_app("vendor/cache/foo-1.0-#{short_ref}")
gemfile <<-G
source "https://gem.repo1"
gem "foo", :git => '#{lib_path("foo-1.0")}'
G
bundle "config set global_gem_cache false"
bundle "config set cache_all true"
bundle "config path vendor/bundle"
bundle :install
# Simulate old cache by copying the real cache folder to vendor/cache
FileUtils.mkdir_p bundled_app("vendor/cache")
FileUtils.cp_r "#{Dir.glob(vendored_gems("cache/bundler/git/foo-1.0-*")).first}/.", cache_dir
FileUtils.rm_rf bundled_app("vendor/bundle")
bundle "install --verbose"
expect(out).to include("Fetching")
# migrates old cache alone
expect(cache_dir.join("lib/foo.rb")).to exist
expect(cache_dir.join("HEAD")).not_to exist
expect(the_bundle).to include_gem "foo 1.0"
end
it "migrates a bundler 2.5.17-2.5.23 cache as a bare repository when running `bundle cache`, even if gems already installed" do
git = build_git "foo"
short_ref = git.ref_for("main", 11)
cache_dir = bundled_app("vendor/cache/foo-1.0-#{short_ref}")
gemfile <<-G
source "https://gem.repo1"
gem "foo", :git => '#{lib_path("foo-1.0")}'
G
bundle "config set global_gem_cache false"
bundle "config set cache_all true"
bundle "config path vendor/bundle"
bundle :install
# Simulate old cache by copying the real cache folder to vendor/cache
FileUtils.mkdir_p bundled_app("vendor/cache")
FileUtils.cp_r "#{Dir.glob(vendored_gems("cache/bundler/git/foo-1.0-*")).first}/.", cache_dir
bundle "cache"
# migrates old cache alone
expect(cache_dir.join("lib/foo.rb")).to exist
expect(cache_dir.join("HEAD")).not_to exist
expect(the_bundle).to include_gem "foo 1.0"
end
it "copies repository to vendor cache, including submodules" do
# CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
system(*%W[git config --global protocol.file.allow always])