blob: 042ec193e8dc126d60df0f52a450fc216f986bd7 [file] [log] [blame]
require 'cocoapods-downloader'
require 'claide/informative_error'
require 'fileutils'
require 'tmpdir'
module Pod
module Downloader
require 'cocoapods/downloader/cache'
require 'cocoapods/downloader/request'
require 'cocoapods/downloader/response'
# Downloads a pod from the given `request` to the given `target` location.
#
# @return [Response] The download response for this download.
#
# @param [Request] request
# the request that describes this pod download.
#
# @param [Pathname,Nil] target
# the location to which this pod should be downloaded. If `nil`,
# then the pod will only be cached.
#
# @param [Boolean] can_cache
# whether caching is allowed.
#
# @param [Pathname,Nil] cache_path
# the path used to cache pod downloads.
#
def self.download(
request,
target,
can_cache: true,
cache_path: Config.instance.cache_root + 'Pods'
)
can_cache &&= !Config.instance.skip_download_cache
request = preprocess_request(request)
if can_cache
raise ArgumentError, 'Must provide a `cache_path` when caching.' unless cache_path
cache = Cache.new(cache_path)
result = cache.download_pod(request)
else
raise ArgumentError, 'Must provide a `target` when caching is disabled.' unless target
require 'cocoapods/installer/pod_source_preparer'
result, = download_request(request, target)
Installer::PodSourcePreparer.new(result.spec, result.location).prepare!
end
if target && result.location && target != result.location
UI.message "Copying #{request.name} from `#{result.location}` to #{UI.path target}", '> ' do
FileUtils.rm_rf target
FileUtils.cp_r(result.location, target)
end
end
result
end
# Performs the download from the given `request` to the given `target` location.
#
# @return [Response, Hash<String,Specification>]
# The download response for this download, and the specifications
# for this download grouped by name.
#
# @param [Request] request
# the request that describes this pod download.
#
# @param [Pathname,Nil] target
# the location to which this pod should be downloaded. If `nil`,
# then the pod will only be cached.
#
def self.download_request(request, target)
result = Response.new
result.checkout_options = download_source(target, request.params)
result.location = target
if request.released_pod?
result.spec = request.spec
podspecs = { request.name => request.spec }
else
podspecs = Sandbox::PodspecFinder.new(target).podspecs
podspecs[request.name] = request.spec if request.spec
podspecs.each do |name, spec|
if request.name == name
result.spec = spec
end
end
end
[result, podspecs]
end
private
# Downloads a pod with the given `params` to `target`.
#
# @param [Pathname] target
#
# @param [Hash<Symbol,String>] params
#
# @return [Hash] The checkout options required to re-download this exact
# same source.
#
def self.download_source(target, params)
FileUtils.rm_rf(target)
downloader = Downloader.for_target(target, params)
downloader.download
target.mkpath
if downloader.options_specific?
params
else
downloader.checkout_options
end
end
# Return a new request after preprocessing by the downloader
#
# @param [Request] request
# the request that needs preprocessing
#
# @return [Request] the preprocessed request
#
def self.preprocess_request(request)
Request.new(
:spec => request.spec,
:released => request.released_pod?,
:name => request.name,
:params => Downloader.preprocess_options(request.params))
end
public
class DownloaderError; include CLAide::InformativeError; end
class Base
override_api do
def execute_command(executable, command, raise_on_failure = false)
Executable.execute_command(executable, command, raise_on_failure)
rescue CLAide::InformativeError => e
raise DownloaderError, e.message
end
# Indicates that an action will be performed. The action is passed as a
# block.
#
# @param [String] message
# The message associated with the action.
#
# @yield The action, this block is always executed.
#
# @return [void]
#
def ui_action(message)
UI.section(" > #{message}", '', 1) do
yield
end
end
# Indicates that a minor action will be performed. The action is passed
# as a block.
#
# @param [String] message
# The message associated with the action.
#
# @yield The action, this block is always executed.
#
# @return [void]
#
def ui_sub_action(message)
UI.section(" > #{message}", '', 2) do
yield
end
end
# Prints an UI message.
#
# @param [String] message
# The message associated with the action.
#
# @return [void]
#
def ui_message(message)
UI.puts message
end
end
end
end
end