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

[rubygems/rubygems] Manage global gem cache directly

Previously, it was maintained in sync with the standard cache. That was
less efficient, and it caused some error messages to point to non
existent files.

https://github.com/rubygems/rubygems/commit/931f8cb8a9
This commit is contained in:
David Rodriguez 2021-10-21 00:04:09 +02:00 committed by Hiroshi SHIBATA
parent 4fc29d17b3
commit f7f85c1feb
No known key found for this signature in database
GPG key ID: F9CF13417264FAC2
3 changed files with 33 additions and 41 deletions

View file

@ -31,7 +31,10 @@ module Bundler
generate_plugins
write_spec
write_cache_file
SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do
write_cache_file
end
say spec.post_install_message unless spec.post_install_message.nil?

View file

@ -357,7 +357,7 @@ module Bundler
end
def cached_path(spec)
possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" }
possibilities = (@caches << download_cache_path(spec)).compact.map {|p| "#{p}/#{spec.file_name}" }
possibilities.find {|p| File.exist?(p) }
end
@ -456,9 +456,15 @@ module Bundler
spec.fetch_platform
download_path = requires_sudo? ? Bundler.tmp(spec.full_name) : rubygems_dir
download_cache_path = "#{download_path}/cache"
gem_path = "#{default_cache_path}/#{spec.file_name}"
cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
gem_path = "#{cache_path}/#{spec.file_name}"
if requires_sudo?
download_path = Bundler.tmp(spec.full_name)
download_cache_path = default_cache_path_for(download_path)
else
download_cache_path = cache_path
end
SharedHelpers.filesystem_access(download_cache_path) do |p|
FileUtils.mkdir_p(p)
@ -466,7 +472,7 @@ module Bundler
download_gem(spec, download_cache_path)
if requires_sudo?
SharedHelpers.filesystem_access(default_cache_path) do |p|
SharedHelpers.filesystem_access(cache_path) do |p|
Bundler.mkdir_p(p)
end
Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}"
@ -489,8 +495,8 @@ module Bundler
Bundler.rubygems.gem_dir
end
def default_cache_path
"#{rubygems_dir}/cache"
def default_cache_path_for(dir)
"#{dir}/cache"
end
def cache_path
@ -509,38 +515,9 @@ module Bundler
# the local directory the .gem will end up in.
#
def download_gem(spec, download_cache_path)
local_path = File.join(download_cache_path, spec.file_name)
if (cache_path = download_cache_path(spec)) && cache_path.file?
SharedHelpers.filesystem_access(local_path) do
FileUtils.cp(cache_path, local_path)
end
else
uri = spec.remote.uri
Bundler.ui.confirm("Fetching #{version_message(spec)}")
Bundler.rubygems.download_gem(spec, uri, download_cache_path)
cache_globally(spec, local_path)
end
end
# Checks if the requested spec exists in the global cache. If it does
# not, we create the relevant global cache subdirectory if it does not
# exist and copy the spec from the local cache to the global cache.
#
# @param [Specification] spec
# the spec we want to copy to the global cache.
#
# @param [String] local_cache_path
# the local directory from which we want to copy the .gem.
#
def cache_globally(spec, local_cache_path)
return unless cache_path = download_cache_path(spec)
return if cache_path.exist?
SharedHelpers.filesystem_access(cache_path.dirname, &:mkpath)
SharedHelpers.filesystem_access(cache_path) do
FileUtils.cp(local_cache_path, cache_path)
end
uri = spec.remote.uri
Bundler.ui.confirm("Fetching #{version_message(spec)}")
Bundler.rubygems.download_gem(spec, uri, download_cache_path)
end
# Returns the global cache path of the calling Rubygems::Source object.
@ -559,7 +536,7 @@ module Bundler
return unless remote = spec.remote
return unless cache_slug = remote.cache_slug
Bundler.user_cache.join("gems", cache_slug, spec.file_name)
Bundler.user_cache.join("gems", cache_slug)
end
def extension_cache_slug(spec)

View file

@ -37,6 +37,18 @@ RSpec.describe "global gem caching" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "shows a proper error message if a cached gem is corrupted" do
source_global_cache.mkpath
FileUtils.touch(source_global_cache("rack-1.0.0.gem"))
install_gemfile <<-G, :artifice => "compact_index_no_gem", :raise_on_error => false
source "#{source}"
gem "rack"
G
expect(err).to include("Gem::Package::FormatError: package metadata is missing in #{source_global_cache("rack-1.0.0.gem")}")
end
describe "when the same gem from different sources is installed" do
it "should use the appropriate one from the global cache" do
install_gemfile <<-G, :artifice => "compact_index"