Commit 8fbb7d55 authored by Samuel E. Giddins's avatar Samuel E. Giddins

[Downloader] Introduce the notion of a download request

parent e733b78c
......@@ -4,6 +4,9 @@ inherit_from:
#- CocoaPods ------------------------------------------------------------------
ParameterLists:
CountKeywordArgs: false
AllCops:
Exclude:
- spec/fixtures/**/*.rb
......
......@@ -6,21 +6,19 @@ require 'tmpdir'
module Pod
module Downloader
require 'cocoapods/downloader/cache'
require 'cocoapods/downloader/request'
def self.download(
name_or_spec,
download_target,
released: false,
downloader_options: nil,
head: false,
request,
target,
cache_path: !Config.instance.skip_download_cache && Config.instance.cache_root + 'Pods'
)
cache_path, tmp_cache = Pathname(Dir.mktmpdir), true unless cache_path
cache = Cache.new(cache_path)
result = cache.download_pod(name_or_spec, released, downloader_options, head)
if download_target
FileUtils.rm_rf download_target
FileUtils.cp_r(result.location, download_target)
result = cache.download_pod(request)
if target
FileUtils.rm_rf target
FileUtils.cp_r(result.location, target)
end
result
ensure
......
......@@ -13,79 +13,57 @@ module Pod
root.mkpath unless root.exist?
end
def download_pod(name_or_spec, released = false, downloader_opts = nil, head = false)
spec = nil
if name_or_spec.is_a? Pod::Specification
spec = name_or_spec.root
name, version, downloader_opts = spec.name, spec.version, spec.source.dup
else
name = Specification.root_name(name_or_spec.to_s)
end
raise ArgumentError, 'Must give spec for a released download.' if released && !spec
result = cached_pod(name, spec, released && version, !released && downloader_opts)
result || uncached_pod(name, spec, released, version, downloader_opts, head)
def download_pod(request)
cached_pod(request) || uncached_pod(request)
rescue Informative
raise
rescue
UI.notice("Error installing #{name}")
UI.notice("Error installing #{request.name}")
raise
end
private
def cache_key(pod_name, version = nil, downloader_opts = nil)
raise ArgumentError, "Need a pod name (#{pod_name}), and either a version (#{version}) or downloader options (#{downloader_opts})." unless pod_name && (version || downloader_opts) && !(version && downloader_opts)
if version
"Release/#{pod_name}/#{version}"
elsif downloader_opts
opts = downloader_opts.to_a.sort_by(&:first).map { |k, v| "#{k}=#{v}" }.join('-').gsub(/#{File::SEPARATOR}+/, '+')
"External/#{pod_name}/#{opts}"
end
end
def path_for_pod(name, version = nil, downloader_opts = nil)
root + cache_key(name, version, downloader_opts)
def path_for_pod(request)
root + request.slug
end
def path_for_spec(name, version = nil, downloader_opts = nil)
path = root + 'Specs' + cache_key(name, version, downloader_opts)
def path_for_spec(request)
path = root + 'Specs' + request.slug
path.sub_ext('.podspec.json')
end
def cached_pod(name, spec, version, downloader_opts)
path = path_for_pod(name, version, downloader_opts)
spec ||= cached_spec(name, version, downloader_opts)
def cached_pod(request)
path = path_for_pod(request)
spec = request.spec || cached_spec(request)
return unless spec && path.directory?
Result.new(path, spec, downloader_opts)
Result.new(path, spec, request.params)
end
def cached_spec(name, version, downloader_opts)
path = path_for_spec(name, version, downloader_opts)
def cached_spec(request)
path = path_for_spec(request)
path.file? && Specification.from_file(path)
end
def uncached_pod(name, spec, released, version, downloader_opts, head)
def uncached_pod(request)
in_tmpdir do |target|
result = Result.new
result.checkout_options = download(name, target, downloader_opts, head)
result.checkout_options = download(request.name, target, request.params, request.head?)
if released
result.location = destination = path_for_pod(name, version)
copy_and_clean(target, destination, spec)
write_spec spec, path_for_spec(name, version)
if request.released_pod?
result.location = destination = path_for_pod(request)
copy_and_clean(target, destination, request.spec)
write_spec(request.spec, path_for_spec(request))
else
podspecs = Sandbox::PodspecFinder.new(target).podspecs
podspecs[name] = spec if spec
podspecs.each do |_, found_spec|
destination = path_for_pod(found_spec.name, nil, result.checkout_options)
copy_and_clean(target, destination, found_spec)
write_spec found_spec, path_for_spec(found_spec.name, nil, result.checkout_options)
if name == found_spec.name
podspecs[request.name] = request.spec if request.spec
podspecs.each do |_, spec|
destination = path_for_pod(request)
copy_and_clean(target, destination, spec)
write_spec(spec, path_for_spec(request))
if request.name == spec.name
result.location = destination
result.spec = found_spec
result.spec = spec
end
end
end
......
module Pod
module Downloader
class Request
attr_reader :released_pod
alias_method :released_pod?, :released_pod
attr_reader :spec
attr_reader :head
alias_method :head?, :head
attr_reader :params
attr_reader :name
def initialize(spec: nil, released: false, name: nil, version: nil, params: false, head: false)
@released_pod = released
@spec = spec
@params = spec ? spec.source.dup : params
@name = spec ? spec.name : name
@head = head
validate!
end
def slug
if released_pod?
"Release/#{name}/#{spec.version}"
else
opts = params.to_a.sort_by(&:first).map { |k, v| "#{k}=#{v}" }.join('-').gsub(/#{Regexp.escape File::SEPARATOR}+/, '+')
"External/#{name}/#{opts}"
end
end
private
def validate!
raise ArgumentError, 'Requires a name' unless name
raise ArgumentError, 'Requires a version if released' if released_pod? && !spec.version
raise ArgumentError, 'Requires params' unless params
raise ArgumentError, 'Must give a spec for a released download request' if released_pod? && !spec
end
end
end
end
......@@ -98,7 +98,7 @@ module Pod
title = "Pre-downloading: `#{name}` #{description}"
UI.titled_section(title, :verbose_prefix => '-> ') do
target = sandbox.pod_dir(name)
download_result = Downloader.download(name, target, :downloader_options => params)
download_result = Downloader.download(download_request, target)
spec = download_result.spec
raise Informative, "Unable to find a specification for '#{name}'." unless spec
......@@ -109,6 +109,13 @@ module Pod
end
end
def download_request
Downloader::Request.new(
name: name,
params: params
)
end
# Stores the podspec in the sandbox and marks it as from an external
# source.
#
......
......@@ -74,13 +74,21 @@ module Pod
# @return [void]
#
def download_source
download_result = Downloader.download(root_spec, root, :released => released?, :head => head_pod?)
download_result = Downloader.download(download_request, root)
if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source
sandbox.store_checkout_source(root_spec.name, specific_source)
end
end
def download_request
Downloader::Request.new(
spec: root_spec,
released: released?,
head: head_pod?,
)
end
extend Executable
executable :bash
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment