Commit d7faa63f authored by Fabio Pelosin's avatar Fabio Pelosin

[Core Extraction] Initial support for CocoaPods-Core.

parent 482c9589
......@@ -3,6 +3,7 @@ source "http://rubygems.org"
gemspec
group :development do
gem "cocoapods-core", :git => "git://github.com/CocoaPods/Core.git"
gem "xcodeproj", :git => "git://github.com/CocoaPods/Xcodeproj.git"
gem "mocha", "~> 0.11.4"
gem "bacon"
......
GIT
remote: git://github.com/CocoaPods/Core.git
revision: 0b028885b07cd7681a889523748f12dbdcf3a6c3
specs:
cocoapods-core (0.16.0.rc2)
activesupport (~> 3.2.6)
faraday (~> 0.8.1)
octokit (~> 1.7)
GIT
remote: git://github.com/CocoaPods/Xcodeproj.git
revision: 97a5a444ecfadf52e42afdbbf054f078f7c2cc5d
......@@ -21,6 +30,7 @@ PATH
cocoapods (0.16.0.rc2)
activesupport (~> 3.2.6)
claide (~> 0.1)
cocoapods-core
colored (~> 1.2)
escape (~> 0.0.4)
faraday (~> 0.8.1)
......@@ -90,6 +100,7 @@ DEPENDENCIES
awesome_print
bacon
cocoapods!
cocoapods-core!
github-markup
kicker!
mocha (~> 0.11.4)
......
......@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
s.executables = %w{ pod }
s.require_paths = %w{ lib }
s.add_runtime_dependency 'cocoapods-core'
s.add_runtime_dependency 'claide', '~> 0.1'
s.add_runtime_dependency 'xcodeproj', '~> 0.4.0.rc1'
......
......@@ -25,26 +25,16 @@ module Pod
end
autoload :Command, 'cocoapods/command'
autoload :Config, 'cocoapods/config'
autoload :Dependency, 'cocoapods/dependency'
autoload :Downloader, 'cocoapods/downloader'
autoload :Executable, 'cocoapods/executable'
autoload :Installer, 'cocoapods/installer'
autoload :LocalPod, 'cocoapods/local_pod'
autoload :Lockfile, 'cocoapods/lockfile'
autoload :Platform, 'cocoapods/platform'
autoload :Podfile, 'cocoapods/podfile'
autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox'
autoload :Source, 'cocoapods/source'
autoload :Spec, 'cocoapods/specification'
autoload :Specification, 'cocoapods/specification'
autoload :UI, 'cocoapods/user_interface'
autoload :Version, 'cocoapods/version_class'
autoload :Pathname, 'pathname'
autoload :FileList, 'cocoapods/file_list'
module Generator
autoload :BridgeSupport, 'cocoapods/generator/bridge_support'
......@@ -54,9 +44,15 @@ module Pod
autoload :Plist, 'cocoapods/generator/acknowledgements/plist'
autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown'
autoload :DummySource, 'cocoapods/generator/dummy_source'
autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
end
end
require 'cocoapods/file_list'
require 'cocoapods-core'
require 'cocoapods/config'
require 'cocoapods/source'
if ENV['COCOA_PODS_ENV'] == 'development'
require 'awesome_print'
end
require 'cocoapods/open_uri'
module Pod
class Dependency < Gem::Dependency
attr_reader :head
alias :head? :head
attr_accessor :specification, :external_source
def initialize(*name_and_version_requirements, &block)
if name_and_version_requirements.empty? && block
@inline_podspec = true
@specification = Specification.new(&block)
super(@specification.name, @specification.version)
elsif !name_and_version_requirements.empty? && block.nil?
version = name_and_version_requirements.last
if name_and_version_requirements.last.is_a?(Hash)
@external_source = ExternalSources.from_params(name_and_version_requirements[0].split('/').first, name_and_version_requirements.pop)
elsif version.is_a?(Symbol) && version == :head || version.is_a?(Version) && version.head?
name_and_version_requirements.pop
@head = true
end
super(*name_and_version_requirements)
if head? && !latest_version?
raise Informative, "A `:head' dependency may not specify version requirements."
end
else
raise Informative, "A dependency needs either a name and version requirements, " \
"a source hash, or a block which defines a podspec."
end
end
def latest_version?
versions = @version_requirements.requirements.map(&:last)
versions == [Gem::Version.new('0')]
end
def ==(other)
super && (head? == other.head?) && (@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.
def top_level_spec_name
subspec_dependency? ? @name.split('/').first : @name
end
# Returns a copy of the dependency, but with the name of the top level
# spec. This is used by Pod::Specification::Set to merge dependencies on
# the complete set, irrespective of what spec in the set wil be used.
def to_top_level_spec_dependency
dep = dup
dep.name = top_level_spec_name
dep
end
def to_s
version = ''
if external?
version << @external_source.description
elsif inline?
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
end
def specification_from_sandbox(sandbox, platform)
@external_source.specification_from_sandbox(sandbox, platform)
end
def match_version?(version)
match?(name, version) && (version.head? == head?)
end
# Taken from RubyGems 1.3.7
unless public_method_defined?(:match?)
def match?(spec_name, spec_version)
pattern = name
if Regexp === pattern
return false unless pattern =~ spec_name
else
return false unless pattern == spec_name
end
return true if requirement.to_s == ">= 0"
requirement.satisfied_by? Gem::Version.new(spec_version)
end
end
# Taken from a newer version of RubyGems
unless public_method_defined?(:merge)
def merge other
unless name == other.name then
raise ArgumentError,
"#{self} and #{other} have different names"
end
default = Gem::Requirement.default
self_req = self.requirement
other_req = other.requirement
return self.class.new name, self_req if other_req == default
return self.class.new name, other_req if self_req == default
self.class.new name, self_req.as_list.concat(other_req.as_list)
end
end
module ExternalSources
def self.from_params(name, params)
return unless name && params
if params.key?(:git)
GitSource.new(name, params)
elsif params.key?(:podspec)
PodspecSource.new(name, params)
elsif params.key?(:local)
LocalSource.new(name, params)
else
raise Informative, "Unknown external source parameters for #{name}: #{params}"
end
end
class AbstractExternalSource
include Config::Mixin
attr_reader :name, :params
def initialize(name, params)
@name, @params = name, params
end
def specification_from_sandbox(sandbox, platform)
specification_from_local(sandbox, platform) || specification_from_external(sandbox, platform)
end
def specification_from_local(sandbox, platform)
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.top_specification
end
end
def specification_from_external(sandbox, platform)
podspec = copy_external_source_into_sandbox(sandbox, platform)
spec = specification_from_local(sandbox, platform)
raise Informative, "No podspec found for `#{name}' in #{description}" unless spec
spec
end
# Can store from a pathname or a string
#
def store_podspec(sandbox, podspec)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath
if podspec.is_a?(String)
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.include?('Spec.new')
output_path.open('w') { |f| f.puts(podspec) }
else
raise Informative, "No podspec found for `#{name}' in #{description}" unless podspec.exist?
FileUtils.copy(podspec, output_path)
end
end
def ==(other)
return if other.nil?
name == other.name && params == other.params
end
end
class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, platform)
UI.info("->".green + " Pre-downloading: '#{name}'") do
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.downloaded = true
end
end
end
def description
"from `#{@params[:git]}'".tap do |description|
description << ", commit `#{@params[:commit]}'" if @params[:commit]
description << ", branch `#{@params[:branch]}'" if @params[:branch]
description << ", tag `#{@params[:tag]}'" if @params[:tag]
end
end
end
# can be http, file, etc
class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, _)
UI.info("->".green + " Fetching podspec for `#{name}' from: #{@params[:podspec]}") do
path = @params[:podspec]
path = Pathname.new(path).expand_path if path.start_with?("~")
open(path) { |io| store_podspec(sandbox, io.read) }
end
end
def description
"from `#{@params[:podspec]}'"
end
end
class LocalSource < AbstractExternalSource
def pod_spec_path
path = Pathname.new(@params[:local]).expand_path
path += "#{name}.podspec"# unless path.to_s.include?("#{name}.podspec")
raise Informative, "No podspec found for `#{name}' in `#{@params[:local]}'" unless path.exist?
path
end
def copy_external_source_into_sandbox(sandbox, _)
store_podspec(sandbox, pod_spec_path)
end
def specification_from_local(sandbox, platform)
specification_from_external(sandbox, platform)
end
def specification_from_external(sandbox, platform)
copy_external_source_into_sandbox(sandbox, platform)
spec = Specification.from_file(pod_spec_path)
spec.source = @params
spec
end
def description
"from `#{@params[:local]}'"
end
end
end
end
end
require 'digest'
module Pod
class Lockfile
# @return [Lockfile] Returns the Lockfile saved in path.
# Returns {nil} If the file can't be loaded.
#
def self.from_file(path)
return nil unless path.exist?
begin
hash = YAML.load(File.open(path))
rescue Exception => e
raise Informative, "Podfile.lock syntax error: #{e.inspect}"
end
lockfile = Lockfile.new(hash)
lockfile.defined_in_file = path
lockfile
end
# @return [Lockfile] Generates a lockfile from a {Podfile} and the
# list of {Specifications} that were installed.
#
def self.generate(podfile, specs)
Lockfile.new(generate_hash_from_podfile(podfile, specs))
end
# @return [String] The file where this Lockfile is defined.
#
attr_accessor :defined_in_file
# @return [String] The hash used to initialize the Lockfile.
#
attr_reader :to_hash
# @param [Hash] hash A Hash representation of a Lockfile.
#
def initialize(hash)
@to_hash = hash
end
# @return [Array<String, Hash{String => Array[String]}>] The pods installed
# and their dependencies.
#
def pods
@pods ||= to_hash['PODS'] || []
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
#
def dependencies
@dependencies ||= to_hash['DEPENDENCIES'].map { |dep| dependency_from_string(dep) } || []
end
# @return [Hash{String => Hash}] A hash where the name of the pods are
# the keys and the values are the parameters of an {AbstractExternalSource}
# of the dependency that required the pod.
#
def external_sources
@external_sources ||= to_hash["EXTERNAL SOURCES"] || {}
end
# @return [Array<String>] The names of the installed Pods.
#
def pods_names
@pods_names ||= pods.map do |pod|
pod = pod.keys.first unless pod.is_a?(String)
name_and_version_for_pod(pod)[0]
end
end
# @return [Hash{String => Version}] A Hash containing the name
# of the installed Pods as the keys and their corresponding {Version}
# as the values.
#
def pods_versions
unless @pods_versions
@pods_versions = {}
pods.each do |pod|
pod = pod.keys.first unless pod.is_a?(String)
name, version = name_and_version_for_pod(pod)
@pods_versions[name] = version
end
end
@pods_versions
end
# @return [Dependency] A dependency that describes the exact installed version
# of a Pod.
#
def dependency_for_installed_pod_named(name)
version = pods_versions[name]
raise Informative, "Attempt to lock a Pod without an known version." unless version
dependency = Dependency.new(name, version)
if external_source = external_sources[name]
dependency.external_source = Dependency::ExternalSources.from_params(dependency.name, external_source)
end
dependency
end
# @param [String] The string that describes a {Specification} generated
# from {Specification#to_s}.
#
# @example Strings examples
# "libPusher"
# "libPusher (1.0)"
# "libPusher (HEAD based on 1.0)"
# "RestKit/JSON"
#
# @return [String, Version] The name and the version of a
# pod.
#
def name_and_version_for_pod(string)
match_data = string.match(/(\S*) \((.*)\)/)
name = match_data[1]
vers = Version.from_string(match_data[2])
[name, vers]
end
# @param [String] The string that describes a {Dependency} generated
# from {Dependency#to_s}.
#
# @example Strings examples
# "libPusher"
# "libPusher (= 1.0)"
# "libPusher (~> 1.0.1)"
# "libPusher (> 1.0, < 2.0)"
# "libPusher (HEAD)"
# "libPusher (from `www.example.com')"
# "libPusher (defined in Podfile)"
# "RestKit/JSON"
#
# @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 /defined in Podfile/
# @TODO: store the whole spec?, the version?
Dependency.new(name)
when /from `(.*)'/
external_source_info = external_sources[name]
Dependency.new(name, external_source_info)
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
# Analyzes the {Lockfile} and detects any changes applied to the {Podfile}
# since the last installation.
#
# For each Pod, it detects one state among the following:
#
# - added: Pods that weren't present in the Podfile.
# - changed: Pods that were present in the Podfile but changed:
# - Pods whose version is not compatible anymore with Podfile,
# - Pods that changed their head or external options.
# - removed: Pods that were removed form the Podfile.
# - unchanged: Pods that are still compatible with Podfile.
#
# @TODO: detect changes for inline dependencies?
#
# @return [Hash{Symbol=>Array[Strings]}] A hash where pods are grouped
# by the state in which they are.
#
def detect_changes_with_podfile(podfile)
previous_podfile_deps = dependencies.map(&:name)
user_installed_pods = pods_names.reject { |name| !previous_podfile_deps.include?(name) }
deps_to_install = podfile.dependencies.dup
result = {}
result[:added] = []
result[:changed] = []
result[:removed] = []
result[:unchanged] = []
user_installed_pods.each do |pod_name|
dependency = deps_to_install.find { |d| d.name == pod_name }
deps_to_install.delete(dependency)
version = pods_versions[pod_name]
external_source = Dependency::ExternalSources.from_params(pod_name, external_sources[pod_name])
if dependency.nil?
result[:removed] << pod_name
elsif !dependency.match_version?(version) || dependency.external_source != external_source
result[:changed] << pod_name
else
result[:unchanged] << pod_name
end
end
deps_to_install.each do |dependency|
result[:added] << dependency.name
end
result
end
# @return [void] Writes the Lockfile to {#path}.
#
def write_to_disk(path)
path.dirname.mkpath unless path.dirname.exist?
File.open(path, 'w') {|f| f.write(to_yaml) }
defined_in_file = path
end
# @return [String] A string useful to represent the Lockfile in a message
# presented to the user.
#
def to_s
"Podfile.lock"
end
# @return [String] The YAML representation of the Lockfile, used for
# serialization.
#
def to_yaml
to_hash.to_yaml.gsub(/^--- ?\n/,"").gsub(/^([A-Z])/,"\n\\1")
end
# @return [Hash] The Hash representation of the Lockfile generated from
# a given Podfile and the list of resolved Specifications.
#
def self.generate_hash_from_podfile(podfile, specs)
hash = {}
# Get list of [name, dependencies] pairs.
pod_and_deps = specs.map do |spec|
[spec.to_s, spec.dependencies.map(&:to_s).sort]
end.uniq
# Merge dependencies of iOS and OS X version of the same pod.
tmp = {}
pod_and_deps.each do |name, deps|
if tmp[name]
tmp[name].concat(deps).uniq!
else
tmp[name] = deps
end
end
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.to_s }.sort
external_sources = {}
deps = podfile.dependencies.select(&:external?).sort{ |d, other| d.name <=> other.name}
deps.each{ |d| external_sources[d.name] = d.external_source.params }
hash["EXTERNAL SOURCES"] = external_sources unless external_sources.empty?
checksums = {}
specs.select { |spec| !spec.defined_in_file.nil? }.each do |spec|
checksum = Digest::SHA1.hexdigest(File.read(spec.defined_in_file))
checksum = checksum.encode('UTF-8') if checksum.respond_to?(:encode)
checksums[spec.name] = checksum
end
hash["SPEC CHECKSUMS"] = checksums unless checksums.empty?
hash["COCOAPODS"] = VERSION
hash
end
end
end
module Pod
# A platform describes an SDK name and deployment target.
#
class Platform
# @return [Platform] Convenience method to initialize an iOS platform.
#
def self.ios
new :ios
end
# @return [Platform] Convenience method to initialize an OS X platform.
#
def self.osx
new :osx
end
# Constructs a platform from either another platform or by
# specifying the symbolic name and optionally the deployment target.
#
# @overload initialize(name, deployment_target)
# @param [Symbol] name The name of platform.
# @param [String, Version] deployment_target The optional deployment.
# If not provided a default value according to the platform name will
# be assigned.
#
# @note that if the name is not specified a default deployment
# target will not be assigned.
#
# @example
#
# Platform.new(:ios)
# Platform.new(:ios, '4.3')
#
# @overload initialize(platform)
# @param [Platform] platform Another {Platform}.
#
# @example
#
# platform = Platform.new(:ios)
# Platform.new(platform)
#
def initialize(input, target = nil)
if input.is_a? Platform
@symbolic_name = input.name
@deployment_target = input.deployment_target
else
@symbolic_name = input
target = target[:deployment_target] if target.is_a?(Hash)
@deployment_target = Version.create(target)
end
end
# @return [Symbol] The name of the SDK represented by the platform.
#
def name
@symbolic_name
end
# @return [Version] The deployment target of the platform.
#
attr_reader :deployment_target
# @param [Platform, Symbol] other The other platform to check.
#
# @note If a symbol is passed the comparison does not take into account
# the deployment target.
#
# @return [Boolean] Whether two platforms are the equivalent.
#
def ==(other)
if other.is_a?(Symbol)
@symbolic_name == other
else
(name == other.name) && (deployment_target == other.deployment_target)
end
end
# In the context of operating system SDKs, a platform supports another
# one if they have the same name and the other platform has a minor or
# equal deployment target.
#
# @return Whether the platform supports another platform.
#
def supports?(other)
other = Platform.new(other)
if other.deployment_target && deployment_target
(other.name == name) && (other.deployment_target <= deployment_target)
else
other.name == name
end
end
# @return [String] A string representation including the deployment target.
#
def to_s
case @symbolic_name
when :ios
s = 'iOS'
when :osx
s = 'OS X'
end
s << " #{deployment_target}" if deployment_target
s
end
# @return [Symbol] A Symbol representation of the name.
#
def to_sym
name
end
# @return Whether the platform requires legacy architectures for iOS.
#
def requires_legacy_ios_archs?
(name == :ios) && deployment_target && (deployment_target < Version.new("4.3"))
end
end
end
This diff is collapsed.
This diff is collapsed.
require 'active_support/core_ext/array/conversions'
module Pod
class Specification
# A Specification::Set is resposible of handling all the specifications of
# a Pod. This class stores the information of the dependencies that reuired
# a Pod in the resolution process.
#
# @note The alpahbetical order of the sets is used to select a specification
# if multiple are available for a given version.
#
# @note The set class is not and should be not aware of the backing store
# of a Source.
#
class Set
# @return [String] The name of the Pod.
#
attr_reader :name
# @return [Array<Source>] The sources that contain the specifications for
# the available versions of a Pod.
#
attr_reader :sources
# @param [String] name The name of the Pod.
#
# @param [Array<Source>,Source] sources
# The sources that contain a Pod.
#
def initialize(name, sources)
@name = name
sources = sources.is_a?(Array) ? sources : [sources]
@sources = sources.sort_by(&:name)
@required_by = []
@dependencies = []
end
# @return [void] Stores a dependency on the Pod.
#
# @param [Dependency] dependency A dependency that requires the Pod.
#
# @param [String] dependent_name The name of the owner of the
# dependency. It is used only to display
# the Pod::Informative.
#
# @raises If the versions requirement of the dependency are not
# compatible with the previously stored dependencies.
#
def required_by(dependency, dependent_name)
unless @required_by.empty? || dependency.requirement.satisfied_by?(Gem::Version.new(required_version.to_s))
raise Informative, "#{dependent_name} tries to activate `#{dependency}', but already activated version `#{required_version}' by #{@required_by.to_sentence}."
end
@specification = nil
@required_by << dependent_name
@dependencies << dependency
end
# @return [Dependency] A dependency including all the versions
# requirements of the stored dependencies.
#
def dependency
@dependencies.inject(Dependency.new(name)) do |previous, dependency|
previous.merge(dependency.to_top_level_spec_dependency)
end
end
# @return [Specification] The specification for the given subspec name,
# from {specification}.
#
# @param [String] name The name of the specification. It can be the
# name of the top level parent or the name of a
# subspec.
#
# @see specification
#
def specification_by_name(name)
specification.top_level_parent.subspec_by_name(name)
end
# @return [Specification] The top level specification of the Pod for the
# {required_version}.
#
# @note If multiple sources have a specification for the
# {required_version} The alpahbetical order of their names is used
# to disambiguate.
#
def specification
unless @specification
sources = []
versions_by_source.each{ |source, versions| sources << source if versions.include?(required_version) }
source = sources.sort_by(&:name).first
@specification = source.specification(name, required_version)
end
@specification
end
# @return [Version] The highest version that satisfies {dependency}.
#
def required_version
versions.find { |v| dependency.match?(name, v) } ||
raise(Informative, "Required version (#{dependency}) not found for `#{name}'.\nAvailable versions: #{versions.join(', ')}")
end
# @return [Array<Version>] All the available versions for the Pod, sorted
# from highest to lowest.
#
def versions
versions_by_source.values.flatten.uniq.sort.reverse
end
# @return [Hash{Source => Version}] All the available versions for the
# Pod groupped by source.
#
def versions_by_source
result = {}
sources.each do |source|
result[source] = source.versions(name)
end
result
end
def ==(other)
self.class === other && @name == other.name && @sources.map(&:name) == other.sources.map(&:name)
end
def to_s
"#<#{self.class.name} for `#{name}' with required version `#{required_version}' available at `#{sources.map(&:name) * ', '}'>"
end
alias_method :inspect, :to_s
# The Set::External class handles Pods from external sources. Pods from
# external sources don't use the {Pod::Sources} and are intialized by a
# given specification.
#
# @note External sources *don't* support subspecs.
#
class External < Set
def initialize(specification)
@specification = specification
@required_by = []
@dependencies = []
end
def name
@specification.top_level_parent.name
end
def ==(other)
self.class === other && @specification == other.specification
end
def required_by(dependency, dependent_name)
before = @specification
super(dependency, dependent_name)
ensure
@specification = before
end
def specification_path
raise "specification_path"
end
def specification
@specification
end
def versions
[@specification.version]
end
end
end
end
end
require 'yaml'
# This is to make sure Faraday doesn't warn the user about the `system_timer` gem missing.
old_warn, $-w = $-w, nil
begin
require 'faraday'
ensure
$-w = old_warn
end
require 'octokit'
module Pod
class Specification
class Statistics
def self.instance
@instance ||= new
end
def self.instance=(instance)
@instance = instance
end
attr_accessor :cache_file, :cache_expiration
def initialize
@cache_file = Config.instance.repos_dir + 'statistics.yml'
@cache_expiration = 60 * 60 * 24 * 3
end
def creation_date(set)
compute_creation_date(set)
end
def creation_dates(sets)
dates = {}
sets.each { |set| dates[set.name] = compute_creation_date(set, false) }
save_cache
dates
end
def github_watchers(set)
github_stats_if_needed(set)
get_value(set, :gh_watchers)
end
def github_forks(set)
github_stats_if_needed(set)
get_value(set, :gh_forks)
end
def github_pushed_at(set)
github_stats_if_needed(set)
get_value(set, :pushed_at)
end
private
def cache
@cache ||= cache_file && cache_file.exist? ? YAML::load(cache_file.read) : {}
end
def get_value(set, key)
if cache[set.name] && cache[set.name][key]
cache[set.name][key]
end
end
def set_value(set, key, value)
cache[set.name] ||= {}
cache[set.name][key] = value
end
def save_cache
File.open(cache_file, 'w') { |f| f.write(YAML::dump(cache)) } if cache_file
end
def compute_creation_date(set, save = true)
date = get_value(set, :creation_date)
unless date
Dir.chdir(set.sources.first.repo) do
date = Time.at(`git log --first-parent --format=%ct #{set.name}`.split("\n").last.to_i)
end
set_value(set, :creation_date, date)
end
save_cache if save
date
end
def github_stats_if_needed(set)
return if get_value(set, :gh_date) && get_value(set, :gh_date) > Time.now - cache_expiration
spec = set.specification
url = spec.source[:git] || ''
repo_id = url[/github.com\/([^\/\.]*\/[^\/\.]*)\.*/, 1]
return unless repo_id
begin
repo = Octokit.repo(repo_id)
rescue
return
end
cache[set.name] ||= {}
set_value(set, :gh_watchers, repo['watchers'])
set_value(set, :gh_forks, repo['forks'])
set_value(set, :pushed_at, repo['pushed_at'])
set_value(set, :gh_date, Time.now)
save_cache
end
end
end
end
module Pod
class Version < Gem::Version
# @returns A Version described by its #to_s method.
#
# @TODO The `from' part of the regexp should be remove before 1.0.0.
#
def self.from_string(string)
if string =~ /HEAD (based on|from) (.*)/
v = Version.new($2)
v.head = true
v
else
Version.new(string)
end
end
attr_accessor :head
alias_method :head?, :head
def to_s
head? ? "HEAD based on #{super}" : super
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Dependency do
it "merges dependencies (taken from newer RubyGems version)" do
dep1 = Dependency.new('bananas', '>= 1.8')
dep2 = Dependency.new('bananas', '1.9')
dep1.merge(dep2).should == Dependency.new('bananas', '>= 1.8', '1.9')
end
it "returns the name of the dependency, or the name of the pod of which this is a subspec" do
dep = Dependency.new('RestKit')
dep.top_level_spec_name.should == 'RestKit'
dep = Dependency.new('RestKit/Networking')
dep.top_level_spec_name.should == 'RestKit'
end
it "returns a copy of the dependency but for the top level spec, if it's a subspec" do
dep = Dependency.new('RestKit', '>= 1.2.3')
dep.to_top_level_spec_dependency.should == Dependency.new('RestKit', '>= 1.2.3')
dep = Dependency.new('RestKit/Networking', '>= 1.2.3')
dep.to_top_level_spec_dependency.should == Dependency.new('RestKit', '>= 1.2.3')
end
it "is equal to another dependency if `external_source' is the same" do
dep1 = Dependency.new('bananas', :git => 'GIT-URL')
dep2 = Dependency.new('bananas')
dep1.should.not == dep2
dep3 = Dependency.new('bananas', :git => 'GIT-URL')
dep1.should == dep3
end
it "is equal to another dependency if `specification' is equal" do
dep1 = Dependency.new { |s| s.name = 'bananas'; s.version = '1' }
dep2 = Dependency.new('bananas')
dep1.should.not == dep2
dep2 = 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 { Dependency.new }.should.raise Informative
end
describe "defined with a block" do
before do
@dependency = 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 "with a hash of external source settings" do
before do
@dependency = Dependency.new("cocoapods", :git => "git://github.com/cocoapods/cocoapods")
end
it 'identifies itself as an external dependency' do
@dependency.should.be.external
end
end
describe "with flags" do
it "identifies itself as a `bleeding edge' dependency" do
dependency = Dependency.new("cocoapods", :head)
dependency.should.be.head
dependency.to_s.should == "cocoapods (HEAD)"
end
it "only supports the `:head' option on the last version of a pod" do
should.raise Informative do
Dependency.new("cocoapods", "1.2.3", :head)
end
end
it "raises if an invalid flag is given" do
should.raise ArgumentError do
Dependency.new("cocoapods", :foot)
end
end
end
describe Dependency::ExternalSources do
before do
@sandbox = temporary_sandbox
end
it "marks a LocalPod as downloaded if it's from GitSource" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
@sandbox.installed_pod_named('Reachability', Platform.ios).downloaded.should.be.true
end
it "creates a copy of the podspec (GitSource)" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (PodspecSource)" do
dependency = Dependency.new("Reachability", :podspec => fixture('integration/Reachability/Reachability.podspec').to_s)
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (LocalSource)" do
dependency = Dependency.new("Reachability", :local => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Lockfile" do
describe "In general" do
extend SpecHelper::TemporaryDirectory
def sample
text = <<-LOCKFILE.strip_heredoc
PODS:
- BananaLib (1.0):
- monkey (< 1.0.9, ~> 1.0.1)
- monkey (1.0.8)
DEPENDENCIES:
- BananaLib (~> 1.0)
SPEC CHECKSUMS:
BananaLib: !binary |-
MjI2Y2RkMTJkMzBhMWU4ZWM4OGM1ZmRkZWU2MDcwZDg0YTI1MGZjMQ==
COCOAPODS: #{Pod::VERSION}
LOCKFILE
end
def podfile
Pod::Podfile.new do
platform :ios
pod 'BananaLib', '~>1.0'
end
end
def specs
specs = [
Pod::Specification.from_file(fixture('banana-lib/BananaLib.podspec')),
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
specs
end
def tmp_path
temporary_directory + 'Podfile.lock'
end
it "loads from a hash" do
lockfile = Pod::Lockfile.new(YAML.load(sample))
lockfile.to_hash.should == YAML.load(sample)
end
it "loads from a file" do
File.open(tmp_path, 'w') {|f| f.write(sample) }
lockfile = Pod::Lockfile.from_file(tmp_path)
lockfile.defined_in_file.should == tmp_path
lockfile.to_hash.should == YAML.load(sample)
end
it "can be generated from a Podfile and a list of Specifications" do
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash.should == YAML.load(sample)
end
before do
@lockfile = Pod::Lockfile.generate(podfile, specs)
end
it "generates a valid YAML representation" do
YAML.load(@lockfile.to_yaml).should == YAML.load(sample)
end
it "generates a valid Dictionary representation" do
@lockfile.to_hash.should == YAML.load(sample)
end
it "returns the list of the installed pods" do
@lockfile.pods_names.should == %w| BananaLib monkey |
end
it "returns the versions of the installed pods" do
@lockfile.pods_versions.should == {
"BananaLib" => Pod::Version.new("1.0"),
"monkey" => Pod::Version.new("1.0.8")
}
end
it "serializes correctly `:head' dependencies" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', :head
end
specs = [
Pod::Specification.new do |s|
s.name = "BananaLib"
s.version = "1.0"
end,
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (HEAD)"
end
it "serializes correctly external dependencies" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BananaLib', { :git => "www.example.com", :tag => '1.0' }
end
specs = [
Pod::Specification.new do |s|
s.name = "BananaLib"
s.version = "1.0"
end,
Pod::Specification.new do |s|
s.name = "monkey"
s.version = "1.0.8"
end
]
specs.each { |s| s.activate_platform(:ios) }
lockfile = Pod::Lockfile.generate(podfile, specs)
lockfile.to_hash["DEPENDENCIES"][0].should == "BananaLib (from `www.example.com', tag `1.0')"
lockfile.to_hash["EXTERNAL SOURCES"]["BananaLib"].should == { :git => "www.example.com", :tag => '1.0' }
end
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
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.generate(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
describe "Concerning initialization from a file" do
extend SpecHelper::TemporaryDirectory
it "returns nil if it can't find the initialization file" do
lockfile = Pod::Lockfile.from_file(temporary_directory + 'Podfile.lock_not_existing')
lockfile.should == nil
end
end
describe "Concerning the identification of changes in the Podfile" do
before do
@podfile = Pod::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 = Pod::Lockfile.generate(@podfile, @specs)
end
it "detects an added Pod" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
pod 'TTTAttributedLabel'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>[],
:unchanged=>["BlocksKit", "JSONKit"],
:added=>["TTTAttributedLabel"]
}
end
it "detects an removed Pod" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>["JSONKit"],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "detects Pods whose version changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', "> 1.4"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "it doesn't mark a changed Pods whose version changed but is still compatible with the Podfile" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', "> 1.0"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>[],
:removed=>[],
:unchanged=>["BlocksKit", "JSONKit"],
:added=>[]
}
end
it "detects Pods whose external source changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :git => "example1.com"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
@lockfile = Pod::Lockfile.generate(podfile, @specs)
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :git => "example2.com"
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
it "detects Pods whose head state changed" do
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit', :head
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
@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"
s.version.head = true
end ]
@specs.each { |s| s.activate_platform(:ios) }
@lockfile = Pod::Lockfile.generate(podfile, @specs)
podfile = Pod::Podfile.new do
platform :ios
pod 'BlocksKit'
pod 'JSONKit'
end
@lockfile.detect_changes_with_podfile(podfile).should == {
:changed=>["JSONKit"],
:removed=>[],
:unchanged=>["BlocksKit"],
:added=>[]
}
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
describe Pod::Platform do
describe "by default" do
it "returns a new Platform instance" do
Pod::Platform.ios.should == Pod::Platform.new(:ios)
Pod::Platform.osx.should == Pod::Platform.new(:osx)
end
it "can be initialized from another platform" do
platform = Pod::Platform.new(:ios)
new = Pod::Platform.new(platform)
new.should == platform
end
before do
@platform = Pod::Platform.ios
end
it "exposes it's symbolic name" do
@platform.name.should == :ios
end
it "can be compared for equality with another platform with the same symbolic name" do
@platform.should == Pod::Platform.new(:ios)
end
it "can be compared for equality with another platform with the same symbolic name and the same deployment target" do
@platform.should.not == Pod::Platform.new(:ios, '4.0')
Pod::Platform.new(:ios, '4.0').should == Pod::Platform.new(:ios, '4.0')
end
it "can be compared for equality with a matching symbolic name (backwards compatibility reasons)" do
@platform.should == :ios
end
it "presents an accurate string representation" do
@platform.to_s.should == "iOS"
Pod::Platform.new(:osx).to_s.should == 'OS X'
Pod::Platform.new(:ios, '5.0.0').to_s.should == 'iOS 5.0.0'
Pod::Platform.new(:osx, '10.7').to_s.should == 'OS X 10.7'
end
it "uses it's name as it's symbold version" do
@platform.to_sym.should == :ios
end
it "allows to specify the deployment target on initialization" do
p = Pod::Platform.new(:ios, '4.0.0')
p.deployment_target.should == Pod::Version.new('4.0.0')
end
it "allows to specify the deployment target in a hash on initialization (backwards compatibility from 0.6)" do
p = Pod::Platform.new(:ios, { :deployment_target => '4.0.0' })
p.deployment_target.should == Pod::Version.new('4.0.0')
end
end
describe "regarding supporting platforms" do
it "supports platforms with the same operating system" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:ios)
p1.should.supports?(p2)
p1 = Pod::Platform.new(:osx)
p2 = Pod::Platform.new(:osx)
p1.should.supports?(p2)
end
it "supports a platform with a lower or equal deployment_target" do
p1 = Pod::Platform.new(:ios, '5.0')
p2 = Pod::Platform.new(:ios, '4.0')
p1.should.supports?(p1)
p1.should.supports?(p2)
p2.should.not.supports?(p1)
end
it "doesn't supports a platform with a different operating system" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:osx)
p1.should.not.supports?(p2)
end
end
end
This diff is collapsed.
require File.expand_path('../../spec_helper', __FILE__)
describe "Pod::Source" do
before do
@source = Pod::Source.new(fixture('spec-repos/master'))
end
it "return its name" do
@source.name.should == 'master'
end
it "returns the sets of all the available Pods" do
set_names = @source.pod_sets.map(&:name)
set_names.should.include('JSONKit')
set_names.should.include('Reachability')
end
it "returns the available versions of a Pod" do
@source.versions('Reachability').map(&:to_s).should == %w| 3.0.0 2.0.5 2.0.4 |
end
it "returns the specification of a given version of a Pod" do
spec = @source.specification('Reachability', Pod::Version.new('3.0.0'))
spec.name.should == 'Reachability'
spec.version.should.to_s == '3.0.0'
end
it "properly configures the sources of a set in seach by name" do
source = Pod::Source.new(fixture('spec-repos/test_repo'))
sets = source.search_by_name('monkey', true)
sets.count.should == 1
set = sets.first
set.name.should == 'BananaLib'
set.sources.map(&:name).should == %w| test_repo |
end
describe "Pod::Source::Aggregate" do
# BananaLib is available only in test_repo.
# JSONKit is in test repo has version 1.4 (duplicated) and the 999.999.999.
it "returns all the sources" do
Pod::Source.all.map(&:name).should == %w| master test_repo |
end
it "returns the name of all the available pods" do
pod_names = Pod::Source::Aggregate.new.all_pods
pod_names.should.include('JSONKit')
pod_names.should.include('BananaLib')
end
it "returns all the available sets with the sources configured" do
sets = Pod::Source.all_sets
banana_sets = sets.select{ |set| set.name == 'BananaLib' }
banana_sets.count.should == 1
banana_sets.first.sources.map(&:name).should == %w| test_repo |
json_set = sets.select{ |set| set.name == 'JSONKit' }
json_set.count.should == 1
json_set.first.sources.map(&:name).should == %w| master test_repo |
end
it "searches the sets by dependency" do
dep = Pod::Dependency.new('JSONKit')
set = Pod::Source.search(dep)
set.name.should == 'JSONKit'
set.sources.map(&:name).should == %w| master test_repo |
end
it "searches the sets specifing a dependency on a subspec" do
dep = Pod::Dependency.new('RestKit/JSON')
set = Pod::Source.search(dep)
set.name.should == 'RestKit'
set.sources.map(&:name).should == %w| master |
end
it "raises if a specification set can't be found" do
lambda {
dep = Pod::Dependency.new('DoesNotExist')
set = Pod::Source.search(dep)
}.should.raise Pod::Informative
end
it "raises if a subspec can't be found" do
lambda {
dep = Pod::Dependency.new('RestKit/DoesNotExist')
set = Pod::Source.search(dep)
}.should.raise Pod::Informative
end
it "searches the sets by name" do
sets = Pod::Source.search_by_name('JSONKit')
sets.count.should == 1
set = sets.first
set.name.should == 'JSONKit'
set.sources.map(&:name).should == %w| master test_repo |
end
it "properly configures the sources of a set in search by name" do
sets = Pod::Source.search_by_name('BananaLib')
sets.count.should == 1
set = sets.first
set.name.should == 'BananaLib'
set.sources.map(&:name).should == %w| test_repo |
end
end
end
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Specification::Set" do
describe "In general" do
before do
@source = Pod::Source.new(fixture('spec-repos/master'))
@set = Pod::Spec::Set.new('CocoaLumberjack', @source)
end
it "returns the name of the pod" do
@set.name.should == 'CocoaLumberjack'
end
it "returns the versions available for this pod ordered from highest to lowest" do
@set.versions.should == %w[1.6 1.3.3 1.3.2 1.3.1 1.3 1.2.3 1.2.2 1.2.1 1.2 1.1 1.0].map { |v| Pod::Version.new(v) }
end
it "checks if the dependency of the specification is compatible with existing requirements" do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '1.2'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.2.1'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '> 1.1'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '~> 1.2.0'), 'Spec')
@set.required_by(Pod::Dependency.new('CocoaLumberjack'), 'Spec')
lambda {
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.0' ), 'Spec')
}.should.raise Pod::Informative
end
it "raises if the required version doesn't exist" do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.0'), 'Spec')
lambda { @set.required_version }.should.raise Pod::Informative
end
it "can test if it is equal to another set" do
@set.should == Pod::Spec::Set.new('CocoaLumberjack', @source)
@set.should.not == Pod::Spec::Set.new('RestKit', @source)
end
before do
@set.required_by(Pod::Dependency.new('CocoaLumberjack', '< 1.2.1'), 'Spec')
end
it "returns the version required for the dependency" do
@set.required_version.should == Pod::Version.new('1.2')
end
it "returns the specification for the required version" do
@set.specification.should == Pod::Spec.new { |s| s.name = 'CocoaLumberjack'; s.version = '1.2' }
end
it "ignores dotfiles when getting the version directories" do
`touch #{fixture('spec-repos/master/CocoaLumberjack/.DS_Store')}`
lambda { @set.versions }.should.not.raise
end
it "raises if a version is incompatible with the activated version" do
spec = Pod::Dependency.new('CocoaLumberjack', '1.2.1')
lambda { @set.required_by(spec, 'Spec') }.should.raise Pod::Informative
end
end
describe "Concerning multiple sources" do
before do
# JSONKit is in test repo has version 1.4 (duplicated) and the 999.999.999.
@set = Pod::Source.search_by_name('JSONKit').first
end
it "returns all the available versions sorted from biggest to lowest" do
@set.versions.map(&:to_s).should == %w| 999.999.999 1.5pre 1.4 |
end
it "returns all the available versions by source sorted from bigest to lowest" do
hash = {}
@set.versions_by_source.each { |source, versions| hash[source.name] = versions.map(&:to_s) }
hash['master'].should == %w| 1.5pre 1.4 |
hash['test_repo'].should == %w| 999.999.999 1.4 |
hash.keys.sort.should == %w| master test_repo |
end
it "returns the specification from the `master` source for the required version" do
dep = Pod::Dependency.new('JSONKit', '1.5pre')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '1.5pre'
spec.defined_in_file.should == fixture('spec-repos/master/JSONKit/1.5pre/JSONKit.podspec')
end
it "returns the specification from `test_repo` source for the required version" do
dep = Pod::Dependency.new('JSONKit', '999.999.999')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '999.999.999'
spec.defined_in_file.should == fixture('spec-repos/test_repo/JSONKit/999.999.999/JSONKit.podspec')
end
it "prefers sources by alphabetical order" do
dep = Pod::Dependency.new('JSONKit', '1.4')
@set.required_by(dep, 'Spec')
spec = @set.specification
spec.name.should == 'JSONKit'
spec.version.to_s.should == '1.4'
spec.defined_in_file.should == fixture('spec-repos/master/JSONKit/1.4/JSONKit.podspec')
end
end
end
This diff is collapsed.
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Version do
it "returns wether or not it's a `bleeding edge' version" do
version = Version.new('1.2.3')
version.should.not.be.head
version.head = true
version.should.be.head
end
it "serializes to and from a string" do
version = Version.from_string('1.2.3')
version.to_s.should == '1.2.3'
version.should.not.be.head
version = Version.from_string('HEAD based on 1.2.3')
version.should.be.head
version.to_s.should == 'HEAD based on 1.2.3'
end
it "supports the previous way that a HEAD version was described" do
version = Version.from_string('HEAD from 1.2.3')
version.should.be.head
version.to_s.should == 'HEAD based on 1.2.3'
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