Commit ce8650bb authored by Luke Redpath's avatar Luke Redpath

Refactor the handling of different external sources within a dependency, and if the specification

for an external source can be loaded from the sandbox, because it's already been downloaded, then
just use it rather than trying to pre-download it again.
parent f6e3c90c
Subproject commit 07cf34ba82c250093fd1bba5dd37d6298bcdfeeb
Subproject commit dd73ed13de67165c2e7e6271482b5a4a20e07f69
module Gem
end
require 'rubygems/dependency'
require 'open-uri'
module Pod
class Dependency < Gem::Dependency
attr_accessor :only_part_of_other_pod
alias_method :only_part_of_other_pod?, :only_part_of_other_pod
attr_accessor :external_spec_source
attr_reader :external_source
attr_accessor :specification
def initialize(*name_and_version_requirements, &block)
......@@ -19,7 +19,7 @@ module Pod
elsif !name_and_version_requirements.empty? && block.nil?
if name_and_version_requirements.last.is_a?(Hash)
@external_spec_source = name_and_version_requirements.pop
@external_source = ExternalSources.from_params(name_and_version_requirements[0], name_and_version_requirements.pop)
end
super(*name_and_version_requirements)
......@@ -33,13 +33,21 @@ module Pod
def ==(other)
super &&
@only_part_of_other_pod == other.only_part_of_other_pod &&
(@specification ? @specification == other.specification : @external_spec_source == other.external_spec_source)
(@specification ? @specification == other.specification : @external_source == other.external_source)
end
def subspec_dependency?
@name.include?('/')
end
def inline?
@inline_podspec
end
def external?
!@external_source.nil?
end
# In case this is a dependency for a subspec, e.g. 'RestKit/Networking',
# this returns 'RestKit', which is what the Pod::Source needs to know to
# retrieve the correct Set from disk.
......@@ -58,11 +66,9 @@ module Pod
def to_s
version = ''
if source = @external_spec_source
version << "from `#{source[:git] || source[:podspec]}'"
version << ", commit `#{source[:commit]}'" if source[:commit]
version << ", tag `#{source[:tag]}'" if source[:tag]
elsif @inline_podspec
if external?
version << @external_source.description
elsif inline?
version << "defined in Podfile"
elsif @version_requirements != Gem::Requirement.default
version << @version_requirements.to_s
......@@ -70,36 +76,8 @@ module Pod
version.empty? ? @name : "#{@name} (#{version})"
end
# In case this dependency was defined with either a repo url, :podspec, or block,
# this method will return the Specification instance.
def specification
@specification ||= begin
if @external_spec_source
config = Config.instance
pod_root = config.project_pods_root + @name
spec = nil
if @external_spec_source[:podspec]
config.project_pods_root.mkpath
spec = config.project_pods_root + "#{@name}.podspec"
source = @external_spec_source[:podspec]
# can be http, file, etc
require 'open-uri'
puts " * Fetching podspec for `#{@name}' from: #{source}" unless config.silent?
open(source) do |io|
spec.open('w') { |f| f << io.read }
end
else
puts " * Pre-downloading: `#{@name}'" unless config.silent?
Downloader.for_dependency(self).download
spec = pod_root + "#{@name}.podspec"
end
Specification.from_file(spec)
end
end
end
def pod_root
Config.instance.project_pods_root + @name
def specification_from_sandbox(sandbox)
@external_source.specification_from_sandbox(sandbox)
end
# Taken from RubyGems 1.3.7
......@@ -138,5 +116,68 @@ module Pod
end
end
module ExternalSources
def self.from_params(name, params)
if params.key?(:git)
GitSource.new(name, params)
elsif params.key?(:podspec)
PodspecSource.new(name, params)
else
raise Informative, "Unknown external source parameters for #{name}: #{params}"
end
end
class AbstractExternalSource
attr_reader :name, :params
def initialize(name, params)
@name, @params = name, params
end
def specification_from_sandbox(sandbox)
if local_pod = sandbox.installed_pod_named(name)
local_pod.specification
else
copy_external_source_into_sandbox(sandbox)
sandbox.installed_pod_named(name).specification
end
end
def ==(other_source)
return if other_source.nil?
name == other_source.name &&
params == other_source.params
end
end
class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox)
puts " * Pre-downloading: '#{name}'" unless Config.instance.silent?
Downloader.for_target(sandbox.root + name, @params).download
end
def description
"from '#{@params[:git]}'".tap do |description|
description << ", commit `#{@params[:commit]}'" if @params[:commit]
description << ", tag `#{@params[:tag]}'" if @params[:tag]
end
end
end
class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
podspec_url = @params[:podspec] # can be http, file, etc
puts " * Fetching podspec for `#{name}' from: #{podspec_url}" unless Config.instance.silent?
open(source) do |io|
output_path.open('w') { |f| f << io.read }
end
end
def description
version << "from '#{source[:podspec]}'"
end
end
end
end
end
......@@ -12,10 +12,6 @@ module Pod
for_target(pod.root, spec.source.dup)
end
def self.for_dependency(dependency)
for_target(dependency.pod_root, dependency.external_spec_source)
end
attr_reader :target_path, :url, :options
def initialize(target_path, url, options)
......
......@@ -22,6 +22,10 @@ module Pod
end
end
def name
specification.name
end
def create
root.mkpath unless exists?
end
......
module Pod
class Resolver
def initialize(podfile)
def initialize(podfile, sandbox)
@podfile = podfile
@sandbox = sandbox
end
def resolve
......@@ -37,8 +38,11 @@ module Pod
end
def find_dependency_set(dependency)
if external_spec = dependency.specification
Specification::Set::External.new(external_spec)
if dependency.specification
Specification::Set::External.new(dependency.specification)
elsif external_source = dependency.external_source
specification = external_source.specification_from_sandbox(@sandbox)
Specification::Set::External.new(specification)
else
Source.search(dependency)
end
......
......@@ -49,5 +49,9 @@ module Pod
LocalPod.from_podspec(Pathname.new(podspec), self)
end
end
def installed_pod_named(name)
installed_pods.find { |pod| pod.name == name }
end
end
end
......@@ -30,12 +30,12 @@ describe "Pod::Dependency" do
dep.to_top_level_spec_dependency.should == Pod::Dependency.new('RestKit', '>= 1.2.3')
end
it "is equal to another dependency if `external_spec_source' is the same" do
it "is equal to another dependency if `external_source' is the same" do
dep1 = Pod::Dependency.new('bananas', :git => 'GIT-URL')
dep2 = Pod::Dependency.new('bananas')
dep1.should.not == dep2
dep2.external_spec_source = { :git => 'GIT-URL' }
dep1.should == dep2
dep3 = Pod::Dependency.new('bananas', :git => 'GIT-URL')
dep1.should == dep3
end
it "is equal to another dependency if `specification' is equal" do
......@@ -45,4 +45,35 @@ describe "Pod::Dependency" do
dep2 = Pod::Dependency.new { |s| s.name = 'bananas'; s.version = '1' }
dep1.should == dep2
end
it 'raises if created without either valid name/version/external requirements or a block' do
lambda { Pod::Dependency.new }.should.raise Pod::Informative
end
end
describe "Pod::Dependency", "defined with a block" do
before do
@dependency = Pod::Dependency.new do |spec|
spec.name = "my-custom-spec"
spec.version = "1.0.3"
end
end
it 'it identifies itself as an inline dependency' do
@dependency.should.be.inline
end
it 'attaches a custom spec to the dependency, configured by the block' do
@dependency.specification.name.should == "my-custom-spec"
end
end
describe "Pod::Dependency", "with a hash of external source settings" do
before do
@dependency = Pod::Dependency.new("cocoapods", :git => "git://github.com/cocoapods/cocoapods")
end
it 'it identifies itself as an external dependency' do
@dependency.should.be.external
end
end
......@@ -23,7 +23,7 @@ describe "Pod::Podfile" do
dependency 'SomeExternalPod', :git => 'GIT-URL', :commit => '1234'
end
dep = podfile.dependency_by_top_level_spec_name('SomeExternalPod')
dep.external_spec_source.should == { :git => 'GIT-URL', :commit => '1234' }
dep.external_source.params.should == { :git => 'GIT-URL', :commit => '1234' }
end
it "adds a dependency on a library outside of a spec repo (the repo does not need to contain a podspec)" do
......@@ -31,7 +31,7 @@ describe "Pod::Podfile" do
dependency 'SomeExternalPod', :podspec => 'http://gist/SomeExternalPod.podspec'
end
dep = podfile.dependency_by_top_level_spec_name('SomeExternalPod')
dep.external_spec_source.should == { :podspec => 'http://gist/SomeExternalPod.podspec' }
dep.external_source.params.should == { :podspec => 'http://gist/SomeExternalPod.podspec' }
end
it "adds a dependency on a library by specifying the podspec inline" do
......
......@@ -39,13 +39,13 @@ describe "Pod::Resolver" do
end
it "returns all specs needed for the dependency" do
specs = Pod::Resolver.new(@podfile).resolve
specs = Pod::Resolver.new(@podfile, stub('sandbox')).resolve
specs.map(&:class).uniq.should == [Pod::Specification]
specs.map(&:name).sort.should == %w{ ASIHTTPRequest ASIWebPageRequest Reachability }
end
it "does not raise if all dependencies match the platform of the root spec (Podfile)" do
resolver = Pod::Resolver.new(@podfile)
resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
@podfile.platform :ios
lambda { resolver.resolve }.should.not.raise
......@@ -54,7 +54,7 @@ describe "Pod::Resolver" do
end
it "raises once any of the dependencies does not match the platform of the root spec (Podfile)" do
resolver = StubbedResolver.new(config.rootspec)
resolver = StubbedResolver.new(config.rootspec, stub('sandbox'))
@podfile.platform :ios
resolver.stub_platform = :ios
......@@ -76,7 +76,7 @@ describe "Pod::Resolver" do
dependency 'RestKit/ObjectMapping'
end
config.rootspec = @podfile
resolver = Pod::Resolver.new(@podfile)
resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
resolver.resolve.map(&:name).sort.should == %w{ LibComponentLogging-Core LibComponentLogging-NSLog RestKit RestKit/Network RestKit/ObjectMapping }
end
end
......
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