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
1baebf67
Commit
1baebf67
authored
Nov 24, 2012
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Resolver] Clean-up and specs update.
parent
ff745f82
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
466 additions
and
441 deletions
+466
-441
resolver.rb
lib/cocoapods/resolver.rb
+155
-88
resolver_spec.rb
spec/unit/resolver_spec.rb
+311
-353
No files found.
lib/cocoapods/resolver.rb
View file @
1baebf67
...
@@ -5,186 +5,253 @@ module Pod
...
@@ -5,186 +5,253 @@ module Pod
#
#
# Its current implementation is naive, in the sense that it can't do full
# Its current implementation is naive, in the sense that it can't do full
# automatic resolves like Bundler:
# automatic resolves like Bundler:
#
# [how-does-bundler-bundle](http://patshaughnessy.net/2011/9/24/how-does-bundler-bundle)
# http://patshaughnessy.net/2011/9/24/how-does-bundler-bundle
#
#
# Another important aspect to keep in mind of the current implementation
# Another important aspect to keep in mind of the current implementation
# is that the order of the dependencies matters.
# is that the order of the dependencies matters.
#
#
class
Resolver
class
Resolver
include
Config
::
Mixin
include
Config
::
Mixin
# @return [Sandbox]
T
he Sandbox used by the resolver to find external
# @return [Sandbox]
t
he Sandbox used by the resolver to find external
# dependencies.
# dependencies.
#
#
attr_reader
:sandbox
attr_reader
:sandbox
# @return [Podfile]
T
he Podfile used by the resolver.
# @return [Podfile]
t
he Podfile used by the resolver.
#
#
attr_reader
:podfile
attr_reader
:podfile
# @return [Array<Dependency>]
T
he list of dependencies locked to a specific
# @return [Array<Dependency>]
t
he list of dependencies locked to a specific
# version.
# version.
#
#
attr_reader
:locked_dependencies
attr_reader
:locked_dependencies
# @return [Bool] Whether the resolver should update the external specs
# @return [Bool] whether the resolver should update the external specs
# in the resolution process. This option is used for detecting changes
# in the resolution process. This option is used for detecting
# in with the Podfile without affecting the existing Pods installation
# changes in with the Podfile without affecting the existing Pods
# (see `pod outdated`).
# installation
#
# @note This option is used by `pod outdated`.
#
#
# @TODO: This implementation is not clean, because if the spec doesn't
# @TODO: This implementation is not clean, because if the spec doesn't
# exists the sandbox will actually download it and result modified.
# exists the sandbox will actually download and modify the
# installation.
#
#
attr_accessor
:update_external_specs
attr_accessor
:update_external_specs
# @param [Sandbox] sandbox @see sandbox
# @param [Podfile] podfile @see podfile
# @param [Array<Dependency>] locked_dependencies @see locked_dependencies
#
def
initialize
(
sandbox
,
podfile
,
locked_dependencies
=
[])
def
initialize
(
sandbox
,
podfile
,
locked_dependencies
=
[])
@sandbox
=
sandbox
@sandbox
=
sandbox
@podfile
=
podfile
@podfile
=
podfile
@locked_dependencies
=
locked_dependencies
@locked_dependencies
=
locked_dependencies
end
end
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
#-------------------------------------------------------------------------#
# Returns the resolved specifications grouped by target.
#
attr_reader
:specs_by_target
# @return [Array<Specification>] All The specifications loaded by the
# @!group Resolution
# resolver.
#
def
specs
@cached_specs
.
values
.
uniq
end
# @return [Array<Strings>] The name of the pods that have an
public
# external source.
#
# @TODO: Add an attribute to the specification class?
#
attr_reader
:pods_from_external_sources
# Identifies the specifications that should be installed.
#
# @return [Hash{TargetDefinition => Array<Specification>}] specs_by_target
# @return [Hash{TargetDefinition => Array<Specification>}] specs_by_target
#
Identifies the specifications that should be installed according
#
the specifications that need to be installed grouped by target
#
whether the resolver is in update mode or not
.
#
definition
.
#
#
def
resolve
def
resolve
@cached_sources
=
Source
::
Aggregate
.
new
(
config
.
repos_dir
)
@cached_sources
=
Source
::
Aggregate
.
new
(
config
.
repos_dir
)
@cached_sets
=
{}
@cached_sets
=
{}
@cached_specs
=
{}
@cached_specs
=
{}
@specs_by_target
=
{}
@specs_by_target
=
{}
@pods_from_external_sources
=
[]
#
@pods_from_external_sources = []
podfile
.
target_definitions
.
values
.
each
do
|
target
_definition
|
podfile
.
target_definitions
.
values
.
each
do
|
target
|
UI
.
section
"Resolving dependencies for target `
#{
target
_definition
.
name
}
' (
#{
target_definition
.
platform
}
)"
do
UI
.
section
"Resolving dependencies for target `
#{
target
.
name
}
' (
#{
target
.
platform
}
)"
do
@loaded_specs
=
[]
@loaded_specs
=
[]
find_dependency_specs
(
podfile
,
target_definition
.
dependencies
,
target_definition
)
find_dependency_specs
(
podfile
,
target
.
dependencies
,
target
)
@specs_by_target
[
target_definition
]
=
@cached_specs
.
values_at
(
*
@loaded_specs
).
sort_by
(
&
:name
)
specs
=
cached_specs
.
values_at
(
*
@loaded_specs
).
sort_by
(
&
:name
)
specs_by_target
[
target
]
=
specs
end
end
end
end
@
cached_specs
.
values
.
sort_by
(
&
:name
)
cached_specs
.
values
.
sort_by
(
&
:name
)
@
specs_by_target
specs_by_target
end
end
#-----------------------------------------------------------------------#
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
# returns the resolved specifications grouped by target.
#
# @note The returned specifications can be subspecs.
#
attr_reader
:specs_by_target
private
# @return [Array<Specification>] All the specifications resolved.
#
def
specs
specs_by_target
.
values
.
flatten
.
uniq
end
# @return [Array<Set>] A cache of the sets used to resolve the dependencies.
# @return [Array<Strings>] The name of the pods that have an
# external source.
#
# TODO: Not sure if needed.
#
#
attr_reader
:cached_set
s
# attr_reader :pods_from_external_source
s
#-------------------------------------------------------------------------#
# !@ Resolution context
private
# @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_reader
:cached_sources
# TODO: Cache the sources globally?
#
attr_accessor
:cached_sources
# @return [
void] Resolves recursively the dependencies of a specification
# @return [
Hash<String => Set>] A cache that keeps tracks of the sets
#
and stores them in @cached_specs
#
loaded by the resolution process.
#
#
# @param [Specification] dependent_specification
# @note Sets keep track of the TODO:
# The specification whose dependencies are being resolved.
#
attr_accessor
:cached_sets
#
#
attr_accessor
:cached_specs
#
#
attr_writer
:specs_by_target
#-------------------------------------------------------------------------#
# !@ Resolution helpers
private
# Resolves recursively the dependencies of a specification and stores them
# in the @cached_specs ivar.
#
# @param [Podfile, Specification] dependent_spec
# the specification whose dependencies are being resolved.
#
#
# @param [Array<Dependency>] dependencies
# @param [Array<Dependency>] dependencies
#
T
he dependencies of the specification.
#
t
he dependencies of the specification.
#
#
# @param [TargetDefinition] target_definition
# @param [TargetDefinition] target_definition
# The target definition that owns the specification.
# the target definition that owns the specification.
#
# @note If there is a locked dependency with the same name of a
# given dependency the locked one is used in place of the
# dependency of the specification. In this way it is possible to
# not updated the installed pods without without introducing
# dependencies in other target definitions.
# TODO: Just add the requirement to the set?
# TODO: Use root name?
#
# @note The recursive process checks if a dependency has already been
# loaded to prevent an infinite loop. For this reason the
# @loaded_specs ivar must be cleaned when changing target
# definition.
#
#
#
def
find_dependency_specs
(
dependent_specification
,
dependencies
,
target_definition
)
# TODO: The set class should be aware whether it is in head mode.
#
# @return [void]
#
def
find_dependency_specs
(
dependent_spec
,
dependencies
,
target_definition
)
dependencies
.
each
do
|
dependency
|
dependencies
.
each
do
|
dependency
|
# Replace the dependency with a more specific one if the pod is already
locked_dep
=
locked_dependencies
.
find
{
|
ld
|
ld
.
name
==
dependency
.
name
}
# installed.
# @TODO: check for compatibility?
locked_dep
=
locked_dependencies
.
find
{
|
locked
|
locked
.
name
==
dependency
.
name
}
dependency
=
locked_dep
if
locked_dep
dependency
=
locked_dep
if
locked_dep
UI
.
message
(
"-
#{
dependency
}
"
,
''
,
2
)
do
UI
.
message
(
"-
#{
dependency
}
"
,
''
,
2
)
do
set
=
find_cached_set
(
dependency
,
target_definition
.
platform
)
set
=
find_cached_set
(
dependency
,
target_definition
.
platform
)
set
.
required_by
(
dependency
,
dependent_spec
ification
.
to_s
)
set
.
required_by
(
dependency
,
dependent_spec
.
to_s
)
# Ensure we don't resolve the same spec twice for one target
unless
@loaded_specs
.
include?
(
dependency
.
name
)
if
@loaded_specs
.
include?
(
dependency
.
name
)
validate_platform
(
@cached_specs
[
dependency
.
name
],
target_definition
)
else
spec
=
set
.
specification
.
subspec_by_name
(
dependency
.
name
)
spec
=
set
.
specification
.
subspec_by_name
(
dependency
.
name
)
@pods_from_external_sources
<<
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
# @pods_from_external_sources << spec.root_name if dependency.external?
validate_platform
(
spec
,
target_definition
)
spec
.
activate_platform
(
target_definition
.
platform
)
spec
.
activate_platform
(
target_definition
.
platform
)
spec
.
version
.
head
=
dependency
.
head?
spec
.
version
.
head
=
dependency
.
head?
# And recursively load the dependencies of the spec.
find_dependency_specs
(
spec
,
spec
.
dependencies
,
target_definition
)
validate_platform
(
spec
,
target_definition
)
find_dependency_specs
(
spec
,
spec
.
dependencies
,
target_definition
)
end
end
end
end
end
end
end
end
# @return [Set] The cached set for a given dependency.
# Loads or returns a previously initialized {Set} for the given dependency.
#
# @param [Dependency] dependency
# the dependency for which the set is needed.
# TODO: check dependency.specification
#
#
# If the update_external_specs flag is activated the dependencies with
# @param [Platform] platform
# external sources are always resolved against the remote. Otherwise the
# the platform on which the dependency is needed this is used by
# specification is retrieved from the sandbox that fetches the external
# the sandbox to locate external sources.
# source only if needed.
# TODO why?
#
# @note If the {#update_external_specs} flag is activated the
# dependencies with external sources are always resolved against
# the remote. Otherwise the specification is retrieved from the
# sandbox that fetches the external source only if needed.
#
# TODO If the set is loaded from a normal source and then from an
# external one that information is lost.
#
# @return [Set] the cached set for a given dependency.
#
#
def
find_cached_set
(
dependency
,
platform
)
def
find_cached_set
(
dependency
,
platform
)
set_name
=
dependency
.
name
.
split
(
'/'
).
first
name
=
dependency
.
root_name
@cached_sets
[
set_name
]
||=
begin
unless
cached_sets
[
name
]
if
dependency
.
specification
if
dependency
.
specification
Specification
::
Set
::
External
.
new
(
dependency
.
specification
)
set
=
Specification
::
Set
::
External
.
new
(
dependency
.
specification
)
elsif
external_source
=
dependency
.
external_source
elsif
dependency
.
external_source
if
update_external_specs
set
=
set_from_external_source
(
dependency
,
platform
)
external_source
=
ExternalSources
.
from_dependency
(
dependency
)
spec
=
external_source
.
specification_from_external
(
@sandbox
,
platform
)
else
else
external_source
=
ExternalSources
.
from_dependency
(
dependency
)
set
=
cached_sources
.
search
(
dependency
)
spec
=
external_source
.
specification_from_sandbox
(
@sandbox
,
platform
)
end
end
set
=
Specification
::
Set
::
External
.
new
(
spec
)
cached_sets
[
name
]
=
set
if
dependency
.
subspec_dependency?
@cached_sets
[
dependency
.
root_name
]
||=
set
end
end
set
cached_sets
[
name
]
else
cached_sources
.
search
(
dependency
)
end
end
# Returns a new set created from an external source
#
def
set_from_external_source
(
dependency
,
platform
)
source
=
ExternalSources
.
from_dependency
(
dependency
)
spec
=
if
update_external_specs
source
.
specification_from_external
(
@sandbox
,
platform
)
else
source
.
specification_from_sandbox
(
@sandbox
,
platform
)
end
end
set
=
Specification
::
Set
::
External
.
new
(
spec
)
set
end
end
# @return [void] Ensures that a spec is compatible with the platform of a
# Ensures that a spec is compatible with the platform of a target.
# target.
#
#
# @raises If the spec is not supported by the target.
# @raises If the spec is not supported by the target.
#
#
# @return [void]
#
def
validate_platform
(
spec
,
target
)
def
validate_platform
(
spec
,
target
)
unless
spec
.
available_platforms
.
any?
{
|
p
latform
|
target
.
platform
.
supports?
(
platform
)
}
unless
spec
.
available_platforms
.
any?
{
|
p
|
target
.
platform
.
supports?
(
p
)
}
raise
Informative
,
"The platform of the target `
#{
target
.
name
}
' "
\
raise
Informative
,
"The platform of the target `
#{
target
.
name
}
` "
\
"(
#{
target
.
platform
}
) is not compatible with `
#{
spec
}
' which "
\
"(
#{
target
.
platform
}
) is not compatible with `
#{
spec
}
` which has "
\
"
has
a minimum requirement of
#{
spec
.
available_platforms
.
join
(
' - '
)
}
."
"a minimum requirement of
#{
spec
.
available_platforms
.
join
(
' - '
)
}
."
end
end
end
end
end
end
...
...
spec/unit/resolver_spec.rb
View file @
1baebf67
...
@@ -2,90 +2,104 @@ require File.expand_path('../../spec_helper', __FILE__)
...
@@ -2,90 +2,104 @@ require File.expand_path('../../spec_helper', __FILE__)
module
Pod
module
Pod
describe
Resolver
do
describe
Resolver
do
describe
"In general"
do
before
do
before
do
config
.
repos_dir
=
fixture
(
'spec-repos'
)
config
.
repos_dir
=
fixture
(
'spec-repos'
)
@podfile
=
Podfile
.
new
do
@podfile
=
Podfile
.
new
do
platform
:ios
platform
:ios
pod
'BlocksKit'
,
'1.5.2'
pod
'BlocksKit'
,
'1.5.2'
end
end
@resolver
=
Resolver
.
new
(
config
.
sandbox
,
@podfile
)
locked_deps
=
[
Dependency
.
new
(
'BlocksKit'
,
'1.5.2'
)]
@resolver
=
Resolver
.
new
(
config
.
sandbox
,
@podfile
,
locked_deps
)
end
end
it
"holds the context state, such as cached specification sets"
do
it
"returns the sandbox"
do
@resolver
.
resolve
@resolver
.
sandbox
.
should
==
config
.
sandbox
cached_sets
=
@resolver
.
send
(
:cached_sets
)
cached_sets
.
values
.
sort_by
(
&
:name
).
should
==
[
Source
.
search_by_name
(
'A2DynamicDelegate'
).
first
,
Source
.
search_by_name
(
'BlocksKit'
).
first
,
Source
.
search_by_name
(
'libffi'
).
first
].
sort_by
(
&
:name
)
end
end
it
"returns all specs needed for the dependency"
do
it
"returns the podfile"
do
specs
=
@resolver
.
resolve
.
values
.
flatten
@resolver
.
podfile
.
should
==
@podfile
specs
.
map
(
&
:class
).
uniq
.
should
==
[
Specification
]
specs
.
map
(
&
:name
).
sort
.
should
==
%w{ A2DynamicDelegate BlocksKit libffi }
end
end
it
"does not raise if all dependencies match the platform of the root spec (Podfile)"
do
it
"returns the locked dependencies"
do
@podfile
.
platform
:ios
,
'6.0'
@resolver
.
locked_dependencies
.
should
==
[
Dependency
.
new
(
'BlocksKit'
,
'1.5.2'
)]
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
@podfile
.
platform
:osx
,
'10.7'
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
end
end
it
"raises once any of the dependencies does not match the platform of its podfile target"
do
it
"allows to specify whether the external sources should be updated against the remote"
do
set
=
Source
.
search_by_name
(
'BlocksKit'
).
first
# TODO
cached_sets
=
@resolver
.
send
(
:cached_sets
)
@resolver
.
update_external_specs
=
true
@resolver
.
stubs
(
:cached_sets
).
returns
({
'BlocksKit'
=>
set
})
@resolver
.
update_external_specs
.
should
.
be
.
true
end
def
set
.
stub_platform
=
(
platform
);
@stubbed_platform
=
platform
;
end
#--------------------------------------#
def
set
.
specification
;
spec
=
super
;
spec
.
platform
=
@stubbed_platform
;
spec
;
end
@podfile
.
platform
:ios
it
"resolves the specification of the podfile"
do
set
.
stub_platform
=
:ios
target_definition
=
@podfile
.
target_definitions
[
:default
]
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
specs
=
@resolver
.
resolve
[
target_definition
]
set
.
stub_platform
=
:osx
specs
.
map
(
&
:to_s
).
should
==
[
lambda
{
@resolver
.
resolve
}.
should
.
raise
Pod
::
StandardError
"A2DynamicDelegate (2.0.2)"
,
"BlocksKit (1.5.2)"
,
"libffi (3.0.11)"
]
end
@podfile
.
platform
:osx
it
"returns the resolved specifications grouped by target definition"
do
set
.
stub_platform
=
:osx
@resolver
.
resolve
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
target_definition
=
@podfile
.
target_definitions
[
:default
]
set
.
stub_platform
=
:ios
specs
=
@resolver
.
specs_by_target
[
target_definition
]
lambda
{
@resolver
.
resolve
}.
should
.
raise
Pod
::
StandardError
specs
.
map
(
&
:to_s
).
should
==
[
"A2DynamicDelegate (2.0.2)"
,
"BlocksKit (1.5.2)"
,
"libffi (3.0.11)"
]
end
end
it
"raises once any of the dependencies does not have a deployment_target compatible with its podfile target"
do
it
"returns all the resolved specifications"
do
set
=
Source
.
search_by_name
(
'BlocksKit'
).
first
@resolver
.
resolve
@resolver
.
stubs
(
:cached_sets
).
returns
({
'BlocksKit'
=>
set
})
@resolver
.
specs
.
map
(
&
:class
).
uniq
.
should
==
[
Specification
]
@podfile
.
platform
:ios
,
"4.0"
@resolver
.
specs
.
map
(
&
:to_s
).
should
==
[
"A2DynamicDelegate (2.0.2)"
,
"BlocksKit (1.5.2)"
,
"libffi (3.0.11)"
]
end
Specification
.
any_instance
.
stubs
(
:available_platforms
).
returns
([
Platform
.
new
(
:ios
,
'4.0'
),
Platform
.
new
(
:osx
,
'10.7'
)
])
xit
"returns the specifications that originated from external sources"
do
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
Specification
.
any_instance
.
stubs
(
:available_platforms
).
returns
([
Platform
.
new
(
:ios
,
'5.0'
),
Platform
.
new
(
:osx
,
'10.7'
)
])
lambda
{
@resolver
.
resolve
}.
should
.
raise
Pod
::
StandardError
end
end
end
#-------------------------------------------------------------------------#
it
"resolves subspecs"
do
describe
"Resolution"
do
before
do
config
.
repos_dir
=
fixture
(
'spec-repos'
)
@podfile
=
Podfile
.
new
do
@podfile
=
Podfile
.
new
do
platform
:ios
platform
:ios
,
'6.0'
pod
'RestKit/Network'
pod
'BlocksKit'
,
'1.5.2'
pod
'RestKit/ObjectMapping/XML'
end
end
resolver
=
Resolver
.
new
(
@podfile
,
nil
,
stub
(
'sandbox'
))
@resolver
=
Resolver
.
new
(
config
.
sandbox
,
@podfile
)
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
.
should
==
%w{
end
FileMD5Hash
ISO8601DateFormatter
LibComponentLogging-Core
it
"holds the context state, such as cached specification sets"
do
LibComponentLogging-NSLog
@resolver
.
resolve
NSData+Base64
cached_sets
=
@resolver
.
send
(
:cached_sets
)
RestKit/Network
cached_sets
.
values
.
sort_by
(
&
:name
).
should
==
[
RestKit/ObjectMapping/XML
Source
.
search_by_name
(
'A2DynamicDelegate'
).
first
,
SOCKit
Source
.
search_by_name
(
'BlocksKit'
).
first
,
XMLReader
Source
.
search_by_name
(
'libffi'
).
first
cocoa-oauth
].
sort_by
(
&
:name
)
}
end
it
"raises once any of the dependencies does not match the platform of its podfile target"
do
Specification
.
any_instance
.
stubs
(
:available_platforms
).
returns
([
Platform
.
new
(
:ios
,
'999'
)])
e
=
lambda
{
@resolver
.
resolve
}.
should
.
raise
Informative
e
.
message
.
should
.
match
(
/platform .* not compatible/
)
end
it
"does not raise if all dependencies are supported by the platform of the target definition"
do
lambda
{
@resolver
.
resolve
}.
should
.
not
.
raise
end
end
it
"includes all the subspecs of a specification node"
do
it
"includes all the subspecs of a specification node"
do
...
@@ -93,7 +107,7 @@ module Pod
...
@@ -93,7 +107,7 @@ module Pod
platform
:ios
platform
:ios
pod
'RestKit'
pod
'RestKit'
end
end
resolver
=
Resolver
.
new
(
@podfile
,
nil
,
stub
(
'sandbox'
)
)
resolver
=
Resolver
.
new
(
config
.
sandbox
,
@podfile
)
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
.
should
==
%w{
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
.
should
==
%w{
FileMD5Hash
FileMD5Hash
ISO8601DateFormatter
ISO8601DateFormatter
...
@@ -112,58 +126,6 @@ module Pod
...
@@ -112,58 +126,6 @@ module Pod
}
}
end
end
# TODO inline podspecs are deprecated
xit
"it includes only the main subspec of a specification node"
do
spec
=
Spec
.
new
do
|
s
|
s
.
name
=
'RestKit'
s
.
version
=
'9999990.10.0'
s
.
preferred_dependency
=
'JSON'
s
.
subspec
'JSON'
do
|
js
|
js
.
dependency
'RestKit/Network'
js
.
dependency
'RestKit/UI'
js
.
dependency
'RestKit/ObjectMapping/JSON'
js
.
dependency
'RestKit/ObjectMapping/CoreData'
end
s
.
subspec
'Network'
do
|
ns
|
ns
.
dependency
'LibComponentLogging-NSLog'
,
'>= 1.0.4'
end
s
.
subspec
'UI'
s
.
subspec
'ObjectMapping'
do
|
os
|
os
.
subspec
'JSON'
os
.
subspec
'XML'
os
.
subspec
'CoreData'
end
end
@podfile
=
Podfile
.
new
do
platform
:ios
pod
'RestKit'
end
Set
.
any_instance
.
stubs
(
:specification
).
returns
(
spec
)
resolver
=
Resolver
.
new
(
@podfile
,
nil
,
stub
(
'sandbox'
))
resolver
.
find_cached_set
()
specs
=
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
specs
.
should
.
not
.
include
'RestKit/ObjectMapping/XML'
spec
=
resolver
.
specs_by_target
.
values
.
first
.
first
spec
.
name
.
should
==
'test'
spec
.
version
.
should
==
'9999990.10.0'
specs
.
should
==
%w{
LibComponentLogging-Core
LibComponentLogging-NSLog
RestKit
RestKit/JSON
RestKit/Network
RestKit/ObjectMapping/CoreData
RestKit/ObjectMapping/JSON
RestKit/UI
}
end
it
"resolves subspecs with external constraints"
do
it
"resolves subspecs with external constraints"
do
@podfile
=
Podfile
.
new
do
@podfile
=
Podfile
.
new
do
platform
:ios
platform
:ios
...
@@ -185,7 +147,7 @@ module Pod
...
@@ -185,7 +147,7 @@ module Pod
end
end
end
end
ExternalSources
::
GitSource
.
any_instance
.
stubs
(
:specification_from_sandbox
).
returns
(
spec
)
ExternalSources
::
GitSource
.
any_instance
.
stubs
(
:specification_from_sandbox
).
returns
(
spec
)
resolver
=
Resolver
.
new
(
@podfile
,
nil
,
stub
(
'sandbox'
)
)
resolver
=
Resolver
.
new
(
config
.
sandbox
,
@podfile
)
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
.
should
==
%w{ MainSpec/FirstSubSpec MainSpec/FirstSubSpec/SecondSubSpec }
resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
sort
.
should
==
%w{ MainSpec/FirstSubSpec MainSpec/FirstSubSpec/SecondSubSpec }
end
end
...
@@ -195,257 +157,253 @@ module Pod
...
@@ -195,257 +157,253 @@ module Pod
pod
'FileMD5Hash'
pod
'FileMD5Hash'
pod
'JSONKit'
,
:head
pod
'JSONKit'
,
:head
end
end
resolver
=
Resolver
.
new
(
podfile
,
nil
,
stub
(
'sandbox'
)
)
resolver
=
Resolver
.
new
(
config
.
sandbox
,
podfile
)
filemd5hash
,
jsonkit
=
resolver
.
resolve
.
values
.
first
.
sort_by
(
&
:name
)
filemd5hash
,
jsonkit
=
resolver
.
resolve
.
values
.
first
.
sort_by
(
&
:name
)
filemd5hash
.
version
.
should
.
not
.
be
.
head
filemd5hash
.
version
.
should
.
not
.
be
.
head
jsonkit
.
version
.
should
.
be
.
head
jsonkit
.
version
.
should
.
be
.
head
end
end
it
"accepts a nil lockfile"
do
lambda
{
Resolver
.
new
(
@podfile
,
nil
,
stub
(
'sandbox'
))}.
should
.
not
.
raise
end
it
"raises if it finds two conflicting dependencies"
do
it
"raises if it finds two conflicting dependencies"
do
podfile
=
Podfile
.
new
do
podfile
=
Podfile
.
new
do
platform
:ios
platform
:ios
pod
'JSONKit'
,
"1.4"
pod
'JSONKit'
,
"1.4"
pod
'JSONKit'
,
"1.5pre"
pod
'JSONKit'
,
"1.5pre"
end
end
resolver
=
Resolver
.
new
(
podfile
,
nil
,
stub
(
'sandbox'
))
resolver
=
Resolver
.
new
(
config
.
sandbox
,
podfile
)
lambda
{
resolver
.
resolve
}.
should
.
raise
Pod
::
StandardError
e
=
lambda
{
resolver
.
resolve
}.
should
.
raise
Pod
::
StandardError
e
.
message
.
should
.
match
(
/already activated version/
)
end
# describe "Concerning Installation mode" do
# before do
# config.repos_dir = fixture('spec-repos')
# @podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit', '1.5.2'
# pod 'JSONKit'
# end
# @specs = [
# Specification.new do |s|
# s.name = "BlocksKit"
# s.version = "1.5.2"
# end,
# Specification.new do |s|
# s.name = "JSONKit"
# s.version = "1.4"
# end ]
# @specs.each { |s| s.activate_platform(:ios) }
# @resolver = Resolver.new(@podfile, @lockfile, stub('sandbox'))
# end
# it "doesn't install pods still compatible with the Podfile" do
# @resolver.resolve
# @resolver.should_install?("BlocksKit").should.be.false
# @resolver.should_install?("JSONKit").should.be.false
# end
# it "doesn't 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
# it "doesn't include pods removed from the Podfile" do
# podfile = Podfile.new { platform :ios; pod 'JSONKit' }
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve.values.flatten.map(&:name).should == %w{ JSONKit }
# end
# it "reinstalls pods updated in the Podfile" do
# podfile = Podfile.new do
# platform :ios
# pod 'JSONKit', '1.5pre'
# pod 'BlocksKit', '1.5.2'
# end
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# installed = @resolver.resolve.values.flatten.map(&:to_s)
# installed.should.include? "BlocksKit (1.5.2)"
# installed.should.include? "JSONKit (1.5pre)"
# end
# it "installs pods added to the Podfile" do
# podfile = Podfile.new do
# platform :ios
# pod 'JSONKit'
# pod 'BlocksKit'
# pod 'libPusher', '1.3' # New pod
# end
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# installed = @resolver.resolve.values.flatten.map(&:to_s)
# installed.should.include? "libPusher (1.3)"
# end
# it "handles head pods" do
# podfile = Podfile.new do
# platform :ios
# pod 'JSONKit', :head # Existing pod switched to head mode
# pod 'libPusher', :head # New pod
# end
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# @resolver.should_install?("JSONKit").should.be.true
# @resolver.should_install?("libPusher").should.be.true
# end
# it "handles pods from external dependencies" do
# podfile = Podfile.new do
# platform :ios
# pod 'libPusher', :git => 'GIT-URL'
# end
# spec = Spec.new do |s|
# s.name = 'libPusher'
# s.version = '1.3'
# end
# ExternalSources::GitSource.any_instance.stubs(:specification_from_sandbox).returns(spec)
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# @resolver.should_install?("JSONKit").should.be.false
# end
# it "doesn't updates the repos if there no change in the pods" do
# podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit'
# pod 'JSONKit'
# end
# config.skip_repo_update = false
# Command::Repo.any_instance.expects(:run).never
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# end
# it "updates the repos if there is a new pod" do
# podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit'
# pod 'JSONKit'
# pod 'libPusher' # New pod
# end
# config.skip_repo_update = false
# Command::Repo::Update.any_instance.expects(:run).once
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# end
# it "doesn't update the repos if config indicate to skip it in any case" do
# podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit'
# pod 'JSONKit', :head #changed to head
# pod 'libPusher' # New pod
# end
# config.skip_repo_update = true
# Command::Repo::Update.any_instance.expects(:run).never
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# end
# it "updates the repos if there is a new pod" do
# podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit'
# pod 'JSONKit', :head #changed to head
# end
# config.skip_repo_update = false
# Command::Repo::Update.any_instance.expects(:run).once
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.resolve
# end
# end
# describe "Concerning Update mode" do
# before do
# config.repos_dir = fixture('spec-repos')
# previous_podfile = Podfile.new do
# platform :ios
# pod 'JSONKit'
# pod 'libPusher'
# end
# @specs = [
# Specification.new do |s|
# s.name = "libPusher"
# s.version = "1.3"
# end,
# Specification.new do |s|
# s.name = "JSONKit"
# s.version = "1.4"
# end ]
# @specs.each { |s| s.activate_platform(:ios) }
# @lockfile = Lockfile.generate(previous_podfile, @specs)
# @podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit', '1.5.2'
# pod 'JSONKit'
# pod 'libPusher'
# end
# @resolver = Resolver.new(@podfile, @lockfile, stub('sandbox'))
# @resolver.update_mode = true
# end
# it "identifies the pods that can be updated" do
# installed = @resolver.resolve.values.flatten.map(&:to_s)
# installed.should.include? "JSONKit (999.999.999)"
# @resolver.should_install?("JSONKit").should.be.true
# end
# it "respects the constraints of the podfile" do
# podfile = Podfile.new do
# platform :ios
# pod 'BlocksKit', '1.5.2'
# pod 'JSONKit', '1.4'
# end
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.update_mode = true
# installed = @resolver.resolve.values.flatten.map(&:to_s)
# installed.should.include? "JSONKit (1.4)"
# @resolver.should_install?("JSONKit").should.be.false
# end
# it "installs new pods" do
# installed = @resolver.resolve.values.flatten.map(&:to_s)
# installed.join(' ').should.include?('BlocksKit')
# @resolver.should_install?("BlocksKit").should.be.true
# end
# it "it always suggests to update pods in head mode" do
# podfile = Podfile.new do
# platform :ios
# pod 'libPusher', :head
# end
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.update_mode = true
# @resolver.resolve
# @resolver.should_install?("libPusher").should.be.true
# end
# it "always updates the repos even if there is change in the pods" do
# podfile = Podfile.new do
# platform :ios
# pod 'JSONKit'
# pod 'libPusher'
# end
# config.skip_repo_update = false
# Command::Repo::Update.any_instance.expects(:run).once
# @resolver = Resolver.new(podfile, @lockfile, stub('sandbox'))
# @resolver.update_mode = true
# @resolver.resolve
# end
# # TODO: stub the specification resolution for the sandbox
# 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
describe
"Concerning Installation mode"
do
before
do
config
.
repos_dir
=
fixture
(
'spec-repos'
)
@podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
,
'1.5.2'
pod
'JSONKit'
end
@specs
=
[
Specification
.
new
do
|
s
|
s
.
name
=
"BlocksKit"
s
.
version
=
"1.5.2"
end
,
Specification
.
new
do
|
s
|
s
.
name
=
"JSONKit"
s
.
version
=
"1.4"
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@lockfile
=
Lockfile
.
generate
(
@podfile
,
@specs
)
@resolver
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
end
it
"doesn't install pods still compatible with the Podfile"
do
@resolver
.
resolve
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
false
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
it
"doesn't 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
it
"doesn't include pods removed from the Podfile"
do
podfile
=
Podfile
.
new
{
platform
:ios
;
pod
'JSONKit'
}
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:name
).
should
==
%w{ JSONKit }
end
it
"reinstalls pods updated in the Podfile"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'JSONKit'
,
'1.5pre'
pod
'BlocksKit'
,
'1.5.2'
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"BlocksKit (1.5.2)"
installed
.
should
.
include?
"JSONKit (1.5pre)"
end
it
"installs pods added to the Podfile"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'JSONKit'
pod
'BlocksKit'
pod
'libPusher'
,
'1.3'
# New pod
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"libPusher (1.3)"
end
it
"handles head pods"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'JSONKit'
,
:head
# Existing pod switched to head mode
pod
'libPusher'
,
:head
# New pod
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
true
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
end
it
"handles pods from external dependencies"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'libPusher'
,
:git
=>
'GIT-URL'
end
spec
=
Spec
.
new
do
|
s
|
s
.
name
=
'libPusher'
s
.
version
=
'1.3'
end
ExternalSources
::
GitSource
.
any_instance
.
stubs
(
:specification_from_sandbox
).
returns
(
spec
)
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
it
"doesn't updates the repos if there no change in the pods"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
pod
'JSONKit'
end
config
.
skip_repo_update
=
false
Command
::
Repo
.
any_instance
.
expects
(
:run
).
never
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
end
it
"updates the repos if there is a new pod"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
pod
'JSONKit'
pod
'libPusher'
# New pod
end
config
.
skip_repo_update
=
false
Command
::
Repo
::
Update
.
any_instance
.
expects
(
:run
).
once
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
end
it
"doesn't update the repos if config indicate to skip it in any case"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
pod
'JSONKit'
,
:head
#changed to head
pod
'libPusher'
# New pod
end
config
.
skip_repo_update
=
true
Command
::
Repo
::
Update
.
any_instance
.
expects
(
:run
).
never
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
end
it
"updates the repos if there is a new pod"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
pod
'JSONKit'
,
:head
#changed to head
end
config
.
skip_repo_update
=
false
Command
::
Repo
::
Update
.
any_instance
.
expects
(
:run
).
once
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
resolve
end
end
describe
"Concerning Update mode"
do
before
do
config
.
repos_dir
=
fixture
(
'spec-repos'
)
previous_podfile
=
Podfile
.
new
do
platform
:ios
pod
'JSONKit'
pod
'libPusher'
end
@specs
=
[
Specification
.
new
do
|
s
|
s
.
name
=
"libPusher"
s
.
version
=
"1.3"
end
,
Specification
.
new
do
|
s
|
s
.
name
=
"JSONKit"
s
.
version
=
"1.4"
end
]
@specs
.
each
{
|
s
|
s
.
activate_platform
(
:ios
)
}
@lockfile
=
Lockfile
.
generate
(
previous_podfile
,
@specs
)
@podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
,
'1.5.2'
pod
'JSONKit'
pod
'libPusher'
end
@resolver
=
Resolver
.
new
(
@podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
end
it
"identifies the pods that can be updated"
do
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"JSONKit (999.999.999)"
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
true
end
it
"respects the constraints of the podfile"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'BlocksKit'
,
'1.5.2'
pod
'JSONKit'
,
'1.4'
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
should
.
include?
"JSONKit (1.4)"
@resolver
.
should_install?
(
"JSONKit"
).
should
.
be
.
false
end
it
"installs new pods"
do
installed
=
@resolver
.
resolve
.
values
.
flatten
.
map
(
&
:to_s
)
installed
.
join
(
' '
).
should
.
include?
(
'BlocksKit'
)
@resolver
.
should_install?
(
"BlocksKit"
).
should
.
be
.
true
end
it
"it always suggests to update pods in head mode"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'libPusher'
,
:head
end
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
@resolver
.
resolve
@resolver
.
should_install?
(
"libPusher"
).
should
.
be
.
true
end
it
"always updates the repos even if there is change in the pods"
do
podfile
=
Podfile
.
new
do
platform
:ios
pod
'JSONKit'
pod
'libPusher'
end
config
.
skip_repo_update
=
false
Command
::
Repo
::
Update
.
any_instance
.
expects
(
:run
).
once
@resolver
=
Resolver
.
new
(
podfile
,
@lockfile
,
stub
(
'sandbox'
))
@resolver
.
update_mode
=
true
@resolver
.
resolve
end
# TODO: stub the specification resolution for the sandbox
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
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