xcocoapods 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6303 -0
  3. data/LICENSE +28 -0
  4. data/README.md +80 -0
  5. data/bin/pod +56 -0
  6. data/bin/sandbox-pod +168 -0
  7. data/lib/cocoapods.rb +73 -0
  8. data/lib/cocoapods/command.rb +175 -0
  9. data/lib/cocoapods/command/cache.rb +28 -0
  10. data/lib/cocoapods/command/cache/clean.rb +90 -0
  11. data/lib/cocoapods/command/cache/list.rb +69 -0
  12. data/lib/cocoapods/command/env.rb +66 -0
  13. data/lib/cocoapods/command/init.rb +128 -0
  14. data/lib/cocoapods/command/install.rb +45 -0
  15. data/lib/cocoapods/command/ipc.rb +19 -0
  16. data/lib/cocoapods/command/ipc/list.rb +40 -0
  17. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  18. data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
  19. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  20. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  21. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  22. data/lib/cocoapods/command/lib.rb +11 -0
  23. data/lib/cocoapods/command/lib/create.rb +105 -0
  24. data/lib/cocoapods/command/lib/lint.rb +121 -0
  25. data/lib/cocoapods/command/list.rb +39 -0
  26. data/lib/cocoapods/command/options/project_directory.rb +36 -0
  27. data/lib/cocoapods/command/options/repo_update.rb +34 -0
  28. data/lib/cocoapods/command/outdated.rb +140 -0
  29. data/lib/cocoapods/command/repo.rb +29 -0
  30. data/lib/cocoapods/command/repo/add.rb +103 -0
  31. data/lib/cocoapods/command/repo/lint.rb +82 -0
  32. data/lib/cocoapods/command/repo/list.rb +93 -0
  33. data/lib/cocoapods/command/repo/push.rb +281 -0
  34. data/lib/cocoapods/command/repo/remove.rb +36 -0
  35. data/lib/cocoapods/command/repo/update.rb +28 -0
  36. data/lib/cocoapods/command/setup.rb +103 -0
  37. data/lib/cocoapods/command/spec.rb +112 -0
  38. data/lib/cocoapods/command/spec/cat.rb +51 -0
  39. data/lib/cocoapods/command/spec/create.rb +283 -0
  40. data/lib/cocoapods/command/spec/edit.rb +87 -0
  41. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  42. data/lib/cocoapods/command/spec/lint.rb +137 -0
  43. data/lib/cocoapods/command/spec/which.rb +43 -0
  44. data/lib/cocoapods/command/update.rb +101 -0
  45. data/lib/cocoapods/config.rb +347 -0
  46. data/lib/cocoapods/core_overrides.rb +1 -0
  47. data/lib/cocoapods/downloader.rb +190 -0
  48. data/lib/cocoapods/downloader/cache.rb +233 -0
  49. data/lib/cocoapods/downloader/request.rb +86 -0
  50. data/lib/cocoapods/downloader/response.rb +16 -0
  51. data/lib/cocoapods/executable.rb +222 -0
  52. data/lib/cocoapods/external_sources.rb +57 -0
  53. data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
  54. data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
  55. data/lib/cocoapods/external_sources/path_source.rb +55 -0
  56. data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
  57. data/lib/cocoapods/gem_version.rb +5 -0
  58. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  59. data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
  60. data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
  61. data/lib/cocoapods/generator/app_target_helper.rb +244 -0
  62. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  63. data/lib/cocoapods/generator/constant.rb +19 -0
  64. data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
  65. data/lib/cocoapods/generator/dummy_source.rb +31 -0
  66. data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
  67. data/lib/cocoapods/generator/header.rb +103 -0
  68. data/lib/cocoapods/generator/info_plist_file.rb +116 -0
  69. data/lib/cocoapods/generator/module_map.rb +99 -0
  70. data/lib/cocoapods/generator/prefix_header.rb +60 -0
  71. data/lib/cocoapods/generator/umbrella_header.rb +46 -0
  72. data/lib/cocoapods/hooks_manager.rb +132 -0
  73. data/lib/cocoapods/installer.rb +703 -0
  74. data/lib/cocoapods/installer/analyzer.rb +972 -0
  75. data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
  76. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
  77. data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
  78. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
  79. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  80. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
  81. data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
  82. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
  83. data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
  84. data/lib/cocoapods/installer/installation_options.rb +158 -0
  85. data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
  86. data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
  87. data/lib/cocoapods/installer/podfile_validator.rb +139 -0
  88. data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
  89. data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
  90. data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
  91. data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
  92. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
  93. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
  94. data/lib/cocoapods/installer/xcode.rb +8 -0
  95. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
  96. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
  97. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
  98. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
  99. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
  100. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
  101. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
  102. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
  103. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
  104. data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
  105. data/lib/cocoapods/open-uri.rb +33 -0
  106. data/lib/cocoapods/project.rb +414 -0
  107. data/lib/cocoapods/resolver.rb +585 -0
  108. data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
  109. data/lib/cocoapods/sandbox.rb +404 -0
  110. data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
  111. data/lib/cocoapods/sandbox/headers_store.rb +146 -0
  112. data/lib/cocoapods/sandbox/path_list.rb +220 -0
  113. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
  114. data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
  115. data/lib/cocoapods/sources_manager.rb +157 -0
  116. data/lib/cocoapods/target.rb +261 -0
  117. data/lib/cocoapods/target/aggregate_target.rb +338 -0
  118. data/lib/cocoapods/target/build_settings.rb +1075 -0
  119. data/lib/cocoapods/target/pod_target.rb +559 -0
  120. data/lib/cocoapods/user_interface.rb +459 -0
  121. data/lib/cocoapods/user_interface/error_report.rb +187 -0
  122. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  123. data/lib/cocoapods/validator.rb +981 -0
  124. metadata +533 -0
@@ -0,0 +1,463 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module Pod
4
+ class Installer
5
+ class UserProjectIntegrator
6
+ # This class is responsible for integrating the library generated by a
7
+ # {TargetDefinition} with its destination project.
8
+ #
9
+ class TargetIntegrator
10
+ autoload :XCConfigIntegrator, 'cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator'
11
+
12
+ # @return [String] the string to use as prefix for every build phase added to the user project
13
+ #
14
+ BUILD_PHASE_PREFIX = '[CP] '.freeze
15
+
16
+ # @return [String] the string to use as prefix for every build phase declared by the user within a podfile
17
+ # or podspec.
18
+ #
19
+ USER_BUILD_PHASE_PREFIX = '[CP-User] '.freeze
20
+
21
+ # @return [String] the name of the check manifest phase
22
+ #
23
+ CHECK_MANIFEST_PHASE_NAME = 'Check Pods Manifest.lock'.freeze
24
+
25
+ # @return [Array<Symbol>] the symbol types, which require that the pod
26
+ # frameworks are embedded in the output directory / product bundle.
27
+ #
28
+ # @note This does not include :app_extension or :watch_extension because
29
+ # these types must have their frameworks embedded in their host targets.
30
+ # For messages extensions, this only applies if it's embedded in a messages
31
+ # application.
32
+ #
33
+ EMBED_FRAMEWORK_TARGET_TYPES = [:application, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
34
+
35
+ # @return [String] the name of the embed frameworks phase
36
+ #
37
+ EMBED_FRAMEWORK_PHASE_NAME = 'Embed Pods Frameworks'.freeze
38
+
39
+ # @return [String] the name of the copy resources phase
40
+ #
41
+ COPY_PODS_RESOURCES_PHASE_NAME = 'Copy Pods Resources'.freeze
42
+
43
+ # @return [Integer] the maximum number of input and output paths to use for a script phase
44
+ #
45
+ MAX_INPUT_OUTPUT_PATHS = 1000
46
+
47
+ # @return [AggregateTarget] the target that should be integrated.
48
+ #
49
+ attr_reader :target
50
+
51
+ # Init a new TargetIntegrator
52
+ #
53
+ # @param [AggregateTarget] target @see #target
54
+ #
55
+ def initialize(target)
56
+ @target = target
57
+ end
58
+
59
+ class << self
60
+ # Adds a shell script build phase responsible to copy (embed) the frameworks
61
+ # generated by the TargetDefinition to the bundle of the product of the
62
+ # targets.
63
+ #
64
+ # @param [PBXNativeTarget] native_target
65
+ # The native target to add the script phase into.
66
+ #
67
+ # @param [String] script_path
68
+ # The script path to execute as part of this script phase.
69
+ #
70
+ # @param [Array<String>] input_paths
71
+ # The input paths (if any) to include for this script phase.
72
+ #
73
+ # @param [Array<String>] output_paths
74
+ # The output paths (if any) to include for this script phase.
75
+ #
76
+ # @return [void]
77
+ #
78
+ def create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
79
+ phase = TargetIntegrator.create_or_update_build_phase(native_target, BUILD_PHASE_PREFIX + EMBED_FRAMEWORK_PHASE_NAME)
80
+ phase.shell_script = %("#{script_path}"\n)
81
+ phase.input_paths = input_paths
82
+ phase.output_paths = output_paths
83
+ end
84
+
85
+ # Delete a 'Embed Pods Frameworks' Copy Files Build Phase if present
86
+ #
87
+ # @param [PBXNativeTarget] native_target
88
+ # The native target to remove the script phase from.
89
+ #
90
+ def remove_embed_frameworks_script_phase_from_target(native_target)
91
+ embed_build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(EMBED_FRAMEWORK_PHASE_NAME) }
92
+ return unless embed_build_phase.present?
93
+ native_target.build_phases.delete(embed_build_phase)
94
+ end
95
+
96
+ # Adds a shell script build phase responsible to copy the resources
97
+ # generated by the TargetDefinition to the bundle of the product of the
98
+ # targets.
99
+ #
100
+ # @param [PBXNativeTarget] native_target
101
+ # The native target to add the script phase into.
102
+ #
103
+ # @param [String] script_path
104
+ # The script path to execute as part of this script phase.
105
+ #
106
+ # @param [Array<String>] input_paths
107
+ # The input paths (if any) to include for this script phase.
108
+ #
109
+ # @param [Array<String>] output_paths
110
+ # The output paths (if any) to include for this script phase.
111
+ #
112
+ # @return [void]
113
+ #
114
+ def create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths = [], output_paths = [])
115
+ phase_name = COPY_PODS_RESOURCES_PHASE_NAME
116
+ phase = TargetIntegrator.create_or_update_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name)
117
+ phase.shell_script = %("#{script_path}"\n)
118
+ phase.input_paths = input_paths
119
+ phase.output_paths = output_paths
120
+ end
121
+
122
+ # Delete a 'Copy Pods Resources' script phase if present
123
+ #
124
+ # @param [PBXNativeTarget] native_target
125
+ # The native target to remove the script phase from.
126
+ #
127
+ def remove_copy_resources_script_phase_from_target(native_target)
128
+ build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(COPY_PODS_RESOURCES_PHASE_NAME) }
129
+ return unless build_phase.present?
130
+ native_target.build_phases.delete(build_phase)
131
+ end
132
+
133
+ # Creates or update a shell script build phase for the given target.
134
+ #
135
+ # @param [PBXNativeTarget] native_target
136
+ # The native target to add the script phase into.
137
+ #
138
+ # @param [String] phase_name
139
+ # The name of the phase to use.
140
+ #
141
+ # @param [Class] phase_class
142
+ # The class of the phase to use.
143
+ #
144
+ # @return [void]
145
+ #
146
+ def create_or_update_build_phase(native_target, phase_name, phase_class = Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
147
+ build_phases = native_target.build_phases.grep(phase_class)
148
+ build_phases.find { |phase| phase.name && phase.name.end_with?(phase_name) }.tap { |p| p.name = phase_name if p } ||
149
+ native_target.project.new(phase_class).tap do |phase|
150
+ UI.message("Adding Build Phase '#{phase_name}' to project.") do
151
+ phase.name = phase_name
152
+ phase.show_env_vars_in_log = '0'
153
+ native_target.build_phases << phase
154
+ end
155
+ end
156
+ end
157
+
158
+ # Updates all target script phases for the current target, including creating or updating, deleting
159
+ # and re-ordering.
160
+ #
161
+ # @return [void]
162
+ #
163
+ def create_or_update_user_script_phases(script_phases, native_target)
164
+ script_phase_names = script_phases.map { |k| k[:name] }
165
+ # Delete script phases no longer present in the target.
166
+ native_target_script_phases = native_target.shell_script_build_phases.select { |bp| !bp.name.nil? && bp.name.start_with?(USER_BUILD_PHASE_PREFIX) }
167
+ native_target_script_phases.each do |script_phase|
168
+ script_phase_name_without_prefix = script_phase.name.sub(USER_BUILD_PHASE_PREFIX, '')
169
+ unless script_phase_names.include?(script_phase_name_without_prefix)
170
+ native_target.build_phases.delete(script_phase)
171
+ end
172
+ end
173
+ # Create or update the ones that are expected to be.
174
+ script_phases.each do |script_phase|
175
+ name_with_prefix = USER_BUILD_PHASE_PREFIX + script_phase[:name]
176
+ phase = TargetIntegrator.create_or_update_build_phase(native_target, name_with_prefix)
177
+ phase.shell_script = script_phase[:script]
178
+ phase.shell_path = script_phase[:shell_path] if script_phase.key?(:shell_path)
179
+ phase.input_paths = script_phase[:input_files] if script_phase.key?(:input_files)
180
+ phase.output_paths = script_phase[:output_files] if script_phase.key?(:output_files)
181
+ phase.show_env_vars_in_log = script_phase[:show_env_vars_in_log] ? '1' : '0' if script_phase.key?(:show_env_vars_in_log)
182
+
183
+ execution_position = script_phase[:execution_position]
184
+ unless execution_position == :any
185
+ compile_build_phase_index = native_target.build_phases.index do |bp|
186
+ bp.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase)
187
+ end
188
+ unless compile_build_phase_index.nil?
189
+ script_phase_index = native_target.build_phases.index do |bp|
190
+ bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && !bp.name.nil? && bp.name == name_with_prefix
191
+ end
192
+ if (execution_position == :before_compile && script_phase_index > compile_build_phase_index) ||
193
+ (execution_position == :after_compile && script_phase_index < compile_build_phase_index)
194
+ native_target.build_phases.move_from(script_phase_index, compile_build_phase_index)
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ # Script phases can have a limited number of input and output paths due to each one being exported to `env`.
202
+ # A large number can cause a build failure because of limitations in `env`. See issue
203
+ # https://github.com/CocoaPods/CocoaPods/issues/7362.
204
+ #
205
+ # @param [Array<String>] input_paths
206
+ # The input paths to trim.
207
+ #
208
+ # @param [Array<String>] output_paths
209
+ # The output paths to trim.
210
+ #
211
+ # @return [void]
212
+ #
213
+ def validate_input_output_path_limit(input_paths, output_paths)
214
+ if (input_paths.count + output_paths.count) > MAX_INPUT_OUTPUT_PATHS
215
+ input_paths.clear
216
+ output_paths.clear
217
+ end
218
+ end
219
+
220
+ # Returns an extension in the target that corresponds to the
221
+ # resource's input extension.
222
+ #
223
+ # @param [String] input_extension
224
+ # The input extension to map to.
225
+ #
226
+ # @return [String] The output extension.
227
+ #
228
+ def output_extension_for_resource(input_extension)
229
+ case input_extension
230
+ when '.storyboard' then '.storyboardc'
231
+ when '.xib' then '.nib'
232
+ when '.framework' then '.framework'
233
+ when '.xcdatamodel' then '.mom'
234
+ when '.xcdatamodeld' then '.momd'
235
+ when '.xcmappingmodel' then '.cdm'
236
+ when '.xcassets' then '.car'
237
+ else input_extension
238
+ end
239
+ end
240
+
241
+ # Returns the resource output paths for all given input paths.
242
+ #
243
+ # @param [Array<String>] resource_input_paths
244
+ # The input paths to map to.
245
+ #
246
+ # @return [Array<String>] The resource output paths.
247
+ #
248
+ def resource_output_paths(resource_input_paths)
249
+ resource_input_paths.map do |resource_input_path|
250
+ base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}'
251
+ extname = File.extname(resource_input_path)
252
+ basename = extname == '.xcassets' ? 'Assets' : File.basename(resource_input_path)
253
+ output_extension = TargetIntegrator.output_extension_for_resource(extname)
254
+ File.join(base_path, File.basename(basename, extname) + output_extension)
255
+ end.uniq
256
+ end
257
+ end
258
+
259
+ # Integrates the user project targets. Only the targets that do **not**
260
+ # already have the Pods library in their frameworks build phase are
261
+ # processed.
262
+ #
263
+ # @return [void]
264
+ #
265
+ def integrate!
266
+ UI.section(integration_message) do
267
+ XCConfigIntegrator.integrate(target, native_targets)
268
+
269
+ add_pods_library
270
+ add_embed_frameworks_script_phase
271
+ remove_embed_frameworks_script_phase_from_embedded_targets
272
+ add_copy_resources_script_phase
273
+ add_check_manifest_lock_script_phase
274
+ add_user_script_phases
275
+ end
276
+ end
277
+
278
+ # @return [String] a string representation suitable for debugging.
279
+ #
280
+ def inspect
281
+ "#<#{self.class} for target `#{target.label}'>"
282
+ end
283
+
284
+ private
285
+
286
+ # @!group Integration steps
287
+ #---------------------------------------------------------------------#
288
+
289
+ # Adds spec product reference to the frameworks build phase of the
290
+ # {TargetDefinition} integration libraries. Adds a file reference to
291
+ # the frameworks group of the project and adds it to the frameworks
292
+ # build phase of the targets.
293
+ #
294
+ # @return [void]
295
+ #
296
+ def add_pods_library
297
+ frameworks = user_project.frameworks_group
298
+ native_targets.each do |native_target|
299
+ build_phase = native_target.frameworks_build_phase
300
+
301
+ # Find and delete possible reference for the other product type
302
+ old_product_name = target.requires_frameworks? ? target.static_library_name : target.framework_name
303
+ old_product_ref = frameworks.files.find { |f| f.path == old_product_name }
304
+ if old_product_ref.present?
305
+ UI.message("Removing old Pod product reference #{old_product_name} from project.")
306
+ build_phase.remove_file_reference(old_product_ref)
307
+ frameworks.remove_reference(old_product_ref)
308
+ end
309
+
310
+ # Find or create and add a reference for the current product type
311
+ target_basename = target.product_basename
312
+ new_product_ref = frameworks.files.find { |f| f.path == target.product_name } ||
313
+ frameworks.new_product_ref_for_target(target_basename, target.product_type)
314
+ build_phase.build_file(new_product_ref) ||
315
+ build_phase.add_file_reference(new_product_ref, true)
316
+ end
317
+ end
318
+
319
+ # Find or create a 'Copy Pods Resources' build phase
320
+ #
321
+ # @return [void]
322
+ #
323
+ def add_copy_resources_script_phase
324
+ native_targets.each do |native_target|
325
+ # Static library targets cannot include resources. Skip this phase from being added instead.
326
+ next if native_target.symbol_type == :static_library
327
+ script_path = target.copy_resources_script_relative_path
328
+ resource_paths_by_config = target.resource_paths_by_config
329
+ if resource_paths_by_config.values.all?(&:empty?)
330
+ TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target)
331
+ else
332
+ resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
333
+ input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
334
+ output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
335
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
336
+ TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
337
+ end
338
+ end
339
+ end
340
+
341
+ # Removes the embed frameworks build phase from embedded targets
342
+ #
343
+ # @note Older versions of CocoaPods would add this build phase to embedded
344
+ # targets. They should be removed on upgrade because embedded targets
345
+ # will have their frameworks embedded in their host targets.
346
+ #
347
+ def remove_embed_frameworks_script_phase_from_embedded_targets
348
+ return unless target.requires_host_target?
349
+ native_targets.each do |native_target|
350
+ if AggregateTarget::EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include? native_target.symbol_type
351
+ TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
352
+ end
353
+ end
354
+ end
355
+
356
+ # Find or create a 'Embed Pods Frameworks' Copy Files Build Phase
357
+ #
358
+ # @return [void]
359
+ #
360
+ def add_embed_frameworks_script_phase
361
+ native_targets_to_embed_in.each do |native_target|
362
+ script_path = target.embed_frameworks_script_relative_path
363
+ framework_paths_by_config = target.framework_paths_by_config.values.flatten.uniq
364
+ if framework_paths_by_config.all?(&:empty?)
365
+ TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
366
+ else
367
+ input_paths = [target.embed_frameworks_script_relative_path, *framework_paths_by_config.map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.flatten.compact]
368
+ output_paths = framework_paths_by_config.map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.flatten.compact.uniq
369
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
370
+ TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
371
+ end
372
+ end
373
+ end
374
+
375
+ # Updates all target script phases for the current target, including creating or updating, deleting
376
+ # and re-ordering.
377
+ #
378
+ # @return [void]
379
+ #
380
+ def add_user_script_phases
381
+ native_targets.each do |native_target|
382
+ TargetIntegrator.create_or_update_user_script_phases(target.target_definition.script_phases, native_target)
383
+ end
384
+ end
385
+
386
+ # Adds a shell script build phase responsible for checking if the Pods
387
+ # locked in the Pods/Manifest.lock file are in sync with the Pods defined
388
+ # in the Podfile.lock.
389
+ #
390
+ # @note The build phase is appended to the front because to fail
391
+ # fast.
392
+ #
393
+ # @return [void]
394
+ #
395
+ def add_check_manifest_lock_script_phase
396
+ phase_name = CHECK_MANIFEST_PHASE_NAME
397
+ native_targets.each do |native_target|
398
+ phase = TargetIntegrator.create_or_update_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name)
399
+ native_target.build_phases.unshift(phase).uniq! unless native_target.build_phases.first == phase
400
+ phase.shell_script = <<-SH.strip_heredoc
401
+ diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
402
+ if [ $? != 0 ] ; then
403
+ # print error to STDERR
404
+ echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
405
+ exit 1
406
+ fi
407
+ # This output is used by Xcode 'outputs' to avoid re-running this script phase.
408
+ echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
409
+ SH
410
+ phase.input_paths = %w(${PODS_PODFILE_DIR_PATH}/Podfile.lock ${PODS_ROOT}/Manifest.lock)
411
+ phase.output_paths = [target.check_manifest_lock_script_output_file_path]
412
+ end
413
+ end
414
+
415
+ private
416
+
417
+ # @!group Private Helpers
418
+ #---------------------------------------------------------------------#
419
+
420
+ # @return [Array<PBXNativeTarget>] The list of all the targets that
421
+ # match the given target.
422
+ #
423
+ def native_targets
424
+ @native_targets ||= target.user_targets
425
+ end
426
+
427
+ # @return [Array<PBXNativeTarget>] The list of all the targets that
428
+ # require that the pod frameworks are embedded in the output
429
+ # directory / product bundle.
430
+ #
431
+ def native_targets_to_embed_in
432
+ return [] if target.requires_host_target?
433
+ native_targets.select do |target|
434
+ EMBED_FRAMEWORK_TARGET_TYPES.include?(target.symbol_type)
435
+ end
436
+ end
437
+
438
+ # Read the project from the disk to ensure that it is up to date as
439
+ # other TargetIntegrators might have modified it.
440
+ #
441
+ # @return [Project]
442
+ #
443
+ def user_project
444
+ target.user_project
445
+ end
446
+
447
+ # @return [Specification::Consumer] the consumer for the specifications.
448
+ #
449
+ def spec_consumers
450
+ @spec_consumers ||= target.pod_targets.map(&:file_accessors).flatten.map(&:spec_consumer)
451
+ end
452
+
453
+ # @return [String] the message that should be displayed for the target
454
+ # integration.
455
+ #
456
+ def integration_message
457
+ "Integrating target `#{target.name}` " \
458
+ "(#{UI.path target.user_project_path} project)"
459
+ end
460
+ end
461
+ end
462
+ end
463
+ end