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
d80a7386
Commit
d80a7386
authored
Jul 26, 2014
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[TargetIntegrator] Factor out XCConfig logic
Also includes some small fixes here and there
parent
2cbbbcc5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
224 additions
and
106 deletions
+224
-106
target_integrator.rb
...ds/installer/user_project_integrator/target_integrator.rb
+53
-101
xcconfig_integrator.rb
...oject_integrator/target_integrator/xcconfig_integrator.rb
+107
-0
xcconfig_integrator_spec.rb
..._integrator/target_integrator/xcconfig_integrator_spec.rb
+60
-0
target_integrator_spec.rb
...staller/user_project_integrator/target_integrator_spec.rb
+0
-0
user_project_integrator_spec.rb
spec/unit/installer/user_project_integrator_spec.rb
+4
-5
No files found.
lib/cocoapods/installer/user_project_integrator/target_integrator.rb
View file @
d80a7386
...
@@ -9,6 +9,8 @@ module Pod
...
@@ -9,6 +9,8 @@ module Pod
#
#
class
TargetIntegrator
class
TargetIntegrator
autoload
:XCConfigIntegrator
,
'cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator'
# @return [Target] the target that should be integrated.
# @return [Target] the target that should be integrated.
#
#
attr_reader
:target
attr_reader
:target
...
@@ -26,9 +28,9 @@ module Pod
...
@@ -26,9 +28,9 @@ module Pod
# @return [void]
# @return [void]
#
#
def
integrate!
def
integrate!
return
if
native_targets
.
empty?
UI
.
section
(
integration_message
)
do
UI
.
section
(
integration_message
)
do
add_xcconfig_base_configuration
XCConfigIntegrator
.
integrate
(
target
,
native_targets
)
return
if
native_targets_to_integrate
.
empty?
add_pods_library
add_pods_library
add_copy_resources_script_phase
add_copy_resources_script_phase
add_check_manifest_lock_script_phase
add_check_manifest_lock_script_phase
...
@@ -36,80 +38,17 @@ module Pod
...
@@ -36,80 +38,17 @@ module Pod
end
end
end
end
# @return [Array<PBXNativeTarget>] the user targets for integration.
#
def
native_targets
unless
@native_targets
target_uuids
=
target
.
user_target_uuids
native_targets
=
target_uuids
.
map
do
|
uuid
|
native_target
=
user_project
.
objects_by_uuid
[
uuid
]
unless
native_target
raise
Informative
,
"[Bug] Unable to find the target with "
\
"the `
#{
uuid
}
` UUID for the `
#{
target
}
` integration library"
end
native_target
end
non_integrated
=
native_targets
.
reject
do
|
native_target
|
native_target
.
frameworks_build_phase
.
files
.
any?
do
|
build_file
|
file_ref
=
build_file
.
file_ref
file_ref
&&
file_ref
.
isa
==
'PBXFileReference'
&&
file_ref
.
display_name
==
target
.
product_name
end
end
@native_targets
=
non_integrated
end
@native_targets
end
# Read the project from the disk to ensure that it is up to date as
# other TargetIntegrators might have modified it.
#
def
user_project
@user_project
||=
Xcodeproj
::
Project
.
open
(
target
.
user_project_path
)
end
# @return [String] a string representation suitable for debugging.
# @return [String] a string representation suitable for debugging.
#
#
def
inspect
def
inspect
"#<
#{
self
.
class
}
for target `
#{
target
.
label
}
'>"
"#<
#{
self
.
class
}
for target `
#{
target
.
label
}
'>"
end
end
#---------------------------------------------------------------------#
# @!group Integration steps
private
private
# @return [Specification::Consumer] the consumer for the specifications.
# @!group Integration steps
#
#---------------------------------------------------------------------#
def
spec_consumers
@spec_consumers
||=
target
.
pod_targets
.
map
(
&
:file_accessors
).
flatten
.
map
(
&
:spec_consumer
)
end
# Adds the `xcconfig` configurations files generated for the current
# {TargetDefinition} to the build configurations of the targets that
# should be integrated.
#
# @note It also checks if any build setting of the build
# configurations overrides the `xcconfig` file and warns the
# user.
#
# @todo If the xcconfig is already set don't override it and inform
# the user.
#
# @return [void]
#
def
add_xcconfig_base_configuration
native_targets
.
each
do
|
native_target
|
native_target
.
build_configurations
.
each
do
|
config
|
path
=
target
.
xcconfig_relative_path
(
config
.
name
)
xcconfig
=
user_project
.
files
.
select
{
|
f
|
f
.
path
==
path
}.
first
||
user_project
.
new_file
(
path
)
check_overridden_build_settings
(
target
.
xcconfigs
[
config
.
name
],
native_target
)
config
.
base_configuration_reference
=
xcconfig
end
end
end
# Adds spec libraries to the frameworks build phase of the
# Adds spec libraries to the frameworks build phase of the
# {TargetDefinition} integration libraries. Adds a file reference to
# {TargetDefinition} integration libraries. Adds a file reference to
...
@@ -120,7 +59,7 @@ module Pod
...
@@ -120,7 +59,7 @@ module Pod
#
#
def
add_pods_library
def
add_pods_library
frameworks
=
user_project
.
frameworks_group
frameworks
=
user_project
.
frameworks_group
native_targets
.
each
do
|
native_target
|
native_targets
_to_integrate
.
each
do
|
native_target
|
library
=
frameworks
.
files
.
select
{
|
f
|
f
.
path
==
target
.
product_name
}.
first
||
library
=
frameworks
.
files
.
select
{
|
f
|
f
.
path
==
target
.
product_name
}.
first
||
frameworks
.
new_product_ref_for_target
(
target
.
name
,
:static_library
)
frameworks
.
new_product_ref_for_target
(
target
.
name
,
:static_library
)
unless
native_target
.
frameworks_build_phase
.
files_references
.
include?
(
library
)
unless
native_target
.
frameworks_build_phase
.
files_references
.
include?
(
library
)
...
@@ -137,7 +76,7 @@ module Pod
...
@@ -137,7 +76,7 @@ module Pod
#
#
def
add_copy_resources_script_phase
def
add_copy_resources_script_phase
phase_name
=
"Copy Pods Resources"
phase_name
=
"Copy Pods Resources"
native_targets
.
each
do
|
native_target
|
native_targets
_to_integrate
.
each
do
|
native_target
|
phase
=
native_target
.
shell_script_build_phases
.
select
{
|
bp
|
bp
.
name
==
phase_name
}.
first
||
phase
=
native_target
.
shell_script_build_phases
.
select
{
|
bp
|
bp
.
name
==
phase_name
}.
first
||
native_target
.
new_shell_script_build_phase
(
phase_name
)
native_target
.
new_shell_script_build_phase
(
phase_name
)
path
=
target
.
copy_resources_script_relative_path
path
=
target
.
copy_resources_script_relative_path
...
@@ -157,7 +96,7 @@ module Pod
...
@@ -157,7 +96,7 @@ module Pod
#
#
def
add_check_manifest_lock_script_phase
def
add_check_manifest_lock_script_phase
phase_name
=
'Check Pods Manifest.lock'
phase_name
=
'Check Pods Manifest.lock'
native_targets
.
each
do
|
native_target
|
native_targets
_to_integrate
.
each
do
|
native_target
|
next
if
native_target
.
shell_script_build_phases
.
any?
{
|
phase
|
phase
.
name
==
phase_name
}
next
if
native_target
.
shell_script_build_phases
.
any?
{
|
phase
|
phase
.
name
==
phase_name
}
phase
=
native_target
.
project
.
new
(
Xcodeproj
::
Project
::
Object
::
PBXShellScriptBuildPhase
)
phase
=
native_target
.
project
.
new
(
Xcodeproj
::
Project
::
Object
::
PBXShellScriptBuildPhase
)
native_target
.
build_phases
.
unshift
(
phase
)
native_target
.
build_phases
.
unshift
(
phase
)
...
@@ -175,42 +114,58 @@ module Pod
...
@@ -175,42 +114,58 @@ module Pod
end
end
end
end
#---------------------------------------------------------------------#
# @!group Private helpers.
private
private
# Informs the user about any build setting of the target which might
# @!group Private helpers
# override the given xcconfig file.
#---------------------------------------------------------------------#
#
# @return [void]
#
def
check_overridden_build_settings
(
xcconfig
,
native_target
)
return
unless
xcconfig
configs_by_overridden_key
=
{}
native_target
.
build_configurations
.
each
do
|
config
|
xcconfig
.
attributes
.
keys
.
each
do
|
key
|
target_value
=
config
.
build_settings
[
key
]
if
target_value
&&
!
target_value
.
include?
(
'$(inherited)'
)
# @return [Array<PBXNativeTarget>] The list of all the targets that
configs_by_overridden_key
[
key
]
||=
[]
# match the given target.
configs_by_overridden_key
[
key
]
<<
config
.
name
#
def
native_targets
unless
@native_targets
target_uuids
=
target
.
user_target_uuids
@native_targets
=
target_uuids
.
map
do
|
uuid
|
native_target
=
user_project
.
objects_by_uuid
[
uuid
]
unless
native_target
raise
Informative
,
"[Bug] Unable to find the target with "
\
"the `
#{
uuid
}
` UUID for the `
#{
target
}
` integration library"
end
end
native_target
end
end
end
@native_targets
end
configs_by_overridden_key
.
each
do
|
key
,
config_names
|
# @return [Array<PBXNativeTarget>] The list of the targets
name
=
"
#{
native_target
.
name
}
[
#{
config_names
.
join
(
' - '
)
}
]"
# that have not been integrated by past installations
actions
=
[
# of
"Use the `$(inherited)` flag, or"
,
#
"Remove the build settings from the target."
def
native_targets_to_integrate
]
unless
@native_targets_to_integrate
UI
.
warn
(
"The target `
#{
name
}
` overrides the `
#{
key
}
` build "
\
@native_targets_to_integrate
=
native_targets
.
reject
do
|
native_target
|
"setting defined in `
#{
target
.
xcconfig_relative_path
(
config
.
name
)
}
'."
,
native_target
.
frameworks_build_phase
.
files
.
any?
do
|
build_file
|
actions
)
file_ref
=
build_file
.
file_ref
file_ref
&&
file_ref
.
isa
==
'PBXFileReference'
&&
file_ref
.
display_name
==
target
.
product_name
end
end
end
end
end
@native_targets_to_integrate
end
# Read the project from the disk to ensure that it is up to date as
# other TargetIntegrators might have modified it.
#
def
user_project
@user_project
||=
Xcodeproj
::
Project
.
open
(
target
.
user_project_path
)
end
# @return [Specification::Consumer] the consumer for the specifications.
#
def
spec_consumers
@spec_consumers
||=
target
.
pod_targets
.
map
(
&
:file_accessors
).
flatten
.
map
(
&
:spec_consumer
)
end
end
# @return [String] the message that should be displayed for the target
# @return [String] the message that should be displayed for the target
...
@@ -222,9 +177,6 @@ module Pod
...
@@ -222,9 +177,6 @@ module Pod
"into aggregate target
#{
target
.
name
}
"
\
"into aggregate target
#{
target
.
name
}
"
\
"of project
#{
UI
.
path
target
.
user_project_path
}
."
"of project
#{
UI
.
path
target
.
user_project_path
}
."
end
end
#---------------------------------------------------------------------#
end
end
end
end
end
end
...
...
lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb
0 → 100644
View file @
d80a7386
module
Pod
class
Installer
class
UserProjectIntegrator
class
TargetIntegrator
# Configures an user target to use the CocoaPods xcconfigs which allow
# lo link against the Pods.
#
class
XCConfigIntegrator
# Integrates the user target.
#
# @param [Target::AggregateTarget] pod_bundle
# The Pods bundle.
#
# @param [Array<PBXNativeTarget>] targets
# The native targets associated which should be integrated
# with the Pod bundle.
#
def
self
.
integrate
(
pod_bundle
,
targets
)
targets
.
each
do
|
target
|
target
.
build_configurations
.
each
do
|
config
|
set_target_xcconfig
(
pod_bundle
,
config
)
check_overrides
(
pod_bundle
,
target
,
config
)
end
end
end
private
# @!group Integration steps
#-------------------------------------------------------------------#
# Creates a file reference to the xcconfig generated by
# CocoaPods (if needed) and sets it as the base configuration of
# build configuration of the user target.
#
# @param [Target::AggregateTarget] pod_bundle
# The Pods bundle.
#
# @param [[Xcodeproj::XCBuildConfiguration] config
# The build configuration.
#
def
self
.
set_target_xcconfig
(
pod_bundle
,
config
)
path
=
pod_bundle
.
xcconfig_relative_path
(
config
.
name
)
file_ref
=
config
.
project
.
files
.
find
{
|
f
|
f
.
path
==
path
}
file_ref
||=
config
.
project
.
new_file
(
path
)
config
.
base_configuration_reference
=
file_ref
end
# Checks whether the settings of the CocoaPods generated xcconfig are
# overridden by the build configuration of a target and prints a
# warning to inform the user if needed.
#
# @param [Target::AggregateTarget] pod_bundle
# The Pods bundle.
#
# @param [XcodeProj::PBXNativeTarget] target
# The native target.
#
# @param [Xcodeproj::XCBuildConfiguration] config
# The build configuration.
#
def
self
.
check_overrides
(
pod_bundle
,
target
,
config
)
xcconfig
=
pod_bundle
.
xcconfigs
[
config
.
name
]
xcconfig
.
attributes
.
keys
.
each
do
|
key
|
target_value
=
config
.
build_settings
[
key
]
if
target_value
&&
!
target_value
.
include?
(
'$(inherited)'
)
print_override_warning
(
pod_bundle
,
target
,
config
,
key
)
end
end
end
private
# @!group Private helpers
#-------------------------------------------------------------------#
# Prints a warning informing the user that a build configuration of
# the integrated target is overriding the CocoaPods build settings.
#
# @param [Target::AggregateTarget] pod_bundle
# The Pods bundle.
#
# @param [XcodeProj::PBXNativeTarget] target
# The native target.
#
# @param [Xcodeproj::XCBuildConfiguration] config
# The build configuration.
#
# @param [String] key
# The key of the overridden build setting.
#
def
self
.
print_override_warning
(
pod_bundle
,
target
,
config
,
key
)
actions
=
[
"Use the `$(inherited)` flag, or"
,
"Remove the build settings from the target."
]
message
=
"The `
#{
target
.
name
}
[
#{
config
.
name
}
]` "
\
"target overrides the `
#{
key
}
` build setting defined in "
\
"`
#{
pod_bundle
.
xcconfig_relative_path
(
config
.
name
)
}
'."
\
"This can lead to problems with the CocoaPods installation"
UI
.
warn
(
message
,
actions
)
end
end
end
end
end
end
spec/unit/installer/user_project_integrator/target_integrator/xcconfig_integrator_spec.rb
0 → 100644
View file @
d80a7386
require
File
.
expand_path
(
'../../../../../spec_helper'
,
__FILE__
)
module
Pod
describe
XCConfigIntegrator
=
Installer
::
UserProjectIntegrator
::
TargetIntegrator
::
XCConfigIntegrator
do
before
do
project_path
=
SpecHelper
.
create_sample_app_copy_from_fixture
(
'SampleProject'
)
@project
=
Xcodeproj
::
Project
.
open
(
project_path
)
Xcodeproj
::
Project
.
new
(
config
.
sandbox
.
project_path
).
save
@target
=
@project
.
targets
.
first
target_definition
=
Podfile
::
TargetDefinition
.
new
(
'Pods'
,
nil
)
target_definition
.
link_with_first_target
=
true
@pod_bundle
=
AggregateTarget
.
new
(
target_definition
,
config
.
sandbox
)
@pod_bundle
.
user_project_path
=
project_path
@pod_bundle
.
client_root
=
project_path
.
dirname
@pod_bundle
.
user_target_uuids
=
[
@target
.
uuid
]
configuration
=
Xcodeproj
::
Config
.
new
({
'GCC_PREPROCESSOR_DEFINITIONS'
=>
'$(inherited) COCOAPODS=1'
})
@pod_bundle
.
xcconfigs
[
'Debug'
]
=
configuration
@pod_bundle
.
xcconfigs
[
'Test'
]
=
configuration
@pod_bundle
.
xcconfigs
[
'Release'
]
=
configuration
@pod_bundle
.
xcconfigs
[
'App Store'
]
=
configuration
end
it
'sets the Pods xcconfig as the base config for each build configuration'
do
XCConfigIntegrator
.
integrate
(
@pod_bundle
,
[
@target
])
@target
.
build_configurations
.
each
do
|
config
|
xcconfig_file
=
@project
.
files
.
find
{
|
f
|
f
.
path
==
@pod_bundle
.
xcconfig_relative_path
(
config
)
}
config
.
base_configuration_reference
.
should
==
xcconfig_file
end
end
it
'does not duplicate the file reference to the CocoaPods xcconfig in the user project'
do
path
=
@pod_bundle
.
xcconfig_relative_path
(
'Release'
)
existing
=
@project
.
new_file
(
path
)
XCConfigIntegrator
.
integrate
(
@pod_bundle
,
[
@target
])
config
=
@target
.
build_configuration_list
[
'Release'
]
config
.
base_configuration_reference
.
should
.
equal
existing
end
it
'check that the integrated target does not override the CocoaPods build settings'
do
UI
.
warnings
=
''
config
=
@target
.
build_configuration_list
[
'Release'
]
config
.
build_settings
[
'GCC_PREPROCESSOR_DEFINITIONS'
]
=
'FLAG=1'
XCConfigIntegrator
.
integrate
(
@pod_bundle
,
[
@target
])
UI
.
warnings
.
should
.
include
'The `SampleProject [Release]` target '
\
'overrides the `GCC_PREPROCESSOR_DEFINITIONS` build setting'
end
it
'allows build settings which inherit the settings form the CocoaPods xcconfig'
do
UI
.
warnings
=
''
config
=
@target
.
build_configuration_list
[
'Release'
]
config
.
build_settings
[
'GCC_PREPROCESSOR_DEFINITIONS'
]
=
'$(inherited)'
XCConfigIntegrator
.
integrate
(
@pod_bundle
,
[
@target
])
UI
.
warnings
.
should
.
not
.
include
'GCC_PREPROCESSOR_DEFINITIONS'
end
end
end
spec/unit/installer/user_project_integrator/target_integrator_spec.rb
View file @
d80a7386
This diff is collapsed.
Click to expand it.
spec/unit/installer/user_project_integrator_spec.rb
View file @
d80a7386
require
File
.
expand_path
(
'../../../spec_helper'
,
__FILE__
)
require
File
.
expand_path
(
'../../../spec_helper'
,
__FILE__
)
module
Pod
module
Pod
describe
Installer
::
UserProjectIntegrator
do
describe
UserProjectIntegrator
=
Installer
::
UserProjectIntegrator
do
describe
"In general"
do
describe
"In general"
do
...
@@ -23,7 +23,7 @@ module Pod
...
@@ -23,7 +23,7 @@ module Pod
@library
.
user_project_path
=
sample_project_path
@library
.
user_project_path
=
sample_project_path
@library
.
user_target_uuids
=
[
'A346496C14F9BE9A0080D870'
]
@library
.
user_target_uuids
=
[
'A346496C14F9BE9A0080D870'
]
empty_library
=
AggregateTarget
.
new
(
@podfile
.
target_definitions
[
:empty
],
config
.
sandbox
)
empty_library
=
AggregateTarget
.
new
(
@podfile
.
target_definitions
[
:empty
],
config
.
sandbox
)
@integrator
=
Installer
::
UserProjectIntegrator
.
new
(
@podfile
,
config
.
sandbox
,
temporary_directory
,
[
@library
,
empty_library
])
@integrator
=
UserProjectIntegrator
.
new
(
@podfile
,
config
.
sandbox
,
temporary_directory
,
[
@library
,
empty_library
])
end
end
#-----------------------------------------------------------------------#
#-----------------------------------------------------------------------#
...
@@ -31,6 +31,7 @@ module Pod
...
@@ -31,6 +31,7 @@ module Pod
describe
"In general"
do
describe
"In general"
do
it
"adds the Pods project to the workspace"
do
it
"adds the Pods project to the workspace"
do
UserProjectIntegrator
::
TargetIntegrator
.
any_instance
.
stubs
(
:integrate!
)
@integrator
.
integrate!
@integrator
.
integrate!
workspace_path
=
@integrator
.
send
(
:workspace_path
)
workspace_path
=
@integrator
.
send
(
:workspace_path
)
workspace
=
Xcodeproj
::
Workspace
.
new_from_xcworkspace
(
workspace_path
)
workspace
=
Xcodeproj
::
Workspace
.
new_from_xcworkspace
(
workspace_path
)
...
@@ -41,10 +42,8 @@ module Pod
...
@@ -41,10 +42,8 @@ module Pod
end
end
it
"integrates the user targets"
do
it
"integrates the user targets"
do
UserProjectIntegrator
::
TargetIntegrator
.
any_instance
.
expects
(
:integrate!
)
@integrator
.
integrate!
@integrator
.
integrate!
user_project
=
Xcodeproj
::
Project
.
open
(
@sample_project_path
)
target
=
user_project
.
objects_by_uuid
[
@library
.
user_target_uuids
.
first
]
target
.
frameworks_build_phase
.
files
.
map
(
&
:display_name
).
should
.
include
(
'libPods.a'
)
end
end
it
"warns if the podfile does not contain any dependency"
do
it
"warns if the podfile does not contain any dependency"
do
...
...
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