cocoapods 1.0.0 → 1.1.0
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 +4 -4
- data/CHANGELOG.md +329 -0
- data/lib/cocoapods/command/init.rb +6 -6
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -0
- data/lib/cocoapods/command/ipc/repl.rb +51 -0
- data/lib/cocoapods/command/ipc/spec.rb +29 -0
- data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
- data/lib/cocoapods/command/ipc.rb +18 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +111 -0
- data/lib/cocoapods/command/lib.rb +3 -207
- data/lib/cocoapods/command/repo/push.rb +44 -20
- data/lib/cocoapods/command/setup.rb +2 -1
- data/lib/cocoapods/command/spec/lint.rb +4 -0
- data/lib/cocoapods/command.rb +2 -1
- data/lib/cocoapods/config.rb +4 -1
- data/lib/cocoapods/downloader/cache.rb +1 -0
- data/lib/cocoapods/downloader.rb +20 -0
- data/lib/cocoapods/executable.rb +1 -1
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/acknowledgements/plist.rb +4 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +4 -10
- data/lib/cocoapods/generator/header.rb +2 -1
- data/lib/cocoapods/generator/prefix_header.rb +0 -12
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +38 -5
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +5 -4
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +5 -1
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +24 -1
- data/lib/cocoapods/installer/analyzer.rb +161 -1
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +29 -9
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +204 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +314 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +401 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +214 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +265 -0
- data/lib/cocoapods/installer/xcode.rb +7 -0
- data/lib/cocoapods/installer.rb +50 -214
- data/lib/cocoapods/resolver.rb +15 -9
- data/lib/cocoapods/sandbox/headers_store.rb +4 -10
- data/lib/cocoapods/sandbox/path_list.rb +20 -9
- data/lib/cocoapods/sources_manager.rb +7 -10
- data/lib/cocoapods/target/aggregate_target.rb +20 -0
- data/lib/cocoapods/target/pod_target.rb +37 -7
- data/lib/cocoapods/user_interface/error_report.rb +7 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/user_interface.rb +7 -5
- data/lib/cocoapods/validator.rb +59 -11
- metadata +112 -83
- data/lib/cocoapods/command/inter_process_communication.rb +0 -177
- data/lib/cocoapods/installer/file_references_installer.rb +0 -310
- data/lib/cocoapods/installer/migrator.rb +0 -86
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +0 -191
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +0 -368
- data/lib/cocoapods/installer/target_installer.rb +0 -210
data/lib/cocoapods/downloader.rb
CHANGED
@@ -33,11 +33,16 @@ module Pod
|
|
33
33
|
cache_path: Config.instance.cache_root + 'Pods'
|
34
34
|
)
|
35
35
|
can_cache &&= !Config.instance.skip_download_cache
|
36
|
+
|
37
|
+
request = preprocess_request(request)
|
38
|
+
|
36
39
|
if can_cache
|
37
40
|
raise ArgumentError, 'Must provide a `cache_path` when caching.' unless cache_path
|
38
41
|
cache = Cache.new(cache_path)
|
39
42
|
result = cache.download_pod(request)
|
40
43
|
else
|
44
|
+
raise ArgumentError, 'Must provide a `target` when caching is disabled.' unless target
|
45
|
+
|
41
46
|
require 'cocoapods/installer/pod_source_preparer'
|
42
47
|
result, = download_request(request, target)
|
43
48
|
Installer::PodSourcePreparer.new(result.spec, result.location).prepare!
|
@@ -110,6 +115,21 @@ module Pod
|
|
110
115
|
end
|
111
116
|
end
|
112
117
|
|
118
|
+
# Return a new request after preprocessing by the downloader
|
119
|
+
#
|
120
|
+
# @param [Request] request
|
121
|
+
# the request that needs preprocessing
|
122
|
+
#
|
123
|
+
# @return [Request] the preprocessed request
|
124
|
+
#
|
125
|
+
def self.preprocess_request(request)
|
126
|
+
Request.new(
|
127
|
+
:spec => request.spec,
|
128
|
+
:released => request.released_pod?,
|
129
|
+
:name => request.name,
|
130
|
+
:params => Downloader.preprocess_options(request.params))
|
131
|
+
end
|
132
|
+
|
113
133
|
public
|
114
134
|
|
115
135
|
class DownloaderError; include CLAide::InformativeError; end
|
data/lib/cocoapods/executable.rb
CHANGED
@@ -108,7 +108,7 @@ module Pod
|
|
108
108
|
#
|
109
109
|
def self.which!(program)
|
110
110
|
which(program).tap do |bin|
|
111
|
-
raise Informative, "Unable to locate the executable `#{
|
111
|
+
raise Informative, "Unable to locate the executable `#{program}`" unless bin
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -33,11 +33,14 @@ module Pod
|
|
33
33
|
|
34
34
|
def hash_for_spec(spec)
|
35
35
|
if (license = license_text(spec))
|
36
|
-
{
|
36
|
+
hash = {
|
37
37
|
:Type => 'PSGroupSpecifier',
|
38
38
|
:Title => sanitize_encoding(spec.name),
|
39
39
|
:FooterText => sanitize_encoding(license),
|
40
40
|
}
|
41
|
+
hash[:License] = sanitize_encoding(spec.license[:type]) if spec.license[:type]
|
42
|
+
|
43
|
+
hash
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -119,12 +119,6 @@ case "${TARGETED_DEVICE_FAMILY}" in
|
|
119
119
|
;;
|
120
120
|
esac
|
121
121
|
|
122
|
-
realpath() {
|
123
|
-
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
124
|
-
FILENAME="${1##*/}"
|
125
|
-
echo "$DIRECTORY/$FILENAME"
|
126
|
-
}
|
127
|
-
|
128
122
|
install_resource()
|
129
123
|
{
|
130
124
|
if [[ "$1" = /* ]] ; then
|
@@ -144,8 +138,8 @@ EOM
|
|
144
138
|
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \\"$RESOURCE_PATH\\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
145
139
|
;;
|
146
140
|
*\.xib)
|
147
|
-
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \\"$RESOURCE_PATH\\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}"
|
148
|
-
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \\"$RESOURCE_PATH\\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}"
|
141
|
+
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \\"$RESOURCE_PATH\\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
|
142
|
+
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \\"$RESOURCE_PATH\\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
149
143
|
;;
|
150
144
|
*.framework)
|
151
145
|
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
@@ -166,7 +160,7 @@ EOM
|
|
166
160
|
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
167
161
|
;;
|
168
162
|
*.xcassets)
|
169
|
-
ABSOLUTE_XCASSET_FILE
|
163
|
+
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
170
164
|
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
171
165
|
;;
|
172
166
|
*)
|
@@ -195,7 +189,7 @@ then
|
|
195
189
|
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
196
190
|
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
197
191
|
while read line; do
|
198
|
-
if [[ $line != "
|
192
|
+
if [[ $line != "${PODS_ROOT}*" ]]; then
|
199
193
|
XCASSET_FILES+=("$line")
|
200
194
|
fi
|
201
195
|
done <<<"$OTHER_XCASSETS"
|
@@ -55,18 +55,6 @@ module Pod
|
|
55
55
|
|
56
56
|
result
|
57
57
|
end
|
58
|
-
|
59
|
-
protected
|
60
|
-
|
61
|
-
# Generates the contents of the header according to the platform.
|
62
|
-
#
|
63
|
-
# @return [String]
|
64
|
-
#
|
65
|
-
def generate_platform_import_header
|
66
|
-
result = "#ifdef __OBJC__\n"
|
67
|
-
result << super
|
68
|
-
result << "#endif\n"
|
69
|
-
end
|
70
58
|
end
|
71
59
|
end
|
72
60
|
end
|
@@ -4,7 +4,7 @@ module Pod
|
|
4
4
|
# Generates the xcconfigs for the aggregate targets.
|
5
5
|
#
|
6
6
|
class AggregateXCConfig
|
7
|
-
# @return [
|
7
|
+
# @return [AggregateTarget] the target represented by this xcconfig.
|
8
8
|
#
|
9
9
|
attr_reader :target
|
10
10
|
|
@@ -60,10 +60,8 @@ module Pod
|
|
60
60
|
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
|
61
61
|
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) ',
|
62
62
|
'LIBRARY_SEARCH_PATHS' => '$(inherited) ',
|
63
|
-
}
|
64
|
-
|
65
|
-
config['EMBEDDED_CONTENT_CONTAINS_SWIFT'] = 'YES'
|
66
|
-
end
|
63
|
+
}.merge(embedded_content_settings)
|
64
|
+
|
67
65
|
@xcconfig = Xcodeproj::Config.new(config)
|
68
66
|
|
69
67
|
@xcconfig.merge!(merged_user_target_xcconfigs)
|
@@ -90,6 +88,41 @@ module Pod
|
|
90
88
|
|
91
89
|
protected
|
92
90
|
|
91
|
+
def target_swift_version
|
92
|
+
settings = target.native_target.resolved_build_setting('SWIFT_VERSION') unless target.native_target.nil?
|
93
|
+
settings.values.compact.uniq.first unless settings.nil?
|
94
|
+
end
|
95
|
+
|
96
|
+
EMBED_STANDARD_LIBRARIES_MINIMUM_VERSION = Gem::Version.new('2.3')
|
97
|
+
|
98
|
+
# @return [Hash<String, String>] the build settings necessary for Swift
|
99
|
+
# targets to be correctly embedded in their host.
|
100
|
+
#
|
101
|
+
def embedded_content_settings
|
102
|
+
# For embedded targets, which live in a host target, CocoaPods
|
103
|
+
# copies all of the embedded target's pod_targets its host
|
104
|
+
# target. Therefore, this check will properly require the Swift
|
105
|
+
# libs in the host target, if the embedded target has any pod targets
|
106
|
+
# that use Swift. Setting this for the embedded target would
|
107
|
+
# cause an App Store rejection because frameworks cannot be embedded
|
108
|
+
# in embedded targets.
|
109
|
+
|
110
|
+
swift_version = Gem::Version.new(target_swift_version)
|
111
|
+
should_embed = !target.requires_host_target? && pod_targets.any?(&:uses_swift?)
|
112
|
+
embed_value = should_embed ? 'YES' : 'NO'
|
113
|
+
|
114
|
+
config = {
|
115
|
+
'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' => embed_value,
|
116
|
+
'EMBEDDED_CONTENT_CONTAINS_SWIFT' => embed_value,
|
117
|
+
}
|
118
|
+
|
119
|
+
if swift_version >= EMBED_STANDARD_LIBRARIES_MINIMUM_VERSION || !should_embed
|
120
|
+
config.delete('EMBEDDED_CONTENT_CONTAINS_SWIFT')
|
121
|
+
end
|
122
|
+
|
123
|
+
config
|
124
|
+
end
|
125
|
+
|
93
126
|
# @return [Hash<String, String>] the build settings necessary to import
|
94
127
|
# the pod targets.
|
95
128
|
#
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/object/try'
|
2
|
+
|
1
3
|
module Pod
|
2
4
|
module Generator
|
3
5
|
module XCConfig
|
@@ -283,9 +285,9 @@ module Pod
|
|
283
285
|
#
|
284
286
|
def self.add_language_specific_settings(target, xcconfig)
|
285
287
|
if target.uses_swift?
|
286
|
-
|
287
|
-
|
288
|
-
}
|
288
|
+
other_swift_flags = ['$(inherited)', quote(%w(-D COCOAPODS))]
|
289
|
+
other_swift_flags << quote(%w(-suppress-warnings)) if target.try(:inhibit_warnings?)
|
290
|
+
build_settings = { 'OTHER_SWIFT_FLAGS' => other_swift_flags.join(' ') }
|
289
291
|
xcconfig.merge!(build_settings)
|
290
292
|
end
|
291
293
|
end
|
@@ -314,7 +316,6 @@ module Pod
|
|
314
316
|
search_paths << search_path
|
315
317
|
end
|
316
318
|
end
|
317
|
-
search_paths
|
318
319
|
end
|
319
320
|
end
|
320
321
|
|
@@ -23,7 +23,11 @@ module Pod
|
|
23
23
|
#
|
24
24
|
def scope_suffixes
|
25
25
|
return { variants.first => nil } if variants.count == 1
|
26
|
-
scope_by_specs
|
26
|
+
Hash[scope_by_specs.map do |variant, scope|
|
27
|
+
require 'digest'
|
28
|
+
scope = Digest::MD5.hexdigest(scope)[0..7] if !scope.nil? && scope.length >= 50
|
29
|
+
[variant, scope]
|
30
|
+
end]
|
27
31
|
end
|
28
32
|
|
29
33
|
# Groups the collection by result of the block.
|
@@ -44,6 +44,7 @@ module Pod
|
|
44
44
|
result.platform = compute_platform(targets)
|
45
45
|
result.archs = compute_archs(targets)
|
46
46
|
result.project = user_project
|
47
|
+
result.target_definition.swift_version = compute_swift_version_from_targets(targets)
|
47
48
|
result
|
48
49
|
end
|
49
50
|
|
@@ -72,7 +73,7 @@ module Pod
|
|
72
73
|
else
|
73
74
|
raise Informative, 'Could not automatically select an Xcode project. ' \
|
74
75
|
"Specify one in your Podfile like so:\n\n" \
|
75
|
-
"
|
76
|
+
" project 'path/to/Project.xcodeproj'\n"
|
76
77
|
end
|
77
78
|
end
|
78
79
|
path
|
@@ -205,6 +206,28 @@ module Pod
|
|
205
206
|
end
|
206
207
|
end
|
207
208
|
end
|
209
|
+
|
210
|
+
# Compute the Swift version for the target build configurations. If more
|
211
|
+
# than one Swift version is defined for a given target, then it will raise.
|
212
|
+
#
|
213
|
+
# @param [Array<PBXNativeTarget>] targets
|
214
|
+
# the targets that are checked for Swift versions.
|
215
|
+
#
|
216
|
+
# @return [String] the targets Swift version or nil
|
217
|
+
#
|
218
|
+
def compute_swift_version_from_targets(targets)
|
219
|
+
versions = targets.flat_map do |target|
|
220
|
+
target.resolved_build_setting('SWIFT_VERSION').values
|
221
|
+
end.flatten.compact.uniq
|
222
|
+
case versions.count
|
223
|
+
when 0
|
224
|
+
nil
|
225
|
+
when 1
|
226
|
+
versions.first
|
227
|
+
else
|
228
|
+
raise Informative, 'There may only be up to 1 unique SWIFT_VERSION per target.'
|
229
|
+
end
|
230
|
+
end
|
208
231
|
end
|
209
232
|
end
|
210
233
|
end
|
@@ -226,16 +226,142 @@ module Pod
|
|
226
226
|
|
227
227
|
private
|
228
228
|
|
229
|
+
# Copies the pod_targets of any of the app embedded aggregate targets into
|
230
|
+
# their potential host aggregate target, if that potential host aggregate target's
|
231
|
+
# user_target hosts any of the app embedded aggregate targets' user_targets
|
232
|
+
#
|
233
|
+
# @param [AggregateTarget] aggregate_target the aggregate target whose user_target
|
234
|
+
# might host one or more of the embedded aggregate targets' user_targets
|
235
|
+
#
|
236
|
+
# @param [Array<AggregateTarget>] embedded_aggregate_targets the aggregate targets
|
237
|
+
# representing the embedded targets to be integrated
|
238
|
+
#
|
239
|
+
def copy_embedded_target_pod_targets_to_host(aggregate_target, embedded_aggregate_targets)
|
240
|
+
return if aggregate_target.requires_host_target?
|
241
|
+
# Get the uuids of the aggregate_target's user_targets' embedded targets if any
|
242
|
+
embedded_uuids = Set.new(aggregate_target.user_targets.map do |target|
|
243
|
+
aggregate_target.user_project.embedded_targets_in_native_target(target).map(&:uuid)
|
244
|
+
end.flatten)
|
245
|
+
return if embedded_uuids.empty?
|
246
|
+
embedded_aggregate_targets.each do |embedded_target|
|
247
|
+
next unless embedded_target.user_targets.map(&:uuid).any? do |embedded_uuid|
|
248
|
+
embedded_uuids.include? embedded_uuid
|
249
|
+
end
|
250
|
+
pod_target_names = aggregate_target.pod_targets.map(&:name)
|
251
|
+
# This embedded target is hosted by the aggregate target's user_target; copy over the non-duplicate pod_targets
|
252
|
+
aggregate_target.pod_targets = aggregate_target.pod_targets + embedded_target.pod_targets.select do |pod_target|
|
253
|
+
!pod_target_names.include? pod_target.name
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Raises an error if there are embedded targets in the Podfile, but
|
259
|
+
# their host targets have not been declared in the Podfile. As it
|
260
|
+
# finds host targets, it collection information on host target types.
|
261
|
+
#
|
262
|
+
# @param [Array<AggregateTarget>] aggregate_targets the generated
|
263
|
+
# aggregate targets
|
264
|
+
#
|
265
|
+
# @param [Array<AggregateTarget>] embedded_aggregate_targets the aggregate targets
|
266
|
+
# representing the embedded targets to be integrated
|
267
|
+
#
|
268
|
+
def analyze_host_targets_in_podfile(aggregate_targets, embedded_aggregate_targets)
|
269
|
+
target_definitions_by_uuid = {}
|
270
|
+
# Collect aggregate target definitions by uuid to later lookup host target
|
271
|
+
# definitions and verify their compatiblity with their embedded targets
|
272
|
+
aggregate_targets.each do |target|
|
273
|
+
target.user_targets.map(&:uuid).each do |uuid|
|
274
|
+
target_definitions_by_uuid[uuid] = target.target_definition
|
275
|
+
end
|
276
|
+
end
|
277
|
+
aggregate_target_user_projects = aggregate_targets.map(&:user_project)
|
278
|
+
embedded_targets_missing_hosts = []
|
279
|
+
host_uuid_to_embedded_target_definitions = {}
|
280
|
+
# Search all of the known user projects for each embedded target's hosts
|
281
|
+
embedded_aggregate_targets.each do |target|
|
282
|
+
host_uuids = []
|
283
|
+
aggregate_target_user_projects.product(target.user_targets).each do |user_project, user_target|
|
284
|
+
host_uuids += user_project.host_targets_for_embedded_target(user_target).map(&:uuid)
|
285
|
+
end
|
286
|
+
# For each host, keep track of its embedded target definitions
|
287
|
+
# to later verify each embedded target's compatiblity with its host,
|
288
|
+
# ignoring the hosts that aren't known to CocoaPods (no target
|
289
|
+
# definitions in the Podfile)
|
290
|
+
host_uuids.each do |uuid|
|
291
|
+
(host_uuid_to_embedded_target_definitions[uuid] ||= []) << target.target_definition if target_definitions_by_uuid.key? uuid
|
292
|
+
end
|
293
|
+
# If none of the hosts are known to CocoaPods (no target definitions
|
294
|
+
# in the Podfile), add it to the list of targets missing hosts
|
295
|
+
embedded_targets_missing_hosts << target unless host_uuids.any? do |uuid|
|
296
|
+
target_definitions_by_uuid.key? uuid
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
unless embedded_targets_missing_hosts.empty?
|
301
|
+
embedded_targets_missing_hosts_product_types = embedded_targets_missing_hosts.map(&:user_targets).flatten.map(&:symbol_type).uniq
|
302
|
+
# If the targets missing hosts are only frameworks, then this is likely
|
303
|
+
# a project for doing framework development. In that case, just warn that
|
304
|
+
# the frameworks that these targets depend on won't be integrated anywhere
|
305
|
+
if embedded_targets_missing_hosts_product_types == [:framework]
|
306
|
+
UI.warn 'The Podfile contains framework targets, for which the Podfile does not contain host targets (targets which embed the framework).' \
|
307
|
+
"\n" \
|
308
|
+
'If this project is for doing framework development, you can ignore this message. Otherwise, add a target to the Podfile that embeds these frameworks to make this message go away (e.g. a test target).'
|
309
|
+
else
|
310
|
+
target_names = embedded_targets_missing_hosts.map do |target|
|
311
|
+
target.name.sub('Pods-', '') # Make the target names more recognizable to the user
|
312
|
+
end.join ', '
|
313
|
+
raise Informative, "Unable to find host target(s) for #{target_names}. Please add the host targets for the embedded targets to the Podfile." \
|
314
|
+
"\n" \
|
315
|
+
'Certain kinds of targets require a host target. A host target is a "parent" target which embeds a "child" target. These are example types of targets that need a host target:' \
|
316
|
+
"\n- Framework" \
|
317
|
+
"\n- App Extension" \
|
318
|
+
"\n- Watch OS 1 Extension" \
|
319
|
+
"\n- Messages Extension (except when used with a Messages Application)"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
target_mismatches = []
|
324
|
+
check_prop = lambda do |target_definition1, target_definition2, attr, msg|
|
325
|
+
attr1 = target_definition1.send(attr)
|
326
|
+
attr2 = target_definition2.send(attr)
|
327
|
+
if attr1 != attr2
|
328
|
+
target_mismatches << "- #{target_definition1.name} (#{attr1}) and #{target_definition2.name} (#{attr2}) #{msg}."
|
329
|
+
end
|
330
|
+
end
|
331
|
+
host_uuid_to_embedded_target_definitions.each do |uuid, target_definitions|
|
332
|
+
host_target_definition = target_definitions_by_uuid[uuid]
|
333
|
+
target_definitions.each do |target_definition|
|
334
|
+
check_prop.call(host_target_definition, target_definition, :platform, 'do not use the same platform')
|
335
|
+
check_prop.call(host_target_definition, target_definition, :uses_frameworks?, 'do not both set use_frameworks!')
|
336
|
+
check_prop.call(host_target_definition, target_definition, :swift_version, 'do not use the same Swift version')
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
unless target_mismatches.empty?
|
341
|
+
heading = 'Unable to integrate the following embedded targets with their respective host targets (a host target is a "parent" target which embeds a "child" target like a framework or extension):'
|
342
|
+
raise Informative, heading + "\n\n" + target_mismatches.sort.uniq.join("\n")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
229
346
|
# Creates the models that represent the targets generated by CocoaPods.
|
230
347
|
#
|
231
348
|
# @return [Array<AggregateTarget>]
|
232
349
|
#
|
233
350
|
def generate_targets
|
234
351
|
specs_by_target = result.specs_by_target.reject { |td, _| td.abstract? }
|
352
|
+
check_pod_target_swift_versions(specs_by_target)
|
235
353
|
pod_targets = generate_pod_targets(specs_by_target)
|
236
354
|
aggregate_targets = specs_by_target.keys.map do |target_definition|
|
237
355
|
generate_target(target_definition, pod_targets)
|
238
356
|
end
|
357
|
+
if installation_options.integrate_targets?
|
358
|
+
# Copy embedded target pods that cannot have their pods embedded as frameworks to their host targets
|
359
|
+
embedded_targets = aggregate_targets.select(&:requires_host_target?).select(&:requires_frameworks?)
|
360
|
+
analyze_host_targets_in_podfile(aggregate_targets, embedded_targets)
|
361
|
+
aggregate_targets.each do |target|
|
362
|
+
copy_embedded_target_pod_targets_to_host(target, embedded_targets)
|
363
|
+
end
|
364
|
+
end
|
239
365
|
aggregate_targets.each do |target|
|
240
366
|
target.search_paths_aggregate_targets = aggregate_targets.select do |aggregate_target|
|
241
367
|
target.target_definition.targets_to_inherit_search_paths.include?(aggregate_target.target_definition)
|
@@ -277,11 +403,45 @@ module Pod
|
|
277
403
|
target.pod_targets = pod_targets.select do |pod_target|
|
278
404
|
pod_target.target_definitions.include?(target_definition)
|
279
405
|
end
|
406
|
+
|
280
407
|
target
|
281
408
|
end
|
282
409
|
|
410
|
+
# Verify that targets using a pod have the same swift version
|
411
|
+
#
|
412
|
+
# @param [Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
|
413
|
+
# the resolved specifications grouped by target.
|
414
|
+
#
|
415
|
+
# @note raises Informative if targets using a pod do not have
|
416
|
+
# the same swift version
|
417
|
+
#
|
418
|
+
def check_pod_target_swift_versions(specs_by_target)
|
419
|
+
targets_by_spec = {}
|
420
|
+
specs_by_target.each do |target, specs|
|
421
|
+
specs.each do |spec|
|
422
|
+
(targets_by_spec[spec] ||= []) << target
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
error_message_for_target = lambda do |target|
|
427
|
+
"#{target.name} (Swift #{target.swift_version})"
|
428
|
+
end
|
429
|
+
|
430
|
+
error_messages = targets_by_spec.map do |spec, targets|
|
431
|
+
swift_targets = targets.reject { |target| target.swift_version.blank? }
|
432
|
+
next if swift_targets.empty? || swift_targets.uniq(&:swift_version).count == 1
|
433
|
+
target_errors = swift_targets.map(&error_message_for_target).join(', ')
|
434
|
+
"- #{spec.name} required by #{target_errors}"
|
435
|
+
end.compact
|
436
|
+
|
437
|
+
unless error_messages.empty?
|
438
|
+
raise Informative, 'The following pods are integrated into targets ' \
|
439
|
+
"that do not have the same Swift version:\n\n#{error_messages.join("\n")}"
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
283
443
|
# Setup the pod targets for an aggregate target. Deduplicates resulting
|
284
|
-
# targets by grouping by
|
444
|
+
# targets by grouping by platform and subspec by their root
|
285
445
|
# to create a {PodTarget} for each spec.
|
286
446
|
#
|
287
447
|
# @param [Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
|
@@ -11,7 +11,7 @@ module Pod
|
|
11
11
|
|
12
12
|
# @return [String] the PACKAGE emoji to use as prefix for every build phase aded to the user project
|
13
13
|
#
|
14
|
-
BUILD_PHASE_PREFIX =
|
14
|
+
BUILD_PHASE_PREFIX = '[CP] '.freeze
|
15
15
|
|
16
16
|
# @return [String] the name of the check manifest phase
|
17
17
|
#
|
@@ -20,7 +20,12 @@ module Pod
|
|
20
20
|
# @return [Array<Symbol>] the symbol types, which require that the pod
|
21
21
|
# frameworks are embedded in the output directory / product bundle.
|
22
22
|
#
|
23
|
-
|
23
|
+
# @note This does not include :app_extension or :watch_extension because
|
24
|
+
# these types must have their frameworks embedded in their host targets.
|
25
|
+
# For messages extensions, this only applies if it's embedded in a messages
|
26
|
+
# application.
|
27
|
+
#
|
28
|
+
EMBED_FRAMEWORK_TARGET_TYPES = [:application, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
|
24
29
|
|
25
30
|
# @return [String] the name of the embed frameworks phase
|
26
31
|
#
|
@@ -54,6 +59,7 @@ module Pod
|
|
54
59
|
|
55
60
|
add_pods_library
|
56
61
|
add_embed_frameworks_script_phase
|
62
|
+
remove_embed_frameworks_script_phase_from_embedded_targets
|
57
63
|
add_copy_resources_script_phase
|
58
64
|
add_check_manifest_lock_script_phase
|
59
65
|
end
|
@@ -110,6 +116,21 @@ module Pod
|
|
110
116
|
end
|
111
117
|
end
|
112
118
|
|
119
|
+
# Removes the embed frameworks build phase from embedded targets
|
120
|
+
#
|
121
|
+
# @note Older versions of CocoaPods would add this build phase to embedded
|
122
|
+
# targets. They should be removed on upgrade because embedded targets
|
123
|
+
# will have their frameworks embedded in their host targets.
|
124
|
+
#
|
125
|
+
def remove_embed_frameworks_script_phase_from_embedded_targets
|
126
|
+
return unless target.requires_host_target?
|
127
|
+
native_targets.each do |native_target|
|
128
|
+
if AggregateTarget::EMBED_FRAMEWORKS_IN_HOST_TARGET_TYPES.include? native_target.symbol_type
|
129
|
+
remove_embed_frameworks_script_phase(native_target)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
113
134
|
def add_embed_frameworks_script_phase_to_target(native_target)
|
114
135
|
phase = create_or_update_build_phase(native_target, EMBED_FRAMEWORK_PHASE_NAME)
|
115
136
|
script_path = target.embed_frameworks_script_relative_path
|
@@ -121,7 +142,7 @@ module Pod
|
|
121
142
|
# @param [PBXNativeTarget] native_target
|
122
143
|
#
|
123
144
|
def remove_embed_frameworks_script_phase(native_target)
|
124
|
-
embed_build_phase = native_target.shell_script_build_phases.find { |bp| bp.name
|
145
|
+
embed_build_phase = native_target.shell_script_build_phases.find { |bp| bp.name && bp.name.end_with?(EMBED_FRAMEWORK_PHASE_NAME) }
|
125
146
|
return unless embed_build_phase.present?
|
126
147
|
native_target.build_phases.delete(embed_build_phase)
|
127
148
|
end
|
@@ -157,10 +178,9 @@ module Pod
|
|
157
178
|
native_target.build_phases.unshift(phase).uniq! unless native_target.build_phases.first == phase
|
158
179
|
phase.shell_script = <<-SH.strip_heredoc
|
159
180
|
diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
|
160
|
-
if [
|
161
|
-
|
162
|
-
|
163
|
-
EOM
|
181
|
+
if [ $? != 0 ] ; then
|
182
|
+
# print error to STDERR
|
183
|
+
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
|
164
184
|
exit 1
|
165
185
|
fi
|
166
186
|
SH
|
@@ -184,6 +204,7 @@ module Pod
|
|
184
204
|
# directory / product bundle.
|
185
205
|
#
|
186
206
|
def native_targets_to_embed_in
|
207
|
+
return [] if target.requires_host_target?
|
187
208
|
native_targets.select do |target|
|
188
209
|
EMBED_FRAMEWORK_TARGET_TYPES.include?(target.symbol_type)
|
189
210
|
end
|
@@ -215,8 +236,7 @@ module Pod
|
|
215
236
|
def create_or_update_build_phase(target, phase_name, phase_class = Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
|
216
237
|
prefixed_phase_name = BUILD_PHASE_PREFIX + phase_name
|
217
238
|
build_phases = target.build_phases.grep(phase_class)
|
218
|
-
build_phases.find { |phase| phase.name
|
219
|
-
build_phases.find { |phase| phase.name == phase_name }.tap { |p| p.name = prefixed_phase_name if p } ||
|
239
|
+
build_phases.find { |phase| phase.name && phase.name.end_with?(phase_name) }.tap { |p| p.name = prefixed_phase_name if p } ||
|
220
240
|
target.project.new(phase_class).tap do |phase|
|
221
241
|
UI.message("Adding Build Phase '#{prefixed_phase_name}' to project.") do
|
222
242
|
phase.name = prefixed_phase_name
|