Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
cocoapods
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gengmeiios
cocoapods
Commits
9cbb2dfd
Commit
9cbb2dfd
authored
Aug 13, 2012
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Install/Update] second iteration.
parent
edea0a11
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
637 additions
and
373 deletions
+637
-373
outdated.rb
lib/cocoapods/command/outdated.rb
+5
-5
dependency.rb
lib/cocoapods/dependency.rb
+8
-3
git.rb
lib/cocoapods/downloader/git.rb
+1
-0
installer.rb
lib/cocoapods/installer.rb
+26
-14
lockfile.rb
lib/cocoapods/lockfile.rb
+155
-44
resolver.rb
lib/cocoapods/resolver.rb
+95
-140
integration_spec.rb
spec/integration_spec.rb
+26
-36
lockfile_spec.rb
spec/unit/lockfile_spec.rb
+305
-122
resolver_spec.rb
spec/unit/resolver_spec.rb
+16
-9
No files found.
lib/cocoapods/command/outdated.rb
View file @
9cbb2dfd
...
...
@@ -36,16 +36,16 @@ module Pod
sandbox
=
Sandbox
.
new
(
config
.
project_pods_root
)
resolver
=
Resolver
.
new
(
podfile
,
lockfile
,
sandbox
)
resolver
.
update_mode
=
true
resolver
.
update
d
_external_specs
=
false
resolver
.
update_external_specs
=
false
resolver
.
resolve
specs_to_install
=
resolver
.
spec
s_to_install
external_pods
=
resolver
.
external_pod
s
pods_to_install
=
resolver
.
pod
s_to_install
external_pods
=
resolver
.
pods_from_external_source
s
known_update_specs
=
[]
head_mode_specs
=
[]
resolver
.
specs
.
each
do
|
s
|
next
if
external_pods
.
include?
(
s
.
name
)
next
unless
spec
s_to_install
.
include?
(
s
.
name
)
next
unless
pod
s_to_install
.
include?
(
s
.
name
)
if
s
.
version
.
head?
head_mode_specs
<<
s
.
name
...
...
@@ -54,7 +54,7 @@ module Pod
end
end
if
spec
s_to_install
.
empty?
if
pod
s_to_install
.
empty?
puts
"
\n
No updates are available.
\n
"
.
yellow
else
...
...
lib/cocoapods/dependency.rb
View file @
9cbb2dfd
...
...
@@ -101,6 +101,10 @@ module Pod
@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
)
...
...
@@ -139,6 +143,7 @@ module Pod
module
ExternalSources
def
self
.
from_params
(
name
,
params
)
return
unless
name
&&
params
if
params
.
key?
(
:git
)
GitSource
.
new
(
name
,
params
)
elsif
params
.
key?
(
:podspec
)
...
...
@@ -172,9 +177,9 @@ module Pod
specification_from_local
(
sandbox
,
platform
)
end
def
==
(
other
_source
)
return
if
other
_source
.
nil?
name
==
other
_source
.
name
&&
params
==
other_source
.
params
def
==
(
other
)
return
if
other
.
nil?
name
==
other
.
name
&&
params
==
other
.
params
end
end
...
...
lib/cocoapods/downloader/git.rb
View file @
9cbb2dfd
...
...
@@ -79,6 +79,7 @@ module Pod
git!
"reset --hard HEAD"
git!
"clean -d -x -f"
git!
"pull origin master"
git!
"fetch --tags"
end
end
...
...
lib/cocoapods/installer.rb
View file @
9cbb2dfd
...
...
@@ -58,18 +58,16 @@ module Pod
end
if
should_install
pod
.
implode
download_pod
(
pod
)
# This will not happen if the pod existed before we started the install
# process.
if
pod
.
downloaded?
# The docs need to be generated before cleaning because the
# documentation is created for all the subspecs.
generate_docs
(
pod
)
# Here we clean pod's that just have been downloaded or have been
# pre-downloaded in AbstractExternalSource#specification_from_sandbox.
pod
.
clean!
if
config
.
clean?
unless
pod
.
downloaded?
pod
.
implode
download_pod
(
pod
)
end
# The docs need to be generated before cleaning because the
# documentation is created for all the subspecs.
generate_docs
(
pod
)
# Here we clean pod's that just have been downloaded or have been
# pre-downloaded in AbstractExternalSource#specification_from_sandbox.
pod
.
clean!
if
config
.
clean?
end
end
end
...
...
@@ -100,12 +98,26 @@ module Pod
end
end
# @TODO: use the local pod implode
#
def
remove_deleted_dependencies!
resolver
.
removed_pods
.
each
do
|
pod_name
|
marker
=
config
.
verbose
?
"
\n
-> "
.
red
:
''
path
=
sandbox
.
root
+
pod_name
puts
marker
<<
"Removing
#{
pod_name
}
"
.
red
path
.
rmtree
if
path
.
exist?
end
end
def
install!
@sandbox
.
prepare_for_install
print_title
"Resolving dependencies of:
#{
@podfile
.
defined_in_file
}
"
specs_by_target
print_title
"Removing deleted dependencies"
unless
resolver
.
removed_pods
.
empty?
remove_deleted_dependencies!
print_title
"Installing dependencies"
install_dependencies!
...
...
@@ -123,12 +135,12 @@ module Pod
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
run_post_install_hooks
puts
"- Writing Xcode project file to `
#{
@sandbox
.
project_path
}
'
\n\n
"
if
config
.
verbose?
puts
"- Writing Xcode project file to `
#{
@sandbox
.
project_path
}
'"
if
config
.
verbose?
project
.
save_as
(
@sandbox
.
project_path
)
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
@lockfile
=
Lockfile
.
generate
(
@podfile
,
specs_by_target
.
values
.
flatten
)
@lockfile
.
write_to_disk
(
config
.
project_lockfile
)
UserProjectIntegrator
.
new
(
@podfile
).
integrate!
if
config
.
integrate_targets?
end
...
...
lib/cocoapods/lockfile.rb
View file @
9cbb2dfd
module
Pod
class
Lockfile
# @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}
# @return [Lockfile] Returns the Lockfile saved in path.
# Returns {nil} If the file can't be loaded.
#
def
self
.
from_file
(
path
)
lockfile
=
Lockfile
.
new
(
path
)
lockfile
.
hash_reppresentation
?
lockfile
:
nil
return
nil
unless
path
.
exist?
hash
=
YAML
.
load
(
File
.
open
(
path
))
lockfile
=
Lockfile
.
new
(
hash
)
lockfile
.
defined_in_file
=
path
lockfile
end
# @return [Lockfile] Creates a new Lockfile ready to be saved in path.
# @return [Lockfile] Generates a lockfile from a {Podfile} and the
# list of {Specifications} that were installed.
#
def
self
.
create
(
path
,
podfile
,
specs
)
Lockfile
.
new
(
path
,
podfile
,
specs
)
def
self
.
generate
(
podfile
,
specs
)
Lockfile
.
new
(
generate_hash_from_podfile
(
podfile
,
specs
)
)
end
attr_reader
:defined_in_file
,
:podfile
,
:specs
,
:hash_reppresentation
# @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 [Pathname] the path of the Lockfile.
# If no other value is provided the Lockfile is read from this path.
# @param [Podfile] the Podfile to use for generating the Lockfile.
# @param [specs] the specs installed.
#
def
initialize
(
path
,
podfile
=
nil
,
specs
=
nil
)
@defined_in_file
=
path
if
podfile
&&
specs
@podfile
=
podfile
@specs
=
specs
else
yaml
=
YAML
.
load
(
File
.
open
(
path
))
if
yaml
&&
Version
.
new
(
yaml
[
"COCOAPODS"
])
>=
Version
.
new
(
"0.10"
)
@hash_reppresentation
=
yaml
end
def
initialize
(
hash
)
if
Version
.
new
(
hash
[
"COCOAPODS"
])
<=
Version
.
new
(
"0.11"
)
# Convert old format to be compatible
# - Pods:
# - libPusher (1.0) [HEAD] -> libPusher (HEAD from 1.0)
# - Dependencies:
# - libPusher [HEAD] -> libPusher (HEAD)
end
@to_hash
=
hash
end
# @return [Array<String, Hash{String => Array[String]}>] The pods installed
# and their dependencies.
#
def
pods
return
[]
unless
to_hash
to_hash
[
'PODS'
]
||
[]
@pods
||=
to_hash
[
'PODS'
]
||
[]
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
#
def
dependencies
return
[]
unless
to_hash
to_hash
[
'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
return
[]
unless
to_hash
to_hash
[
"EXTERNAL SOURCES"
]
||
[]
@external_sources
||=
to_hash
[
"EXTERNAL SOURCES"
]
||
{}
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
# @return [Array<String>] The names of the installed Pods.
#
def
podfile_dependencies
dependencies
.
map
{
|
dep
|
dependency_from_string
(
dep
)
}
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 [Array<Dependency>] The dependencies that require the installed
# pods with their exact version.
# @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
# @param [String] The string that describes a {Specification} generated
# from {Specification#to_s}.
#
# @example Strings examples
# "libPusher"
# "libPusher (1.0)"
# "libPusher (HEAD from 1.0)"
# "RestKit/JSON"
#
def
dependencies_for_pods
pods
.
map
{
|
pod
|
dependency_from_string
(
pod
.
is_a?
(
String
)
?
pod
:
pod
.
keys
[
0
])
}
# @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_s
(
match_data
[
2
])
return
[
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
)
...
...
@@ -79,8 +136,8 @@ module Pod
# @TODO: store the whole spec?, the version?
Dependency
.
new
(
name
)
when
/from `(.*)'/
external_source_info
=
external_sources
.
find
{
|
hash
|
hash
.
keys
[
0
]
==
name
}
||
{}
Dependency
.
new
(
name
,
external_source_info
[
name
]
)
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.
...
...
@@ -90,10 +147,60 @@ module Pod
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
File
.
open
(
defined_in_file
,
'w'
)
{
|
f
|
f
.
write
(
to_yaml
)
}
def
write_to_disk
(
path
)
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
...
...
@@ -112,9 +219,7 @@ module Pod
# @return [Dictionary] The Dictionary representation of the Lockfile.
#
def
to_hash
return
@hash_reppresentation
if
@hash_reppresentation
return
nil
unless
@podfile
&&
@specs
def
self
.
generate_hash_from_podfile
(
podfile
,
specs
)
hash
=
{}
# Get list of [name, dependencies] pairs.
...
...
@@ -122,7 +227,7 @@ module Pod
[
spec
.
to_s
,
spec
.
dependencies
.
map
(
&
:to_s
).
sort
]
end
.
uniq
# Merge dependencies of i
os and osx
version of the same pod.
# Merge dependencies of i
OS and OS X
version of the same pod.
tmp
=
{}
pod_and_deps
.
each
do
|
name
,
deps
|
if
tmp
[
name
]
...
...
@@ -136,12 +241,18 @@ module Pod
end
hash
[
"PODS"
]
=
pod_and_deps
hash
[
"DEPENDENCIES"
]
=
podfile
.
dependencies
.
map
{
|
d
|
"
#{
d
}
"
}.
sort
hash
[
"DEPENDENCIES"
]
=
podfile
.
dependencies
.
map
{
|
d
|
d
.
to_s
}.
sort
external_sources
=
podfile
.
dependencies
.
select
(
&
:external?
).
sort
{
|
d
,
other
|
d
.
name
<=>
other
.
name
}.
map
{
|
d
|
{
d
.
name
=>
d
.
external_source
.
params
}
}
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?
# hash["SPECS_CHECKSUM"]
checksums
=
{}
specs
.
select
{
|
spec
|
!
spec
.
defined_in_file
.
nil?
}.
each
do
|
spec
|
checksums
[
spec
.
name
]
=
Digest
::
SHA1
.
hexdigest
(
File
.
read
(
spec
.
defined_in_file
)).
to_s
end
hash
[
"SPECS CHECKSUM"
]
=
checksums
unless
checksums
.
empty?
hash
[
"COCOAPODS"
]
=
VERSION
hash
end
...
...
lib/cocoapods/resolver.rb
View file @
9cbb2dfd
...
...
@@ -4,6 +4,16 @@ module Pod
class
Resolver
include
Config
::
Mixin
# @return [Bool] Whether the resolver should find the pods to install or
# the pods to update.
#
attr_accessor
:update_mode
# @return [Bool] Whether the resolver should update the external specs
# in the resolution process.
#
attr_accessor
:update_external_specs
# @return [Podfile] The Podfile used by the resolver.
#
attr_reader
:podfile
...
...
@@ -17,142 +27,127 @@ module Pod
#
attr_reader
:sandbox
# @return [Bool] Whether the resolver should find the pods to install or
# the pods to update.
#
attr_accessor
:update_mode
# @return [Bool] Whether the resolver should update the external specs
# in the resolution process.
#
attr_accessor
:updated_external_specs
# @return [Array<Strings>] The name of the pods coming from an
# external sources
#
attr_reader
:
external_pod
s
attr_reader
:
pods_from_external_source
s
# @return [Array<Set>] The set used to resolve the dependencies.
#
attr_
accesso
r
:cached_sets
attr_
reade
r
:cached_sets
# @return [Source::Aggregate] A cache of the sources needed to find the
# podspecs.
#
attr_accessor
:cached_sources
attr_reader
:cached_sources
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
# Returns the resolved specifications grouped by target.
#
attr_reader
:specs_by_target
def
initialize
(
podfile
,
lockfile
,
sandbox
)
@podfile
=
podfile
@lockfile
=
lockfile
@sandbox
=
sandbox
@update_external_specs
=
true
@cached_sets
=
{}
@cached_sources
=
Source
::
Aggregate
.
new
@cached_specs
=
{}
@specs_by_target
=
{}
@pods_from_external_sources
=
[]
@dependencies_podfile_incompatible
=
[]
@log_indent
=
0
;
@updated_external_specs
=
true
end
# Identifies the specifications that should be installed according whether
# the resolver is in update mode or not.
#
# @return [
void]
# @return [
Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
#
def
resolve
if
config
.
verbose?
unless
podfile_dependencies
.
empty?
puts
"
\n
Already installed Podfile dependencies detected (Podfile.lock):"
.
green
podfile_dependencies
.
each
{
|
dependency
|
puts
" -
#{
dependency
}
"
}
end
unless
dependencies_for_pods
.
empty?
puts
"
\n
Installed Pods detected (Podfile.lock):"
.
green
dependencies_for_pods
.
each
{
|
dependency
|
puts
" -
#{
dependency
}
"
}
if
@lockfile
puts
"
\n
Finding added, modified or removed dependencies:"
.
green
if
config
.
verbose?
@pods_by_state
=
@lockfile
.
detect_changes_with_podfile
(
podfile
)
if
config
.
verbose?
@pods_by_state
.
each
do
|
symbol
,
pod_names
|
case
symbol
when
:added
mark
=
"A"
.
green
when
:changed
mark
=
"M"
.
yellow
when
:removed
mark
=
"R"
.
red
when
:unchanged
mark
=
"-"
end
pod_names
.
each
do
|
pod_name
|
puts
"
#{
mark
}
"
<<
pod_name
end
end
end
pods_not_to_lock
=
@pods_by_state
[
:added
]
+
@pods_by_state
[
:changed
]
+
@pods_by_state
[
:removed
]
lock_versions
(
lockfile
.
pods_names
-
pods_not_to_lock
)
unless
update_mode
end
@cached_specs
=
{}
@targets_and_specs
=
{}
@external_pods
=
[]
@dependencies_podfile_incompatible
=
[]
@removed_pods
=
[]
lock_dependencies_version
unless
update_mode
@podfile
.
target_definitions
.
values
.
each
do
|
target_definition
|
puts
"
\n
Resolving dependencies for target `
#{
target_definition
.
name
}
' (
#{
target_definition
.
platform
}
):"
.
green
if
config
.
verbose?
@loaded_specs
=
[]
find_dependency_specs
(
@podfile
,
target_definition
.
dependencies
,
target_definition
)
@
targets_and_specs
[
target_definition
]
=
@cached_specs
.
values_at
(
*
@loaded_specs
).
sort_by
(
&
:name
)
@
specs_by_target
[
target_definition
]
=
@cached_specs
.
values_at
(
*
@loaded_specs
).
sort_by
(
&
:name
)
end
@cached_specs
.
values
.
sort_by
(
&
:name
)
@targets_and_specs
@specs_by_target
end
# @return [Array<Specification>] The specifications loaded by the resolver.
#
def
specs
@cached_specs
.
values
.
uniq
end
# @return [Bool] Whether a pod should be installed/reinstalled.
#
def
should_install?
(
name
)
specs_to_install
.
include?
(
name
)
pods_to_install
.
include?
name
end
# @return [Array<String
>] The list of the names of the pods that need
#
to be
installed.
# @return [Array<String
s>] The name of the pods that should be
#
installed/re
installed.
#
# - Install mode: a specification will be installed only if its
# dependency in Podfile changed since the last installation.
# New Pods will always be installed and Pods already installed will be
# reinstalled only if they are not compatible anymore with the Podfile.
# - Update mode: a Pod will be installed only if there is a new
# version and it was already installed. In no case new Pods will be
# installed.
#
def
specs_to_install
@specs_to_install
||=
begin
specs
=
@targets_and_specs
.
values
.
flatten
to_install
=
[]
specs
.
each
do
|
spec
|
def
pods_to_install
unless
@pods_to_install
if
lockfile
@pods_to_install
=
specs
.
select
{
|
spec
|
spec
.
version
!=
lockfile
.
pods_versions
[
spec
.
pod_name
]
}.
map
(
&
:name
)
if
update_mode
# Installation mode
installed_dependency
=
dependencies_for_pods
.
find
{
|
d
|
d
.
name
==
spec
.
name
}
outdated
=
installed_dependency
&&
!
installed_dependency
.
matches_spec?
(
spec
)
head
=
spec
.
version
.
head?
if
outdated
||
head
||
@external_pods
.
include?
(
spec
.
pod_name
)
to_install
<<
spec
end
else
# Installation mode
spec_incompatible_with_podfile
=
@dependencies_podfile_incompatible
.
any?
{
|
d
|
d
.
name
==
spec
.
name
}
spec_installed
=
dependencies_for_pods
.
any?
{
|
d
|
d
.
name
==
spec
.
name
}
if
!
spec_installed
||
spec_incompatible_with_podfile
to_install
<<
spec
unless
@external_pods
.
include?
(
spec
.
pod_name
)
end
@pods_to_install
+=
specs
.
select
{
|
spec
|
spec
.
version
.
head?
||
pods_from_external_sources
.
include?
(
spec
.
pod_name
)
}.
map
(
&
:name
)
end
@pods_to_install
+=
@pods_by_state
[
:added
]
+
@pods_by_state
[
:changed
]
else
@pods_to_install
=
specs
.
map
(
&
:name
)
end
to_install
.
map
{
|
s
|
s
.
top_level_parent
.
name
}.
uniq
end
end
# @return [Array<Specification>] The specifications loaded by the resolver.
#
def
specs
@cached_specs
.
values
.
uniq
end
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
# Returns the resolved specifications grouped by target.
#
def
specs_by_target
@targets_and_specs
@pods_to_install
end
# @return [Array<Strings>] The name of the pods that were installed
# but don't have any dependency anymore.
# but don't have any dependency anymore. It returns the name
# of the Pod stripped from subspecs.
#
def
removed_pods
if
update_mode
[]
# It should never remove any pod in update mode
else
[]
# @TODO: Implement
return
[]
unless
lockfile
unless
@removed_pods
previusly_installed
=
lockfile
.
pods_names
.
map
{
|
pod_name
|
pod_name
.
split
(
'/'
).
first
}
installed
=
specs
.
map
{
|
spec
|
spec
.
name
.
split
(
'/'
).
first
}
@removed_pods
=
previusly_installed
-
installed
end
@removed_pods
end
private
...
...
@@ -162,53 +157,18 @@ module Pod
#
# @return [void]
#
def
lock_
dependencies_version
def
lock_
versions
(
pods
)
return
unless
lockfile
puts
"
\n
Finding updated or removed pods:"
.
green
if
config
.
verbose?
podfile_deps_names
=
podfile_dependencies
.
map
(
&
:name
)
dependencies_for_pods
.
each
do
|
dependency
|
# Skip the dependency if it was not requested in the Podfile in the
# previous installation.
next
unless
podfile_deps_names
.
include?
(
dependency
.
name
)
podfile_dependency
=
podfile
.
dependencies
.
find
{
|
d
|
d
.
name
==
dependency
.
name
}
# Don't lock the dependency if it can't be found in the Podfile as it
# it means that it was removed.
unless
podfile_dependency
puts
" R "
.
red
<<
dependency
.
to_s
if
config
.
verbose?
@removed_pods
<<
dependency
.
name
#TODO: use the pod name?
next
end
# Check if the dependency necessary to load the pod is still compatible with
# the podfile.
# @TODO: pattern match might not be the most appropriate method.
if
podfile_dependency
=~
dependency
puts
" - "
<<
dependency
.
to_s
if
config
.
verbose?
set
=
find_cached_set
(
dependency
,
nil
)
set
.
required_by
(
dependency
,
lockfile
.
to_s
)
else
puts
" U "
.
yellow
<<
"
#{
dependency
}
->
#{
podfile_dependency
}
"
if
config
.
verbose?
@dependencies_podfile_incompatible
<<
dependency
end
# Add a specific Dependency to lock the version in the resolution process
pods
.
each
do
|
pod_name
|
version
=
lockfile
.
pods_versions
[
pod_name
]
raise
Informative
,
"Attempt to lock a Pod without an known version."
unless
version
dependency
=
Dependency
.
new
(
pod_name
,
version
)
set
=
find_cached_set
(
dependency
,
nil
)
set
.
required_by
(
dependency
,
lockfile
.
to_s
)
end
end
# @return [Array<Dependency>] Cached copy of the dependencies that require
# the installed pods with their exact version.
#
def
dependencies_for_pods
@dependencies_for_pods
||=
lockfile
?
lockfile
.
dependencies_for_pods
:
[]
end
# @return [Array<Dependency>] Cached copy of the Podfile dependencies used
# during the last install.
#
def
podfile_dependencies
@podfile_dependencies
||=
lockfile
?
lockfile
.
podfile_dependencies
:
[]
end
# @return [Set] The cached set for a given dependency.
#
def
find_cached_set
(
dependency
,
platform
)
...
...
@@ -217,12 +177,11 @@ module Pod
if
dependency
.
specification
Specification
::
Set
::
External
.
new
(
dependency
.
specification
)
elsif
external_source
=
dependency
.
external_source
# The platform isn't actually being used by the LocalPod instance
# that's being used behind the scenes, but passing it anyways for
# completeness sake.
if
update_mode
&&
updated_external_specs
if
update_mode
&&
update_external_specs
# Always update external sources in update mode.
specification
=
external_source
.
specification_from_external
(
@sandbox
,
platform
)
else
# Don't update external sources in install mode if not needed.
specification
=
external_source
.
specification_from_sandbox
(
@sandbox
,
platform
)
end
set
=
Specification
::
Set
::
External
.
new
(
specification
)
...
...
@@ -238,6 +197,10 @@ module Pod
# Resolves the dependencies of a specification and stores them in @cached_specs
#
# @param [Specification] dependent_specification
# @param [Array<Dependency>] dependencies
# @param [TargetDefinition] target_definition
#
# @return [void]
#
def
find_dependency_specs
(
dependent_specification
,
dependencies
,
target_definition
)
...
...
@@ -247,18 +210,10 @@ module Pod
set
=
find_cached_set
(
dependency
,
target_definition
.
platform
)
set
.
required_by
(
dependency
,
dependent_specification
.
to_s
)
# Ensure that we don't load new pods in update mode
# @TODO: filter the dependencies of the target before calling #find_dependency_specs
if
update_mode
mode_wants_spec
=
dependencies_for_pods
.
any?
{
|
d
|
d
.
name
==
dependency
.
name
}
else
mode_wants_spec
=
true
end
# Ensure we don't resolve the same spec twice for one target
if
mode_wants_spec
&&
!
@loaded_specs
.
include?
(
dependency
.
name
)
unless
@loaded_specs
.
include?
(
dependency
.
name
)
spec
=
set
.
specification_by_name
(
dependency
.
name
)
@
external_pod
s
<<
spec
.
pod_name
if
dependency
.
external?
@
pods_from_external_source
s
<<
spec
.
pod_name
if
dependency
.
external?
@loaded_specs
<<
spec
.
name
@cached_specs
[
spec
.
name
]
=
spec
# Configure the specification
...
...
spec/integration_spec.rb
View file @
9cbb2dfd
...
...
@@ -73,14 +73,10 @@ else
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
installer
=
Pod
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
lockfile
.
to_hash
.
should
==
{
'PODS'
=>
[
'SSToolkit (0.1.3)'
],
'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
}
result
=
installer
.
lockfile
.
to_hash
result
[
'PODS'
].
should
==
[
'SSToolkit (0.1.3)'
]
result
[
'DEPENDENCIES'
].
should
==
[
"SSToolkit (from `
#{
url
}
', commit `
#{
commit
}
')"
]
result
[
'EXTERNAL SOURCES'
].
should
==
{
"SSToolkit"
=>
{
:git
=>
url
,
:commit
=>
commit
}}
end
it
"installs a library with a podspec outside of the repo"
do
...
...
@@ -92,18 +88,13 @@ else
pod
'Reachability'
,
:podspec
=>
url
end
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
lockfile
.
to_hash
.
should
==
{
'PODS'
=>
[
'Reachability (1.2.3)'
],
'DEPENDENCIES'
=>
[
"Reachability (from `
#{
url
}
')"
],
"EXTERNAL SOURCES"
=>
[{
"Reachability"
=>
{
:podspec
=>
"https://raw.github.com/gist/1349824/3ec6aa60c19113573fc48eac19d0fafd6a69e033/Reachability.podspec"
}}],
'COCOAPODS'
=>
Pod
::
VERSION
}
result
=
installer
.
lockfile
.
to_hash
result
[
'PODS'
].
should
==
[
'Reachability (1.2.3)'
]
result
[
'DEPENDENCIES'
].
should
==
[
"Reachability (from `
#{
url
}
')"
]
result
[
'EXTERNAL SOURCES'
].
should
==
{
"Reachability"
=>
{
:podspec
=>
"https://raw.github.com/gist/1349824/3ec6aa60c19113573fc48eac19d0fafd6a69e033/Reachability.podspec"
}}
end
it
"installs a dummy source file"
do
...
...
@@ -203,19 +194,19 @@ else
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
result
=
installer
.
lockfile
.
to_hash
result
[
'PODS'
].
should
==
[
{
"ASIHTTPRequest (1.8.1)"
=>
[
"ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)"
,
"ASIHTTPRequest/CloudFiles (= 1.8.1)"
,
"ASIHTTPRequest/S3 (= 1.8.1)"
,
"Reachability"
]},
{
"ASIHTTPRequest/ASIWebPageRequest (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/CloudFiles (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/S3 (1.8.1)"
=>
[
"Reachability"
]
},
"JSONKit (1.4)"
,
"Reachability (3.0.0)"
]
result
[
'DEPENDENCIES'
].
should
==
[
"ASIHTTPRequest"
,
"JSONKit (= 1.4)"
]
# TODO might be nicer looking to not show the dependencies of the top level spec for each subspec (Reachability).
installer
.
lockfile
.
to_hash
.
should
==
{
"PODS"
=>
[{
"ASIHTTPRequest (1.8.1)"
=>
[
"ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)"
,
"ASIHTTPRequest/CloudFiles (= 1.8.1)"
,
"ASIHTTPRequest/S3 (= 1.8.1)"
,
"Reachability"
]},
{
"ASIHTTPRequest/ASIWebPageRequest (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/CloudFiles (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/S3 (1.8.1)"
=>
[
"Reachability"
]
},
"JSONKit (1.4)"
,
"Reachability (3.0.0)"
],
"DEPENDENCIES"
=>
[
"ASIHTTPRequest"
,
"JSONKit (= 1.4)"
],
"COCOAPODS"
=>
Pod
::
VERSION
}
should_xcodebuild
(
podfile
.
target_definitions
[
:ios_target
])
should_xcodebuild
(
podfile
.
target_definitions
[
:osx_target
])
...
...
@@ -313,7 +304,9 @@ else
lockfile_contents
[
'PODS'
].
delete_at
(
1
)
# lockfile_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
end
installer
.
lockfile
.
to_hash
.
should
==
lockfile_contents
result
=
installer
.
lockfile
.
to_hash
result
.
delete
(
"SPECS CHECKSUM"
)
result
.
should
==
lockfile_contents
root
=
config
.
project_pods_root
(
root
+
'Pods.xcconfig'
).
read
.
should
==
installer
.
target_installers
.
first
.
xcconfig
.
to_s
...
...
@@ -335,12 +328,9 @@ else
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
lockfile
.
to_hash
.
tap
{
|
d
|
d
.
delete
(
"COCOAPODS"
)
}.
should
==
{
# 'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }],
'PODS'
=>
[
'Reachability (2.0.4)'
],
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
'DEPENDENCIES'
=>
[
"Reachability (= 2.0.4)"
]
}
result
=
installer
.
lockfile
.
to_hash
result
[
'PODS'
].
should
==
[
'Reachability (2.0.4)'
]
result
[
'DEPENDENCIES'
].
should
==
[
"Reachability (= 2.0.4)"
]
end
end
...
...
spec/unit/lockfile_spec.rb
View file @
9cbb2dfd
require
File
.
expand_path
(
'../../spec_helper'
,
__FILE__
)
describe
"Pod::Lockfile"
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)
COCOAPODS:
#{
Pod
::
VERSION
}
LOCKFILE
end
def
podfile
Pod
::
Podfile
.
new
do
platform
:ios
pod
'BananaLib'
,
'~>1.0'
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)
SPECS CHECKSUM:
BananaLib: !binary |-
MjI2Y2RkMTJkMzBhMWU4ZWM4OGM1ZmRkZWU2MDcwZDg0YTI1MGZjMQ==
COCOAPODS: 0.11.1
LOCKFILE
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"
def
podfile
Pod
::
Podfile
.
new
do
platform
:ios
pod
'BananaLib'
,
'~>1.0'
end
]
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
specs
end
end
def
tmp_path
temporary_directory
+
'Podfile.lock'
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
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
def
tmp_path
temporary_directory
+
'Podfile.lock'
end
before
do
@lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
end
it
"loads from a hash"
do
lockfile
=
Pod
::
Lockfile
.
new
(
YAML
.
load
(
sample
))
lockfile
.
to_hash
.
should
==
YAML
.
load
(
sample
)
end
it
"generates a valid YAML representation"
do
YAML
.
load
(
@lockfile
.
to_yaml
).
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
"generates a valid Dictionary representation"
do
@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
it
"returns the Podfile dependencies"
do
@lockfile
.
podfile_dependencies
.
should
==
[
Pod
::
Dependency
.
new
(
"BananaLib"
,
"~> 1.0"
)
]
end
before
do
@lockfile
=
Pod
::
Lockfile
.
generate
(
podfile
,
specs
)
end
it
"returns the dependencies for the installed pods"
do
@lockfile
.
dependencies_for_pods
.
should
==
[
Pod
::
Dependency
.
new
(
"BananaLib"
,
"= 1.0"
),
Pod
::
Dependency
.
new
(
"monkey"
,
"= 1.0.8"
)
]
end
it
"generates a valid YAML representation"
do
YAML
.
load
(
@lockfile
.
to_yaml
).
should
==
YAML
.
load
(
sample
)
end
it
"can check if it is compatible with a file"
do
File
.
open
(
tmp_path
,
'w'
)
{
|
f
|
f
.
write
(
sample
.
gsub
(
"COCOAPODS:
#{
Pod
::
VERSION
}
"
,
""
))
}
lockfile
=
Pod
::
Lockfile
.
from_file
(
tmp_path
)
lockfile
.
should
==
nil
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"
it
"serializes correctly `:head' dependencies"
do
podfile
=
Pod
::
Podfile
.
new
do
platform
:ios
pod
'BananaLib'
,
:head
end
]
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
lockfile
.
to_hash
[
"DEPENDENCIES"
][
0
].
should
==
"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"
it
"serializes correctly external dependencies"
do
podfile
=
Pod
::
Podfile
.
new
do
platform
:ios
pod
'BananaLib'
,
{
:git
=>
"www.example.com"
,
:tag
=>
'1.0'
}
end
]
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
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
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
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
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
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
xit
"updates files generated by old versions of CocoaPods"
do
tmp_path
=
temporary_directory
+
'Podfile.lock'
text
=
<<-
LOCKFILE
.
strip_heredoc
PODS:
- BananaLib (1.0) [HEAD]:
- monkey (< 1.0.9, ~> 1.0.1)
- monkey (1.0.8)
DEPENDENCIES:
- BananaLib (HEAD)
LOCKFILE
File
.
open
(
tmp_path
,
'w'
)
{
|
f
|
f
.
write
(
text
)
}
lockfile
=
Pod
::
Lockfile
.
from_file
(
tmp_path
)
lockfile
.
to_hash
.
should
==
{
"PODS"
=>
[
{
"BananaLib (HEAD from 1.0)"
=>
[
"monkey (< 1.0.9, ~> 1.0.1)"
]},
"monkey (1.0.8)"
],
"DEPENDENCIES"
=>
[
"BananaLib (~> 1.0)"
]
}
end
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'"
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
spec/unit/resolver_spec.rb
View file @
9cbb2dfd
...
...
@@ -223,7 +223,7 @@ module Pod
s
.
version
=
"1.4"
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@lockfile
=
Lockfile
.
create
(
nil
,
@podfile
,
@specs
)
@lockfile
=
Lockfile
.
generate
(
@podfile
,
@specs
)
@resolver
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
end
...
...
@@ -233,7 +233,7 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
it
"doesn't update
s
pods still compatible with the Podfile"
do
it
"doesn't update
the version of
pods still compatible with the Podfile"
do
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"JSONKit (1.4)"
end
...
...
@@ -315,7 +315,7 @@ module Pod
s
.
version
=
"1.4"
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@lockfile
=
Lockfile
.
create
(
nil
,
@podfile
,
@specs
)
@lockfile
=
Lockfile
.
generate
(
@podfile
,
@specs
)
@resolver
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
end
...
...
@@ -326,7 +326,7 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
true
end
it
"respecs the constraints of the pofile"
do
it
"respec
t
s the constraints of the pofile"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
...
...
@@ -339,10 +339,10 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
it
"
doesn't install new pods in `update_mode'
"
do
it
"
installs new pods
"
do
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
join
(
' '
).
should
.
not
.
include?
(
'BlocksKit'
)
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
fals
e
installed
.
join
(
' '
).
should
.
include?
(
'BlocksKit'
)
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
tru
e
end
it
"it always suggests to update pods in head mode"
do
...
...
@@ -356,8 +356,15 @@ module Pod
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
end
xit
"it suggests to update pods from external sources"
do
xit
"it always suggests to update pods from external sources"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'libPusher'
,
:git
=>
"example.com"
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
@resolver
.
resolve
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment