instance method
Gem::RemoteFetcher#download
download(spec, source_uri, install_dir = Gem.dir)
lib/rubygems/remote_fetcher.rb
View on GitHub ↗
# File tmp/rubies/ruby-4.0.0/lib/rubygems/remote_fetcher.rb, line 113
def download(spec, source_uri, install_dir = Gem.dir)
install_cache_dir = File.join install_dir, "cache"
cache_dir =
if Dir.pwd == install_dir # see fetch_command
install_dir
elsif File.writable?(install_cache_dir) || (File.writable?(install_dir) && !File.exist?(install_cache_dir))
install_cache_dir
else
File.join Gem.user_dir, "cache"
end
gem_file_name = File.basename spec.cache_file
local_gem_path = File.join cache_dir, gem_file_name
require "fileutils"
begin
FileUtils.mkdir_p cache_dir
rescue StandardError
nil
end unless File.exist? cache_dir
source_uri = Gem::Uri.new(source_uri)
scheme = source_uri.scheme
# Gem::URI.parse gets confused by MS Windows paths with forward slashes.
scheme = nil if /^[a-z]$/i.match?(scheme)
# REFACTOR: split this up and dispatch on scheme (eg download_http)
# REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
case scheme
when "http", "https", "s3" then
unless File.exist? local_gem_path
begin
verbose "Downloading gem #{gem_file_name}"
remote_gem_path = source_uri + "gems/#{gem_file_name}"
cache_update_path remote_gem_path, local_gem_path
rescue FetchError
raise if spec.original_platform == spec.platform
alternate_name = "#{spec.original_name}.gem"
verbose "Failed, downloading gem #{alternate_name}"
remote_gem_path = source_uri + "gems/#{alternate_name}"
cache_update_path remote_gem_path, local_gem_path
end
end
when "file" then
begin
path = source_uri.path
path = File.dirname(path) if File.extname(path) == ".gem"
remote_gem_path = Gem::Util.correct_for_windows_path(File.join(path, "gems", gem_file_name))
FileUtils.cp(remote_gem_path, local_gem_path)
rescue Errno::EACCES
local_gem_path = source_uri.to_s
end
verbose "Using local gem #{local_gem_path}"
when nil then # TODO: test for local overriding cache
source_path = if Gem.win_platform? && source_uri.scheme &&
!source_uri.path.include?(":")
"#{source_uri.scheme}:#{source_uri.path}"
else
source_uri.path
end
source_path = Gem::UriFormatter.new(source_path).unescape
begin
FileUtils.cp source_path, local_gem_path unless
File.identical?(source_path, local_gem_path)
rescue Errno::EACCES
local_gem_path = source_uri.to_s
end
verbose "Using local gem #{local_gem_path}"
else
raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}"
end
local_gem_path
end
Moves the gem spec from source_uri to the cache dir unless it is already there. If the source_uri is local the gem cache dir copy is always replaced.
See also
#close_all
#download_to_cache
#cache_update_path
#fetch_file
also in
4.1 · 3.4 · 3.3 · 3.2 · 3.1 · 3.0