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
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
524 additions
and
260 deletions
+524
-260
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
+19
-7
lockfile.rb
lib/cocoapods/lockfile.rb
+155
-44
resolver.rb
lib/cocoapods/resolver.rb
+90
-135
integration_spec.rb
spec/integration_spec.rb
+21
-31
lockfile_spec.rb
spec/unit/lockfile_spec.rb
+209
-26
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
...
@@ -36,16 +36,16 @@ module Pod
sandbox
=
Sandbox
.
new
(
config
.
project_pods_root
)
sandbox
=
Sandbox
.
new
(
config
.
project_pods_root
)
resolver
=
Resolver
.
new
(
podfile
,
lockfile
,
sandbox
)
resolver
=
Resolver
.
new
(
podfile
,
lockfile
,
sandbox
)
resolver
.
update_mode
=
true
resolver
.
update_mode
=
true
resolver
.
update
d
_external_specs
=
false
resolver
.
update_external_specs
=
false
resolver
.
resolve
resolver
.
resolve
specs_to_install
=
resolver
.
spec
s_to_install
pods_to_install
=
resolver
.
pod
s_to_install
external_pods
=
resolver
.
external_pod
s
external_pods
=
resolver
.
pods_from_external_source
s
known_update_specs
=
[]
known_update_specs
=
[]
head_mode_specs
=
[]
head_mode_specs
=
[]
resolver
.
specs
.
each
do
|
s
|
resolver
.
specs
.
each
do
|
s
|
next
if
external_pods
.
include?
(
s
.
name
)
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?
if
s
.
version
.
head?
head_mode_specs
<<
s
.
name
head_mode_specs
<<
s
.
name
...
@@ -54,7 +54,7 @@ module Pod
...
@@ -54,7 +54,7 @@ module Pod
end
end
end
end
if
spec
s_to_install
.
empty?
if
pod
s_to_install
.
empty?
puts
"
\n
No updates are available.
\n
"
.
yellow
puts
"
\n
No updates are available.
\n
"
.
yellow
else
else
...
...
lib/cocoapods/dependency.rb
View file @
9cbb2dfd
...
@@ -101,6 +101,10 @@ module Pod
...
@@ -101,6 +101,10 @@ module Pod
@external_source
.
specification_from_sandbox
(
sandbox
,
platform
)
@external_source
.
specification_from_sandbox
(
sandbox
,
platform
)
end
end
def
match_version?
(
version
)
match?
(
name
,
version
)
&&
(
version
.
head?
==
head?
)
end
# Taken from RubyGems 1.3.7
# Taken from RubyGems 1.3.7
unless
public_method_defined?
(
:match?
)
unless
public_method_defined?
(
:match?
)
def
match?
(
spec_name
,
spec_version
)
def
match?
(
spec_name
,
spec_version
)
...
@@ -139,6 +143,7 @@ module Pod
...
@@ -139,6 +143,7 @@ module Pod
module
ExternalSources
module
ExternalSources
def
self
.
from_params
(
name
,
params
)
def
self
.
from_params
(
name
,
params
)
return
unless
name
&&
params
if
params
.
key?
(
:git
)
if
params
.
key?
(
:git
)
GitSource
.
new
(
name
,
params
)
GitSource
.
new
(
name
,
params
)
elsif
params
.
key?
(
:podspec
)
elsif
params
.
key?
(
:podspec
)
...
@@ -172,9 +177,9 @@ module Pod
...
@@ -172,9 +177,9 @@ module Pod
specification_from_local
(
sandbox
,
platform
)
specification_from_local
(
sandbox
,
platform
)
end
end
def
==
(
other
_source
)
def
==
(
other
)
return
if
other
_source
.
nil?
return
if
other
.
nil?
name
==
other
_source
.
name
&&
params
==
other_source
.
params
name
==
other
.
name
&&
params
==
other
.
params
end
end
end
end
...
...
lib/cocoapods/downloader/git.rb
View file @
9cbb2dfd
...
@@ -79,6 +79,7 @@ module Pod
...
@@ -79,6 +79,7 @@ module Pod
git!
"reset --hard HEAD"
git!
"reset --hard HEAD"
git!
"clean -d -x -f"
git!
"clean -d -x -f"
git!
"pull origin master"
git!
"pull origin master"
git!
"fetch --tags"
end
end
end
end
...
...
lib/cocoapods/installer.rb
View file @
9cbb2dfd
...
@@ -58,11 +58,10 @@ module Pod
...
@@ -58,11 +58,10 @@ module Pod
end
end
if
should_install
if
should_install
unless
pod
.
downloaded?
pod
.
implode
pod
.
implode
download_pod
(
pod
)
download_pod
(
pod
)
# This will not happen if the pod existed before we started the install
end
# process.
if
pod
.
downloaded?
# The docs need to be generated before cleaning because the
# The docs need to be generated before cleaning because the
# documentation is created for all the subspecs.
# documentation is created for all the subspecs.
generate_docs
(
pod
)
generate_docs
(
pod
)
...
@@ -72,7 +71,6 @@ module Pod
...
@@ -72,7 +71,6 @@ module Pod
end
end
end
end
end
end
end
def
download_pod
(
pod
)
def
download_pod
(
pod
)
downloader
=
Downloader
.
for_pod
(
pod
)
downloader
=
Downloader
.
for_pod
(
pod
)
...
@@ -100,12 +98,26 @@ module Pod
...
@@ -100,12 +98,26 @@ module Pod
end
end
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!
def
install!
@sandbox
.
prepare_for_install
@sandbox
.
prepare_for_install
print_title
"Resolving dependencies of:
#{
@podfile
.
defined_in_file
}
"
print_title
"Resolving dependencies of:
#{
@podfile
.
defined_in_file
}
"
specs_by_target
specs_by_target
print_title
"Removing deleted dependencies"
unless
resolver
.
removed_pods
.
empty?
remove_deleted_dependencies!
print_title
"Installing dependencies"
print_title
"Installing dependencies"
install_dependencies!
install_dependencies!
...
@@ -123,12 +135,12 @@ module Pod
...
@@ -123,12 +135,12 @@ module Pod
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
run_post_install_hooks
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
)
project
.
save_as
(
@sandbox
.
project_path
)
puts
"- Writing lockfile in `
#{
config
.
project_lockfile
}
'
\n\n
"
if
config
.
verbose?
puts
"- Writing lockfile in `
#{
config
.
project_lockfile
}
'
\n\n
"
if
config
.
verbose?
@lockfile
=
Lockfile
.
create
(
config
.
project_lockfile
,
@podfile
,
specs_by_target
.
values
.
flatten
)
@lockfile
=
Lockfile
.
generate
(
@podfile
,
specs_by_target
.
values
.
flatten
)
@lockfile
.
write_to_disk
@lockfile
.
write_to_disk
(
config
.
project_lockfile
)
UserProjectIntegrator
.
new
(
@podfile
).
integrate!
if
config
.
integrate_targets?
UserProjectIntegrator
.
new
(
@podfile
).
integrate!
if
config
.
integrate_targets?
end
end
...
...
lib/cocoapods/lockfile.rb
View file @
9cbb2dfd
module
Pod
module
Pod
class
Lockfile
class
Lockfile
# @return [Lockfile] Returns the Lockfile saved in path. If the
# @return [Lockfile] Returns the Lockfile saved in path.
# file could not be loaded or is not compatible with current
# Returns {nil} If the file can't be loaded.
# version of CocoaPods {nil}
#
#
def
self
.
from_file
(
path
)
def
self
.
from_file
(
path
)
lockfile
=
Lockfile
.
new
(
path
)
return
nil
unless
path
.
exist?
lockfile
.
hash_reppresentation
?
lockfile
:
nil
hash
=
YAML
.
load
(
File
.
open
(
path
))
lockfile
=
Lockfile
.
new
(
hash
)
lockfile
.
defined_in_file
=
path
lockfile
end
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
)
def
self
.
generate
(
podfile
,
specs
)
Lockfile
.
new
(
path
,
podfile
,
specs
)
Lockfile
.
new
(
generate_hash_from_podfile
(
podfile
,
specs
)
)
end
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.
# @param [Pathname] the path of the Lockfile.
# If no other value is provided the Lockfile is read from this path.
# If no other value is provided the Lockfile is read from this path.
# @param [Podfile] the Podfile to use for generating the Lockfile.
# @param [Podfile] the Podfile to use for generating the Lockfile.
# @param [specs] the specs installed.
# @param [specs] the specs installed.
#
#
def
initialize
(
path
,
podfile
=
nil
,
specs
=
nil
)
def
initialize
(
hash
)
@defined_in_file
=
path
if
Version
.
new
(
hash
[
"COCOAPODS"
])
<=
Version
.
new
(
"0.11"
)
if
podfile
&&
specs
# Convert old format to be compatible
@podfile
=
podfile
# - Pods:
@specs
=
specs
# - libPusher (1.0) [HEAD] -> libPusher (HEAD from 1.0)
else
# - Dependencies:
yaml
=
YAML
.
load
(
File
.
open
(
path
))
# - libPusher [HEAD] -> libPusher (HEAD)
if
yaml
&&
Version
.
new
(
yaml
[
"COCOAPODS"
])
>=
Version
.
new
(
"0.10"
)
@hash_reppresentation
=
yaml
end
end
end
@to_hash
=
hash
end
end
# @return [Array<String, Hash{String => Array[String]}>] The pods installed
# and their dependencies.
#
def
pods
def
pods
return
[]
unless
to_hash
@pods
||=
to_hash
[
'PODS'
]
||
[]
to_hash
[
'PODS'
]
||
[]
end
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# install.
#
def
dependencies
def
dependencies
return
[]
unless
to_hash
@dependencies
||=
to_hash
[
'DEPENDENCIES'
].
map
{
|
dep
|
dependency_from_string
(
dep
)
}
||
[]
to_hash
[
'DEPENDENCIES'
]
||
[]
end
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
def
external_sources
return
[]
unless
to_hash
@external_sources
||=
to_hash
[
"EXTERNAL SOURCES"
]
||
{}
to_hash
[
"EXTERNAL SOURCES"
]
||
[]
end
end
# @return [Array<Dependency>] The Podfile dependencies used during the last
# @return [Array<String>] The names of the installed Pods.
# install.
#
#
def
podfile_dependencies
def
pods_names
dependencies
.
map
{
|
dep
|
dependency_from_string
(
dep
)
}
@pods_names
||=
pods
.
map
do
|
pod
|
pod
=
pod
.
keys
.
first
unless
pod
.
is_a?
(
String
)
name_and_version_for_pod
(
pod
)[
0
]
end
end
end
# @return [Array<Dependency>] The dependencies that require the installed
# @return [Hash{String => Version}] A Hash containing the name
# pods with their exact version.
# of the installed Pods as the keys and their corresponding {Version}
# as the values.
#
#
def
dependencies_for_pods
def
pods_versions
pods
.
map
{
|
pod
|
dependency_from_string
(
pod
.
is_a?
(
String
)
?
pod
:
pod
.
keys
[
0
])
}
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
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"
#
# @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.
# @return [Dependency] The dependency described by the string.
#
#
def
dependency_from_string
(
string
)
def
dependency_from_string
(
string
)
...
@@ -79,8 +136,8 @@ module Pod
...
@@ -79,8 +136,8 @@ module Pod
# @TODO: store the whole spec?, the version?
# @TODO: store the whole spec?, the version?
Dependency
.
new
(
name
)
Dependency
.
new
(
name
)
when
/from `(.*)'/
when
/from `(.*)'/
external_source_info
=
external_sources
.
find
{
|
hash
|
hash
.
keys
[
0
]
==
name
}
||
{}
external_source_info
=
external_sources
[
name
]
Dependency
.
new
(
name
,
external_source_info
[
name
]
)
Dependency
.
new
(
name
,
external_source_info
)
when
/HEAD/
when
/HEAD/
# @TODO: find a way to serialize from the Downloader the information
# @TODO: find a way to serialize from the Downloader the information
# necessary to restore a head version.
# necessary to restore a head version.
...
@@ -90,10 +147,60 @@ module Pod
...
@@ -90,10 +147,60 @@ module Pod
end
end
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}.
# @return [void] Writes the Lockfile to {#path}.
#
#
def
write_to_disk
def
write_to_disk
(
path
)
File
.
open
(
defined_in_file
,
'w'
)
{
|
f
|
f
.
write
(
to_yaml
)
}
File
.
open
(
path
,
'w'
)
{
|
f
|
f
.
write
(
to_yaml
)
}
defined_in_file
=
path
end
end
# @return [String] A string useful to represent the Lockfile in a message
# @return [String] A string useful to represent the Lockfile in a message
...
@@ -112,9 +219,7 @@ module Pod
...
@@ -112,9 +219,7 @@ module Pod
# @return [Dictionary] The Dictionary representation of the Lockfile.
# @return [Dictionary] The Dictionary representation of the Lockfile.
#
#
def
to_hash
def
self
.
generate_hash_from_podfile
(
podfile
,
specs
)
return
@hash_reppresentation
if
@hash_reppresentation
return
nil
unless
@podfile
&&
@specs
hash
=
{}
hash
=
{}
# Get list of [name, dependencies] pairs.
# Get list of [name, dependencies] pairs.
...
@@ -122,7 +227,7 @@ module Pod
...
@@ -122,7 +227,7 @@ module Pod
[
spec
.
to_s
,
spec
.
dependencies
.
map
(
&
:to_s
).
sort
]
[
spec
.
to_s
,
spec
.
dependencies
.
map
(
&
:to_s
).
sort
]
end
.
uniq
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
=
{}
tmp
=
{}
pod_and_deps
.
each
do
|
name
,
deps
|
pod_and_deps
.
each
do
|
name
,
deps
|
if
tmp
[
name
]
if
tmp
[
name
]
...
@@ -136,12 +241,18 @@ module Pod
...
@@ -136,12 +241,18 @@ module Pod
end
end
hash
[
"PODS"
]
=
pod_and_deps
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
[
"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
[
"COCOAPODS"
]
=
VERSION
hash
hash
end
end
...
...
lib/cocoapods/resolver.rb
View file @
9cbb2dfd
...
@@ -4,6 +4,16 @@ module Pod
...
@@ -4,6 +4,16 @@ module Pod
class
Resolver
class
Resolver
include
Config
::
Mixin
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.
# @return [Podfile] The Podfile used by the resolver.
#
#
attr_reader
:podfile
attr_reader
:podfile
...
@@ -17,142 +27,127 @@ module Pod
...
@@ -17,142 +27,127 @@ module Pod
#
#
attr_reader
:sandbox
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
# @return [Array<Strings>] The name of the pods coming from an
# external sources
# external sources
#
#
attr_reader
:
external_pod
s
attr_reader
:
pods_from_external_source
s
# @return [Array<Set>] The set used to resolve the dependencies.
# @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
# @return [Source::Aggregate] A cache of the sources needed to find the
# podspecs.
# 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
)
def
initialize
(
podfile
,
lockfile
,
sandbox
)
@podfile
=
podfile
@podfile
=
podfile
@lockfile
=
lockfile
@lockfile
=
lockfile
@sandbox
=
sandbox
@sandbox
=
sandbox
@update_external_specs
=
true
@cached_sets
=
{}
@cached_sets
=
{}
@cached_sources
=
Source
::
Aggregate
.
new
@cached_sources
=
Source
::
Aggregate
.
new
@cached_specs
=
{}
@specs_by_target
=
{}
@pods_from_external_sources
=
[]
@dependencies_podfile_incompatible
=
[]
@log_indent
=
0
;
@log_indent
=
0
;
@updated_external_specs
=
true
end
end
# Identifies the specifications that should be installed according whether
# Identifies the specifications that should be installed according whether
# the resolver is in update mode or not.
# the resolver is in update mode or not.
#
#
# @return [
void]
# @return [
Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
#
#
def
resolve
def
resolve
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?
if
config
.
verbose?
unless
podfile_dependencies
.
empty?
@pods_by_state
.
each
do
|
symbol
,
pod_names
|
puts
"
\n
Already installed Podfile dependencies detected (Podfile.lock):"
.
green
case
symbol
podfile_dependencies
.
each
{
|
dependency
|
puts
" -
#{
dependency
}
"
}
when
:added
mark
=
"A"
.
green
when
:changed
mark
=
"M"
.
yellow
when
:removed
mark
=
"R"
.
red
when
:unchanged
mark
=
"-"
end
end
unless
dependencies_for_pods
.
empty?
pod_names
.
each
do
|
pod_name
|
puts
"
\n
Installed Pods detected (Podfile.lock):"
.
green
puts
"
#{
mark
}
"
<<
pod_name
dependencies_for_pods
.
each
{
|
dependency
|
puts
" -
#{
dependency
}
"
}
end
end
end
end
end
@cached_specs
=
{}
pods_not_to_lock
=
@pods_by_state
[
:added
]
+
@pods_by_state
[
:changed
]
+
@pods_by_state
[
:removed
]
@targets_and_specs
=
{}
lock_versions
(
lockfile
.
pods_names
-
pods_not_to_lock
)
unless
update_mode
@external_pods
=
[]
end
@dependencies_podfile_incompatible
=
[]
@removed_pods
=
[]
lock_dependencies_version
unless
update_mode
@podfile
.
target_definitions
.
values
.
each
do
|
target_definition
|
@podfile
.
target_definitions
.
values
.
each
do
|
target_definition
|
puts
"
\n
Resolving dependencies for target `
#{
target_definition
.
name
}
' (
#{
target_definition
.
platform
}
):"
.
green
if
config
.
verbose?
puts
"
\n
Resolving dependencies for target `
#{
target_definition
.
name
}
' (
#{
target_definition
.
platform
}
):"
.
green
if
config
.
verbose?
@loaded_specs
=
[]
@loaded_specs
=
[]
find_dependency_specs
(
@podfile
,
target_definition
.
dependencies
,
target_definition
)
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
end
@cached_specs
.
values
.
sort_by
(
&
:name
)
@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
end
# @return [Bool] Whether a pod should be installed/reinstalled.
# @return [Bool] Whether a pod should be installed/reinstalled.
#
#
def
should_install?
(
name
)
def
should_install?
(
name
)
specs_to_install
.
include?
(
name
)
pods_to_install
.
include?
name
end
end
# @return [Array<String>] The list of the names of the pods that need
# @return [Array<Strings>] The name of the pods that should be
# to be installed.
# installed/reinstalled.
#
# - 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
def
pods_to_install
@specs_to_install
||=
begin
unless
@pods_to_install
specs
=
@targets_and_specs
.
values
.
flatten
if
lockfile
to_install
=
[]
@pods_to_install
=
specs
.
select
{
|
spec
|
specs
.
each
do
|
spec
|
spec
.
version
!=
lockfile
.
pods_versions
[
spec
.
pod_name
]
}.
map
(
&
:name
)
if
update_mode
if
update_mode
# Installation mode
@pods_to_install
+=
specs
.
select
{
|
spec
|
installed_dependency
=
dependencies_for_pods
.
find
{
|
d
|
d
.
name
==
spec
.
name
}
spec
.
version
.
head?
||
pods_from_external_sources
.
include?
(
spec
.
pod_name
)
outdated
=
installed_dependency
&&
!
installed_dependency
.
matches_spec?
(
spec
)
}.
map
(
&
:name
)
head
=
spec
.
version
.
head?
if
outdated
||
head
||
@external_pods
.
include?
(
spec
.
pod_name
)
to_install
<<
spec
end
end
@pods_to_install
+=
@pods_by_state
[
:added
]
+
@pods_by_state
[
:changed
]
else
else
# Installation mode
@pods_to_install
=
specs
.
map
(
&
:name
)
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
end
end
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
end
@pods_to_install
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
# Returns the resolved specifications grouped by target.
#
def
specs_by_target
@targets_and_specs
end
end
# @return [Array<Strings>] The name of the pods that were installed
# @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
def
removed_pods
if
update_mode
return
[]
unless
lockfile
[]
# It should never remove any pod in update mode
unless
@removed_pods
else
previusly_installed
=
lockfile
.
pods_names
.
map
{
|
pod_name
|
pod_name
.
split
(
'/'
).
first
}
[]
# @TODO: Implement
installed
=
specs
.
map
{
|
spec
|
spec
.
name
.
split
(
'/'
).
first
}
@removed_pods
=
previusly_installed
-
installed
end
end
@removed_pods
end
end
private
private
...
@@ -162,53 +157,18 @@ module Pod
...
@@ -162,53 +157,18 @@ module Pod
#
#
# @return [void]
# @return [void]
#
#
def
lock_
dependencies_version
def
lock_
versions
(
pods
)
return
unless
lockfile
return
unless
lockfile
# Add a specific Dependency to lock the version in the resolution process
puts
"
\n
Finding updated or removed pods:"
.
green
if
config
.
verbose?
pods
.
each
do
|
pod_name
|
podfile_deps_names
=
podfile_dependencies
.
map
(
&
:name
)
version
=
lockfile
.
pods_versions
[
pod_name
]
raise
Informative
,
"Attempt to lock a Pod without an known version."
unless
version
dependencies_for_pods
.
each
do
|
dependency
|
dependency
=
Dependency
.
new
(
pod_name
,
version
)
# 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
=
find_cached_set
(
dependency
,
nil
)
set
.
required_by
(
dependency
,
lockfile
.
to_s
)
set
.
required_by
(
dependency
,
lockfile
.
to_s
)
else
puts
" U "
.
yellow
<<
"
#{
dependency
}
->
#{
podfile_dependency
}
"
if
config
.
verbose?
@dependencies_podfile_incompatible
<<
dependency
end
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
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
end
# @return [Set] The cached set for a given dependency.
# @return [Set] The cached set for a given dependency.
#
#
def
find_cached_set
(
dependency
,
platform
)
def
find_cached_set
(
dependency
,
platform
)
...
@@ -217,12 +177,11 @@ module Pod
...
@@ -217,12 +177,11 @@ module Pod
if
dependency
.
specification
if
dependency
.
specification
Specification
::
Set
::
External
.
new
(
dependency
.
specification
)
Specification
::
Set
::
External
.
new
(
dependency
.
specification
)
elsif
external_source
=
dependency
.
external_source
elsif
external_source
=
dependency
.
external_source
# The platform isn't actually being used by the LocalPod instance
if
update_mode
&&
update_external_specs
# that's being used behind the scenes, but passing it anyways for
# Always update external sources in update mode.
# completeness sake.
if
update_mode
&&
updated_external_specs
specification
=
external_source
.
specification_from_external
(
@sandbox
,
platform
)
specification
=
external_source
.
specification_from_external
(
@sandbox
,
platform
)
else
else
# Don't update external sources in install mode if not needed.
specification
=
external_source
.
specification_from_sandbox
(
@sandbox
,
platform
)
specification
=
external_source
.
specification_from_sandbox
(
@sandbox
,
platform
)
end
end
set
=
Specification
::
Set
::
External
.
new
(
specification
)
set
=
Specification
::
Set
::
External
.
new
(
specification
)
...
@@ -238,6 +197,10 @@ module Pod
...
@@ -238,6 +197,10 @@ module Pod
# Resolves the dependencies of a specification and stores them in @cached_specs
# 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]
# @return [void]
#
#
def
find_dependency_specs
(
dependent_specification
,
dependencies
,
target_definition
)
def
find_dependency_specs
(
dependent_specification
,
dependencies
,
target_definition
)
...
@@ -247,18 +210,10 @@ module Pod
...
@@ -247,18 +210,10 @@ module Pod
set
=
find_cached_set
(
dependency
,
target_definition
.
platform
)
set
=
find_cached_set
(
dependency
,
target_definition
.
platform
)
set
.
required_by
(
dependency
,
dependent_specification
.
to_s
)
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
# 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
)
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
@loaded_specs
<<
spec
.
name
@cached_specs
[
spec
.
name
]
=
spec
@cached_specs
[
spec
.
name
]
=
spec
# Configure the specification
# Configure the specification
...
...
spec/integration_spec.rb
View file @
9cbb2dfd
...
@@ -73,14 +73,10 @@ else
...
@@ -73,14 +73,10 @@ else
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
installer
=
Pod
::
Installer
.
new
(
resolver
)
installer
=
Pod
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
install!
installer
.
lockfile
.
to_hash
.
should
==
{
result
=
installer
.
lockfile
.
to_hash
'PODS'
=>
[
'SSToolkit (0.1.3)'
],
result
[
'PODS'
].
should
==
[
'SSToolkit (0.1.3)'
]
'DEPENDENCIES'
=>
[
"SSToolkit (from `
#{
url
}
', commit `
#{
commit
}
')"
],
result
[
'DEPENDENCIES'
].
should
==
[
"SSToolkit (from `
#{
url
}
', commit `
#{
commit
}
')"
]
'EXTERNAL SOURCES'
=>
[
{
"SSToolkit"
=>
{
result
[
'EXTERNAL SOURCES'
].
should
==
{
"SSToolkit"
=>
{
:git
=>
url
,
:commit
=>
commit
}}
:git
=>
"/Users/fabio/Documents/GitHub/CP/CocoaPods/spec/fixtures/integration/sstoolkit"
,
:commit
=>
"2adcd0f81740d6b0cd4589af98790eee3bd1ae7b"
}}],
'COCOAPODS'
=>
Pod
::
VERSION
}
end
end
it
"installs a library with a podspec outside of the repo"
do
it
"installs a library with a podspec outside of the repo"
do
...
@@ -92,18 +88,13 @@ else
...
@@ -92,18 +88,13 @@ else
pod
'Reachability'
,
:podspec
=>
url
pod
'Reachability'
,
:podspec
=>
url
end
end
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
resolver
=
Pod
::
Resolver
.
new
(
podfile
,
nil
,
Pod
::
Sandbox
.
new
(
config
.
project_pods_root
))
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
install!
result
=
installer
.
lockfile
.
to_hash
installer
.
lockfile
.
to_hash
.
should
==
{
result
[
'PODS'
].
should
==
[
'Reachability (1.2.3)'
]
'PODS'
=>
[
'Reachability (1.2.3)'
],
result
[
'DEPENDENCIES'
].
should
==
[
"Reachability (from `
#{
url
}
')"
]
'DEPENDENCIES'
=>
[
"Reachability (from `
#{
url
}
')"
],
result
[
'EXTERNAL SOURCES'
].
should
==
{
"Reachability"
=>
{
:podspec
=>
"https://raw.github.com/gist/1349824/3ec6aa60c19113573fc48eac19d0fafd6a69e033/Reachability.podspec"
}}
"EXTERNAL SOURCES"
=>
[{
"Reachability"
=>
{
:podspec
=>
"https://raw.github.com/gist/1349824/3ec6aa60c19113573fc48eac19d0fafd6a69e033/Reachability.podspec"
}}],
'COCOAPODS'
=>
Pod
::
VERSION
}
end
end
it
"installs a dummy source file"
do
it
"installs a dummy source file"
do
...
@@ -203,19 +194,19 @@ else
...
@@ -203,19 +194,19 @@ else
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
install!
# TODO might be nicer looking to not show the dependencies of the top level spec for each subspec (Reachability).
result
=
installer
.
lockfile
.
to_hash
installer
.
lockfile
.
to_hash
.
should
==
{
result
[
'PODS'
].
should
==
[
"PODS"
=>
[{
"ASIHTTPRequest (1.8.1)"
=>
[
"ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)"
,
{
"ASIHTTPRequest (1.8.1)"
=>
[
"ASIHTTPRequest/ASIWebPageRequest (= 1.8.1)"
,
"ASIHTTPRequest/CloudFiles (= 1.8.1)"
,
"ASIHTTPRequest/CloudFiles (= 1.8.1)"
,
"ASIHTTPRequest/S3 (= 1.8.1)"
,
"ASIHTTPRequest/S3 (= 1.8.1)"
,
"Reachability"
]},
"Reachability"
]},
{
"ASIHTTPRequest/ASIWebPageRequest (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/ASIWebPageRequest (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/CloudFiles (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/CloudFiles (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/S3 (1.8.1)"
=>
[
"Reachability"
]
},
{
"ASIHTTPRequest/S3 (1.8.1)"
=>
[
"Reachability"
]
},
"JSONKit (1.4)"
,
"Reachability (3.0.0)"
]
,
"JSONKit (1.4)"
,
"DEPENDENCIES"
=>
[
"ASIHTTPRequest"
,
"JSONKit (= 1.4)"
],
"Reachability (3.0.0)"
]
"COCOAPODS"
=>
Pod
::
VERSION
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).
should_xcodebuild
(
podfile
.
target_definitions
[
:ios_target
])
should_xcodebuild
(
podfile
.
target_definitions
[
:ios_target
])
should_xcodebuild
(
podfile
.
target_definitions
[
:osx_target
])
should_xcodebuild
(
podfile
.
target_definitions
[
:osx_target
])
...
@@ -313,7 +304,9 @@ else
...
@@ -313,7 +304,9 @@ else
lockfile_contents
[
'PODS'
].
delete_at
(
1
)
lockfile_contents
[
'PODS'
].
delete_at
(
1
)
# lockfile_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
# lockfile_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
end
end
installer
.
lockfile
.
to_hash
.
should
==
lockfile_contents
result
=
installer
.
lockfile
.
to_hash
result
.
delete
(
"SPECS CHECKSUM"
)
result
.
should
==
lockfile_contents
root
=
config
.
project_pods_root
root
=
config
.
project_pods_root
(
root
+
'Pods.xcconfig'
).
read
.
should
==
installer
.
target_installers
.
first
.
xcconfig
.
to_s
(
root
+
'Pods.xcconfig'
).
read
.
should
==
installer
.
target_installers
.
first
.
xcconfig
.
to_s
...
@@ -335,12 +328,9 @@ else
...
@@ -335,12 +328,9 @@ else
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
=
SpecHelper
::
Installer
.
new
(
resolver
)
installer
.
install!
installer
.
install!
installer
.
lockfile
.
to_hash
.
tap
{
|
d
|
d
.
delete
(
"COCOAPODS"
)
}.
should
==
{
result
=
installer
.
lockfile
.
to_hash
# 'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }],
result
[
'PODS'
].
should
==
[
'Reachability (2.0.4)'
]
'PODS'
=>
[
'Reachability (2.0.4)'
],
result
[
'DEPENDENCIES'
].
should
==
[
"Reachability (= 2.0.4)"
]
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
'DEPENDENCIES'
=>
[
"Reachability (= 2.0.4)"
]
}
end
end
end
end
...
...
spec/unit/lockfile_spec.rb
View file @
9cbb2dfd
require
File
.
expand_path
(
'../../spec_helper'
,
__FILE__
)
require
File
.
expand_path
(
'../../spec_helper'
,
__FILE__
)
describe
"Pod::Lockfile"
do
describe
"Pod::Lockfile"
do
describe
"In general"
do
extend
SpecHelper
::
TemporaryDirectory
extend
SpecHelper
::
TemporaryDirectory
def
sample
def
sample
text
=
<<-
LOCKFILE
.
strip_heredoc
text
=
<<-
LOCKFILE
.
strip_heredoc
PODS:
PODS:
- BananaLib (1.0):
- BananaLib (1.0):
- monkey (< 1.0.9, ~> 1.0.1)
- monkey (< 1.0.9, ~> 1.0.1)
- monkey (1.0.8)
- monkey (1.0.8)
DEPENDENCIES:
- BananaLib (~> 1.0)
DEPENDENCIES:
COCOAPODS:
#{
Pod
::
VERSION
}
- BananaLib (~> 1.0)
SPECS CHECKSUM:
BananaLib: !binary |-
MjI2Y2RkMTJkMzBhMWU4ZWM4OGM1ZmRkZWU2MDcwZDg0YTI1MGZjMQ==
COCOAPODS: 0.11.1
LOCKFILE
LOCKFILE
end
end
...
@@ -38,6 +46,11 @@ describe "Pod::Lockfile" do
...
@@ -38,6 +46,11 @@ describe "Pod::Lockfile" do
temporary_directory
+
'Podfile.lock'
temporary_directory
+
'Podfile.lock'
end
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
it
"loads from a file"
do
File
.
open
(
tmp_path
,
'w'
)
{
|
f
|
f
.
write
(
sample
)
}
File
.
open
(
tmp_path
,
'w'
)
{
|
f
|
f
.
write
(
sample
)
}
lockfile
=
Pod
::
Lockfile
.
from_file
(
tmp_path
)
lockfile
=
Pod
::
Lockfile
.
from_file
(
tmp_path
)
...
@@ -45,8 +58,13 @@ describe "Pod::Lockfile" do
...
@@ -45,8 +58,13 @@ describe "Pod::Lockfile" do
lockfile
.
to_hash
.
should
==
YAML
.
load
(
sample
)
lockfile
.
to_hash
.
should
==
YAML
.
load
(
sample
)
end
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
before
do
@lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
@lockfile
=
Pod
::
Lockfile
.
generate
(
podfile
,
specs
)
end
end
it
"generates a valid YAML representation"
do
it
"generates a valid YAML representation"
do
...
@@ -57,23 +75,15 @@ describe "Pod::Lockfile" do
...
@@ -57,23 +75,15 @@ describe "Pod::Lockfile" do
@lockfile
.
to_hash
.
should
==
YAML
.
load
(
sample
)
@lockfile
.
to_hash
.
should
==
YAML
.
load
(
sample
)
end
end
it
"returns the Podfile dependencies"
do
it
"returns the list of the installed pods"
do
@lockfile
.
podfile_dependencies
.
should
==
[
@lockfile
.
pods_names
.
should
==
%w| BananaLib monkey |
Pod
::
Dependency
.
new
(
"BananaLib"
,
"~> 1.0"
)
]
end
end
it
"returns the dependencies for the installed pods"
do
it
"returns the versions of the installed pods"
do
@lockfile
.
dependencies_for_pods
.
should
==
[
@lockfile
.
pods_versions
.
should
==
{
Pod
::
Dependency
.
new
(
"BananaLib"
,
"= 1.0"
),
"BananaLib"
=>
Pod
::
Version
.
new
(
"1.0"
),
Pod
::
Dependency
.
new
(
"monkey"
,
"= 1.0.8"
)
"monkey"
=>
Pod
::
Version
.
new
(
"1.0.8"
)
]
}
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
end
it
"serializes correctly `:head' dependencies"
do
it
"serializes correctly `:head' dependencies"
do
...
@@ -92,7 +102,7 @@ describe "Pod::Lockfile" do
...
@@ -92,7 +102,7 @@ describe "Pod::Lockfile" do
end
end
]
]
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
lockfile
=
Pod
::
Lockfile
.
generate
(
podfile
,
specs
)
lockfile
.
to_hash
[
"DEPENDENCIES"
][
0
].
should
==
"BananaLib (HEAD)"
lockfile
.
to_hash
[
"DEPENDENCIES"
][
0
].
should
==
"BananaLib (HEAD)"
end
end
...
@@ -112,9 +122,9 @@ describe "Pod::Lockfile" do
...
@@ -112,9 +122,9 @@ describe "Pod::Lockfile" do
end
end
]
]
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
specs
)
lockfile
=
Pod
::
Lockfile
.
generate
(
podfile
,
specs
)
lockfile
.
to_hash
[
"DEPENDENCIES"
][
0
].
should
==
"BananaLib (from `www.example.com', tag `1.0')"
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'
}
lockfile
.
to_hash
[
"EXTERNAL SOURCES"
][
"BananaLib"
].
should
==
{
:git
=>
"www.example.com"
,
:tag
=>
'1.0'
}
end
end
it
"creates a dependency from a string"
do
it
"creates a dependency from a string"
do
...
@@ -138,11 +148,184 @@ describe "Pod::Lockfile" do
...
@@ -138,11 +148,184 @@ describe "Pod::Lockfile" do
platform
:ios
platform
:ios
pod
'BananaLib'
,
{
:git
=>
"www.example.com"
,
:tag
=>
'1.0'
}
pod
'BananaLib'
,
{
:git
=>
"www.example.com"
,
:tag
=>
'1.0'
}
end
end
lockfile
=
Pod
::
Lockfile
.
create
(
tmp_path
,
podfile
,
[])
lockfile
=
Pod
::
Lockfile
.
generate
(
podfile
,
[])
d
=
lockfile
.
dependency_from_string
(
"BananaLib (from `www.example.com', tag `1.0')"
)
d
=
lockfile
.
dependency_from_string
(
"BananaLib (from `www.example.com', tag `1.0')"
)
d
.
name
.
should
==
"BananaLib"
d
.
name
.
should
==
"BananaLib"
d
.
requirement
.
should
.
be
.
none?
d
.
requirement
.
should
.
be
.
none?
d
.
external?
.
should
.
be
.
true
d
.
external?
.
should
.
be
.
true
d
.
external_source
.
description
.
should
==
"from `www.example.com', tag `1.0'"
d
.
external_source
.
description
.
should
==
"from `www.example.com', tag `1.0'"
end
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
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
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
end
spec/unit/resolver_spec.rb
View file @
9cbb2dfd
...
@@ -223,7 +223,7 @@ module Pod
...
@@ -223,7 +223,7 @@ module Pod
s
.
version
=
"1.4"
s
.
version
=
"1.4"
end
]
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@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
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
end
end
...
@@ -233,7 +233,7 @@ module Pod
...
@@ -233,7 +233,7 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
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
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"JSONKit (1.4)"
installed
.
should
.
include?
"JSONKit (1.4)"
end
end
...
@@ -315,7 +315,7 @@ module Pod
...
@@ -315,7 +315,7 @@ module Pod
s
.
version
=
"1.4"
s
.
version
=
"1.4"
end
]
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@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
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
@resolver
.
update_mode
=
true
end
end
...
@@ -326,7 +326,7 @@ module Pod
...
@@ -326,7 +326,7 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
true
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
true
end
end
it
"respecs the constraints of the pofile"
do
it
"respec
t
s the constraints of the pofile"
do
podfile
=
Podfile
.
new
do
podfile
=
Podfile
.
new
do
platform
:ios
platform
:ios
pod
'BlocksKit'
pod
'BlocksKit'
...
@@ -339,10 +339,10 @@ module Pod
...
@@ -339,10 +339,10 @@ module Pod
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
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
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
join
(
' '
).
should
.
not
.
include?
(
'BlocksKit'
)
installed
.
join
(
' '
).
should
.
include?
(
'BlocksKit'
)
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
fals
e
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
tru
e
end
end
it
"it always suggests to update pods in head mode"
do
it
"it always suggests to update pods in head mode"
do
...
@@ -356,8 +356,15 @@ module Pod
...
@@ -356,8 +356,15 @@ module Pod
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
end
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
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