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
b8160f92
Commit
b8160f92
authored
Sep 08, 2013
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PodsProjectGenerator] Improve sync logic
parent
8c401549
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
229 additions
and
121 deletions
+229
-121
pods_project_generator.rb
lib/cocoapods/installer/pods_project_generator.rb
+214
-81
pods_project_generator_spec.rb
spec/unit/installer/pods_project_generator_spec.rb
+15
-40
No files found.
lib/cocoapods/installer/pods_project_generator.rb
View file @
b8160f92
module
Pod
class
Installer
# Generates the Pods project according to the targets identified by the
# analyzer.
#
class
PodsProjectGenerator
autoload
:FileReferencesInstaller
,
'cocoapods/installer/pods_project_generator/file_references_installer'
autoload
:TargetInstaller
,
'cocoapods/installer/pods_project_generator/target_installer'
autoload
:AggregateTargetInstaller
,
'cocoapods/installer/pods_project_generator/target_installer/aggregate_target_installer'
autoload
:FileReferencesInstaller
,
'cocoapods/installer/pods_project_generator/file_references_installer'
autoload
:PodTargetInstaller
,
'cocoapods/installer/pods_project_generator/target_installer/pod_target_installer'
autoload
:TargetInstaller
,
'cocoapods/installer/pods_project_generator/target_installer'
# @return [Sandbox] The sandbox of the installation.
#
...
...
@@ -30,7 +29,7 @@ module Pod
@user_build_configurations
=
[]
end
# @return [
Pathname
] The path of the Podfile.
# @return [
Array
] The path of the Podfile.
#
attr_accessor
:podfile_path
...
...
@@ -45,10 +44,10 @@ module Pod
#
def
install
prepare_project
install_file_reference
s
install
_targets
install_system_framework
s
s
et_target_dependenc
ies
sync_pod_target
s
sync_aggregate
_targets
sync_target_dependencie
s
s
ync_aggregate_targets_librar
ies
end
# @return [Project] the generated Pods project.
...
...
@@ -59,9 +58,9 @@ module Pod
#
# @return [void]
#
def
write_p
od_p
roject
UI
.
message
"- Writing Xcode project file
to
#{
UI
.
path
sandbox
.
project_path
}
"
do
clean_up_project
def
write_project
UI
.
message
"- Writing Xcode project file"
do
project
.
prepare_for_serialization
project
.
save
end
end
...
...
@@ -77,80 +76,139 @@ module Pod
# @return [void]
#
def
prepare_project
UI
.
message
"- Creating Pods project"
do
@project
=
Pod
::
Project
.
new
(
sandbox
.
project_path
)
user_build_configurations
.
each
do
|
name
,
type
|
project
.
add_build_configuration
(
name
,
type
)
if
should_create_new_project?
UI
.
message
"- Initializing new project"
do
@project
=
Pod
::
Project
.
new
(
sandbox
.
project_path
)
@new_project
=
true
end
pod_names
=
pod_targets
.
map
(
&
:pod_name
).
uniq
pod_names
.
each
do
|
pod_name
|
path
=
sandbox
.
pod_dir
(
pod_name
)
local
=
sandbox
.
local?
(
pod_name
)
project
.
add_pod_group
(
pod_name
,
path
,
local
)
else
UI
.
message
"- Opening existing project"
do
@project
=
Pod
::
Project
.
open
(
sandbox
.
project_path
)
detect_native_targets
end
end
if
podfile_path
project
.
add_podfile
(
podfile_path
)
end
project
.
set_podfile
(
podfile_path
)
setup_build_configurations
sandbox
.
project
=
project
end
sandbox
.
project
=
@project
platforms
=
aggregate_targets
.
map
(
&
:platform
)
osx_deployment_target
=
platforms
.
select
{
|
p
|
p
.
name
==
:osx
}.
map
(
&
:deployment_target
).
min
ios_deployment_target
=
platforms
.
select
{
|
p
|
p
.
name
==
:ios
}.
map
(
&
:deployment_target
).
min
project
.
build_configurations
.
each
do
|
build_configuration
|
build_configuration
.
build_settings
[
'MACOSX_DEPLOYMENT_TARGET'
]
=
osx_deployment_target
.
to_s
if
osx_deployment_target
build_configuration
.
build_settings
[
'IPHONEOS_DEPLOYMENT_TARGET'
]
=
ios_deployment_target
.
to_s
if
ios_deployment_target
build_configuration
.
build_settings
[
'STRIP_INSTALLED_PRODUCT'
]
=
'NO'
# Matches the native targets of the Pods project with the targets
# generated by the analyzer.
#
# @return [void]
#
def
detect_native_targets
UI
.
message
"- Matching targets"
do
p
native_targets_by_name
=
project
.
targets
.
group_by
(
&
:name
)
p
cp_targets
=
aggregate_targets
+
all_pod_targets
cp_targets
.
each
do
|
pod_target
|
native_targets
=
native_targets_by_name
[
pod_target
.
label
]
if
native_targets
pod_target
.
target
=
native_targets
.
first
end
end
end
end
# Installs the file references in the Pods project. This is done once per
# Pod as the same file reference might be shared by multiple aggregate
# targets.
#
# @return [void]
#
def
install_file_references
installer
=
FileReferencesInstaller
.
new
(
sandbox
,
pod_targets
,
project
)
installer
.
install!
def
sync_pod_targets
pods_to_remove
.
each
do
|
name
|
remove_pod
(
name
)
end
pods_to_install
.
each
do
|
name
|
add_pod
(
name
)
end
end
# Installs the pods and the aggregate targets generating their support
# files.
# Adds and removes aggregate targets to the
#
# @return [void]
#
def
install_targets
UI
.
message
"- Installing Targets"
do
pod_targets
.
sort_by
(
&
:name
).
each
do
|
pod_target
|
next
if
pod_target
.
target_definition
.
empty?
target_installer
=
PodTargetInstaller
.
new
(
sandbox
,
pod_target
)
target_installer
.
install!
def
sync_aggregate_targets
targets_to_remove
=
[]
targets_to_install
.
each
do
|
target
|
add_aggregate_target
(
target
)
end
targets_to_remove
.
each
do
|
target
|
remove_aggregate_target
(
target
)
end
# TODO: clean up dependencies and linking
# TODO: clean removed targets and their support files
# TODO: clean stray and unrecognized targets
# TODO: skip empty aggregate targets
# TODO: Install aggregate targets first
# TODO: sort targets by name before serialization in the project
end
#
#
def
add_aggregate_target
(
target
)
UI
.
message
"- Installing `
#{
target
.
label
}
`"
do
# TODO: the support files should be created from scratch in any case
AggregateTargetInstaller
.
new
(
sandbox
,
target
).
install!
end
end
#
#
def
remove_aggregate_target
(
target
)
UI
.
message
"- Removing `
#{
target
.
label
}
`"
do
target
.
remove_from_project
target
.
product_reference
.
remove_from_project
project
.
support_files_group
[
target
.
name
].
remove_from_project
end
end
#
#
def
add_pod
(
name
)
UI
.
message
"- Installing `
#{
name
}
`"
do
pod_targets
=
all_pod_targets
.
select
{
|
target
|
target
.
pod_name
==
name
}
UI
.
message
"- Installing file references"
do
path
=
sandbox
.
pod_dir
(
name
)
local
=
sandbox
.
local?
(
name
)
project
.
add_pod_group
(
name
,
path
,
local
)
FileReferencesInstaller
.
new
(
sandbox
,
pod_targets
).
install!
end
aggregate_targets
.
sort_by
(
&
:name
).
each
do
|
target
|
next
if
target
.
target_definition
.
empty?
target_installer
=
AggregateTargetInstaller
.
new
(
sandbox
,
target
)
target_installer
.
install!
pod_targets
.
each
do
|
pod_
target
|
UI
.
message
"- Installing targets"
do
PodTargetInstaller
.
new
(
sandbox
,
pod_target
).
install!
end
end
end
end
# Generates file references to the system frameworks used by the targets.
# This is done for informative purposes and is not needed as the
# canonical source for the build settings are the xcconfig files.
#
# @return [void]
#
def
install_system_frameworks
pod_targets
.
each
do
|
pod_target
|
pod_target
.
specs
.
each
do
|
spec
|
spec
.
consumer
(
pod_target
.
platform
).
frameworks
.
each
do
|
framework
|
project
.
add_system_framework
(
framework
,
pod_target
.
target
)
def
remove_pod
(
name
)
UI
.
message
"- Removing `
#{
name
}
`"
do
products_group
=
project
.
group_for_spec
(
name
,
:products
)
UI
.
message
"- Removing targets"
do
targets
=
project
.
targets
.
select
{
|
target
|
products_group
.
children
.
include?
(
target
.
product_reference
)
}
targets
.
each
do
|
target
|
target
.
referrers
.
each
do
|
ref
|
if
ref
.
isa
==
'PBXTargetDependency'
ref
.
remove_from_project
end
end
target
.
remove_from_project
end
end
UI
.
message
"- Removing file references"
do
group
=
project
.
pod_group
(
name
)
group
.
remove_from_project
end
end
end
...
...
@@ -159,13 +217,24 @@ module Pod
#
# @return [void]
#
def
set_target_dependencies
aggregate_targets
.
each
do
|
aggregate_target
|
aggregate_target
.
pod_targets
.
each
do
|
pod_target
|
aggregate_target
.
target
.
add_dependency
(
pod_target
.
target
)
pod_target
.
dependencies
.
each
do
|
dep
|
pod_dependency_target
=
aggregate_target
.
pod_targets
.
find
{
|
target
|
target
.
pod_name
==
dep
}
pod_target
.
target
.
add_dependency
(
pod_dependency_target
.
target
)
def
sync_target_dependencies
UI
.
message
"- Setting-up dependencies"
do
aggregate_targets
.
each
do
|
aggregate_target
|
aggregate_target
.
pod_targets
.
each
do
|
dep
|
if
dep
.
target
aggregate_target
.
target
.
add_dependency
(
dep
.
target
)
else
puts
"[BUG]
#{
dep
}
"
end
end
end
aggregate_targets
.
each
do
|
aggregate_target
|
aggregate_target
.
pod_targets
.
each
do
|
pod_target
|
dependencies
=
pod_target
.
dependencies
.
map
{
|
dep_name
|
aggregate_target
.
pod_targets
.
find
{
|
target
|
target
.
pod_name
==
dep_name
}
}
dependencies
.
each
do
|
dep
|
pod_target
.
target
.
add_dependency
(
dep
.
target
)
end
end
end
end
...
...
@@ -175,6 +244,16 @@ module Pod
#
# @return [void]
#
def
sync_aggregate_targets_libraries
UI
.
message
"- Populating aggregate targets"
do
aggregate_targets
.
each
do
|
aggregate_target
|
native_target
=
aggregate_target
.
target
aggregate_target
.
pod_targets
.
each
do
|
pod_target
|
product
=
pod_target
.
target
.
product_reference
unless
native_target
.
frameworks_build_phase
.
files_references
.
include?
(
product
)
native_target
.
frameworks_build_phase
.
add_file_reference
(
product
)
end
end
end
end
end
...
...
@@ -182,32 +261,86 @@ module Pod
private
# @!group
Write step
s
# @!group
Private Helper
s
#-----------------------------------------------------------------------#
# Cleans up the project to prepare it for serialization.
#
# @return [void]
#
def
clean_up_project
project
.
pods
.
remove_from_project
if
project
.
pods
.
empty?
project
.
development_pods
.
remove_from_project
if
project
.
development_pods
.
empty?
project
.
main_group
.
recursively_sort_by_type
def
should_create_new_project?
# TODO
incompatible
=
false
incompatible
||
!
sandbox
.
project_path
.
exist?
end
private
# @!group Private Helpers
#-----------------------------------------------------------------------#
#
#
attr_accessor
:new_project
alias_method
:new_project?
,
:new_project
# @return [Array<PodTarget>] The pod targets generated by the installation
# process.
#
def
pod_targets
def
all_
pod_targets
aggregate_targets
.
map
(
&
:pod_targets
).
flatten
end
#
#
def
pods_to_install
if
new_project
puts
"$$$ Installing all Pods"
all_pod_targets
.
map
(
&
:pod_name
).
uniq
.
sort
else
# TODO: Add missing groups
missing_target
=
all_pod_targets
.
select
{
|
pod_target
|
pod_target
.
target
.
nil?
}.
map
(
&
:pod_name
).
uniq
puts
"$$$ missing target:
#{
missing_target
}
"
puts
"$$$ sandbox.state.added:
#{
sandbox
.
state
.
added
}
"
puts
"$$$ sandbox.state.changed:
#{
sandbox
.
state
.
changed
}
"
@pods_to_install
||=
(
sandbox
.
state
.
added
|
sandbox
.
state
.
changed
|
missing_target
).
uniq
.
sort
end
end
#
#
def
pods_to_remove
return
[]
if
new_project
# TODO: Superfluous groups
@pods_to_remove
||=
(
sandbox
.
state
.
deleted
|
sandbox
.
state
.
changed
).
sort
end
def
targets_to_install
aggregate_targets
.
select
do
|
aggregate_target
|
if
new_project
true
else
missing
=
aggregate_target
.
target
.
nil?
empty
=
aggregate_target
.
target_definition
.
empty?
missing
||
empty
end
end
end
# Sets the build configuration of the Pods project according the build
# configurations of the user as detected by the analyzer and other
# default values.
#
# @return [void]
#
def
setup_build_configurations
user_build_configurations
.
each
do
|
name
,
type
|
project
.
add_build_configuration
(
name
,
type
)
end
platforms
=
aggregate_targets
.
map
(
&
:platform
)
osx_deployment_target
=
platforms
.
select
{
|
p
|
p
.
name
==
:osx
}.
map
(
&
:deployment_target
).
min
ios_deployment_target
=
platforms
.
select
{
|
p
|
p
.
name
==
:ios
}.
map
(
&
:deployment_target
).
min
project
.
build_configurations
.
each
do
|
build_configuration
|
build_configuration
.
build_settings
[
'MACOSX_DEPLOYMENT_TARGET'
]
=
osx_deployment_target
.
to_s
if
osx_deployment_target
build_configuration
.
build_settings
[
'IPHONEOS_DEPLOYMENT_TARGET'
]
=
ios_deployment_target
.
to_s
if
ios_deployment_target
build_configuration
.
build_settings
[
'STRIP_INSTALLED_PRODUCT'
]
=
'NO'
end
end
#-----------------------------------------------------------------------#
end
...
...
spec/unit/installer/pods_project_generator_spec.rb
View file @
b8160f92
...
...
@@ -17,10 +17,11 @@ module Pod
@sut
.
project
.
should
.
not
.
be
.
nil
end
it
"
can write
the pods project"
do
it
"
writes
the pods project"
do
@sut
.
send
(
:install
)
@sut
.
project
.
expects
(
:prepare_for_serialization
)
@sut
.
project
.
expects
(
:save
)
@sut
.
send
(
:write_p
od_p
roject
)
@sut
.
send
(
:write_project
)
end
end
...
...
@@ -39,7 +40,7 @@ module Pod
@sut
.
project
.
class
.
should
==
Pod
::
Project
end
it
"creates a group for each Pod"
do
x
it
"creates a group for each Pod"
do
pod_target
=
PodTarget
.
new
([],
nil
,
config
.
sandbox
)
pod_target
.
stubs
(
:pod_name
).
returns
(
'BananaLib'
)
@sut
.
stubs
(
:pod_targets
).
returns
([
pod_target
])
...
...
@@ -47,7 +48,7 @@ module Pod
@sut
.
project
[
'Pods/BananaLib'
].
should
.
not
.
be
.
nil
end
it
"creates a group for each development Pod"
do
x
it
"creates a group for each development Pod"
do
pod_target
=
PodTarget
.
new
([],
nil
,
config
.
sandbox
)
pod_target
.
stubs
(
:pod_name
).
returns
(
'BananaLib'
)
@sut
.
stubs
(
:pod_targets
).
returns
([
pod_target
])
...
...
@@ -99,7 +100,7 @@ module Pod
@sut
=
PodsProjectGenerator
.
new
(
config
.
sandbox
,
[])
end
it
"installs the file references"
do
x
it
"installs the file references"
do
Installer
::
PodsProjectGenerator
::
FileReferencesInstaller
.
any_instance
.
expects
(
:install!
)
@sut
.
send
(
:install_file_references
)
end
...
...
@@ -119,21 +120,21 @@ module Pod
@sut
=
PodsProjectGenerator
.
new
(
config
.
sandbox
,
[
aggregate_target
])
end
it
"install the aggregate targets"
do
x
it
"install the aggregate targets"
do
@target_definition
.
store_pod
(
'BananaLib'
)
Installer
::
PodsProjectGenerator
::
PodTargetInstaller
.
any_instance
.
stubs
(
:install!
)
Installer
::
PodsProjectGenerator
::
AggregateTargetInstaller
.
any_instance
.
expects
(
:install!
)
@sut
.
send
(
:install_targets
)
end
it
"install the Pod targets"
do
x
it
"install the Pod targets"
do
@target_definition
.
store_pod
(
'BananaLib'
)
Installer
::
PodsProjectGenerator
::
AggregateTargetInstaller
.
any_instance
.
stubs
(
:install!
)
Installer
::
PodsProjectGenerator
::
PodTargetInstaller
.
any_instance
.
expects
(
:install!
)
@sut
.
send
(
:install_targets
)
end
it
"skips empty targets"
do
x
it
"skips empty targets"
do
Installer
::
PodsProjectGenerator
::
PodTargetInstaller
.
any_instance
.
expects
(
:install!
).
never
Installer
::
PodsProjectGenerator
::
PodTargetInstaller
.
any_instance
.
expects
(
:install!
).
never
@sut
.
send
(
:install_targets
)
...
...
@@ -158,7 +159,7 @@ module Pod
@sut
.
send
(
:prepare_project
)
end
it
'adds the frameworks required by to the pod to the project for informative purposes'
do
x
it
'adds the frameworks required by to the pod to the project for informative purposes'
do
Project
.
any_instance
.
expects
(
:add_system_framework
).
with
(
'QuartzCore'
,
@pod_native_target
)
@sut
.
send
(
:install_system_frameworks
)
end
...
...
@@ -166,7 +167,7 @@ module Pod
#-----------------------------------------------------------------------#
describe
"#s
et
_target_dependencies"
do
describe
"#s
ync
_target_dependencies"
do
before
do
project
=
Pod
::
Project
.
new
(
config
.
sandbox
.
project_path
)
...
...
@@ -187,14 +188,14 @@ module Pod
it
"sets the pod targets as dependencies of the aggregate target"
do
@sut
.
send
(
:s
et
_target_dependencies
)
@sut
.
send
(
:s
ync
_target_dependencies
)
dependencies
=
@aggregate_target
.
target
.
dependencies
dependencies
.
map
{
|
d
|
d
.
target
.
name
}.
should
==
[
"Pods-BananaLib"
,
"Pods-monkey"
]
end
it
"sets the dependencies of the pod targets"
do
@pod_target_1
.
stubs
(
:dependencies
).
returns
([
'monkey'
])
@sut
.
send
(
:s
et
_target_dependencies
)
@sut
.
send
(
:s
ync
_target_dependencies
)
dependencies
=
@pod_target_1
.
target
.
dependencies
dependencies
.
map
{
|
d
|
d
.
target
.
name
}.
should
==
[
"Pods-monkey"
]
end
...
...
@@ -203,7 +204,7 @@ module Pod
#-----------------------------------------------------------------------#
describe
"#
link_aggregate_target
"
do
describe
"#
sync_aggregate_targets_libraries
"
do
before
do
project
=
Pod
::
Project
.
new
(
config
.
sandbox
.
project_path
)
...
...
@@ -218,7 +219,7 @@ module Pod
end
it
"links the aggregate targets to the pod targets"
do
@sut
.
send
(
:
link_aggregate_target
)
@sut
.
send
(
:
sync_aggregate_targets_libraries
)
@aggregate_native_target
.
frameworks_build_phase
.
files
.
map
(
&
:file_ref
).
should
.
include?
(
@pod_native_target
.
product_reference
)
end
...
...
@@ -226,32 +227,6 @@ module Pod
#-----------------------------------------------------------------------#
describe
"#clean_up_project"
do
before
do
@sut
=
PodsProjectGenerator
.
new
(
config
.
sandbox
,
[])
@sut
.
install
end
it
"removes the Pods group if empty"
do
@sut
.
send
(
:write_pod_project
)
@sut
.
project
[
'Pods'
].
should
.
be
.
nil
end
it
"removes the Development Pods group if empty"
do
@sut
.
send
(
:write_pod_project
)
@sut
.
project
[
'Development Pods'
].
should
.
be
.
nil
end
it
"recursively sorts the project by type"
do
@sut
.
project
.
main_group
.
expects
(
:recursively_sort_by_type
)
@sut
.
send
(
:write_pod_project
)
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