Commit 33c9710e authored by Fabio Pelosin's avatar Fabio Pelosin

[Install/Update] First complete draft.

parent a4dbe7a4
...@@ -6,7 +6,7 @@ module Pod ...@@ -6,7 +6,7 @@ module Pod
$ pod outdated $ pod outdated
Shows the dependencies that would be installed by `pod update'. } Show all of the outdated pods in the current Podfile.lock. }
end end
def self.options def self.options
...@@ -28,21 +28,51 @@ module Pod ...@@ -28,21 +28,51 @@ module Pod
raise Informative, "No `Podfile.lock' found in the current working directory, run `pod install'." raise Informative, "No `Podfile.lock' found in the current working directory, run `pod install'."
end end
# if @update_repo if @update_repo
# print_title 'Updating Spec Repositories', true print_title 'Updating Spec Repositories', true
# Re"o.new(ARGV.new(["update"])).run Repo.new(ARGV.new(["update"])).run
# end end
sandbox = Sandbox.new(config.project_pods_root) sandbox = Sandbox.new(config.project_pods_root)
resolver = Resolver.new(podfile, lockfile, sandbox) resolver = Resolver.new(podfile, lockfile, sandbox)
resolver.update_mode = true resolver.update_mode = true
resolver.updated_external_specs = false
resolver.resolve resolver.resolve
specs_to_install = resolver.specs_to_install specs_to_install = resolver.specs_to_install
external_pods = resolver.external_pods
known_update_specs = []
head_mode_specs = []
resolver.specs.each do |s|
next if external_pods.include?(s.name)
next unless specs_to_install.include?(s.name)
if s.version.head?
head_mode_specs << s.name
else
known_update_specs << s.to_s
end
end
if specs_to_install.empty? if specs_to_install.empty?
puts "\nNo updates are available.\n".yellow puts "\nNo updates are available.\n".yellow
else else
puts "\nThe following updates are available:".green
puts " - " << specs_to_install.join("\n - ") << "\n\n" unless known_update_specs.empty?
puts "\nThe following updates are available:".green
puts " - " << known_update_specs.join("\n - ") << "\n"
end
unless head_mode_specs.empty?
puts "\nThe following pods might present updates as they are in head mode:".green
puts " - " << head_mode_specs.join("\n - ") << "\n"
end
unless (external_pods).empty?
puts "\nThe following pods might present updates as they loaded from an external source:".green
puts " - " << external_pods.join("\n - ") << "\n"
end
puts
end end
end end
end end
......
...@@ -49,7 +49,8 @@ module Pod ...@@ -49,7 +49,8 @@ module Pod
@headers_symlink_root ||= "#{project_pods_root}/Headers" @headers_symlink_root ||= "#{project_pods_root}/Headers"
end end
# Returns the spec at the pat returned from `project_podfile`. # @return [Podfile] The Podfile to use for the current execution.
#
def podfile def podfile
@podfile ||= begin @podfile ||= begin
Podfile.from_file(project_podfile) if project_podfile.exist? Podfile.from_file(project_podfile) if project_podfile.exist?
...@@ -57,6 +58,8 @@ module Pod ...@@ -57,6 +58,8 @@ module Pod
end end
attr_writer :podfile attr_writer :podfile
# @return [Lockfile] The Lockfile to use for the current execution.
#
def lockfile def lockfile
@lockfile ||= begin @lockfile ||= begin
Lockfile.from_file(project_lockfile) if project_lockfile.exist? Lockfile.from_file(project_lockfile) if project_lockfile.exist?
......
...@@ -40,7 +40,7 @@ module Pod ...@@ -40,7 +40,7 @@ module Pod
end end
def ==(other) def ==(other)
super && (@specification ? @specification == other.specification : @external_source == other.external_source) super && (head? == other.head?) && (@specification ? @specification == other.specification : @external_source == other.external_source)
end end
def subspec_dependency? def subspec_dependency?
...@@ -55,6 +55,16 @@ module Pod ...@@ -55,6 +55,16 @@ module Pod
!@external_source.nil? !@external_source.nil?
end end
def =~(other)
if head?
name === other.name && other.head?
elsif external?
name === other.name && external_source == other.external_source
else
super && !other.head? && !other.external?
end
end
# In case this is a dependency for a subspec, e.g. 'RestKit/Networking', # 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 # this returns 'RestKit', which is what the Pod::Source needs to know to
# retrieve the correct Set from disk. # retrieve the correct Set from disk.
...@@ -76,13 +86,14 @@ module Pod ...@@ -76,13 +86,14 @@ module Pod
if external? if external?
version << @external_source.description version << @external_source.description
elsif inline? elsif inline?
version << "defined in Podfile" version << 'defined in Podfile'
elsif head?
version << 'HEAD'
elsif @version_requirements != Gem::Requirement.default elsif @version_requirements != Gem::Requirement.default
version << @version_requirements.to_s version << @version_requirements.to_s
end end
result = @name.dup result = @name.dup
result += " (#{version})" unless version.empty? result << " (#{version})" unless version.empty?
result += " [HEAD]" if head?
result result
end end
...@@ -169,7 +180,9 @@ module Pod ...@@ -169,7 +180,9 @@ module Pod
class GitSource < AbstractExternalSource class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, platform) def copy_external_source_into_sandbox(sandbox, platform)
puts " * Pre-downloading: '#{name}'" unless config.silent? puts "-> Pre-downloading: '#{name}'" unless config.silent?
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params) downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download downloader.download
if local_pod = sandbox.installed_pod_named(name, platform) if local_pod = sandbox.installed_pod_named(name, platform)
...@@ -191,7 +204,7 @@ module Pod ...@@ -191,7 +204,7 @@ module Pod
def copy_external_source_into_sandbox(sandbox, _) def copy_external_source_into_sandbox(sandbox, _)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec" output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath output_path.dirname.mkpath
puts " * Fetching podspec for `#{name}' from: #{@params[:podspec]}" unless config.silent? puts "-> Fetching podspec for `#{name}' from: #{@params[:podspec]}" unless config.silent?
open(@params[:podspec]) do |io| open(@params[:podspec]) do |io|
output_path.open('w') { |f| f << io.read } output_path.open('w') { |f| f << io.read }
end end
......
...@@ -37,6 +37,11 @@ module Pod ...@@ -37,6 +37,11 @@ module Pod
end.compact end.compact
end end
# Install the pods. If the resolver wants the installation of pod it is done
# even if it exits. In any case if the pod doesn't exits it is installed.
#
# @return [void]
#
def install_dependencies! def install_dependencies!
pods.each do |pod| pods.each do |pod|
name = pod.top_specification.name name = pod.top_specification.name
...@@ -49,7 +54,6 @@ module Pod ...@@ -49,7 +54,6 @@ module Pod
else else
name = pod.to_s name = pod.to_s
end end
name << " [HEAD]" if pod.top_specification.version.head?
puts marker << ( should_install ? "Installing #{name}".green : "Using #{name}" ) puts marker << ( should_install ? "Installing #{name}".green : "Using #{name}" )
end end
...@@ -122,7 +126,7 @@ module Pod ...@@ -122,7 +126,7 @@ module Pod
puts "- Writing Xcode project file to `#{@sandbox.project_path}'\n\n" if config.verbose? puts "- Writing Xcode project file to `#{@sandbox.project_path}'\n\n" if config.verbose?
project.save_as(@sandbox.project_path) project.save_as(@sandbox.project_path)
puts "- Writing lockfile in `#{lockfile.defined_in_file}'\n\n" if config.verbose? puts "- Writing lockfile in `#{config.project_lockfile}'\n\n" if config.verbose?
@lockfile = Lockfile.create(config.project_lockfile, @podfile, specs_by_target.values.flatten) @lockfile = Lockfile.create(config.project_lockfile, @podfile, specs_by_target.values.flatten)
@lockfile.write_to_disk @lockfile.write_to_disk
......
...@@ -45,16 +45,18 @@ module Pod ...@@ -45,16 +45,18 @@ module Pod
attr_accessor :downloaded attr_accessor :downloaded
alias_method :downloaded?, :downloaded alias_method :downloaded?, :downloaded
# @param [Specification] specification # @param [Specification] specification The first activated specification
# The first activated specification of the pod. # of the pod.
# @param [Sandbox] sandbox #
# The sandbox where the files of the pod will be located. # @param [Sandbox] sandbox The sandbox where the files of the
# @param [Platform] platform # pod will be located.
# The platform that will be used to build the pod. #
# @param [Platform] platform The platform that will be used to
# build the pod.
# #
# @todo The local pod should be initialized with all the activated # @todo The local pod should be initialized with all the activated
# specifications passed as an array, in order to be able to cache the # specifications passed as an array, in order to be able to cache the
# computed values. In other words, it should be immutable. # computed values. In other words, it should be immutable.
# #
def initialize(specification, sandbox, platform) def initialize(specification, sandbox, platform)
@top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform @top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform
...@@ -93,7 +95,7 @@ module Pod ...@@ -93,7 +95,7 @@ module Pod
end end
# @return [String] A string representation of the pod which indicates if # @return [String] A string representation of the pod which indicates if
# the pods comes from a local source. # the pods comes from a local source.
# #
def to_s def to_s
result = top_specification.to_s result = top_specification.to_s
......
module Pod module Pod
class Lockfile class Lockfile
# @return [Lockfile] Returns the Lockfile saved in path. # @return [Lockfile] Returns the Lockfile saved in path. If the
# file could not be loaded or is not compatible with current
# version of CocoaPods {nil}
# #
def self.from_file(path) def self.from_file(path)
Lockfile.new(path) lockfile = Lockfile.new(path)
lockfile.hash_reppresentation ? lockfile : nil
end end
# @return [Lockfile] Creates a new Lockfile ready to be saved in path. # @return [Lockfile] Creates a new Lockfile ready to be saved in path.
...@@ -13,7 +16,7 @@ module Pod ...@@ -13,7 +16,7 @@ module Pod
Lockfile.new(path, podfile, specs) Lockfile.new(path, podfile, specs)
end end
attr_reader :defined_in_file, :podfile, :specs, :dictionary_reppresenation attr_reader :defined_in_file, :podfile, :specs, :hash_reppresentation
# @param [Pathname] the path of the Lockfile. # @param [Pathname] the path of the Lockfile.
# If no other value is provided the Lockfile is read from this path. # If no other value is provided the Lockfile is read from this path.
...@@ -28,36 +31,65 @@ module Pod ...@@ -28,36 +31,65 @@ module Pod
else else
yaml = YAML.load(File.open(path)) yaml = YAML.load(File.open(path))
if yaml && Version.new(yaml["COCOAPODS"]) >= Version.new("0.10") if yaml && Version.new(yaml["COCOAPODS"]) >= Version.new("0.10")
@dictionary_reppresenation = yaml @hash_reppresentation = yaml
end end
end end
end end
# @return [Array<Dependency>] The dependencies used during the last install. def pods
return [] unless to_hash
to_hash['PODS'] || []
end
def dependencies
return [] unless to_hash
to_hash['DEPENDENCIES'] || []
end
def external_sources
return [] unless to_hash
to_hash["EXTERNAL SOURCES"] || []
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
# #
def podfile_dependencies def podfile_dependencies
return [] unless to_dict dependencies.map { |dep| dependency_from_string(dep) }
dependencies = to_dict['DEPENDENCIES'] | []
dependencies.map { |dep|
match_data = dep.match(/(\S*)( (.*))/)
Dependency.new(match_data[1], match_data[2].gsub(/[()]/,''))
}
end end
# @return [Array<Dependency>] The dependencies that require exactly, # @return [Array<Dependency>] The dependencies that require the installed
# the installed pods. # pods with their exact version.
# #
def installed_dependencies def dependencies_for_pods
return [] unless to_dict pods.map { |pod| dependency_from_string(pod.is_a?(String) ? pod : pod.keys[0]) }
pods = to_dict['PODS'] | []
pods.map { |pod|
name_and_version = pod.is_a?(String) ? pod : pod.keys[0]
match_data = name_and_version.match(/(\S*)( (.*))/)
Dependency.new(match_data[1], match_data[2].gsub(/[()]/,''))
}
end end
# @return [void] Writes the Lockfile to path. # @return [Dependency] The dependency described by the string.
#
def dependency_from_string(string)
match_data = string.match(/(\S*)( (.*))?/)
name = match_data[1]
version = match_data[2]
version = version.gsub(/[()]/,'') if version
case version
when nil
Dependency.new(name)
when /from `(.*)'/
# @TODO: find a way to serialize the external specs and support
# all the options
external_source_info = external_sources.find {|hash| hash.keys[0] == name} || {}
Dependency.new(name, external_source_info[name])
when /HEAD/
# @TODO: find a way to serialize from the Downloader the information
# necessary to restore a head version.
Dependency.new(name, :head)
else
Dependency.new(name, version)
end
end
# @return [void] Writes the Lockfile to {#path}.
# #
def write_to_disk def write_to_disk
File.open(defined_in_file, 'w') {|f| f.write(to_yaml) } File.open(defined_in_file, 'w') {|f| f.write(to_yaml) }
...@@ -74,14 +106,15 @@ module Pod ...@@ -74,14 +106,15 @@ module Pod
# serialization. # serialization.
# #
def to_yaml def to_yaml
to_dict.to_yaml.gsub(/^--- ?\n/,"") to_hash.to_yaml.gsub(/^--- ?\n/,"").gsub(/^([A-Z])/,"\n\\1")
end end
# @return [Dictionary] The Dictionary representation of the Lockfile. # @return [Dictionary] The Dictionary representation of the Lockfile.
# #
def to_dict def to_hash
return @dictionary_reppresenation if @dictionary_reppresenation return @hash_reppresentation if @hash_reppresentation
return nil unless @podfile && @specs return nil unless @podfile && @specs
hash = {}
# Get list of [name, dependencies] pairs. # Get list of [name, dependencies] pairs.
pod_and_deps = specs.map do |spec| pod_and_deps = specs.map do |spec|
...@@ -100,14 +133,16 @@ module Pod ...@@ -100,14 +133,16 @@ module Pod
pod_and_deps = tmp.sort_by(&:first).map do |name, deps| pod_and_deps = tmp.sort_by(&:first).map do |name, deps|
deps.empty? ? name : {name => deps} deps.empty? ? name : {name => deps}
end end
hash["PODS"] = pod_and_deps
hash["DEPENDENCIES"] = podfile.dependencies.map{ |d| "#{d}" }.sort
external_sources = podfile.dependencies.select(&:external?).sort{ |d, other| d.name <=> other.name}.map{ |d| { d.name => d.external_source.params } }
hash["EXTERNAL SOURCES"] = external_sources unless external_sources.empty?
dict = {} # hash["SPECS_CHECKSUM"]
dict["PODS"] = pod_and_deps hash["COCOAPODS"] = VERSION
dict["DEPENDENCIES"] = podfile.dependencies.map(&:to_s).sort hash
# dict["SPECS_CHECKSUM"] =
# dict["HEAD_SPECS_INFO"] =
dict["COCOAPODS"] = VERSION
dict
end end
end end
end end
......
This diff is collapsed.
...@@ -172,6 +172,12 @@ module Pod ...@@ -172,6 +172,12 @@ module Pod
end end
attr_writer :name attr_writer :name
# @return [String] The name of the pod.
#
def pod_name
top_level_parent.name
end
### Attributes that return the first value defined in the chain ### Attributes that return the first value defined in the chain
def platform def platform
...@@ -441,7 +447,13 @@ module Pod ...@@ -441,7 +447,13 @@ module Pod
end end
def to_s def to_s
"#{name} (#{version})" if !version
name
elsif version.head?
"#{name} (HEAD from #{version})"
else
"#{name} (#{version})"
end
end end
def inspect def inspect
......
...@@ -70,14 +70,16 @@ else ...@@ -70,14 +70,16 @@ else
end end
# Note that we are *not* using the stubbed SpecHelper::Installer subclass. # Note that we are *not* using the stubbed SpecHelper::Installer subclass.
resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root)) resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root))
installer = Pod::Installer.new(resolver) installer = Pod::Installer.new(resolver)
installer.install! installer.install!
installer.lockfile.to_hash.should == {
installer.lockfile.to_dict.tap {|d| d.delete("COCOAPODS") }.should == {
'PODS' => ['SSToolkit (0.1.3)'], 'PODS' => ['SSToolkit (0.1.3)'],
'DEPENDENCIES' => ["SSToolkit (from `#{url}', commit `#{commit}')"] 'DEPENDENCIES' => ["SSToolkit (from `#{url}', commit `#{commit}')"],
'EXTERNAL SOURCES' => [ {"SSToolkit" => {
:git=>"/Users/fabio/Documents/GitHub/CP/CocoaPods/spec/fixtures/integration/sstoolkit", :commit=>"2adcd0f81740d6b0cd4589af98790eee3bd1ae7b"
}}],
'COCOAPODS' => Pod::VERSION
} }
end end
...@@ -95,10 +97,12 @@ else ...@@ -95,10 +97,12 @@ else
installer = SpecHelper::Installer.new(resolver) installer = SpecHelper::Installer.new(resolver)
installer.install! installer.install!
installer.lockfile.to_dict.tap {|d| d.delete("COCOAPODS") }.should == { installer.lockfile.to_hash.should == {
'PODS' => [ 'Reachability (1.2.3)' ], 'PODS' => [ 'Reachability (1.2.3)' ],
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"], 'DEPENDENCIES' => ["Reachability (from `#{url}')"],
'DEPENDENCIES' => ["Reachability (from `#{url}')"] "EXTERNAL SOURCES"=>[{"Reachability"=>{
:podspec=>"https://raw.github.com/gist/1349824/3ec6aa60c19113573fc48eac19d0fafd6a69e033/Reachability.podspec"}}],
'COCOAPODS' => Pod::VERSION
} }
end end
...@@ -170,7 +174,7 @@ else ...@@ -170,7 +174,7 @@ else
installer = SpecHelper::Installer.new(resolver) installer = SpecHelper::Installer.new(resolver)
installer.install! installer.install!
installer.lockfile.to_dict.tap {|d| d.delete("COCOAPODS") }.should == { installer.lockfile.to_hash.tap {|d| d.delete("COCOAPODS") }.should == {
'PODS' => ['JSONKit (1.2)', 'SSZipArchive (0.1.0)'], 'PODS' => ['JSONKit (1.2)', 'SSZipArchive (0.1.0)'],
'DEPENDENCIES' => ["JSONKit (defined in Podfile)", "SSZipArchive (defined in Podfile)"] 'DEPENDENCIES' => ["JSONKit (defined in Podfile)", "SSZipArchive (defined in Podfile)"]
} }
...@@ -200,7 +204,7 @@ else ...@@ -200,7 +204,7 @@ else
installer.install! installer.install!
# TODO might be nicer looking to not show the dependencies of the top level spec for each subspec (Reachability). # TODO might be nicer looking to not show the dependencies of the top level spec for each subspec (Reachability).
installer.lockfile.to_dict.should == { installer.lockfile.to_hash.should == {
"PODS" => [{ "ASIHTTPRequest (1.8.1)" => ["ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)", "PODS" => [{ "ASIHTTPRequest (1.8.1)" => ["ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)",
"ASIHTTPRequest/CloudFiles (= 1.8.1)", "ASIHTTPRequest/CloudFiles (= 1.8.1)",
"ASIHTTPRequest/S3 (= 1.8.1)", "ASIHTTPRequest/S3 (= 1.8.1)",
...@@ -258,7 +262,7 @@ else ...@@ -258,7 +262,7 @@ else
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
pod 'SSZipArchive' pod 'SSZipArchive', '0.1.0'
post_install do |installer| post_install do |installer|
target = installer.project.targets.first target = installer.project.targets.first
...@@ -277,15 +281,13 @@ else ...@@ -277,15 +281,13 @@ else
end end
# TODO add a simple source file which uses the compiled lib to check that it really really works # TODO add a simple source file which uses the compiled lib to check that it really really works
# TODO update for specification refactor
it "activates required pods and create a working static library xcode project" do it "activates required pods and create a working static library xcode project" do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
pod 'Reachability', '> 2.0.5' if platform == :ios pod 'Reachability', '> 2.0.5' if platform == :ios
# pod 'ASIWebPageRequest', '>= 1.8.1'
pod 'JSONKit', '>= 1.0' pod 'JSONKit', '>= 1.0'
pod 'SSZipArchive', '< 2' pod 'SSZipArchive', '< 0.1.2'
end end
resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root)) resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root))
...@@ -294,17 +296,14 @@ else ...@@ -294,17 +296,14 @@ else
lockfile_contents = { lockfile_contents = {
'PODS' => [ 'PODS' => [
# { 'ASIHTTPRequest (1.8.1)' => ["Reachability"] },
# { 'ASIWebPageRequest (1.8.1)' => ["ASIHTTPRequest (= 1.8.1)"] },
'JSONKit (1.5pre)', 'JSONKit (1.5pre)',
'Reachability (3.0.0)', 'Reachability (3.0.0)',
'SSZipArchive (0.2.2)', 'SSZipArchive (0.1.1)',
], ],
'DEPENDENCIES' => [ 'DEPENDENCIES' => [
# "ASIWebPageRequest (>= 1.8.1)",
"JSONKit (>= 1.0)", "JSONKit (>= 1.0)",
"Reachability (> 2.0.5)", "Reachability (> 2.0.5)",
"SSZipArchive (< 2)", "SSZipArchive (< 0.1.2)",
], ],
"COCOAPODS" => Pod::VERSION "COCOAPODS" => Pod::VERSION
} }
...@@ -314,7 +313,7 @@ else ...@@ -314,7 +313,7 @@ else
lockfile_contents['PODS'].delete_at(1) lockfile_contents['PODS'].delete_at(1)
# lockfile_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)' # lockfile_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
end end
installer.lockfile.to_dict.should == lockfile_contents installer.lockfile.to_hash.should == lockfile_contents
root = config.project_pods_root root = config.project_pods_root
(root + 'Pods.xcconfig').read.should == installer.target_installers.first.xcconfig.to_s (root + 'Pods.xcconfig').read.should == installer.target_installers.first.xcconfig.to_s
...@@ -325,7 +324,6 @@ else ...@@ -325,7 +324,6 @@ else
end end
if platform == :ios if platform == :ios
# TODO: update for Specification Refactor
it "does not activate pods that are only part of other pods" do it "does not activate pods that are only part of other pods" do
spec = Pod::Podfile.new do spec = Pod::Podfile.new do
self.platform platform self.platform platform
...@@ -337,7 +335,7 @@ else ...@@ -337,7 +335,7 @@ else
installer = SpecHelper::Installer.new(resolver) installer = SpecHelper::Installer.new(resolver)
installer.install! installer.install!
installer.lockfile.to_dict.tap {|d| d.delete("COCOAPODS") }.should == { installer.lockfile.to_hash.tap {|d| d.delete("COCOAPODS") }.should == {
# 'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }], # 'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }],
'PODS' => [ 'Reachability (2.0.4)' ], 'PODS' => [ 'Reachability (2.0.4)' ],
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"], # 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
...@@ -350,7 +348,7 @@ else ...@@ -350,7 +348,7 @@ else
spec = Pod::Podfile.new do spec = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
pod 'SSZipArchive' pod 'SSZipArchive', '0.1.0'
end end
resolver = Pod::Resolver.new(spec, nil, Pod::Sandbox.new(config.project_pods_root)) resolver = Pod::Resolver.new(spec, nil, Pod::Sandbox.new(config.project_pods_root))
...@@ -378,7 +376,7 @@ else ...@@ -378,7 +376,7 @@ else
spec = Pod::Podfile.new do spec = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
pod 'SSZipArchive' pod 'SSZipArchive', '0.1.0'
end end
resolver = Pod::Resolver.new(spec, nil, Pod::Sandbox.new(config.project_pods_root)) resolver = Pod::Resolver.new(spec, nil, Pod::Sandbox.new(config.project_pods_root))
installer = SpecHelper::Installer.new(resolver) installer = SpecHelper::Installer.new(resolver)
...@@ -392,7 +390,7 @@ else ...@@ -392,7 +390,7 @@ else
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
target(:debug) { pod 'SSZipArchive' } target(:debug) { pod 'SSZipArchive', '0.1.0' }
target(:test, :exclusive => true) { pod 'JSONKit' } target(:test, :exclusive => true) { pod 'JSONKit' }
pod 'ASIHTTPRequest' pod 'ASIHTTPRequest'
end end
...@@ -447,7 +445,7 @@ else ...@@ -447,7 +445,7 @@ else
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj projpath xcodeproj projpath
pod 'SSZipArchive' pod 'SSZipArchive', '0.1.0'
end end
resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root)) resolver = Pod::Resolver.new(podfile, nil, Pod::Sandbox.new(config.project_pods_root))
...@@ -473,7 +471,7 @@ else ...@@ -473,7 +471,7 @@ else
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
self.platform platform self.platform platform
xcodeproj 'dummy' xcodeproj 'dummy'
target(:debug) { pod 'SSZipArchive' } target(:debug) { pod 'SSZipArchive', '0.1.0' }
target(:test, :exclusive => true) { pod 'JSONKit' } target(:test, :exclusive => true) { pod 'JSONKit' }
pod 'ASIHTTPRequest' pod 'ASIHTTPRequest'
end end
......
...@@ -37,7 +37,7 @@ module Pod ...@@ -37,7 +37,7 @@ module Pod
dep2 = Dependency.new { |s| s.name = 'bananas'; s.version = '1' } dep2 = Dependency.new { |s| s.name = 'bananas'; s.version = '1' }
dep1.should == dep2 dep1.should == dep2
end end
it 'raises if created without either valid name/version/external requirements or a block' do it 'raises if created without either valid name/version/external requirements or a block' do
lambda { Dependency.new }.should.raise Informative lambda { Dependency.new }.should.raise Informative
end end
...@@ -49,11 +49,11 @@ module Pod ...@@ -49,11 +49,11 @@ module Pod
spec.version = "1.0.3" spec.version = "1.0.3"
end end
end end
it 'it identifies itself as an inline dependency' do it 'it identifies itself as an inline dependency' do
@dependency.should.be.inline @dependency.should.be.inline
end end
it 'attaches a custom spec to the dependency, configured by the block' do it 'attaches a custom spec to the dependency, configured by the block' do
@dependency.specification.name.should == "my-custom-spec" @dependency.specification.name.should == "my-custom-spec"
end end
...@@ -73,7 +73,7 @@ module Pod ...@@ -73,7 +73,7 @@ module Pod
it "identifies itself as a `bleeding edge' dependency" do it "identifies itself as a `bleeding edge' dependency" do
dependency = Dependency.new("cocoapods", :head) dependency = Dependency.new("cocoapods", :head)
dependency.should.be.head dependency.should.be.head
dependency.to_s.should == "cocoapods [HEAD]" dependency.to_s.should == "cocoapods (HEAD)"
end end
it "only supports the `:head' option on the last version of a pod" do it "only supports the `:head' option on the last version of a pod" do
...@@ -98,7 +98,7 @@ module Pod ...@@ -98,7 +98,7 @@ module Pod
Downloader.stubs(:for_target).returns(stub_everything) Downloader.stubs(:for_target).returns(stub_everything)
pod = mock('LocaPod', :downloaded= => true) pod = mock('LocaPod', :downloaded= => true)
sandbox = stub('Sandbox', :root => '', :installed_pod_named => pod) sandbox = stub('Sandbox', :root => temporary_sandbox.root, :installed_pod_named => pod)
@dependency.external_source.copy_external_source_into_sandbox(sandbox, Platform.ios) @dependency.external_source.copy_external_source_into_sandbox(sandbox, Platform.ios)
end end
end end
......
...@@ -42,7 +42,7 @@ describe "Pod::Lockfile" do ...@@ -42,7 +42,7 @@ describe "Pod::Lockfile" do
File.open(tmp_path, 'w') {|f| f.write(sample) } File.open(tmp_path, 'w') {|f| f.write(sample) }
lockfile = Pod::Lockfile.from_file(tmp_path) lockfile = Pod::Lockfile.from_file(tmp_path)
lockfile.defined_in_file.should == tmp_path lockfile.defined_in_file.should == tmp_path
lockfile.to_dict.should == YAML.load(sample) lockfile.to_hash.should == YAML.load(sample)
end end
before do before do
...@@ -54,7 +54,7 @@ describe "Pod::Lockfile" do ...@@ -54,7 +54,7 @@ describe "Pod::Lockfile" do
end end
it "generates a valid Dictionary representation" do it "generates a valid Dictionary representation" do
@lockfile.to_dict.should == YAML.load(sample) @lockfile.to_hash.should == YAML.load(sample)
end end
it "returns the Podfile dependencies" do it "returns the Podfile dependencies" do
...@@ -64,7 +64,7 @@ describe "Pod::Lockfile" do ...@@ -64,7 +64,7 @@ describe "Pod::Lockfile" do
end end
it "returns the dependencies for the installed pods" do it "returns the dependencies for the installed pods" do
@lockfile.installed_dependencies.should == [ @lockfile.dependencies_for_pods.should == [
Pod::Dependency.new("BananaLib", "= 1.0"), Pod::Dependency.new("BananaLib", "= 1.0"),
Pod::Dependency.new("monkey", "= 1.0.8") Pod::Dependency.new("monkey", "= 1.0.8")
] ]
...@@ -73,7 +73,7 @@ describe "Pod::Lockfile" do ...@@ -73,7 +73,7 @@ describe "Pod::Lockfile" do
it "can check if it is compatible with a file" do it "can check if it is compatible with a file" do
File.open(tmp_path, 'w') {|f| f.write(sample.gsub("COCOAPODS: #{Pod::VERSION}", "")) } File.open(tmp_path, 'w') {|f| f.write(sample.gsub("COCOAPODS: #{Pod::VERSION}", "")) }
lockfile = Pod::Lockfile.from_file(tmp_path) lockfile = Pod::Lockfile.from_file(tmp_path)
lockfile.to_dict.should == nil lockfile.should == nil
end end
it "serializes correctly `:head' dependencies" do it "serializes correctly `:head' dependencies" do
...@@ -93,13 +93,13 @@ describe "Pod::Lockfile" do ...@@ -93,13 +93,13 @@ describe "Pod::Lockfile" do
] ]
specs.each { |s| s.activate_platform(:ios) } specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.create(tmp_path, podfile, specs) lockfile = Pod::Lockfile.create(tmp_path, podfile, specs)
lockfile.to_dict["DEPENDENCIES"][0].should == "BananaLib [HEAD]" lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (HEAD)"
end end
it "serializes correctly external dependencies" do it "serializes correctly external dependencies" do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
platform :ios platform :ios
pod 'BananaLib', :git => "www.example.com" pod 'BananaLib', { :git => "www.example.com", :tag => '1.0' }
end end
specs = [ specs = [
Pod::Specification.new do |s| Pod::Specification.new do |s|
...@@ -113,12 +113,36 @@ describe "Pod::Lockfile" do ...@@ -113,12 +113,36 @@ describe "Pod::Lockfile" do
] ]
specs.each { |s| s.activate_platform(:ios) } specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.create(tmp_path, podfile, specs) lockfile = Pod::Lockfile.create(tmp_path, podfile, specs)
lockfile.to_dict["DEPENDENCIES"][0].should == "BananaLib (from `www.example.com')" lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (from `www.example.com', tag `1.0')"
lockfile.to_hash["EXTERNAL SOURCES"][0]["BananaLib"].should == { :git => "www.example.com", :tag => '1.0' }
end end
xit "reads `:heads' dependencies correctly" do it "creates a dependency from a string" do
d = @lockfile.dependency_from_string("BananaLib (1.0)")
d.name.should == "BananaLib"
d.requirement.should =~ Pod::Version.new("1.0")
d.head.should.be.nil
d.external_source.should.be.nil
end end
xit "reads external dependencies dependencies correctly" do it "creates a head dependency from a string" do
d = @lockfile.dependency_from_string("BananaLib (HEAD)")
d.name.should == "BananaLib"
d.requirement.should.be.none?
d.head.should.be.true
d.external_source.should.be.nil
end
it "creates an external dependency from a string" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', { :git => "www.example.com", :tag => '1.0' }
end
lockfile = Pod::Lockfile.create(tmp_path, podfile, [])
d = lockfile.dependency_from_string("BananaLib (from `www.example.com', tag `1.0')")
d.name.should == "BananaLib"
d.requirement.should.be.none?
d.external?.should.be.true
d.external_source.description.should == "from `www.example.com', tag `1.0'"
end end
end end
...@@ -191,42 +191,175 @@ module Pod ...@@ -191,42 +191,175 @@ module Pod
jsonkit.version.should.be.head jsonkit.version.should.be.head
end end
xit "raises if it finds two conflicting dependencies" do it "accepts a nil lockfile" do
lambda { Resolver.new(@podfile, nil, stub('sandbox'))}.should.not.raise
end
it "raises if it finds two conflicting dependencies" do
podfile = Podfile.new do
platform :ios
pod 'JSONKit', "1.4"
pod 'JSONKit', "1.5pre"
end
resolver = Resolver.new(podfile, nil, stub('sandbox'))
lambda {resolver.resolve}.should.raise Pod::Informative
end end
describe "Concerning the Lockfile" do describe "Concerning Installation mode" do
xit "accepts a nil lockfile" do before do
lambda { Resolver.new(@podfile, nil, stub('sandbox'))}.should.not.raise config.repos_dir = fixture('spec-repos')
@podfile = Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
end
@specs = [
Pod::Specification.new do |s|
s.name = "BlocksKit"
s.version = "1.0.0"
end,
Pod::Specification.new do |s|
s.name = "JSONKit"
s.version = "1.4"
end ]
@specs.each { |s| s.activate_platform(:ios) }
@lockfile = Lockfile.create(nil, @podfile, @specs)
@resolver = Resolver.new(@podfile, @lockfile, stub('sandbox'))
end end
xit "detects the pods that need to be installed" do it "doesn't install pods still compatible with the Podfile" do
@resolver.resolve
@resolver.should_install?("BlocksKit").should.be.false
@resolver.should_install?("JSONKit").should.be.false
end
it "doesn't updates pods still compatible with the Podfile" do
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "JSONKit (1.4)"
end end
xit "detects the pods that don't need to be installed" do it "doesn't include pods removed from the Podfile" do
podfile = Podfile.new { platform :ios; pod 'JSONKit' }
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve.values.flatten.map(&:name).should == %w{ JSONKit }
end
it "reinstalls pods updated in the Podfile" do
podfile = Podfile.new do
platform :ios
pod 'JSONKit', '1.5pre'
pod 'BlocksKit'
end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "BlocksKit (1.0.0)"
installed.should.include? "JSONKit (1.5pre)"
end end
xit "detects the pods that can be updated" do it "installs pods added to the Podfile" do
podfile = Podfile.new do
platform :ios
pod 'JSONKit'
pod 'BlocksKit'
pod 'libPusher'
end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "libPusher (1.3)"
end
it "handles head pods" do
podfile = Podfile.new do
platform :ios
pod 'JSONKit', :head # Existing pod switched to head mode
pod 'libPusher', :head # New pod
end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve
@resolver.should_install?("JSONKit").should.be.true
@resolver.should_install?("libPusher").should.be.true
end end
xit "doesn't install new pods in `update_mode'" do it "handles pods from external dependencies" do
podfile = Podfile.new do
platform :ios
pod 'libPusher', :git => 'GIT-URL'
end
spec = Spec.new do |s|
s.name = 'libPusher'
s.version = '1.3'
end
podfile.dependencies.first.external_source.stubs(:specification_from_sandbox).returns(spec)
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.resolve
@resolver.should_install?("JSONKit").should.be.false
end
end
describe "Concerning Update mode" do
before do
config.repos_dir = fixture('spec-repos')
@podfile = Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
pod 'libPusher'
end
@specs = [
Pod::Specification.new do |s|
s.name = "libPusher"
s.version = "1.3"
end,
Pod::Specification.new do |s|
s.name = "JSONKit"
s.version = "1.4"
end ]
@specs.each { |s| s.activate_platform(:ios) }
@lockfile = Lockfile.create(nil, @podfile, @specs)
@resolver = Resolver.new(@podfile, @lockfile, stub('sandbox'))
@resolver.update_mode = true
end end
xit "handles correctly pods with external source" do it "identifies the pods that can be updated" do
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "JSONKit (1.5pre)"
@resolver.should_install?("JSONKit").should.be.true
end
it "respecs the constraints of the pofile" do
podfile = Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', '1.4'
end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.update_mode = true
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.should.include? "JSONKit (1.4)"
@resolver.should_install?("JSONKit").should.be.false
end end
xit "it always suggest to update pods in head mode" do it "doesn't install new pods in `update_mode'" do
installed = @resolver.resolve.values.flatten.map(&:to_s)
installed.join(' ').should.not.include?('BlocksKit')
@resolver.should_install?("BlocksKit").should.be.false
end
it "it always suggests to update pods in head mode" do
podfile = Podfile.new do
platform :ios
pod 'libPusher', :head
end
@resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
@resolver.update_mode = true
@resolver.resolve
@resolver.should_install?("libPusher").should.be.true
end end
xit "it prevents a pod from upgrading during an install" do xit "it suggests to update pods from external sources" do
end end
end end
end end
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