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
3cfb3053
Commit
3cfb3053
authored
Feb 22, 2013
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new class Analyzer::SandboxAnalyzer
parent
d7c82883
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
421 additions
and
40 deletions
+421
-40
installer.rb
lib/cocoapods/installer.rb
+0
-6
analyzer.rb
lib/cocoapods/installer/analyzer.rb
+12
-33
sandbox_analyzer.rb
lib/cocoapods/installer/analyzer/sandbox_analyzer.rb
+231
-0
inter_process_communication_spec.rb
spec/functional/command/inter_process_communication_spec.rb
+1
-1
sandbox_analyzer_spec.rb
spec/unit/installer/analyzer/sandbox_analyzer_spec.rb
+177
-0
No files found.
lib/cocoapods/installer.rb
View file @
3cfb3053
...
...
@@ -171,9 +171,6 @@ module Pod
#
# @todo [#534] Detect if the folder of a Pod is empty (even if it exits).
#
# @todo There could be issues with the current implementation regarding
# external specs.
#
def
detect_pods_to_install
names
=
[]
...
...
@@ -214,9 +211,6 @@ module Pod
#
# @todo [#247] Clean the headers of only the pods to install.
#
# @todo Clean the podspecs of all the pods that aren't unchanged so the
# resolution process doesn't get confused by them.
#
def
clean_sandbox
sandbox
.
build_headers
.
implode!
sandbox
.
public_headers
.
implode!
...
...
lib/cocoapods/installer/analyzer.rb
View file @
3cfb3053
...
...
@@ -8,6 +8,8 @@ module Pod
include
Config
::
Mixin
autoload
:SandboxAnalyzer
,
'cocoapods/installer/analyzer/sandbox_analyzer'
# @return [Sandbox] The sandbox where the Pods should be installed.
#
attr_reader
:sandbox
...
...
@@ -200,11 +202,14 @@ module Pod
# that prevent the resolver to update a Pod.
#
def
generate_version_locking_dependencies
return
[]
if
update_mode?
if
update_mode?
[]
else
result
.
podfile_state
.
unchanged
.
map
do
|
pod
|
lockfile
.
dependency_to_lock_pod_named
(
pod
)
end
end
end
# Converts the Podfile in a list of specifications grouped by target.
#
...
...
@@ -291,39 +296,10 @@ module Pod
# specifications.
#
def
generate_sandbox_state
sandbox_lockfile
=
sandbox
.
manifest
||
lockfile
sandbox_state
=
SpecsState
.
new
sandbox_state
=
nil
UI
.
section
"Comparing resolved specification to the sandbox manifest"
do
resolved_subspecs_names
=
result
.
specifications
.
group_by
{
|
s
|
s
.
root
.
name
}
resolved_names
=
resolved_subspecs_names
.
keys
if
sandbox_lockfile
sandbox_subspecs_names
=
sandbox_lockfile
.
pod_names
.
group_by
{
|
name
|
Specification
.
root_name
(
name
)
}
sandbox_names
=
sandbox_subspecs_names
.
keys
all_names
=
(
resolved_names
+
sandbox_names
).
uniq
.
sort
root_specs
=
result
.
specifications
.
map
(
&
:root
).
uniq
is_changed
=
lambda
do
|
name
|
spec
=
root_specs
.
find
{
|
r_spec
|
r_spec
.
name
==
name
}
spec
.
version
!=
sandbox_lockfile
.
version
(
name
)
\
||
spec
.
checksum
!=
sandbox_lockfile
.
checksum
(
name
)
\
||
resolved_subspecs_names
[
name
]
=!
sandbox_subspecs_names
[
name
]
\
end
all_names
.
each
do
|
name
|
state
=
case
when
resolved_names
.
include?
(
name
)
&&
!
sandbox_names
.
include?
(
name
)
then
:added
when
!
resolved_names
.
include?
(
name
)
&&
sandbox_names
.
include?
(
name
)
then
:deleted
when
is_changed
.
call
(
name
)
then
:changed
else
:unchanged
end
sandbox_state
.
add_name
(
name
,
state
)
end
else
sandbox_state
.
added
.
concat
(
resolved_names
)
end
sandbox_analyzer
=
SandboxAnalyzer
.
new
(
sandbox
,
result
.
specifications
,
update_mode
,
lockfile
)
sandbox_state
=
sandbox_analyzer
.
analyze
sandbox_state
.
print
end
sandbox_state
...
...
@@ -493,6 +469,9 @@ module Pod
# @note The names of the pods stored by this class are always the **root**
# name of the specification.
#
# @note The motivation for this class is to ensure that the names of the
# subspecs are added instead of the name of the Pods.
#
class
SpecsState
# @param [Hash{Symbol=>String}] pods_by_state
...
...
lib/cocoapods/installer/analyzer/sandbox_analyzer.rb
0 → 100644
View file @
3cfb3053
module
Pod
class
Installer
class
Analyzer
# Analyze the sandbox to detect which Pods should be removed, and which
# ones should be reinstalled.
#
class
SandboxAnalyzer
# @return [Sandbox] The sandbox to analyze.
#
attr_reader
:sandbox
# @return [Array<Specifications>] The specifications returned by the
# resolver.
#
attr_reader
:specs
# @return [Bool] Whether the installation is performed in update mode.
#
attr_reader
:update_mode
# @return [Lockfile] The lockfile of the installation as a fall-back if
# there is no sandbox manifest. This is indented as a temporary
# solution to prevent the full re-installation from users which
# are upgrading from CP < 0.17.
#
# @todo Remove for CP 0.18.
#
attr_reader
:lockfile
# @param [Sandbox] sandbox @see sandbox
# @param [Array<Specifications>] specs @see specs
# @param [Bool] update_mode @see update_mode
# @param [Lockfile] lockfile @see lockfile
#
def
initialize
(
sandbox
,
specs
,
update_mode
,
lockfile
=
nil
)
@sandbox
=
sandbox
@specs
=
specs
@update_mode
=
update_mode
@lockfile
=
lockfile
end
# Performs the analysis to the detect the state of the sandbox respect
# to the resolved specifications.
#
# @return [SpecsState] the state of the sandbox.
#
def
analyze
state
=
SpecsState
.
new
if
sandbox_manifest
all_names
=
(
resolved_pods
+
sandbox_pods
).
uniq
.
sort
all_names
.
sort
.
each
do
|
name
|
state
.
add_name
(
name
,
pod_state
(
name
))
end
else
state
.
added
.
concat
(
resolved_pods
)
end
state
end
#---------------------------------------------------------------------#
private
# @!group Pod state
# Returns the state of the Pod with the given name.
#
# @param [String] pod
# the name of the Pod.
#
# @return [Symbol] The state
#
def
pod_state
(
pod
)
return
:added
if
pod_added?
(
pod
)
return
:deleted
if
pod_deleted?
(
pod
)
return
:changed
if
pod_changed?
(
pod
)
return
:unchanged
end
# Returns whether the Pod with the given name should be installed.
#
# @note A Pod whose folder doesn't exists is considered added.
#
# @param [String] pod
# the name of the Pod.
#
# @return [Bool] Whether the Pod is added.
#
def
pod_added?
(
pod
)
return
true
if
resolved_pods
.
include?
(
pod
)
&&
!
sandbox_pods
.
include?
(
pod
)
return
true
if
!
folder_exist?
(
pod
)
return
false
end
# Returns whether the Pod with the given name should be removed from
# the installation.
#
# @param [String] pod
# the name of the Pod.
#
# @return [Bool] Whether the Pod is deleted.
#
def
pod_deleted?
(
pod
)
return
true
if
!
resolved_pods
.
include?
(
pod
)
&&
sandbox_pods
.
include?
(
pod
)
return
false
end
# Returns whether the Pod with the given name should be considered
# changed and thus should be reinstalled.
#
# @note In update mode, as there is no way to know if a remote source
# hash changed the Pods in head mode and the ones from external
# sources are always marked as changed.
#
# @note A Pod whose folder is empty is considered changed.
#
# @param [String] pod
# the name of the Pod.
#
# @return [Bool] Whether the Pod is changed.
#
def
pod_changed?
(
pod
)
spec
=
root_spec
(
pod
)
return
true
if
spec
.
version
!=
sandbox_version
(
pod
)
return
true
if
spec
.
checksum
!=
sandbox_checksum
(
pod
)
return
true
if
resolved_spec_names
(
pod
)
!=
sandbox_spec_names
(
pod
)
return
true
if
folder_empty?
(
pod
)
if
update_mode
return
true
if
spec
.
version
.
head?
# return true if sandbox.external_source?(pod) TODO
end
return
false
end
#---------------------------------------------------------------------#
private
# @!group Private helpers
# @return [Lockfile] The manifest to use for the sandbox.
#
def
sandbox_manifest
sandbox
.
manifest
||
lockfile
end
#--------------------------------------#
# @return [Array<String>] The name of the resolved Pods.
#
def
resolved_pods
specs
.
map
{
|
spec
|
spec
.
root
.
name
}.
uniq
end
# @return [Array<String>] The name of the Pods stored in the sandbox
# manifest.
#
def
sandbox_pods
sandbox_manifest
.
pod_names
.
map
{
|
name
|
Specification
.
root_name
(
name
)
}.
uniq
end
# @return [Array<String>] The name of the resolved specifications
# (includes subspecs).
#
# @param [String] pod
# the name of the Pod.
#
def
resolved_spec_names
(
pod
)
specs
.
select
{
|
s
|
s
.
root
.
name
==
pod
}.
map
(
&
:name
).
uniq
end
# @return [Array<String>] The name of the specifications stored in the
# sandbox manifest (includes subspecs).
#
# @param [String] pod
# the name of the Pod.
#
def
sandbox_spec_names
(
pod
)
sandbox_manifest
.
pod_names
.
select
{
|
name
|
Specification
.
root_name
(
name
)
==
pod
}.
uniq
end
# @return [Specification] The root specification for the Pod with the
# given name.
#
# @param [String] pod
# the name of the Pod.
#
def
root_spec
(
pod
)
specs
.
find
{
|
s
|
s
.
root
.
name
==
pod
}.
root
end
#--------------------------------------#
# @return [Version] The version of Pod with the given name stored in
# the sandbox.
#
# @param [String] pod
# the name of the Pod.
#
def
sandbox_version
(
pod
)
sandbox_manifest
.
version
(
pod
)
end
# @return [String] The checksum of the specification of the Pod with
# the given name stored in the sandbox.
#
# @param [String] pod
# the name of the Pod.
#
def
sandbox_checksum
(
pod
)
sandbox_manifest
.
checksum
(
pod
)
end
#--------------------------------------#
def
folder_exist?
(
pod
)
sandbox
.
pod_dir
(
pod
).
exist?
end
def
folder_empty?
(
pod
)
Dir
.
glob
(
sandbox
.
pod_dir
(
pod
)
+
'*'
).
empty?
end
#---------------------------------------------------------------------#
end
end
end
end
spec/functional/command/inter_process_communication_spec.rb
View file @
3cfb3053
...
...
@@ -23,7 +23,7 @@ module Pod
out
=
run_command
(
'ipc'
,
'podfile'
,
fixture
(
'Podfile'
))
out
.
should
.
include
(
'---'
)
out
.
should
.
match
/target_definitions:/
out
.
should
.
match
/platform:
:
ios/
out
.
should
.
match
/platform: ios/
out
.
should
.
match
/- SSZipArchive:/
end
...
...
spec/unit/installer/analyzer/sandbox_analyzer_spec.rb
0 → 100644
View file @
3cfb3053
require
File
.
expand_path
(
'../../../../spec_helper'
,
__FILE__
)
#-----------------------------------------------------------------------------#
module
Pod
describe
Installer
::
Analyzer
::
SandboxAnalyzer
do
before
do
@spec
=
fixture_spec
(
'banana-lib/BananaLib.podspec'
)
@sandbox
=
config
.
sandbox
lockfile_hash
=
{
'PODS'
=>
[
'BananaLib (1.0)'
]
}
@manifest
=
Pod
::
Lockfile
.
new
(
lockfile_hash
)
@sandbox
.
stubs
(
:manifest
).
returns
(
@manifest
)
@analyzer
=
Installer
::
Analyzer
::
SandboxAnalyzer
.
new
(
@sandbox
,
[
@spec
],
false
)
end
#-------------------------------------------------------------------------#
describe
"Analysis"
do
it
"returns the sandbox state"
do
@analyzer
.
stubs
(
:folder_exist?
).
returns
(
true
)
@analyzer
.
stubs
(
:folder_empty?
).
returns
(
false
)
@analyzer
.
stubs
(
:sandbox_checksum
).
returns
(
@spec
.
checksum
)
state
=
@analyzer
.
analyze
state
.
class
.
should
==
Installer
::
Analyzer
::
SpecsState
state
.
unchanged
.
should
==
[
"BananaLib"
]
end
it
"marks all the pods as added if no sandbox manifest is available"
do
@sandbox
.
stubs
(
:manifest
)
@analyzer
.
analyze
.
added
.
should
==
[
'BananaLib'
]
end
end
#-------------------------------------------------------------------------#
describe
"Analysis"
do
before
do
@analyzer
.
stubs
(
:folder_exist?
).
returns
(
true
)
@analyzer
.
stubs
(
:folder_empty?
).
returns
(
false
)
@analyzer
.
stubs
(
:sandbox_checksum
).
returns
(
@spec
.
checksum
)
end
it
"returns whether a Pod is unchanged"
do
@analyzer
.
send
(
:pod_state
,
'BananaLib'
).
should
==
:unchanged
end
it
"considers a Pod as added if it is not recorded in the sandbox manifest"
do
@analyzer
.
stubs
(
:sandbox_pods
).
returns
([])
@analyzer
.
send
(
:pod_added?
,
'BananaLib'
).
should
==
true
end
it
"considers a Pod as added if it folder doesn't exits"
do
@analyzer
.
stubs
(
:folder_exist?
).
returns
(
false
)
@analyzer
.
send
(
:pod_added?
,
'BananaLib'
).
should
==
true
end
it
"considers deleted a Pod without any resolved specification"
do
@analyzer
.
stubs
(
:resolved_pods
).
returns
([])
@analyzer
.
send
(
:pod_deleted?
,
'BananaLib'
).
should
==
true
end
it
"considers changed a Pod whose versions do not match"
do
@analyzer
.
stubs
(
:sandbox_version
).
returns
(
Version
.
new
(
999
))
@analyzer
.
send
(
:pod_changed?
,
'BananaLib'
).
should
==
true
end
it
"considers changed a Pod whose checksums do not match"
do
@analyzer
.
stubs
(
:sandbox_checksum
).
returns
(
'SHA'
)
@analyzer
.
send
(
:pod_changed?
,
'BananaLib'
).
should
==
true
end
it
"considers changed a Pod whose activated specifications do not match"
do
@analyzer
.
stubs
(
:sandbox_spec_names
).
returns
([
'BananaLib'
,
'BananaLib/Subspec'
])
@analyzer
.
send
(
:pod_changed?
,
'BananaLib'
).
should
==
true
end
it
"considers changed a Pod whose folder is empty"
do
@analyzer
.
stubs
(
:folder_empty?
).
returns
(
true
)
@analyzer
.
send
(
:pod_changed?
,
'BananaLib'
).
should
==
true
end
it
"considers changed a Pod whose specification is in head mode if in update mode"
do
@spec
.
version
.
head
=
true
@analyzer
.
stubs
(
:update_mode
).
returns
(
true
)
@analyzer
.
send
(
:pod_changed?
,
'BananaLib'
).
should
==
true
end
xit
"considers changed a Pod fetched from an external source if in update mode"
do
end
end
#-------------------------------------------------------------------------#
describe
"Private helpers"
do
it
"returns the sandbox manifest"
do
@analyzer
.
send
(
:sandbox_manifest
).
should
==
@manifest
end
it
"returns the lockfile as the sandbox if one is not available"
do
lockfile
=
Lockfile
.
new
({})
@sandbox
.
stubs
(
:manifest
)
@analyzer
.
stubs
(
:lockfile
).
returns
(
lockfile
)
@analyzer
.
send
(
:sandbox_manifest
).
should
==
lockfile
end
#--------------------------------------#
it
"returns the root name of the resolved Pods"
do
subspec
=
Spec
.
new
(
@spec
,
'Subspec'
)
@analyzer
.
stubs
(
:specs
).
returns
([
@spec
,
subspec
])
@analyzer
.
send
(
:resolved_pods
).
should
==
[
'BananaLib'
]
end
it
"returns the root name of pods stored in the sandbox manifest"
do
@manifest
.
stubs
(
:pod_names
).
returns
([
'BananaLib'
,
'BananaLib/Subspec'
])
@analyzer
.
send
(
:sandbox_pods
).
should
==
[
'BananaLib'
]
end
it
"returns the name of the resolved specifications"
do
subspec
=
Spec
.
new
(
@spec
,
'Subspec'
)
@analyzer
.
stubs
(
:specs
).
returns
([
@spec
,
subspec
])
@analyzer
.
send
(
:resolved_spec_names
,
'BananaLib'
).
should
==
[
'BananaLib'
,
'BananaLib/Subspec'
]
end
it
"returns the name of the specifications stored in the sandbox manifest"
do
@manifest
.
stubs
(
:pod_names
).
returns
([
'BananaLib'
,
'BananaLib/Subspec'
])
@analyzer
.
send
(
:sandbox_spec_names
,
'BananaLib'
).
should
==
[
'BananaLib'
,
'BananaLib/Subspec'
]
end
it
"returns the root specification for the Pod with the given name"
do
subspec
=
Spec
.
new
(
@spec
,
'Subspec'
)
@analyzer
.
stubs
(
:specs
).
returns
([
@spec
,
subspec
])
@analyzer
.
send
(
:root_spec
,
'BananaLib'
).
should
==
@spec
end
#--------------------------------------#
it
"returns the version for the Pod with the given name stored in the manifest"
do
@analyzer
.
send
(
:sandbox_version
,
'BananaLib'
).
should
==
Version
.
new
(
'1.0'
)
end
it
"returns the checksum for the spec of the Pods with the given name stored in the manifest"
do
@manifest
.
stubs
(
:checksum
).
returns
(
@spec
.
checksum
)
@analyzer
.
send
(
:sandbox_checksum
,
'BananaLib'
).
should
==
@spec
.
checksum
end
#--------------------------------------#
it
"returns whether the folder containing the Pod with the given name is empty"
do
@analyzer
.
send
(
:folder_exist?
,
'BananaLib'
).
should
.
be
.
false
path
=
temporary_directory
+
'Pods/BananaLib'
path
.
mkpath
@analyzer
.
send
(
:folder_exist?
,
'BananaLib'
).
should
.
be
.
true
end
it
"returns whether the folder containing the Pod with the given name is empty"
do
@analyzer
.
send
(
:folder_empty?
,
'BananaLib'
).
should
.
be
.
true
path
=
temporary_directory
+
'Pods/BananaLib'
path
.
mkpath
File
.
open
(
path
+
"file"
,
"w"
)
{}
@analyzer
.
send
(
:folder_empty?
,
'BananaLib'
).
should
.
be
.
false
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