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
#
class
TargetIntegrator
autoload
:XCConfigIntegrator
,
'cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator'
# @return [Target] the target that should be integrated.
#
attr_reader
:target
...
...
@@ -26,9 +28,9 @@ module Pod
# @return [void]
#
def
integrate!
return
if
native_targets
.
empty?
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_copy_resources_script_phase
add_check_manifest_lock_script_phase
...
...
@@ -36,80 +38,17 @@ module Pod
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.
#
def
inspect
"#<
#{
self
.
class
}
for target `
#{
target
.
label
}
'>"
end
#---------------------------------------------------------------------#
# @!group Integration steps
private
# @return [Specification::Consumer] the consumer for the specifications.
#
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
# @!group Integration steps
#---------------------------------------------------------------------#
# Adds spec libraries to the frameworks build phase of the
# {TargetDefinition} integration libraries. Adds a file reference to
...
...
@@ -120,7 +59,7 @@ module Pod
#
def
add_pods_library
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
||
frameworks
.
new_product_ref_for_target
(
target
.
name
,
:static_library
)
unless
native_target
.
frameworks_build_phase
.
files_references
.
include?
(
library
)
...
...
@@ -137,7 +76,7 @@ module Pod
#
def
add_copy_resources_script_phase
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
||
native_target
.
new_shell_script_build_phase
(
phase_name
)
path
=
target
.
copy_resources_script_relative_path
...
...
@@ -157,7 +96,7 @@ module Pod
#
def
add_check_manifest_lock_script_phase
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
}
phase
=
native_target
.
project
.
new
(
Xcodeproj
::
Project
::
Object
::
PBXShellScriptBuildPhase
)
native_target
.
build_phases
.
unshift
(
phase
)
...
...
@@ -175,42 +114,58 @@ module Pod
end
end
#---------------------------------------------------------------------#
# @!group Private helpers.
private
# Informs the user about any build setting of the target which might
# 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
]
# @!group Private helpers
#---------------------------------------------------------------------#
if
target_value
&&
!
target_value
.
include?
(
'$(inherited)'
)
configs_by_overridden_key
[
key
]
||=
[]
configs_by_overridden_key
[
key
]
<<
config
.
name
# @return [Array<PBXNativeTarget>] The list of all the targets that
# match the given target.
#
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
end
@native_targets
end
configs_by_overridden_key
.
each
do
|
key
,
config_names
|
name
=
"
#{
native_target
.
name
}
[
#{
config_names
.
join
(
' - '
)
}
]"
actions
=
[
"Use the `$(inherited)` flag, or"
,
"Remove the build settings from the target."
]
UI
.
warn
(
"The target `
#{
name
}
` overrides the `
#{
key
}
` build "
\
"setting defined in `
#{
target
.
xcconfig_relative_path
(
config
.
name
)
}
'."
,
actions
)
# @return [Array<PBXNativeTarget>] The list of the targets
# that have not been integrated by past installations
# of
#
def
native_targets_to_integrate
unless
@native_targets_to_integrate
@native_targets_to_integrate
=
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
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
# @return [String] the message that should be displayed for the target
...
...
@@ -222,9 +177,6 @@ module Pod
"into aggregate target
#{
target
.
name
}
"
\
"of project
#{
UI
.
path
target
.
user_project_path
}
."
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__
)
module
Pod
describe
Installer
::
UserProjectIntegrator
do
describe
UserProjectIntegrator
=
Installer
::
UserProjectIntegrator
do
describe
"In general"
do
...
...
@@ -23,7 +23,7 @@ module Pod
@library
.
user_project_path
=
sample_project_path
@library
.
user_target_uuids
=
[
'A346496C14F9BE9A0080D870'
]
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
#-----------------------------------------------------------------------#
...
...
@@ -31,6 +31,7 @@ module Pod
describe
"In general"
do
it
"adds the Pods project to the workspace"
do
UserProjectIntegrator
::
TargetIntegrator
.
any_instance
.
stubs
(
:integrate!
)
@integrator
.
integrate!
workspace_path
=
@integrator
.
send
(
:workspace_path
)
workspace
=
Xcodeproj
::
Workspace
.
new_from_xcworkspace
(
workspace_path
)
...
...
@@ -41,10 +42,8 @@ module Pod
end
it
"integrates the user targets"
do
UserProjectIntegrator
::
TargetIntegrator
.
any_instance
.
expects
(
: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
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