Class: Pod::Installer::UserProjectIntegrator::TargetIntegrator
- Inherits:
-
Object
- Object
- Pod::Installer::UserProjectIntegrator::TargetIntegrator
- Defined in:
- lib/cocoapods/installer/user_project_integrator/target_integrator.rb,
lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb
Overview
This class is responsible for integrating the library generated by a TargetDefinition with its destination project.
Defined Under Namespace
Classes: XCConfigIntegrator, XCFileListConfigKey
Constant Summary collapse
- BUILD_PHASE_PREFIX =
Returns the string to use as prefix for every build phase added to the user project.
'[CP] '.freeze
- USER_BUILD_PHASE_PREFIX =
Returns the string to use as prefix for every build phase declared by the user within a podfile or podspec.
'[CP-User] '.freeze
- CHECK_MANIFEST_PHASE_NAME =
Returns the name of the check manifest phase.
'Check Pods Manifest.lock'.freeze
- EMBED_FRAMEWORK_TARGET_TYPES =
Note:
This does not include :app_extension or :watch_extension because
frameworks are embedded in the output directory / product bundle.
these types must have their frameworks embedded in their host targets. For messages extensions, this only applies if it's embedded in a messages application.
[:application, :application_on_demand_install_capable, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
- EMBED_FRAMEWORK_PHASE_NAME =
Returns the name of the embed frameworks phase.
'Embed Pods Frameworks'.freeze
- COPY_XCFRAMEWORKS_PHASE_NAME =
Returns the name of the copy xcframeworks phase.
'Copy XCFrameworks'.freeze
- COPY_PODS_RESOURCES_PHASE_NAME =
Returns the name of the copy resources phase.
'Copy Pods Resources'.freeze
- COPY_DSYM_FILES_PHASE_NAME =
Returns the name of the copy dSYM files phase.
'Copy dSYMs'.freeze
- MAX_INPUT_OUTPUT_PATHS =
Returns the maximum number of input and output paths to use for a script phase.
1000
- REMOVED_SCRIPT_PHASE_NAMES =
Returns names of script phases that existed in previous versions of CocoaPods.
[ 'Prepare Artifacts'.freeze, ].freeze
- MIN_FILE_LIST_COMPATIBILITY_VERSION =
Returns Minimum Xcode Compatibility version for FileLists
9.3
- MIN_FILE_LIST_OBJECT_VERSION =
Returns Minimum Xcode Object version for FileLists
50
Instance Attribute Summary collapse
-
#target ⇒ AggregateTarget
readonly
The target that should be integrated.
-
#use_input_output_paths ⇒ Boolean
(also: #use_input_output_paths?)
readonly
Whether to use input/output paths for build phase scripts.
Integration steps collapse
-
#add_check_manifest_lock_script_phase ⇒ void
private
Adds a shell script build phase responsible for checking if the Pods locked in the Pods/Manifest.lock file are in sync with the Pods defined in the Podfile.lock.
-
#add_copy_resources_script_phase ⇒ void
private
Find or create a 'Copy Pods Resources' build phase.
-
#add_embed_frameworks_script_phase ⇒ void
private
Find or create a 'Embed Pods Frameworks' Copy Files Build Phase.
- #add_on_demand_resources ⇒ Object private
-
#add_pods_library ⇒ void
private
Adds spec product reference to the frameworks build phase of the TargetDefinition integration libraries.
-
#add_user_script_phases ⇒ void
private
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
-
#remove_embed_frameworks_script_phase_from_embedded_targets ⇒ Object
private
Removes the embed frameworks build phase from embedded targets.
- #remove_obsolete_script_phases(removed_phase_names = REMOVED_SCRIPT_PHASE_NAMES) ⇒ Object private
Private Helpers collapse
-
#integration_message ⇒ String
private
The message that should be displayed for the target integration.
-
#native_targets ⇒ Array<PBXNativeTarget>
private
The list of all the targets that match the given target.
-
#native_targets_to_embed_in ⇒ Array<PBXNativeTarget>
private
The list of all the targets that require that the pod frameworks are embedded in the output directory / product bundle.
-
#spec_consumers ⇒ Specification::Consumer
private
The consumer for the specifications.
-
#user_project ⇒ Project
private
Read the project from the disk to ensure that it is up to date as other TargetIntegrators might have modified it.
Class Method Summary collapse
-
.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
Adds a shell script build phase responsible to copy the resources generated by the TargetDefinition to the bundle of the product of the targets.
-
.create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
Adds a shell script build phase responsible to copy the xcframework slice to the intermediate build directory.
-
.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
Adds a shell script build phase responsible to copy (embed) the frameworks generated by the TargetDefinition to the bundle of the product of the targets.
-
.create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') ⇒ PBXShellScriptBuildPhase
Creates or update a shell script build phase for the given target.
-
.create_or_update_user_script_phases(script_phases, native_target) ⇒ void
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
-
.embed_frameworks_input_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework input paths for the given framework paths.
-
.embed_frameworks_output_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework output paths for the given framework paths.
-
.input_output_paths_use_filelist?(object) ⇒ Boolean
Whether input & output paths for the given object should be stored in a file list file.
-
.remove_copy_resources_script_phase_from_target(native_target) ⇒ Object
Delete a 'Copy Pods Resources' script phase if present.
-
.remove_copy_xcframeworks_script_phase_from_target(native_target) ⇒ Object
Delete a 'Copy XCFrameworks' Script Build Phase if present.
-
.remove_embed_frameworks_script_phase_from_target(native_target) ⇒ Object
Delete a 'Embed Pods Frameworks' Script Build Phase if present.
-
.remove_script_phase_from_target(native_target, phase_name) ⇒ Object
Removes a script phase from a native target by name.
- .reorder_script_phase(native_target, script_phase, execution_position) ⇒ Object
-
.resource_output_paths(resource_input_paths) ⇒ Array<String>
Returns the resource output paths for all given input paths.
-
.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) ⇒ Void
Sets the input & output paths for the given script build phase.
-
.update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group, target_odr_group_name) ⇒ void
Updates a projects native targets to include on demand resources specified by the supplied parameters.
- .update_on_demand_resources_build_settings(native_target, category_to_tags) ⇒ Object
-
.validate_input_output_path_limit(input_paths, output_paths) ⇒ void
Script phases can have a limited number of input and output paths due to each one being exported to
env
.
Instance Method Summary collapse
-
#initialize(target, use_input_output_paths: true) ⇒ TargetIntegrator
constructor
Init a new TargetIntegrator.
-
#inspect ⇒ String
A string representation suitable for debugging.
-
#integrate! ⇒ void
Integrates the user project targets.
Constructor Details
#initialize(target, use_input_output_paths: true) ⇒ TargetIntegrator
Init a new TargetIntegrator
86 87 88 89 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 86 def initialize(target, use_input_output_paths: true) @target = target @use_input_output_paths = use_input_output_paths end |
Instance Attribute Details
#target ⇒ AggregateTarget (readonly)
Returns the target that should be integrated.
74 75 76 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 74 def target @target end |
#use_input_output_paths ⇒ Boolean (readonly) Also known as: use_input_output_paths?
Returns whether to use input/output paths for build phase scripts.
78 79 80 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 78 def use_input_output_paths @use_input_output_paths end |
Class Method Details
.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
Adds a shell script build phase responsible to copy the resources generated by the TargetDefinition to the bundle of the product of the targets.
243 244 245 246 247 248 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 243 def create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase_name = COPY_PODS_RESOURCES_PHASE_NAME phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) end |
.create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
Adds a shell script build phase responsible to copy the xcframework slice to the intermediate build directory.
195 196 197 198 199 200 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 195 def create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + COPY_XCFRAMEWORKS_PHASE_NAME) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) reorder_script_phase(native_target, phase, :before_compile) end |
.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) ⇒ void
This method returns an undefined value.
Adds a shell script build phase responsible to copy (embed) the frameworks generated by the TargetDefinition to the bundle of the product of the targets.
163 164 165 166 167 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 163 def (native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {}) phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + EMBED_FRAMEWORK_PHASE_NAME) phase.shell_script = %("#{script_path}"\n) TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) end |
.create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') ⇒ PBXShellScriptBuildPhase
Creates or update a shell script build phase for the given target.
275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 275 def create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0') build_phases = native_target.build_phases.grep(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) build_phases.find { |phase| phase.name && phase.name.end_with?(script_phase_name) }.tap { |p| p.name = script_phase_name if p } || native_target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase).tap do |phase| UI.("Adding Build Phase '#{script_phase_name}' to project.") do phase.name = script_phase_name unless show_env_vars_in_log.nil? phase.show_env_vars_in_log = show_env_vars_in_log end native_target.build_phases << phase end end end |
.create_or_update_user_script_phases(script_phases, native_target) ⇒ void
This method returns an undefined value.
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 294 def create_or_update_user_script_phases(script_phases, native_target) script_phase_names = script_phases.map { |k| k[:name] } # Delete script phases no longer present in the target. native_target_script_phases = native_target.shell_script_build_phases.select do |bp| !bp.name.nil? && bp.name.start_with?(USER_BUILD_PHASE_PREFIX) end native_target_script_phases.each do |script_phase| script_phase_name_without_prefix = script_phase.name.sub(USER_BUILD_PHASE_PREFIX, '') unless script_phase_names.include?(script_phase_name_without_prefix) native_target.build_phases.delete(script_phase) end end # Create or update the ones that are expected to be. script_phases.each do |script_phase| name_with_prefix = USER_BUILD_PHASE_PREFIX + script_phase[:name] phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, name_with_prefix, nil) phase.shell_script = script_phase[:script] phase.shell_path = script_phase[:shell_path] || '/bin/sh' phase.input_paths = script_phase[:input_files] phase.output_paths = script_phase[:output_files] phase.input_file_list_paths = script_phase[:input_file_lists] phase.output_file_list_paths = script_phase[:output_file_lists] phase.dependency_file = script_phase[:dependency_file] phase.always_out_of_date = script_phase[:always_out_of_date] # At least with Xcode 10 `showEnvVarsInLog` is *NOT* set to any value even if it's checked and it only # gets set to '0' if the user has explicitly disabled this. if (show_env_vars_in_log = script_phase.fetch(:show_env_vars_in_log, '1')) == '0' phase.show_env_vars_in_log = show_env_vars_in_log end execution_position = script_phase[:execution_position] reorder_script_phase(native_target, phase, execution_position) end end |
.embed_frameworks_input_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework input paths for the given framework paths
407 408 409 410 411 412 413 414 415 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 407 def (framework_paths, xcframeworks) input_paths = framework_paths.map(&:source_path) # Only include dynamic xcframeworks as the input since we will not be copying static xcframework slices xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.each do |xcframework| name = xcframework.name input_paths << "#{Pod::Target::BuildSettings.xcframework_intermediate_dir(xcframework)}/#{name}.framework/#{name}" end input_paths end |
.embed_frameworks_output_paths(framework_paths, xcframeworks) ⇒ Array<String>
Returns the framework output paths for the given framework paths
427 428 429 430 431 432 433 434 435 436 437 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 427 def (framework_paths, xcframeworks) paths = framework_paths.map do |framework_path| "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}" end.uniq # Static xcframeworks are not copied to the build dir # so only include dynamic artifacts that will be copied to the build folder xcframework_paths = xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.map do |xcframework| "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{xcframework.name}.framework" end paths + xcframework_paths end |
.input_output_paths_use_filelist?(object) ⇒ Boolean
Returns Whether input & output paths for the given object should be stored in a file list file.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 101 def input_output_paths_use_filelist?(object) unless object.project.root_object.compatibility_version.nil? version_match = object.project.root_object.compatibility_version.match(/Xcode ([0-9]*\.[0-9]*)/).to_a end if version_match&.at(1).nil? object.project.object_version.to_i >= MIN_FILE_LIST_OBJECT_VERSION else Pod::Version.new(version_match[1]) >= Pod::Version.new(MIN_FILE_LIST_COMPATIBILITY_VERSION) end end |
.remove_copy_resources_script_phase_from_target(native_target) ⇒ Object
Delete a 'Copy Pods Resources' script phase if present
255 256 257 258 259 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 255 def remove_copy_resources_script_phase_from_target(native_target) build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(COPY_PODS_RESOURCES_PHASE_NAME) } return unless build_phase.present? native_target.build_phases.delete(build_phase) end |
.remove_copy_xcframeworks_script_phase_from_target(native_target) ⇒ Object
Delete a 'Copy XCFrameworks' Script Build Phase if present
207 208 209 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 207 def remove_copy_xcframeworks_script_phase_from_target(native_target) remove_script_phase_from_target(native_target, COPY_XCFRAMEWORKS_PHASE_NAME) end |
.remove_embed_frameworks_script_phase_from_target(native_target) ⇒ Object
Delete a 'Embed Pods Frameworks' Script Build Phase if present
174 175 176 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 174 def (native_target) remove_script_phase_from_target(native_target, EMBED_FRAMEWORK_PHASE_NAME) end |
.remove_script_phase_from_target(native_target, phase_name) ⇒ Object
Removes a script phase from a native target by name
219 220 221 222 223 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 219 def remove_script_phase_from_target(native_target, phase_name) build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(phase_name) } return unless build_phase.present? native_target.build_phases.delete(build_phase) end |
.reorder_script_phase(native_target, script_phase, execution_position) ⇒ Object
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 329 def reorder_script_phase(native_target, script_phase, execution_position) return if execution_position == :any || execution_position.to_s.empty? target_phase_type = case execution_position when :before_compile, :after_compile Xcodeproj::Project::Object::PBXSourcesBuildPhase when :before_headers, :after_headers Xcodeproj::Project::Object::PBXHeadersBuildPhase else raise ArgumentError, "Unknown execution position `#{execution_position}`" end order_before = case execution_position when :before_compile, :before_headers true when :after_compile, :after_headers false else raise ArgumentError, "Unknown execution position `#{execution_position}`" end target_phase_index = native_target.build_phases.index do |bp| bp.is_a?(target_phase_type) end return if target_phase_index.nil? script_phase_index = native_target.build_phases.index do |bp| bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && !bp.name.nil? && bp.name == script_phase.name end if (order_before && script_phase_index > target_phase_index) || (!order_before && script_phase_index < target_phase_index) native_target.build_phases.move_from(script_phase_index, target_phase_index) end end |
.resource_output_paths(resource_input_paths) ⇒ Array<String>
Returns the resource output paths for all given input paths.
387 388 389 390 391 392 393 394 395 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 387 def resource_output_paths(resource_input_paths) resource_input_paths.map do |resource_input_path| base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}' extname = File.extname(resource_input_path) basename = extname == '.xcassets' ? 'Assets' : File.basename(resource_input_path) output_extension = Target.output_extension_for_resource(extname) File.join(base_path, File.basename(basename, extname) + output_extension) end.uniq end |
.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) ⇒ Void
Sets the input & output paths for the given script build phase.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 120 def set_input_output_paths(phase, input_paths_by_config, output_paths_by_config) if input_output_paths_use_filelist?(phase) [input_paths_by_config, output_paths_by_config].each do |hash| hash.each do |file_list, files| generator = Generator::FileList.new(files) Xcode::PodsProjectGenerator::TargetInstallerHelper.update_changed_file(generator, file_list.file_list_path) end end phase.input_paths = nil phase.output_paths = nil phase.input_file_list_paths = input_paths_by_config.each_key.map(&:file_list_relative_path).uniq phase.output_file_list_paths = output_paths_by_config.each_key.map(&:file_list_relative_path).uniq else input_paths = input_paths_by_config.values.flatten(1).uniq output_paths = output_paths_by_config.values.flatten(1).uniq TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths) phase.input_paths = input_paths phase.output_paths = output_paths phase.input_file_list_paths = nil phase.output_file_list_paths = nil end end |
.update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group, target_odr_group_name) ⇒ void
This method returns an undefined value.
Updates a projects native targets to include on demand resources specified by the supplied parameters. Note that currently, only app level targets are allowed to include on demand resources.
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 462 def update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group, target_odr_group_name) = {} file_accessors = Array(file_accessors) native_targets = Array(native_targets) # Target no longer provides ODR references so remove everything related to this target. if file_accessors.all? { |fa| fa.on_demand_resources.empty? } old_target_odr_group = parent_odr_group[target_odr_group_name] old_odr_file_refs = old_target_odr_group&.recursive_children_groups&.each_with_object({}) do |group, hash| hash[group.name] = group.files end || {} native_targets.each do |native_target| native_target.remove_on_demand_resources(old_odr_file_refs) update_on_demand_resources_build_settings(native_target, nil => old_odr_file_refs.keys) end old_target_odr_group&.remove_from_project return end target_odr_group = parent_odr_group[target_odr_group_name] || parent_odr_group.new_group(target_odr_group_name) current_file_refs = target_odr_group.recursive_children_groups.flat_map(&:files) added_file_refs = file_accessors.flat_map do |file_accessor| target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, value| tag_group = target_odr_group[tag] || target_odr_group.new_group(tag) [value[:category]] ||= [] [value[:category]] << tag resources_file_refs = value[:paths].map do |resource| odr_resource_file_ref = Pathname.new(resource).relative_path_from(sandbox.root) tag_group.find_file_by_path(odr_resource_file_ref.to_s) || tag_group.new_file(odr_resource_file_ref) end [tag, resources_file_refs] end] native_targets.each do |native_target| native_target.add_on_demand_resources(target_odr_files_refs) end target_odr_files_refs.values.flatten end # if the target ODR file references were updated, make sure we remove the ones that are no longer present # for the target. remaining_refs = current_file_refs - added_file_refs remaining_refs.each do |ref| native_targets.each do |user_target| user_target.resources_build_phase.remove_file_reference(ref) end ref.remove_from_project end target_odr_group.recursive_children_groups.each { |g| g.remove_from_project if g.empty? } attributes = project.root_object.attributes attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | .values.flatten project.root_object.attributes = attributes native_targets.each do |native_target| update_on_demand_resources_build_settings(native_target, ) end end |
.update_on_demand_resources_build_settings(native_target, category_to_tags) ⇒ Object
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 522 def update_on_demand_resources_build_settings(native_target, ) %w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key| native_target.build_configurations.each do |c| key = case category_key when 'ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS' :initial_install when 'ON_DEMAND_RESOURCES_PREFETCH_ORDER' :prefetched else :download_on_demand end = (c.build_settings[category_key] || '').split = .dup = .delete(key) || [] = .values.flatten = ( + - ).flatten.compact.uniq if .empty? val = c.build_settings.delete(category_key) native_target.project.mark_dirty! unless val.nil? else = .join(' ') unless c.build_settings[category_key] == c.build_settings[category_key] = native_target.project.mark_dirty! end end end end end |
.validate_input_output_path_limit(input_paths, output_paths) ⇒ void
This method returns an undefined value.
Script phases can have a limited number of input and output paths due to each one being exported to env
.
A large number can cause a build failure because of limitations in env
. See issue
https://github.com/CocoaPods/CocoaPods/issues/7362.
373 374 375 376 377 378 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 373 def validate_input_output_path_limit(input_paths, output_paths) if (input_paths.count + output_paths.count) > MAX_INPUT_OUTPUT_PATHS input_paths.clear output_paths.clear end end |
Instance Method Details
#add_check_manifest_lock_script_phase ⇒ void (private)
The build phase is appended to the front because to fail fast.
This method returns an undefined value.
Adds a shell script build phase responsible for checking if the Pods locked in the Pods/Manifest.lock file are in sync with the Pods defined in the Podfile.lock.
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 723 def add_check_manifest_lock_script_phase phase_name = CHECK_MANIFEST_PHASE_NAME native_targets.each do |native_target| phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name) native_target.build_phases.unshift(phase).uniq! unless native_target.build_phases.first == phase phase.shell_script = <<-SH.strip_heredoc diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null if [ $? != 0 ] ; then # print error to STDERR echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2 exit 1 fi # This output is used by Xcode 'outputs' to avoid re-running this script phase. echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}" SH phase.input_paths = %w(${PODS_PODFILE_DIR_PATH}/Podfile.lock ${PODS_ROOT}/Manifest.lock) phase.output_paths = [target.check_manifest_lock_script_output_file_path] end end |
#add_copy_resources_script_phase ⇒ void (private)
This method returns an undefined value.
Find or create a 'Copy Pods Resources' build phase
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 622 def add_copy_resources_script_phase unless target.includes_resources? native_targets.each do |native_target| TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target) end return end script_path = target.copy_resources_script_relative_path input_paths_by_config = {} output_paths_by_config = {} if use_input_output_paths target.resource_paths_by_config.each do |config, resource_paths| input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config), target.copy_resources_script_input_files_relative_path) input_paths_by_config[input_paths_key] = [script_path] + resource_paths output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config), target.copy_resources_script_output_files_relative_path) output_paths_by_config[output_paths_key] = TargetIntegrator.resource_output_paths(resource_paths) end end native_targets.each do |native_target| # Static library targets cannot include resources. Skip this phase from being added instead. next if native_target.symbol_type == :static_library TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config) end end |
#add_embed_frameworks_script_phase ⇒ void (private)
This method returns an undefined value.
Find or create a 'Embed Pods Frameworks' Copy Files Build Phase
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 673 def unless target.includes_frameworks? || (target.xcframeworks_by_config.values.flatten.any? { |xcf| xcf.build_type.dynamic_framework? }) .each do |native_target| TargetIntegrator.(native_target) end return end script_path = target. input_paths_by_config = {} output_paths_by_config = {} if use_input_output_paths? configs = Set.new(target.framework_paths_by_config.keys + target.xcframeworks_by_config.keys).sort configs.each do |config| framework_paths = target.framework_paths_by_config[config] || [] xcframeworks = target.xcframeworks_by_config[config] || [] input_paths_key = XCFileListConfigKey.new(target.(config), target.) input_paths_by_config[input_paths_key] = [script_path] + TargetIntegrator.(framework_paths, xcframeworks) output_paths_key = XCFileListConfigKey.new(target.(config), target.) output_paths_by_config[output_paths_key] = TargetIntegrator.(framework_paths, xcframeworks) end end .each do |native_target| TargetIntegrator.(native_target, script_path, input_paths_by_config, output_paths_by_config) end end |
#add_on_demand_resources ⇒ Object (private)
754 755 756 757 758 759 760 761 762 763 764 765 766 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 754 def add_on_demand_resources target.pod_targets.each do |pod_target| # When integrating with the user's project we are only interested in integrating ODRs from library specs # and not test specs or app specs. library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? } target_odr_group_name = "#{pod_target.label}-OnDemandResources" # The 'Pods' group would always be there for production code however for tests its sometimes not added. # This ensures its always present and makes it easier for existing and new tests. parent_odr_group = target.user_project.main_group['Pods'] || target.user_project.new_group('Pods') TargetIntegrator.update_on_demand_resources(target.sandbox, target.user_project, target.user_targets, library_file_accessors, parent_odr_group, target_odr_group_name) end end |
#add_pods_library ⇒ void (private)
This method returns an undefined value.
Adds spec product reference to the frameworks build phase of the TargetDefinition integration libraries. Adds a file reference to the frameworks group of the project and adds it to the frameworks build phase of the targets.
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 592 def add_pods_library frameworks = user_project.frameworks_group native_targets.each do |native_target| build_phase = native_target.frameworks_build_phase product_name = target.product_name # Delete previously integrated references. product_build_files = build_phase.files.select do |build_file| build_file.display_name =~ Pod::Deintegrator::FRAMEWORK_NAMES end product_build_files.each do |product_file| next unless product_name != product_file.display_name UI.("Removing old product reference `#{product_file.display_name}` from project.") frameworks.remove_reference(product_file.file_ref) build_phase.remove_build_file(product_file) end # Find or create and add a reference for the current product type new_product_ref = frameworks.files.find { |f| f.path == product_name } || frameworks.new_product_ref_for_target(target.product_basename, target.product_type) build_phase.build_file(new_product_ref) || build_phase.add_file_reference(new_product_ref, true) end end |
#add_user_script_phases ⇒ void (private)
This method returns an undefined value.
Updates all target script phases for the current target, including creating or updating, deleting and re-ordering.
708 709 710 711 712 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 708 def add_user_script_phases native_targets.each do |native_target| TargetIntegrator.create_or_update_user_script_phases(target.target_definition.script_phases, native_target) end end |
#inspect ⇒ String
Returns a string representation suitable for debugging.
576 577 578 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 576 def inspect "#<#{self.class} for target `#{target.label}'>" end |
#integrate! ⇒ void
This method returns an undefined value.
Integrates the user project targets. Only the targets that do not already have the Pods library in their frameworks build phase are processed.
559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 559 def integrate! UI.section() do XCConfigIntegrator.integrate(target, native_targets) remove_obsolete_script_phases add_pods_library add_copy_resources_script_phase add_check_manifest_lock_script_phase add_user_script_phases add_on_demand_resources end end |
#integration_message ⇒ String (private)
Returns the message that should be displayed for the target integration.
809 810 811 812 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 809 def "Integrating target `#{target.name}` " \ "(#{UI.path target.user_project_path} project)" end |
#native_targets ⇒ Array<PBXNativeTarget> (private)
Returns The list of all the targets that match the given target.
776 777 778 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 776 def native_targets @native_targets ||= target.user_targets end |
#native_targets_to_embed_in ⇒ Array<PBXNativeTarget> (private)
Returns The list of all the targets that require that the pod frameworks are embedded in the output directory / product bundle.
784 785 786 787 788 789 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 784 def return [] if target.requires_host_target? native_targets.select do |target| EMBED_FRAMEWORK_TARGET_TYPES.include?(target.symbol_type) end end |
#remove_embed_frameworks_script_phase_from_embedded_targets ⇒ Object (private)
Older versions of CocoaPods would add this build phase to embedded targets. They should be removed on upgrade because embedded targets will have their frameworks embedded in their host targets.
Removes the embed frameworks build phase from embedded targets
660 661 662 663 664 665 666 667 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 660 def return unless target.requires_host_target? native_targets.each do |native_target| if AggregateTarget::EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include? native_target.symbol_type TargetIntegrator.(native_target) end end end |
#remove_obsolete_script_phases(removed_phase_names = REMOVED_SCRIPT_PHASE_NAMES) ⇒ Object (private)
746 747 748 749 750 751 752 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 746 def remove_obsolete_script_phases(removed_phase_names = REMOVED_SCRIPT_PHASE_NAMES) native_targets.each do |native_target| removed_phase_names.each do |phase_name| TargetIntegrator.remove_script_phase_from_target(native_target, phase_name) end end end |
#spec_consumers ⇒ Specification::Consumer (private)
Returns the consumer for the specifications.
802 803 804 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 802 def spec_consumers @spec_consumers ||= target.pod_targets.map(&:file_accessors).flatten.map(&:spec_consumer) end |
#user_project ⇒ Project (private)
Read the project from the disk to ensure that it is up to date as other TargetIntegrators might have modified it.
796 797 798 |
# File 'lib/cocoapods/installer/user_project_integrator/target_integrator.rb', line 796 def user_project target.user_project end |