summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rodriguez <deivid.rodriguez@riseup.net>2021-10-20 21:15:52 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2021-10-25 20:48:51 +0900
commit4edcda67b321de12d2fdc5005ff1230d8d0a0c3f (patch)
tree43b64f3050f713ec6346397869c35accf0403405
parent03a563b47e0f021f3b7a8dc14b162068071b4d53 (diff)
downloadruby-4edcda67b321de12d2fdc5005ff1230d8d0a0c3f.tar.gz
[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. https://github.com/rubygems/rubygems/commit/8fe74a77e4
-rw-r--r--lib/bundler/rubygems_integration.rb23
-rw-r--r--lib/bundler/source/rubygems.rb12
-rw-r--r--spec/bundler/bundler/rubygems_integration_spec.rb11
3 files changed, 27 insertions, 19 deletions
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index 70366c4d48..effb88c1cd 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -506,13 +506,32 @@ module Bundler
specs.concat(pres)
end
- def download_gem(spec, uri, path)
+ def download_gem(spec, uri, cache_dir)
require "rubygems/remote_fetcher"
uri = Bundler.settings.mirror_for(uri)
fetcher = gem_remote_fetcher
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
- 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
rescue Gem::RemoteFetcher::FetchError => e
raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 12b7a941f1..ae77f41753 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -521,17 +521,7 @@ module Bundler
else
uri = spec.remote.uri
Bundler.ui.confirm("Fetching #{version_message(spec)}")
- rubygems_local_path = Bundler.rubygems.download_gem(spec, uri, File.dirname(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
+ Bundler.rubygems.download_gem(spec, uri, download_cache_path)
cache_globally(spec, local_path)
end
end
diff --git a/spec/bundler/bundler/rubygems_integration_spec.rb b/spec/bundler/bundler/rubygems_integration_spec.rb
index a48c6410f3..94abf70ddd 100644
--- a/spec/bundler/bundler/rubygems_integration_spec.rb
+++ b/spec/bundler/bundler/rubygems_integration_spec.rb
@@ -43,11 +43,10 @@ RSpec.describe Bundler::RubygemsIntegration do
describe "#download_gem" do
let(:bundler_retry) { double(Bundler::Retry) }
- let(:uri) { Bundler::URI.parse("https://foo.bar") }
- let(:path) { Gem.path.first }
+ let(:uri) { Bundler::URI.parse("https://foo.bar") }
+ let(:cache_dir) { "#{Gem.path.first}/cache" }
let(:spec) do
- spec = Bundler::RemoteSpecification.new("Foo", Gem::Version.new("2.5.2"),
- Gem::Platform::RUBY, nil)
+ spec = Gem::Specification.new("Foo", Gem::Version.new("2.5.2"))
spec.remote = Bundler::Source::Rubygems::Remote.new(uri.to_s)
spec
end
@@ -59,9 +58,9 @@ RSpec.describe Bundler::RubygemsIntegration do
expect(Bundler::Retry).to receive(:new).with("download gem from #{uri}/").
and_return(bundler_retry)
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