1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[rubygems/rubygems] Simplify gem downloading inside bundler

We can skip most stuff in `Gem::RemoteFetcher#download`, and use
`Gem::RemoteFetcher#update_cache_path` directly.

This has the benefit of allowing us to remove some workarounds to
support several rubygems versions, but also allows us to pass the target
folder where the gem should be downloaded directly and skip the logic
inside `Gem::RemoteFetcher#download` to infer the cache path. This will
be useful later to fix some issues with the `global_gem_cache` feature
flag.

8fe74a77e4
This commit is contained in:
David Rodriguez 2021-10-20 21:15:52 +02:00 committed by Hiroshi SHIBATA
parent 03a563b47e
commit 4edcda67b3
No known key found for this signature in database
GPG key ID: F9CF13417264FAC2
3 changed files with 27 additions and 19 deletions

View file

@ -506,13 +506,32 @@ module Bundler
specs.concat(pres) specs.concat(pres)
end end
def download_gem(spec, uri, path) def download_gem(spec, uri, cache_dir)
require "rubygems/remote_fetcher" require "rubygems/remote_fetcher"
uri = Bundler.settings.mirror_for(uri) uri = Bundler.settings.mirror_for(uri)
fetcher = gem_remote_fetcher fetcher = gem_remote_fetcher
fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
Bundler::Retry.new("download gem from #{uri}").attempts do Bundler::Retry.new("download gem from #{uri}").attempts do
fetcher.download(spec, uri, path) gem_file_name = spec.file_name
local_gem_path = File.join cache_dir, gem_file_name
return if File.exist? local_gem_path
begin
remote_gem_path = uri + "gems/#{gem_file_name}"
remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
SharedHelpers.filesystem_access(local_gem_path) do
fetcher.cache_update_path remote_gem_path, local_gem_path
end
rescue Gem::RemoteFetcher::FetchError
raise if spec.original_platform == spec.platform
original_gem_file_name = "#{spec.original_name}.gem"
raise if gem_file_name == original_gem_file_name
gem_file_name = original_gem_file_name
retry
end
end end
rescue Gem::RemoteFetcher::FetchError => e rescue Gem::RemoteFetcher::FetchError => e
raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>" raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"

View file

@ -521,17 +521,7 @@ module Bundler
else else
uri = spec.remote.uri uri = spec.remote.uri
Bundler.ui.confirm("Fetching #{version_message(spec)}") Bundler.ui.confirm("Fetching #{version_message(spec)}")
rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, File.dirname(download_cache_path)) Bundler.rubygems.download_gem(spec, uri, download_cache_path)
# older rubygems return varying file:// variants depending on version
rubygems_local_path = rubygems_local_path.gsub(/\Afile:/, "") unless Bundler.rubygems.provides?(">= 3.2.0.rc.2")
rubygems_local_path = rubygems_local_path.gsub(%r{\A//}, "") if Bundler.rubygems.provides?("< 3.1.0")
if rubygems_local_path != local_path
SharedHelpers.filesystem_access(local_path) do
FileUtils.mv(rubygems_local_path, local_path)
end
end
cache_globally(spec, local_path) cache_globally(spec, local_path)
end end
end end

View file

@ -43,11 +43,10 @@ RSpec.describe Bundler::RubygemsIntegration do
describe "#download_gem" do describe "#download_gem" do
let(:bundler_retry) { double(Bundler::Retry) } let(:bundler_retry) { double(Bundler::Retry) }
let(:uri) { Bundler::URI.parse("https://foo.bar") } let(:uri) { Bundler::URI.parse("https://foo.bar") }
let(:path) { Gem.path.first } let(:cache_dir) { "#{Gem.path.first}/cache" }
let(:spec) do let(:spec) do
spec = Bundler::RemoteSpecification.new("Foo", Gem::Version.new("2.5.2"), spec = Gem::Specification.new("Foo", Gem::Version.new("2.5.2"))
Gem::Platform::RUBY, nil)
spec.remote = Bundler::Source::Rubygems::Remote.new(uri.to_s) spec.remote = Bundler::Source::Rubygems::Remote.new(uri.to_s)
spec spec
end end
@ -59,9 +58,9 @@ RSpec.describe Bundler::RubygemsIntegration do
expect(Bundler::Retry).to receive(:new).with("download gem from #{uri}/"). expect(Bundler::Retry).to receive(:new).with("download gem from #{uri}/").
and_return(bundler_retry) and_return(bundler_retry)
expect(bundler_retry).to receive(:attempts).and_yield expect(bundler_retry).to receive(:attempts).and_yield
expect(fetcher).to receive(:download).with(spec, uri, path) expect(fetcher).to receive(:cache_update_path)
Bundler.rubygems.download_gem(spec, uri, path) Bundler.rubygems.download_gem(spec, uri, cache_dir)
end end
end end