cocoapods-tt 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/cocoapods-tt/command/native/install.rb +56 -0
- data/lib/cocoapods-tt/command/native/update.rb +157 -0
- data/lib/cocoapods-tt/command/tt/make.rb +92 -0
- data/lib/cocoapods-tt/command/tt.rb +115 -0
- data/lib/cocoapods-tt/command.rb +1 -0
- data/lib/cocoapods-tt/gem_version.rb +3 -0
- data/lib/cocoapods-tt/native/command.rb +185 -0
- data/lib/cocoapods-tt/native/config.rb +366 -0
- data/lib/cocoapods-tt/native/core_overrides.rb +1 -0
- data/lib/cocoapods-tt/native/downloader/cache.rb +322 -0
- data/lib/cocoapods-tt/native/downloader/request.rb +86 -0
- data/lib/cocoapods-tt/native/downloader/response.rb +16 -0
- data/lib/cocoapods-tt/native/downloader.rb +192 -0
- data/lib/cocoapods-tt/native/executable.rb +247 -0
- data/lib/cocoapods-tt/native/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods-tt/native/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods-tt/native/external_sources/path_source.rb +55 -0
- data/lib/cocoapods-tt/native/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods-tt/native/external_sources.rb +57 -0
- data/lib/cocoapods-tt/native/gem_version.rb +5 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods-tt/native/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods-tt/native/generator/app_target_helper.rb +363 -0
- data/lib/cocoapods-tt/native/generator/bridge_support.rb +22 -0
- data/lib/cocoapods-tt/native/generator/constant.rb +19 -0
- data/lib/cocoapods-tt/native/generator/copy_dsyms_script.rb +56 -0
- data/lib/cocoapods-tt/native/generator/copy_resources_script.rb +223 -0
- data/lib/cocoapods-tt/native/generator/copy_xcframework_script.rb +227 -0
- data/lib/cocoapods-tt/native/generator/dummy_source.rb +31 -0
- data/lib/cocoapods-tt/native/generator/embed_frameworks_script.rb +196 -0
- data/lib/cocoapods-tt/native/generator/file_list.rb +39 -0
- data/lib/cocoapods-tt/native/generator/header.rb +103 -0
- data/lib/cocoapods-tt/native/generator/info_plist_file.rb +128 -0
- data/lib/cocoapods-tt/native/generator/module_map.rb +99 -0
- data/lib/cocoapods-tt/native/generator/prefix_header.rb +60 -0
- data/lib/cocoapods-tt/native/generator/script_phase_constants.rb +100 -0
- data/lib/cocoapods-tt/native/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods-tt/native/hooks_manager.rb +132 -0
- data/lib/cocoapods-tt/native/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods-tt/native/installer/analyzer/locking_dependency_analyzer.rb +103 -0
- data/lib/cocoapods-tt/native/installer/analyzer/pod_variant.rb +87 -0
- data/lib/cocoapods-tt/native/installer/analyzer/pod_variant_set.rb +175 -0
- data/lib/cocoapods-tt/native/installer/analyzer/podfile_dependency_cache.rb +55 -0
- data/lib/cocoapods-tt/native/installer/analyzer/sandbox_analyzer.rb +268 -0
- data/lib/cocoapods-tt/native/installer/analyzer/specs_state.rb +108 -0
- data/lib/cocoapods-tt/native/installer/analyzer/target_inspection_result.rb +58 -0
- data/lib/cocoapods-tt/native/installer/analyzer/target_inspector.rb +258 -0
- data/lib/cocoapods-tt/native/installer/analyzer.rb +1204 -0
- data/lib/cocoapods-tt/native/installer/base_install_hooks_context.rb +135 -0
- data/lib/cocoapods-tt/native/installer/installation_options.rb +195 -0
- data/lib/cocoapods-tt/native/installer/pod_source_installer.rb +224 -0
- data/lib/cocoapods-tt/native/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods-tt/native/installer/podfile_validator.rb +168 -0
- data/lib/cocoapods-tt/native/installer/post_install_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/post_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods-tt/native/installer/pre_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache.rb +11 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analysis_result.rb +53 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analyzer.rb +200 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_cache_version.rb +43 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_installation_cache.rb +103 -0
- data/lib/cocoapods-tt/native/installer/project_cache/project_metadata_cache.rb +73 -0
- data/lib/cocoapods-tt/native/installer/project_cache/target_cache_key.rb +176 -0
- data/lib/cocoapods-tt/native/installer/project_cache/target_metadata.rb +74 -0
- data/lib/cocoapods-tt/native/installer/sandbox_dir_cleaner.rb +105 -0
- data/lib/cocoapods-tt/native/installer/sandbox_header_paths_installer.rb +45 -0
- data/lib/cocoapods-tt/native/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods-tt/native/installer/target_uuid_generator.rb +34 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +179 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator.rb +815 -0
- data/lib/cocoapods-tt/native/installer/user_project_integrator.rb +280 -0
- data/lib/cocoapods-tt/native/installer/xcode/multi_pods_project_generator.rb +82 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +66 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb +192 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/app_host_installer.rb +154 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/file_references_installer.rb +329 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +195 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_installer.rb +1239 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_integrator.rb +312 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pods_project_writer.rb +90 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/project_generator.rb +120 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installation_result.rb +140 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer.rb +257 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer_helper.rb +110 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator.rb +291 -0
- data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator_result.rb +54 -0
- data/lib/cocoapods-tt/native/installer/xcode/single_pods_project_generator.rb +38 -0
- data/lib/cocoapods-tt/native/installer/xcode/target_validator.rb +170 -0
- data/lib/cocoapods-tt/native/installer/xcode.rb +11 -0
- data/lib/cocoapods-tt/native/installer.rb +1044 -0
- data/lib/cocoapods-tt/native/native_target_extension.rb +60 -0
- data/lib/cocoapods-tt/native/open-uri.rb +33 -0
- data/lib/cocoapods-tt/native/podfile.rb +13 -0
- data/lib/cocoapods-tt/native/project.rb +544 -0
- data/lib/cocoapods-tt/native/resolver/lazy_specification.rb +88 -0
- data/lib/cocoapods-tt/native/resolver/resolver_specification.rb +41 -0
- data/lib/cocoapods-tt/native/resolver.rb +600 -0
- data/lib/cocoapods-tt/native/sandbox/file_accessor.rb +532 -0
- data/lib/cocoapods-tt/native/sandbox/headers_store.rb +163 -0
- data/lib/cocoapods-tt/native/sandbox/path_list.rb +242 -0
- data/lib/cocoapods-tt/native/sandbox/pod_dir_cleaner.rb +71 -0
- data/lib/cocoapods-tt/native/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods-tt/native/sandbox.rb +470 -0
- data/lib/cocoapods-tt/native/sources_manager.rb +221 -0
- data/lib/cocoapods-tt/native/target/aggregate_target.rb +558 -0
- data/lib/cocoapods-tt/native/target/build_settings.rb +1385 -0
- data/lib/cocoapods-tt/native/target/pod_target.rb +1168 -0
- data/lib/cocoapods-tt/native/target.rb +378 -0
- data/lib/cocoapods-tt/native/user_interface/error_report.rb +204 -0
- data/lib/cocoapods-tt/native/user_interface/inspector_reporter.rb +102 -0
- data/lib/cocoapods-tt/native/user_interface.rb +463 -0
- data/lib/cocoapods-tt/native/validator.rb +1170 -0
- data/lib/cocoapods-tt/native/version_metadata.rb +26 -0
- data/lib/cocoapods-tt/native/xcode/framework_paths.rb +54 -0
- data/lib/cocoapods-tt/native/xcode/linkage_analyzer.rb +22 -0
- data/lib/cocoapods-tt/native/xcode/xcframework/xcframework_slice.rb +138 -0
- data/lib/cocoapods-tt/native/xcode/xcframework.rb +99 -0
- data/lib/cocoapods-tt/native/xcode.rb +7 -0
- data/lib/cocoapods-tt.rb +1 -0
- data/lib/cocoapods_plugin.rb +17 -0
- metadata +193 -0
@@ -0,0 +1,815 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'cocoapods/xcode/framework_paths'
|
3
|
+
require 'cocoapods/target/build_settings'
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
class Installer
|
7
|
+
class UserProjectIntegrator
|
8
|
+
# This class is responsible for integrating the library generated by a
|
9
|
+
# {TargetDefinition} with its destination project.
|
10
|
+
#
|
11
|
+
class TargetIntegrator
|
12
|
+
autoload :XCConfigIntegrator, 'cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator'
|
13
|
+
|
14
|
+
# @return [String] the string to use as prefix for every build phase added to the user project
|
15
|
+
#
|
16
|
+
BUILD_PHASE_PREFIX = '[CP] '.freeze
|
17
|
+
|
18
|
+
# @return [String] the string to use as prefix for every build phase declared by the user within a podfile
|
19
|
+
# or podspec.
|
20
|
+
#
|
21
|
+
USER_BUILD_PHASE_PREFIX = '[CP-User] '.freeze
|
22
|
+
|
23
|
+
# @return [String] the name of the check manifest phase
|
24
|
+
#
|
25
|
+
CHECK_MANIFEST_PHASE_NAME = 'Check Pods Manifest.lock'.freeze
|
26
|
+
|
27
|
+
# @return [Array<Symbol>] the symbol types, which require that the pod
|
28
|
+
# frameworks are embedded in the output directory / product bundle.
|
29
|
+
#
|
30
|
+
# @note This does not include :app_extension or :watch_extension because
|
31
|
+
# these types must have their frameworks embedded in their host targets.
|
32
|
+
# For messages extensions, this only applies if it's embedded in a messages
|
33
|
+
# application.
|
34
|
+
#
|
35
|
+
EMBED_FRAMEWORK_TARGET_TYPES = [:application, :application_on_demand_install_capable, :unit_test_bundle,
|
36
|
+
:ui_test_bundle, :watch2_extension, :messages_application].freeze
|
37
|
+
|
38
|
+
# @return [String] the name of the embed frameworks phase
|
39
|
+
#
|
40
|
+
EMBED_FRAMEWORK_PHASE_NAME = 'Embed Pods Frameworks'.freeze
|
41
|
+
|
42
|
+
# @return [String] the name of the copy xcframeworks phase
|
43
|
+
#
|
44
|
+
COPY_XCFRAMEWORKS_PHASE_NAME = 'Copy XCFrameworks'.freeze
|
45
|
+
|
46
|
+
# @return [String] the name of the copy resources phase
|
47
|
+
#
|
48
|
+
COPY_PODS_RESOURCES_PHASE_NAME = 'Copy Pods Resources'.freeze
|
49
|
+
|
50
|
+
# @return [String] the name of the copy dSYM files phase
|
51
|
+
#
|
52
|
+
COPY_DSYM_FILES_PHASE_NAME = 'Copy dSYMs'.freeze
|
53
|
+
|
54
|
+
# @return [Integer] the maximum number of input and output paths to use for a script phase
|
55
|
+
#
|
56
|
+
MAX_INPUT_OUTPUT_PATHS = 1000
|
57
|
+
|
58
|
+
# @return [Array<String>] names of script phases that existed in previous versions of CocoaPods
|
59
|
+
#
|
60
|
+
REMOVED_SCRIPT_PHASE_NAMES = [
|
61
|
+
'Prepare Artifacts'.freeze,
|
62
|
+
].freeze
|
63
|
+
|
64
|
+
# @return [float] Returns Minimum Xcode Compatibility version for FileLists
|
65
|
+
#
|
66
|
+
MIN_FILE_LIST_COMPATIBILITY_VERSION = 9.3
|
67
|
+
|
68
|
+
# @return [String] Returns Minimum Xcode Object version for FileLists
|
69
|
+
#
|
70
|
+
MIN_FILE_LIST_OBJECT_VERSION = 50
|
71
|
+
|
72
|
+
# @return [AggregateTarget] the target that should be integrated.
|
73
|
+
#
|
74
|
+
attr_reader :target
|
75
|
+
|
76
|
+
# @return [Boolean] whether to use input/output paths for build phase scripts
|
77
|
+
#
|
78
|
+
attr_reader :use_input_output_paths
|
79
|
+
alias use_input_output_paths? use_input_output_paths
|
80
|
+
|
81
|
+
# Init a new TargetIntegrator
|
82
|
+
#
|
83
|
+
# @param [AggregateTarget] target @see #target
|
84
|
+
# @param [Boolean] use_input_output_paths @see #use_input_output_paths
|
85
|
+
#
|
86
|
+
def initialize(target, use_input_output_paths: true)
|
87
|
+
@target = target
|
88
|
+
@use_input_output_paths = use_input_output_paths
|
89
|
+
end
|
90
|
+
|
91
|
+
# @private
|
92
|
+
#
|
93
|
+
XCFileListConfigKey = Struct.new(:file_list_path, :file_list_relative_path)
|
94
|
+
|
95
|
+
class << self
|
96
|
+
# @param [Xcodeproj::Project::Object::AbstractObject] object
|
97
|
+
#
|
98
|
+
# @return [Boolean] Whether input & output paths for the given object
|
99
|
+
# should be stored in a file list file.
|
100
|
+
#
|
101
|
+
def input_output_paths_use_filelist?(object)
|
102
|
+
unless object.project.root_object.compatibility_version.nil?
|
103
|
+
version_match = object.project.root_object.compatibility_version.match(/Xcode ([0-9]*\.[0-9]*)/).to_a
|
104
|
+
end
|
105
|
+
if version_match&.at(1).nil?
|
106
|
+
object.project.object_version.to_i >= MIN_FILE_LIST_OBJECT_VERSION
|
107
|
+
else
|
108
|
+
Pod::Version.new(version_match[1]) >= Pod::Version.new(MIN_FILE_LIST_COMPATIBILITY_VERSION)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Sets the input & output paths for the given script build phase.
|
113
|
+
#
|
114
|
+
# @param [Xcodeproj::Project::Object::PBXShellScriptBuildPhase] phase
|
115
|
+
# The phase to set input & output paths on.
|
116
|
+
#
|
117
|
+
# @param [Hash] input_paths_by_config
|
118
|
+
#
|
119
|
+
# @return [Void]
|
120
|
+
def set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
121
|
+
if input_output_paths_use_filelist?(phase)
|
122
|
+
[input_paths_by_config, output_paths_by_config].each do |hash|
|
123
|
+
hash.each do |file_list, files|
|
124
|
+
generator = Generator::FileList.new(files)
|
125
|
+
Xcode::PodsProjectGenerator::TargetInstallerHelper.update_changed_file(generator, file_list.file_list_path)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
phase.input_paths = nil
|
130
|
+
phase.output_paths = nil
|
131
|
+
phase.input_file_list_paths = input_paths_by_config.each_key.map(&:file_list_relative_path).uniq
|
132
|
+
phase.output_file_list_paths = output_paths_by_config.each_key.map(&:file_list_relative_path).uniq
|
133
|
+
else
|
134
|
+
input_paths = input_paths_by_config.values.flatten(1).uniq
|
135
|
+
output_paths = output_paths_by_config.values.flatten(1).uniq
|
136
|
+
TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
|
137
|
+
|
138
|
+
phase.input_paths = input_paths
|
139
|
+
phase.output_paths = output_paths
|
140
|
+
phase.input_file_list_paths = nil
|
141
|
+
phase.output_file_list_paths = nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Adds a shell script build phase responsible to copy (embed) the frameworks
|
146
|
+
# generated by the TargetDefinition to the bundle of the product of the
|
147
|
+
# targets.
|
148
|
+
#
|
149
|
+
# @param [PBXNativeTarget] native_target
|
150
|
+
# The native target to add the script phase into.
|
151
|
+
#
|
152
|
+
# @param [String] script_path
|
153
|
+
# The script path to execute as part of this script phase.
|
154
|
+
#
|
155
|
+
# @param [Hash<Array, String>] input_paths_by_config
|
156
|
+
# The input paths (if any) to include for this script phase.
|
157
|
+
#
|
158
|
+
# @param [Hash<Array, String>] output_paths_by_config
|
159
|
+
# The output paths (if any) to include for this script phase.
|
160
|
+
#
|
161
|
+
# @return [void]
|
162
|
+
#
|
163
|
+
def create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {})
|
164
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + EMBED_FRAMEWORK_PHASE_NAME)
|
165
|
+
phase.shell_script = %("#{script_path}"\n)
|
166
|
+
TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Delete a 'Embed Pods Frameworks' Script Build Phase if present
|
170
|
+
#
|
171
|
+
# @param [PBXNativeTarget] native_target
|
172
|
+
# The native target to remove the script phase from.
|
173
|
+
#
|
174
|
+
def remove_embed_frameworks_script_phase_from_target(native_target)
|
175
|
+
remove_script_phase_from_target(native_target, EMBED_FRAMEWORK_PHASE_NAME)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Adds a shell script build phase responsible to copy the xcframework slice
|
179
|
+
# to the intermediate build directory.
|
180
|
+
#
|
181
|
+
# @param [PBXNativeTarget] native_target
|
182
|
+
# The native target to add the script phase into.
|
183
|
+
#
|
184
|
+
# @param [String] script_path
|
185
|
+
# The script path to execute as part of this script phase.
|
186
|
+
#
|
187
|
+
# @param [Hash<Array, String>] input_paths_by_config
|
188
|
+
# The input paths (if any) to include for this script phase.
|
189
|
+
#
|
190
|
+
# @param [Hash<Array, String>] output_paths_by_config
|
191
|
+
# The output paths (if any) to include for this script phase.
|
192
|
+
#
|
193
|
+
# @return [void]
|
194
|
+
#
|
195
|
+
def create_or_update_copy_xcframeworks_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {})
|
196
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + COPY_XCFRAMEWORKS_PHASE_NAME)
|
197
|
+
phase.shell_script = %("#{script_path}"\n)
|
198
|
+
TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
199
|
+
reorder_script_phase(native_target, phase, :before_compile)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Delete a 'Copy XCFrameworks' Script Build Phase if present
|
203
|
+
#
|
204
|
+
# @param [PBXNativeTarget] native_target
|
205
|
+
# The native target to remove the script phase from.
|
206
|
+
#
|
207
|
+
def remove_copy_xcframeworks_script_phase_from_target(native_target)
|
208
|
+
remove_script_phase_from_target(native_target, COPY_XCFRAMEWORKS_PHASE_NAME)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Removes a script phase from a native target by name
|
212
|
+
#
|
213
|
+
# @param [PBXNativeTarget] native_target
|
214
|
+
# The target from which the script phased should be removed
|
215
|
+
#
|
216
|
+
# @param [String] phase_name
|
217
|
+
# The name of the script phase to remove
|
218
|
+
#
|
219
|
+
def remove_script_phase_from_target(native_target, phase_name)
|
220
|
+
build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(phase_name) }
|
221
|
+
return unless build_phase.present?
|
222
|
+
native_target.build_phases.delete(build_phase)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Adds a shell script build phase responsible to copy the resources
|
226
|
+
# generated by the TargetDefinition to the bundle of the product of the
|
227
|
+
# targets.
|
228
|
+
#
|
229
|
+
# @param [PBXNativeTarget] native_target
|
230
|
+
# The native target to add the script phase into.
|
231
|
+
#
|
232
|
+
# @param [String] script_path
|
233
|
+
# The script path to execute as part of this script phase.
|
234
|
+
#
|
235
|
+
# @param [Hash<Array, String>] input_paths_by_config
|
236
|
+
# The input paths (if any) to include for this script phase.
|
237
|
+
#
|
238
|
+
# @param [Hash<Array, String>] output_paths_by_config
|
239
|
+
# The output paths (if any) to include for this script phase.
|
240
|
+
#
|
241
|
+
# @return [void]
|
242
|
+
#
|
243
|
+
def create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config = {}, output_paths_by_config = {})
|
244
|
+
phase_name = COPY_PODS_RESOURCES_PHASE_NAME
|
245
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name)
|
246
|
+
phase.shell_script = %("#{script_path}"\n)
|
247
|
+
TargetIntegrator.set_input_output_paths(phase, input_paths_by_config, output_paths_by_config)
|
248
|
+
end
|
249
|
+
|
250
|
+
# Delete a 'Copy Pods Resources' script phase if present
|
251
|
+
#
|
252
|
+
# @param [PBXNativeTarget] native_target
|
253
|
+
# The native target to remove the script phase from.
|
254
|
+
#
|
255
|
+
def remove_copy_resources_script_phase_from_target(native_target)
|
256
|
+
build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(COPY_PODS_RESOURCES_PHASE_NAME) }
|
257
|
+
return unless build_phase.present?
|
258
|
+
native_target.build_phases.delete(build_phase)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Creates or update a shell script build phase for the given target.
|
262
|
+
#
|
263
|
+
# @param [PBXNativeTarget] native_target
|
264
|
+
# The native target to add the script phase into.
|
265
|
+
#
|
266
|
+
# @param [String] script_phase_name
|
267
|
+
# The name of the script phase to use.
|
268
|
+
#
|
269
|
+
# @param [String] show_env_vars_in_log
|
270
|
+
# The value to set for show environment variables in the log during execution of this script phase or
|
271
|
+
# `nil` for not setting the value at all.
|
272
|
+
#
|
273
|
+
# @return [PBXShellScriptBuildPhase] The existing or newly created shell script build phase.
|
274
|
+
#
|
275
|
+
def create_or_update_shell_script_build_phase(native_target, script_phase_name, show_env_vars_in_log = '0')
|
276
|
+
build_phases = native_target.build_phases.grep(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
|
277
|
+
build_phases.find { |phase| phase.name && phase.name.end_with?(script_phase_name) }.tap { |p| p.name = script_phase_name if p } ||
|
278
|
+
native_target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase).tap do |phase|
|
279
|
+
UI.message("Adding Build Phase '#{script_phase_name}' to project.") do
|
280
|
+
phase.name = script_phase_name
|
281
|
+
unless show_env_vars_in_log.nil?
|
282
|
+
phase.show_env_vars_in_log = show_env_vars_in_log
|
283
|
+
end
|
284
|
+
native_target.build_phases << phase
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Updates all target script phases for the current target, including creating or updating, deleting
|
290
|
+
# and re-ordering.
|
291
|
+
#
|
292
|
+
# @return [void]
|
293
|
+
#
|
294
|
+
def create_or_update_user_script_phases(script_phases, native_target)
|
295
|
+
script_phase_names = script_phases.map { |k| k[:name] }
|
296
|
+
# Delete script phases no longer present in the target.
|
297
|
+
native_target_script_phases = native_target.shell_script_build_phases.select do |bp|
|
298
|
+
!bp.name.nil? && bp.name.start_with?(USER_BUILD_PHASE_PREFIX)
|
299
|
+
end
|
300
|
+
native_target_script_phases.each do |script_phase|
|
301
|
+
script_phase_name_without_prefix = script_phase.name.sub(USER_BUILD_PHASE_PREFIX, '')
|
302
|
+
unless script_phase_names.include?(script_phase_name_without_prefix)
|
303
|
+
native_target.build_phases.delete(script_phase)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
# Create or update the ones that are expected to be.
|
307
|
+
script_phases.each do |script_phase|
|
308
|
+
name_with_prefix = USER_BUILD_PHASE_PREFIX + script_phase[:name]
|
309
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, name_with_prefix, nil)
|
310
|
+
phase.shell_script = script_phase[:script]
|
311
|
+
phase.shell_path = script_phase[:shell_path] || '/bin/sh'
|
312
|
+
phase.input_paths = script_phase[:input_files]
|
313
|
+
phase.output_paths = script_phase[:output_files]
|
314
|
+
phase.input_file_list_paths = script_phase[:input_file_lists]
|
315
|
+
phase.output_file_list_paths = script_phase[:output_file_lists]
|
316
|
+
phase.dependency_file = script_phase[:dependency_file]
|
317
|
+
# At least with Xcode 10 `showEnvVarsInLog` is *NOT* set to any value even if it's checked and it only
|
318
|
+
# gets set to '0' if the user has explicitly disabled this.
|
319
|
+
if (show_env_vars_in_log = script_phase.fetch(:show_env_vars_in_log, '1')) == '0'
|
320
|
+
phase.show_env_vars_in_log = show_env_vars_in_log
|
321
|
+
end
|
322
|
+
|
323
|
+
execution_position = script_phase[:execution_position]
|
324
|
+
reorder_script_phase(native_target, phase, execution_position)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def reorder_script_phase(native_target, script_phase, execution_position)
|
329
|
+
return if execution_position == :any || execution_position.to_s.empty?
|
330
|
+
target_phase_type = case execution_position
|
331
|
+
when :before_compile, :after_compile
|
332
|
+
Xcodeproj::Project::Object::PBXSourcesBuildPhase
|
333
|
+
when :before_headers, :after_headers
|
334
|
+
Xcodeproj::Project::Object::PBXHeadersBuildPhase
|
335
|
+
else
|
336
|
+
raise ArgumentError, "Unknown execution position `#{execution_position}`"
|
337
|
+
end
|
338
|
+
order_before = case execution_position
|
339
|
+
when :before_compile, :before_headers
|
340
|
+
true
|
341
|
+
when :after_compile, :after_headers
|
342
|
+
false
|
343
|
+
else
|
344
|
+
raise ArgumentError, "Unknown execution position `#{execution_position}`"
|
345
|
+
end
|
346
|
+
|
347
|
+
target_phase_index = native_target.build_phases.index do |bp|
|
348
|
+
bp.is_a?(target_phase_type)
|
349
|
+
end
|
350
|
+
return if target_phase_index.nil?
|
351
|
+
script_phase_index = native_target.build_phases.index do |bp|
|
352
|
+
bp.is_a?(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) && !bp.name.nil? && bp.name == script_phase.name
|
353
|
+
end
|
354
|
+
if (order_before && script_phase_index > target_phase_index) ||
|
355
|
+
(!order_before && script_phase_index < target_phase_index)
|
356
|
+
native_target.build_phases.move_from(script_phase_index, target_phase_index)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
# Script phases can have a limited number of input and output paths due to each one being exported to `env`.
|
361
|
+
# A large number can cause a build failure because of limitations in `env`. See issue
|
362
|
+
# https://github.com/CocoaPods/CocoaPods/issues/7362.
|
363
|
+
#
|
364
|
+
# @param [Array<String>] input_paths
|
365
|
+
# The input paths to trim.
|
366
|
+
#
|
367
|
+
# @param [Array<String>] output_paths
|
368
|
+
# The output paths to trim.
|
369
|
+
#
|
370
|
+
# @return [void]
|
371
|
+
#
|
372
|
+
def validate_input_output_path_limit(input_paths, output_paths)
|
373
|
+
if (input_paths.count + output_paths.count) > MAX_INPUT_OUTPUT_PATHS
|
374
|
+
input_paths.clear
|
375
|
+
output_paths.clear
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
# Returns the resource output paths for all given input paths.
|
380
|
+
#
|
381
|
+
# @param [Array<String>] resource_input_paths
|
382
|
+
# The input paths to map to.
|
383
|
+
#
|
384
|
+
# @return [Array<String>] The resource output paths.
|
385
|
+
#
|
386
|
+
def resource_output_paths(resource_input_paths)
|
387
|
+
resource_input_paths.map do |resource_input_path|
|
388
|
+
base_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}'
|
389
|
+
extname = File.extname(resource_input_path)
|
390
|
+
basename = extname == '.xcassets' ? 'Assets' : File.basename(resource_input_path)
|
391
|
+
output_extension = Target.output_extension_for_resource(extname)
|
392
|
+
File.join(base_path, File.basename(basename, extname) + output_extension)
|
393
|
+
end.uniq
|
394
|
+
end
|
395
|
+
|
396
|
+
# Returns the framework input paths for the given framework paths
|
397
|
+
#
|
398
|
+
# @param [Array<Xcode::FrameworkPaths>] framework_paths
|
399
|
+
# The target's framework paths to map to input paths.
|
400
|
+
#
|
401
|
+
# @param [Array<XCFramework>] xcframeworks
|
402
|
+
# The target's xcframeworks to map to input paths.
|
403
|
+
#
|
404
|
+
# @return [Array<String>] The embed frameworks script input paths
|
405
|
+
#
|
406
|
+
def embed_frameworks_input_paths(framework_paths, xcframeworks)
|
407
|
+
input_paths = framework_paths.map(&:source_path)
|
408
|
+
# Only include dynamic xcframeworks as the input since we will not be copying static xcframework slices
|
409
|
+
xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.each do |xcframework|
|
410
|
+
name = xcframework.name
|
411
|
+
input_paths << "#{Pod::Target::BuildSettings.xcframework_intermediate_dir(xcframework)}/#{name}.framework/#{name}"
|
412
|
+
end
|
413
|
+
input_paths
|
414
|
+
end
|
415
|
+
|
416
|
+
# Returns the framework output paths for the given framework paths
|
417
|
+
#
|
418
|
+
# @param [Array<Xcode::FrameworkPaths>] framework_paths
|
419
|
+
# The framework input paths to map to output paths.
|
420
|
+
#
|
421
|
+
# @param [Array<XCFramework>] xcframeworks
|
422
|
+
# The installed xcframeworks.
|
423
|
+
#
|
424
|
+
# @return [Array<String>] The embed framework script output paths
|
425
|
+
#
|
426
|
+
def embed_frameworks_output_paths(framework_paths, xcframeworks)
|
427
|
+
paths = framework_paths.map do |framework_path|
|
428
|
+
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}"
|
429
|
+
end.uniq
|
430
|
+
# Static xcframeworks are not copied to the build dir
|
431
|
+
# so only include dynamic artifacts that will be copied to the build folder
|
432
|
+
xcframework_paths = xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.map do |xcframework|
|
433
|
+
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{xcframework.name}.framework"
|
434
|
+
end
|
435
|
+
paths + xcframework_paths
|
436
|
+
end
|
437
|
+
|
438
|
+
# Updates a projects native targets to include on demand resources specified by the supplied parameters.
|
439
|
+
# Note that currently, only app level targets are allowed to include on demand resources.
|
440
|
+
#
|
441
|
+
# @param [Sandbox] sandbox
|
442
|
+
# The sandbox to use for calculating ODR file references.
|
443
|
+
#
|
444
|
+
# @param [Xcodeproj::Project] project
|
445
|
+
# The project to update known asset tags as well as add the ODR group.
|
446
|
+
#
|
447
|
+
# @param [Xcodeproj::PBXNativeTarget, Array<Xcodeproj::PBXNativeTarget>] native_targets
|
448
|
+
# The native targets to integrate on demand resources into.
|
449
|
+
#
|
450
|
+
# @param [Sandbox::FileAccessor, Array<Sandbox::FileAccessor>] file_accessors
|
451
|
+
# The file accessors that that provide the ODRs to integrate.
|
452
|
+
#
|
453
|
+
# @param [Xcodeproj::PBXGroup] parent_odr_group
|
454
|
+
# The group to use as the parent to add ODR file references into.
|
455
|
+
#
|
456
|
+
# @param [String] target_odr_group_name
|
457
|
+
# The name to use for the group created that contains the ODR file references.
|
458
|
+
#
|
459
|
+
# @return [void]
|
460
|
+
#
|
461
|
+
def update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group,
|
462
|
+
target_odr_group_name)
|
463
|
+
category_to_tags = {}
|
464
|
+
file_accessors = Array(file_accessors)
|
465
|
+
native_targets = Array(native_targets)
|
466
|
+
|
467
|
+
# Target no longer provides ODR references so remove everything related to this target.
|
468
|
+
if file_accessors.all? { |fa| fa.on_demand_resources.empty? }
|
469
|
+
old_target_odr_group = parent_odr_group[target_odr_group_name]
|
470
|
+
old_odr_file_refs = old_target_odr_group&.recursive_children_groups&.each_with_object({}) do |group, hash|
|
471
|
+
hash[group.name] = group.files
|
472
|
+
end || {}
|
473
|
+
native_targets.each do |native_target|
|
474
|
+
native_target.remove_on_demand_resources(old_odr_file_refs)
|
475
|
+
update_on_demand_resources_build_settings(native_target, nil => old_odr_file_refs.keys)
|
476
|
+
end
|
477
|
+
old_target_odr_group&.remove_from_project
|
478
|
+
return
|
479
|
+
end
|
480
|
+
|
481
|
+
target_odr_group = parent_odr_group[target_odr_group_name] || parent_odr_group.new_group(target_odr_group_name)
|
482
|
+
current_file_refs = target_odr_group.recursive_children_groups.flat_map(&:files)
|
483
|
+
|
484
|
+
added_file_refs = file_accessors.flat_map do |file_accessor|
|
485
|
+
target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, value|
|
486
|
+
tag_group = target_odr_group[tag] || target_odr_group.new_group(tag)
|
487
|
+
category_to_tags[value[:category]] ||= []
|
488
|
+
category_to_tags[value[:category]] << tag
|
489
|
+
resources_file_refs = value[:paths].map do |resource|
|
490
|
+
odr_resource_file_ref = Pathname.new(resource).relative_path_from(sandbox.root)
|
491
|
+
tag_group.find_file_by_path(odr_resource_file_ref.to_s) || tag_group.new_file(odr_resource_file_ref)
|
492
|
+
end
|
493
|
+
[tag, resources_file_refs]
|
494
|
+
end]
|
495
|
+
native_targets.each do |native_target|
|
496
|
+
native_target.add_on_demand_resources(target_odr_files_refs)
|
497
|
+
end
|
498
|
+
target_odr_files_refs.values.flatten
|
499
|
+
end
|
500
|
+
|
501
|
+
# if the target ODR file references were updated, make sure we remove the ones that are no longer present
|
502
|
+
# for the target.
|
503
|
+
remaining_refs = current_file_refs - added_file_refs
|
504
|
+
remaining_refs.each do |ref|
|
505
|
+
native_targets.each do |user_target|
|
506
|
+
user_target.resources_build_phase.remove_file_reference(ref)
|
507
|
+
end
|
508
|
+
ref.remove_from_project
|
509
|
+
end
|
510
|
+
target_odr_group.recursive_children_groups.each { |g| g.remove_from_project if g.empty? }
|
511
|
+
|
512
|
+
attributes = project.root_object.attributes
|
513
|
+
attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | category_to_tags.values.flatten
|
514
|
+
project.root_object.attributes = attributes
|
515
|
+
|
516
|
+
native_targets.each do |native_target|
|
517
|
+
update_on_demand_resources_build_settings(native_target, category_to_tags)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
def update_on_demand_resources_build_settings(native_target, category_to_tags)
|
522
|
+
%w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key|
|
523
|
+
native_target.build_configurations.each do |c|
|
524
|
+
key = case category_key
|
525
|
+
when 'ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'
|
526
|
+
:initial_install
|
527
|
+
when 'ON_DEMAND_RESOURCES_PREFETCH_ORDER'
|
528
|
+
:prefetched
|
529
|
+
else
|
530
|
+
:download_on_demand
|
531
|
+
end
|
532
|
+
tags_for_category = (c.build_settings[category_key] || '').split
|
533
|
+
category_to_tags_dup = category_to_tags.dup
|
534
|
+
tags_to_add = category_to_tags_dup.delete(key) || []
|
535
|
+
tags_to_delete = category_to_tags_dup.values.flatten
|
536
|
+
tags_for_category = (tags_for_category + tags_to_add - tags_to_delete).flatten.compact.uniq
|
537
|
+
if tags_for_category.empty?
|
538
|
+
val = c.build_settings.delete(category_key)
|
539
|
+
native_target.project.mark_dirty! unless val.nil?
|
540
|
+
else
|
541
|
+
tags = tags_for_category.join(' ')
|
542
|
+
unless c.build_settings[category_key] == tags
|
543
|
+
c.build_settings[category_key] = tags
|
544
|
+
native_target.project.mark_dirty!
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|
548
|
+
end
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
# Integrates the user project targets. Only the targets that do **not**
|
553
|
+
# already have the Pods library in their frameworks build phase are
|
554
|
+
# processed.
|
555
|
+
#
|
556
|
+
# @return [void]
|
557
|
+
#
|
558
|
+
def integrate!
|
559
|
+
UI.section(integration_message) do
|
560
|
+
XCConfigIntegrator.integrate(target, native_targets)
|
561
|
+
|
562
|
+
remove_obsolete_script_phases
|
563
|
+
add_pods_library
|
564
|
+
add_embed_frameworks_script_phase
|
565
|
+
remove_embed_frameworks_script_phase_from_embedded_targets
|
566
|
+
add_copy_resources_script_phase
|
567
|
+
add_check_manifest_lock_script_phase
|
568
|
+
add_user_script_phases
|
569
|
+
add_on_demand_resources
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
# @return [String] a string representation suitable for debugging.
|
574
|
+
#
|
575
|
+
def inspect
|
576
|
+
"#<#{self.class} for target `#{target.label}'>"
|
577
|
+
end
|
578
|
+
|
579
|
+
private
|
580
|
+
|
581
|
+
# @!group Integration steps
|
582
|
+
#---------------------------------------------------------------------#
|
583
|
+
|
584
|
+
# Adds spec product reference to the frameworks build phase of the
|
585
|
+
# {TargetDefinition} integration libraries. Adds a file reference to
|
586
|
+
# the frameworks group of the project and adds it to the frameworks
|
587
|
+
# build phase of the targets.
|
588
|
+
#
|
589
|
+
# @return [void]
|
590
|
+
#
|
591
|
+
def add_pods_library
|
592
|
+
frameworks = user_project.frameworks_group
|
593
|
+
native_targets.each do |native_target|
|
594
|
+
build_phase = native_target.frameworks_build_phase
|
595
|
+
product_name = target.product_name
|
596
|
+
|
597
|
+
# Delete previously integrated references.
|
598
|
+
product_build_files = build_phase.files.select do |build_file|
|
599
|
+
build_file.display_name =~ Pod::Deintegrator::FRAMEWORK_NAMES
|
600
|
+
end
|
601
|
+
|
602
|
+
product_build_files.each do |product_file|
|
603
|
+
next unless product_name != product_file.display_name
|
604
|
+
UI.message("Removing old product reference `#{product_file.display_name}` from project.")
|
605
|
+
frameworks.remove_reference(product_file.file_ref)
|
606
|
+
build_phase.remove_build_file(product_file)
|
607
|
+
end
|
608
|
+
|
609
|
+
# Find or create and add a reference for the current product type
|
610
|
+
new_product_ref = frameworks.files.find { |f| f.path == product_name } ||
|
611
|
+
frameworks.new_product_ref_for_target(target.product_basename, target.product_type)
|
612
|
+
build_phase.build_file(new_product_ref) ||
|
613
|
+
build_phase.add_file_reference(new_product_ref, true)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
# Find or create a 'Copy Pods Resources' build phase
|
618
|
+
#
|
619
|
+
# @return [void]
|
620
|
+
#
|
621
|
+
def add_copy_resources_script_phase
|
622
|
+
unless target.includes_resources?
|
623
|
+
native_targets.each do |native_target|
|
624
|
+
TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target)
|
625
|
+
end
|
626
|
+
return
|
627
|
+
end
|
628
|
+
|
629
|
+
script_path = target.copy_resources_script_relative_path
|
630
|
+
input_paths_by_config = {}
|
631
|
+
output_paths_by_config = {}
|
632
|
+
if use_input_output_paths
|
633
|
+
target.resource_paths_by_config.each do |config, resource_paths|
|
634
|
+
input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config),
|
635
|
+
target.copy_resources_script_input_files_relative_path)
|
636
|
+
input_paths_by_config[input_paths_key] = [script_path] + resource_paths
|
637
|
+
|
638
|
+
output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config),
|
639
|
+
target.copy_resources_script_output_files_relative_path)
|
640
|
+
output_paths_by_config[output_paths_key] = TargetIntegrator.resource_output_paths(resource_paths)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
native_targets.each do |native_target|
|
645
|
+
# Static library targets cannot include resources. Skip this phase from being added instead.
|
646
|
+
next if native_target.symbol_type == :static_library
|
647
|
+
TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path,
|
648
|
+
input_paths_by_config,
|
649
|
+
output_paths_by_config)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
# Removes the embed frameworks build phase from embedded targets
|
654
|
+
#
|
655
|
+
# @note Older versions of CocoaPods would add this build phase to embedded
|
656
|
+
# targets. They should be removed on upgrade because embedded targets
|
657
|
+
# will have their frameworks embedded in their host targets.
|
658
|
+
#
|
659
|
+
def remove_embed_frameworks_script_phase_from_embedded_targets
|
660
|
+
return unless target.requires_host_target?
|
661
|
+
native_targets.each do |native_target|
|
662
|
+
if AggregateTarget::EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include? native_target.symbol_type
|
663
|
+
TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
# Find or create a 'Embed Pods Frameworks' Copy Files Build Phase
|
669
|
+
#
|
670
|
+
# @return [void]
|
671
|
+
#
|
672
|
+
def add_embed_frameworks_script_phase
|
673
|
+
unless target.includes_frameworks? || (target.xcframeworks_by_config.values.flatten.any? { |xcf| xcf.build_type.dynamic_framework? })
|
674
|
+
native_targets_to_embed_in.each do |native_target|
|
675
|
+
TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
|
676
|
+
end
|
677
|
+
return
|
678
|
+
end
|
679
|
+
|
680
|
+
script_path = target.embed_frameworks_script_relative_path
|
681
|
+
input_paths_by_config = {}
|
682
|
+
output_paths_by_config = {}
|
683
|
+
if use_input_output_paths?
|
684
|
+
configs = Set.new(target.framework_paths_by_config.keys + target.xcframeworks_by_config.keys).sort
|
685
|
+
configs.each do |config|
|
686
|
+
framework_paths = target.framework_paths_by_config[config] || []
|
687
|
+
xcframeworks = target.xcframeworks_by_config[config] || []
|
688
|
+
|
689
|
+
input_paths_key = XCFileListConfigKey.new(target.embed_frameworks_script_input_files_path(config), target.embed_frameworks_script_input_files_relative_path)
|
690
|
+
input_paths_by_config[input_paths_key] = [script_path] + TargetIntegrator.embed_frameworks_input_paths(framework_paths, xcframeworks)
|
691
|
+
|
692
|
+
output_paths_key = XCFileListConfigKey.new(target.embed_frameworks_script_output_files_path(config), target.embed_frameworks_script_output_files_relative_path)
|
693
|
+
output_paths_by_config[output_paths_key] = TargetIntegrator.embed_frameworks_output_paths(framework_paths, xcframeworks)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
native_targets_to_embed_in.each do |native_target|
|
698
|
+
TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
# Updates all target script phases for the current target, including creating or updating, deleting
|
703
|
+
# and re-ordering.
|
704
|
+
#
|
705
|
+
# @return [void]
|
706
|
+
#
|
707
|
+
def add_user_script_phases
|
708
|
+
native_targets.each do |native_target|
|
709
|
+
TargetIntegrator.create_or_update_user_script_phases(target.target_definition.script_phases, native_target)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
# Adds a shell script build phase responsible for checking if the Pods
|
714
|
+
# locked in the Pods/Manifest.lock file are in sync with the Pods defined
|
715
|
+
# in the Podfile.lock.
|
716
|
+
#
|
717
|
+
# @note The build phase is appended to the front because to fail
|
718
|
+
# fast.
|
719
|
+
#
|
720
|
+
# @return [void]
|
721
|
+
#
|
722
|
+
def add_check_manifest_lock_script_phase
|
723
|
+
phase_name = CHECK_MANIFEST_PHASE_NAME
|
724
|
+
native_targets.each do |native_target|
|
725
|
+
phase = TargetIntegrator.create_or_update_shell_script_build_phase(native_target, BUILD_PHASE_PREFIX + phase_name)
|
726
|
+
native_target.build_phases.unshift(phase).uniq! unless native_target.build_phases.first == phase
|
727
|
+
phase.shell_script = <<-SH.strip_heredoc
|
728
|
+
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
|
729
|
+
if [ $? != 0 ] ; then
|
730
|
+
# print error to STDERR
|
731
|
+
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
|
732
|
+
exit 1
|
733
|
+
fi
|
734
|
+
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
|
735
|
+
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
|
736
|
+
SH
|
737
|
+
phase.input_paths = %w(${PODS_PODFILE_DIR_PATH}/Podfile.lock ${PODS_ROOT}/Manifest.lock)
|
738
|
+
phase.output_paths = [target.check_manifest_lock_script_output_file_path]
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
# @param [Array<String>] removed_phase_names
|
743
|
+
# The names of the script phases that should be removed
|
744
|
+
#
|
745
|
+
def remove_obsolete_script_phases(removed_phase_names = REMOVED_SCRIPT_PHASE_NAMES)
|
746
|
+
native_targets.each do |native_target|
|
747
|
+
removed_phase_names.each do |phase_name|
|
748
|
+
TargetIntegrator.remove_script_phase_from_target(native_target, phase_name)
|
749
|
+
end
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
def add_on_demand_resources
|
754
|
+
target.pod_targets.each do |pod_target|
|
755
|
+
# When integrating with the user's project we are only interested in integrating ODRs from library specs
|
756
|
+
# and not test specs or app specs.
|
757
|
+
library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? }
|
758
|
+
target_odr_group_name = "#{pod_target.label}-OnDemandResources"
|
759
|
+
# The 'Pods' group would always be there for production code however for tests its sometimes not added.
|
760
|
+
# This ensures its always present and makes it easier for existing and new tests.
|
761
|
+
parent_odr_group = target.user_project.main_group['Pods'] || target.user_project.new_group('Pods')
|
762
|
+
TargetIntegrator.update_on_demand_resources(target.sandbox, target.user_project, target.user_targets,
|
763
|
+
library_file_accessors, parent_odr_group, target_odr_group_name)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
private
|
768
|
+
|
769
|
+
# @!group Private Helpers
|
770
|
+
#---------------------------------------------------------------------#
|
771
|
+
|
772
|
+
# @return [Array<PBXNativeTarget>] The list of all the targets that
|
773
|
+
# match the given target.
|
774
|
+
#
|
775
|
+
def native_targets
|
776
|
+
@native_targets ||= target.user_targets
|
777
|
+
end
|
778
|
+
|
779
|
+
# @return [Array<PBXNativeTarget>] The list of all the targets that
|
780
|
+
# require that the pod frameworks are embedded in the output
|
781
|
+
# directory / product bundle.
|
782
|
+
#
|
783
|
+
def native_targets_to_embed_in
|
784
|
+
return [] if target.requires_host_target?
|
785
|
+
native_targets.select do |target|
|
786
|
+
EMBED_FRAMEWORK_TARGET_TYPES.include?(target.symbol_type)
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
# Read the project from the disk to ensure that it is up to date as
|
791
|
+
# other TargetIntegrators might have modified it.
|
792
|
+
#
|
793
|
+
# @return [Project]
|
794
|
+
#
|
795
|
+
def user_project
|
796
|
+
target.user_project
|
797
|
+
end
|
798
|
+
|
799
|
+
# @return [Specification::Consumer] the consumer for the specifications.
|
800
|
+
#
|
801
|
+
def spec_consumers
|
802
|
+
@spec_consumers ||= target.pod_targets.map(&:file_accessors).flatten.map(&:spec_consumer)
|
803
|
+
end
|
804
|
+
|
805
|
+
# @return [String] the message that should be displayed for the target
|
806
|
+
# integration.
|
807
|
+
#
|
808
|
+
def integration_message
|
809
|
+
"Integrating target `#{target.name}` " \
|
810
|
+
"(#{UI.path target.user_project_path} project)"
|
811
|
+
end
|
812
|
+
end
|
813
|
+
end
|
814
|
+
end
|
815
|
+
end
|