Permalink
Browse files

[Install/Update] First complete draft.

  • Loading branch information...
fabiopelosin committed Aug 9, 2012
1 parent a4dbe7a commit 33c9710ea75b6e3ff7f50314ce31c0619b1649ba
@@ -6,7 +6,7 @@ def self.banner
$ pod outdated
- Shows the dependencies that would be installed by `pod update'. }
+ Show all of the outdated pods in the current Podfile.lock. }
end
def self.options
@@ -28,21 +28,51 @@ def run
raise Informative, "No `Podfile.lock' found in the current working directory, run `pod install'."
end
- # if @update_repo
- # print_title 'Updating Spec Repositories', true
- # Re"o.new(ARGV.new(["update"])).run
- # end
+ if @update_repo
+ print_title 'Updating Spec Repositories', true
+ Repo.new(ARGV.new(["update"])).run
+ end
sandbox = Sandbox.new(config.project_pods_root)
resolver = Resolver.new(podfile, lockfile, sandbox)
resolver.update_mode = true
+ resolver.updated_external_specs = false
resolver.resolve
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?
puts "\nNo updates are available.\n".yellow
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
View
@@ -49,14 +49,17 @@ def headers_symlink_root
@headers_symlink_root ||= "#{project_pods_root}/Headers"
end
- # Returns the spec at the pat returned from `project_podfile`.
+ # @return [Podfile] The Podfile to use for the current execution.
+ #
def podfile
@podfile ||= begin
Podfile.from_file(project_podfile) if project_podfile.exist?
end
end
attr_writer :podfile
+ # @return [Lockfile] The Lockfile to use for the current execution.
+ #
def lockfile
@lockfile ||= begin
Lockfile.from_file(project_lockfile) if project_lockfile.exist?
@@ -40,7 +40,7 @@ def latest_version?
end
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
def subspec_dependency?
@@ -55,6 +55,16 @@ def external?
!@external_source.nil?
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',
# this returns 'RestKit', which is what the Pod::Source needs to know to
# retrieve the correct Set from disk.
@@ -76,13 +86,14 @@ def to_s
if external?
version << @external_source.description
elsif inline?
- version << "defined in Podfile"
+ version << 'defined in Podfile'
+ elsif head?
+ version << 'HEAD'
elsif @version_requirements != Gem::Requirement.default
version << @version_requirements.to_s
end
result = @name.dup
- result += " (#{version})" unless version.empty?
- result += " [HEAD]" if head?
+ result << " (#{version})" unless version.empty?
result
end
@@ -169,7 +180,9 @@ def ==(other_source)
class GitSource < AbstractExternalSource
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.download
if local_pod = sandbox.installed_pod_named(name, platform)
@@ -191,7 +204,7 @@ class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, _)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
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|
output_path.open('w') { |f| f << io.read }
end
@@ -37,6 +37,11 @@ def target_installers
end.compact
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!
pods.each do |pod|
name = pod.top_specification.name
@@ -49,7 +54,6 @@ def install_dependencies!
else
name = pod.to_s
end
- name << " [HEAD]" if pod.top_specification.version.head?
puts marker << ( should_install ? "Installing #{name}".green : "Using #{name}" )
end
@@ -122,7 +126,7 @@ def install!
puts "- Writing Xcode project file to `#{@sandbox.project_path}'\n\n" if config.verbose?
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.write_to_disk
View
@@ -45,16 +45,18 @@ class LocalPod
attr_accessor :downloaded
alias_method :downloaded?, :downloaded
- # @param [Specification] specification
- # The first activated specification of the pod.
- # @param [Sandbox] sandbox
- # The sandbox where the files of the pod will be located.
- # @param [Platform] platform
- # The platform that will be used to build the pod.
+ # @param [Specification] specification The first activated specification
+ # of the pod.
+ #
+ # @param [Sandbox] sandbox The sandbox where the files of the
+ # pod will be located.
+ #
+ # @param [Platform] platform The platform that will be used to
+ # build the pod.
#
# @todo The local pod should be initialized with all the activated
- # specifications passed as an array, in order to be able to cache the
- # computed values. In other words, it should be immutable.
+ # specifications passed as an array, in order to be able to cache the
+ # computed values. In other words, it should be immutable.
#
def initialize(specification, sandbox, platform)
@top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform
@@ -93,7 +95,7 @@ def root
end
# @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
result = top_specification.to_s
View
@@ -1,10 +1,13 @@
module Pod
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)
- Lockfile.new(path)
+ lockfile = Lockfile.new(path)
+ lockfile.hash_reppresentation ? lockfile : nil
end
# @return [Lockfile] Creates a new Lockfile ready to be saved in path.
@@ -13,7 +16,7 @@ def self.create(path, podfile, specs)
Lockfile.new(path, podfile, specs)
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.
# If no other value is provided the Lockfile is read from this path.
@@ -28,36 +31,65 @@ def initialize(path, podfile = nil, specs = nil)
else
yaml = YAML.load(File.open(path))
if yaml && Version.new(yaml["COCOAPODS"]) >= Version.new("0.10")
- @dictionary_reppresenation = yaml
+ @hash_reppresentation = yaml
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
- return [] unless to_dict
- dependencies = to_dict['DEPENDENCIES'] | []
- dependencies.map { |dep|
- match_data = dep.match(/(\S*)( (.*))/)
- Dependency.new(match_data[1], match_data[2].gsub(/[()]/,''))
- }
+ dependencies.map { |dep| dependency_from_string(dep) }
end
- # @return [Array<Dependency>] The dependencies that require exactly,
- # the installed pods.
+ # @return [Array<Dependency>] The dependencies that require the installed
+ # pods with their exact version.
#
- def installed_dependencies
- return [] unless to_dict
- 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(/[()]/,''))
- }
+ def dependencies_for_pods
+ pods.map { |pod| dependency_from_string(pod.is_a?(String) ? pod : pod.keys[0]) }
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
File.open(defined_in_file, 'w') {|f| f.write(to_yaml) }
@@ -74,14 +106,15 @@ def to_s
# serialization.
#
def to_yaml
- to_dict.to_yaml.gsub(/^--- ?\n/,"")
+ to_hash.to_yaml.gsub(/^--- ?\n/,"").gsub(/^([A-Z])/,"\n\\1")
end
# @return [Dictionary] The Dictionary representation of the Lockfile.
#
- def to_dict
- return @dictionary_reppresenation if @dictionary_reppresenation
+ def to_hash
+ return @hash_reppresentation if @hash_reppresentation
return nil unless @podfile && @specs
+ hash = {}
# Get list of [name, dependencies] pairs.
pod_and_deps = specs.map do |spec|
@@ -100,14 +133,16 @@ def to_dict
pod_and_deps = tmp.sort_by(&:first).map do |name, deps|
deps.empty? ? name : {name => deps}
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 = {}
- dict["PODS"] = pod_and_deps
- dict["DEPENDENCIES"] = podfile.dependencies.map(&:to_s).sort
- # dict["SPECS_CHECKSUM"] =
- # dict["HEAD_SPECS_INFO"] =
- dict["COCOAPODS"] = VERSION
- dict
+ # hash["SPECS_CHECKSUM"]
+ hash["COCOAPODS"] = VERSION
+ hash
end
end
end
Oops, something went wrong.

0 comments on commit 33c9710

Please sign in to comment.