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: ...@@ -4,6 +4,9 @@ inherit_from:
#- CocoaPods ------------------------------------------------------------------ #- CocoaPods ------------------------------------------------------------------
ParameterLists:
CountKeywordArgs: false
AllCops: AllCops:
Exclude: Exclude:
- spec/fixtures/**/*.rb - spec/fixtures/**/*.rb
......
...@@ -6,21 +6,19 @@ require 'tmpdir' ...@@ -6,21 +6,19 @@ require 'tmpdir'
module Pod module Pod
module Downloader module Downloader
require 'cocoapods/downloader/cache' require 'cocoapods/downloader/cache'
require 'cocoapods/downloader/request'
def self.download( def self.download(
name_or_spec, request,
download_target, target,
released: false,
downloader_options: nil,
head: false,
cache_path: !Config.instance.skip_download_cache && Config.instance.cache_root + 'Pods' cache_path: !Config.instance.skip_download_cache && Config.instance.cache_root + 'Pods'
) )
cache_path, tmp_cache = Pathname(Dir.mktmpdir), true unless cache_path cache_path, tmp_cache = Pathname(Dir.mktmpdir), true unless cache_path
cache = Cache.new(cache_path) cache = Cache.new(cache_path)
result = cache.download_pod(name_or_spec, released, downloader_options, head) result = cache.download_pod(request)
if download_target if target
FileUtils.rm_rf download_target FileUtils.rm_rf target
FileUtils.cp_r(result.location, download_target) FileUtils.cp_r(result.location, target)
end end
result result
ensure ensure
......
...@@ -13,79 +13,57 @@ module Pod ...@@ -13,79 +13,57 @@ module Pod
root.mkpath unless root.exist? root.mkpath unless root.exist?
end end
def download_pod(name_or_spec, released = false, downloader_opts = nil, head = false) def download_pod(request)
spec = nil cached_pod(request) || uncached_pod(request)
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)
rescue Informative rescue Informative
raise raise
rescue rescue
UI.notice("Error installing #{name}") UI.notice("Error installing #{request.name}")
raise raise
end end
private private
def cache_key(pod_name, version = nil, downloader_opts = nil) def path_for_pod(request)
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) root + request.slug
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)
end end
def path_for_spec(name, version = nil, downloader_opts = nil) def path_for_spec(request)
path = root + 'Specs' + cache_key(name, version, downloader_opts) path = root + 'Specs' + request.slug
path.sub_ext('.podspec.json') path.sub_ext('.podspec.json')
end end
def cached_pod(name, spec, version, downloader_opts) def cached_pod(request)
path = path_for_pod(name, version, downloader_opts) path = path_for_pod(request)
spec ||= cached_spec(name, version, downloader_opts) spec = request.spec || cached_spec(request)
return unless spec && path.directory? return unless spec && path.directory?
Result.new(path, spec, downloader_opts) Result.new(path, spec, request.params)
end end
def cached_spec(name, version, downloader_opts) def cached_spec(request)
path = path_for_spec(name, version, downloader_opts) path = path_for_spec(request)
path.file? && Specification.from_file(path) path.file? && Specification.from_file(path)
end end
def uncached_pod(name, spec, released, version, downloader_opts, head) def uncached_pod(request)
in_tmpdir do |target| in_tmpdir do |target|
result = Result.new 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 if request.released_pod?
result.location = destination = path_for_pod(name, version) result.location = destination = path_for_pod(request)
copy_and_clean(target, destination, spec) copy_and_clean(target, destination, request.spec)
write_spec spec, path_for_spec(name, version) write_spec(request.spec, path_for_spec(request))
else else
podspecs = Sandbox::PodspecFinder.new(target).podspecs podspecs = Sandbox::PodspecFinder.new(target).podspecs
podspecs[name] = spec if spec podspecs[request.name] = request.spec if request.spec
podspecs.each do |_, found_spec| podspecs.each do |_, spec|
destination = path_for_pod(found_spec.name, nil, result.checkout_options) destination = path_for_pod(request)
copy_and_clean(target, destination, found_spec) copy_and_clean(target, destination, spec)
write_spec found_spec, path_for_spec(found_spec.name, nil, result.checkout_options) write_spec(spec, path_for_spec(request))
if name == found_spec.name if request.name == spec.name
result.location = destination result.location = destination
result.spec = found_spec result.spec = spec
end end
end 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 ...@@ -98,7 +98,7 @@ module Pod
title = "Pre-downloading: `#{name}` #{description}" title = "Pre-downloading: `#{name}` #{description}"
UI.titled_section(title, :verbose_prefix => '-> ') do UI.titled_section(title, :verbose_prefix => '-> ') do
target = sandbox.pod_dir(name) 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 spec = download_result.spec
raise Informative, "Unable to find a specification for '#{name}'." unless spec raise Informative, "Unable to find a specification for '#{name}'." unless spec
...@@ -109,6 +109,13 @@ module Pod ...@@ -109,6 +109,13 @@ module Pod
end end
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 # Stores the podspec in the sandbox and marks it as from an external
# source. # source.
# #
......
...@@ -74,13 +74,21 @@ module Pod ...@@ -74,13 +74,21 @@ module Pod
# @return [void] # @return [void]
# #
def download_source 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 if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source
sandbox.store_checkout_source(root_spec.name, specific_source) sandbox.store_checkout_source(root_spec.name, specific_source)
end end
end end
def download_request
Downloader::Request.new(
spec: root_spec,
released: released?,
head: head_pod?,
)
end
extend Executable extend Executable
executable :bash 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