cocoapods 1.2.1 → 1.3.0.beta.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 +4 -4
- data/CHANGELOG.md +89 -1
- data/lib/cocoapods/command/lib/lint.rb +3 -0
- data/lib/cocoapods/command/repo/push.rb +1 -1
- data/lib/cocoapods/command/spec/lint.rb +3 -0
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/copy_resources_script.rb +11 -11
- data/lib/cocoapods/generator/embed_frameworks_script.rb +18 -6
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +6 -66
- data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +16 -3
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +102 -6
- data/lib/cocoapods/installer.rb +17 -76
- data/lib/cocoapods/installer/analyzer.rb +48 -44
- data/lib/cocoapods/installer/xcode.rb +1 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +22 -9
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +11 -5
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +78 -5
- data/lib/cocoapods/installer/xcode/target_validator.rb +126 -0
- data/lib/cocoapods/project.rb +5 -0
- data/lib/cocoapods/resolver.rb +1 -1
- data/lib/cocoapods/resolver/lazy_specification.rb +2 -2
- data/lib/cocoapods/sandbox.rb +23 -0
- data/lib/cocoapods/target/pod_target.rb +72 -5
- data/lib/cocoapods/validator.rb +101 -46
- metadata +9 -8
@@ -0,0 +1,126 @@
|
|
1
|
+
module Pod
|
2
|
+
class Installer
|
3
|
+
class Xcode
|
4
|
+
# The {Xcode::TargetValidator} ensures that the pod and aggregate target
|
5
|
+
# configuration is valid for installation.
|
6
|
+
#
|
7
|
+
class TargetValidator
|
8
|
+
# @return [Array<AggregateTarget>] The aggregate targets that should be
|
9
|
+
# validated.
|
10
|
+
#
|
11
|
+
attr_reader :aggregate_targets
|
12
|
+
|
13
|
+
# @return [Array<PodTarget>] The pod targets that should be validated.
|
14
|
+
#
|
15
|
+
attr_reader :pod_targets
|
16
|
+
|
17
|
+
# Create a new TargetValidator with aggregate and pod targets to
|
18
|
+
# validate.
|
19
|
+
#
|
20
|
+
# @param [Array<AggregateTarget>] aggregate_targets
|
21
|
+
# The aggregate targets to validate.
|
22
|
+
#
|
23
|
+
# @param [Array<PodTarget>] pod_targets
|
24
|
+
# The pod targets to validate.
|
25
|
+
#
|
26
|
+
def initialize(aggregate_targets, pod_targets)
|
27
|
+
@aggregate_targets = aggregate_targets
|
28
|
+
@pod_targets = pod_targets
|
29
|
+
end
|
30
|
+
|
31
|
+
# Perform the validation steps for the provided aggregate and pod
|
32
|
+
# targets.
|
33
|
+
#
|
34
|
+
def validate!
|
35
|
+
verify_no_duplicate_framework_and_library_names
|
36
|
+
verify_no_static_framework_transitive_dependencies
|
37
|
+
verify_no_pods_used_with_multiple_swift_versions
|
38
|
+
verify_framework_usage
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def verify_no_duplicate_framework_and_library_names
|
44
|
+
aggregate_targets.each do |aggregate_target|
|
45
|
+
aggregate_target.user_build_configurations.keys.each do |config|
|
46
|
+
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
47
|
+
file_accessors = pod_targets.flat_map(&:file_accessors)
|
48
|
+
|
49
|
+
frameworks = file_accessors.flat_map(&:vendored_frameworks).uniq.map(&:basename)
|
50
|
+
frameworks += pod_targets.select { |pt| pt.should_build? && pt.requires_frameworks? }.map(&:product_module_name)
|
51
|
+
verify_no_duplicate_names(frameworks, aggregate_target.label, 'frameworks')
|
52
|
+
|
53
|
+
libraries = file_accessors.flat_map(&:vendored_libraries).uniq.map(&:basename)
|
54
|
+
libraries += pod_targets.select { |pt| pt.should_build? && !pt.requires_frameworks? }.map(&:product_name)
|
55
|
+
verify_no_duplicate_names(libraries, aggregate_target.label, 'libraries')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def verify_no_duplicate_names(names, label, type)
|
61
|
+
duplicates = names.map { |n| n.to_s.downcase }.group_by { |f| f }.select { |_, v| v.size > 1 }.keys
|
62
|
+
|
63
|
+
unless duplicates.empty?
|
64
|
+
raise Informative, "The '#{label}' target has " \
|
65
|
+
"#{type} with conflicting names: #{duplicates.to_sentence}."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def verify_no_static_framework_transitive_dependencies
|
70
|
+
aggregate_targets.each do |aggregate_target|
|
71
|
+
next unless aggregate_target.requires_frameworks?
|
72
|
+
|
73
|
+
aggregate_target.user_build_configurations.keys.each do |config|
|
74
|
+
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
75
|
+
|
76
|
+
dependencies = pod_targets.select(&:should_build?).flat_map(&:dependencies)
|
77
|
+
dependended_upon_targets = pod_targets.select { |t| dependencies.include?(t.pod_name) && !t.should_build? }
|
78
|
+
|
79
|
+
static_libs = dependended_upon_targets.flat_map(&:file_accessors).flat_map(&:vendored_static_artifacts)
|
80
|
+
unless static_libs.empty?
|
81
|
+
raise Informative, "The '#{aggregate_target.label}' target has " \
|
82
|
+
"transitive dependencies that include static binaries: (#{static_libs.to_sentence})"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def verify_no_pods_used_with_multiple_swift_versions
|
89
|
+
error_message_for_target = lambda do |target|
|
90
|
+
"#{target.name} (Swift #{target.swift_version})"
|
91
|
+
end
|
92
|
+
swift_pod_targets = pod_targets.select(&:uses_swift?)
|
93
|
+
error_messages = swift_pod_targets.map do |pod_target|
|
94
|
+
swift_target_definitions = pod_target.target_definitions.reject { |target| target.swift_version.blank? }
|
95
|
+
next if swift_target_definitions.empty? || swift_target_definitions.uniq(&:swift_version).count == 1
|
96
|
+
target_errors = swift_target_definitions.map(&error_message_for_target).join(', ')
|
97
|
+
"- #{pod_target.name} required by #{target_errors}"
|
98
|
+
end.compact
|
99
|
+
|
100
|
+
unless error_messages.empty?
|
101
|
+
raise Informative, 'The following pods are integrated into targets ' \
|
102
|
+
"that do not have the same Swift version:\n\n#{error_messages.join("\n")}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def verify_framework_usage
|
107
|
+
aggregate_targets.each do |aggregate_target|
|
108
|
+
next if aggregate_target.requires_frameworks?
|
109
|
+
|
110
|
+
aggregate_target.user_build_configurations.keys.each do |config|
|
111
|
+
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
112
|
+
|
113
|
+
swift_pods = pod_targets.select(&:uses_swift?)
|
114
|
+
unless swift_pods.empty?
|
115
|
+
raise Informative, 'Pods written in Swift can only be integrated as frameworks; ' \
|
116
|
+
'add `use_frameworks!` to your Podfile or target to opt into using it. ' \
|
117
|
+
"The Swift #{swift_pods.size == 1 ? 'Pod being used is' : 'Pods being used are'}: " +
|
118
|
+
swift_pods.map(&:name).to_sentence
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/cocoapods/project.rb
CHANGED
data/lib/cocoapods/resolver.rb
CHANGED
@@ -305,7 +305,7 @@ module Pod
|
|
305
305
|
find_cached_set(dependency).
|
306
306
|
all_specifications(installation_options.warn_for_multiple_pod_sources).
|
307
307
|
select { |s| requirement.satisfied_by? s.version }.
|
308
|
-
map { |s| s.subspec_by_name(dependency.name, false) }.
|
308
|
+
map { |s| s.subspec_by_name(dependency.name, false, true) }.
|
309
309
|
compact.
|
310
310
|
reverse
|
311
311
|
end
|
@@ -18,11 +18,11 @@ module Pod
|
|
18
18
|
specification.respond_to?(method, include_all)
|
19
19
|
end
|
20
20
|
|
21
|
-
def subspec_by_name(name = nil, raise_if_missing = true)
|
21
|
+
def subspec_by_name(name = nil, raise_if_missing = true, include_test_specifications = false)
|
22
22
|
if !name || name == self.name
|
23
23
|
self
|
24
24
|
else
|
25
|
-
specification.subspec_by_name(name, raise_if_missing)
|
25
|
+
specification.subspec_by_name(name, raise_if_missing, include_test_specifications)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/lib/cocoapods/sandbox.rb
CHANGED
@@ -386,5 +386,28 @@ module Pod
|
|
386
386
|
end
|
387
387
|
|
388
388
|
#-------------------------------------------------------------------------#
|
389
|
+
|
390
|
+
public
|
391
|
+
|
392
|
+
# @!group Pods Helpers
|
393
|
+
|
394
|
+
# Creates the file accessors for the given Pod Targets.
|
395
|
+
#
|
396
|
+
# @param [Array<PodTarget>] pod_targets
|
397
|
+
# The Pod Targets to create file accessors for.
|
398
|
+
#
|
399
|
+
def create_file_accessors(pod_targets)
|
400
|
+
pod_targets.each do |pod_target|
|
401
|
+
pod_root = pod_dir(pod_target.root_spec.name)
|
402
|
+
path_list = PathList.new(pod_root)
|
403
|
+
file_accessors = pod_target.specs.map do |spec|
|
404
|
+
FileAccessor.new(path_list, spec.consumer(pod_target.platform))
|
405
|
+
end
|
406
|
+
pod_target.file_accessors ||= []
|
407
|
+
pod_target.file_accessors.concat(file_accessors)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
#-------------------------------------------------------------------------#
|
389
412
|
end
|
390
413
|
end
|
@@ -28,6 +28,16 @@ module Pod
|
|
28
28
|
#
|
29
29
|
attr_accessor :dependent_targets
|
30
30
|
|
31
|
+
# @return [Array<PodTarget>] the targets that this target has a test dependency
|
32
|
+
# upon.
|
33
|
+
#
|
34
|
+
attr_accessor :test_dependent_targets
|
35
|
+
|
36
|
+
# return [Array<PBXNativeTarget>] the test target generated in the Pods project for
|
37
|
+
# this library or `nil` if there is no test target created.
|
38
|
+
#
|
39
|
+
attr_accessor :test_native_targets
|
40
|
+
|
31
41
|
# @param [Array<Specification>] specs @see #specs
|
32
42
|
# @param [Array<TargetDefinition>] target_definitions @see #target_definitions
|
33
43
|
# @param [Sandbox] sandbox @see #sandbox
|
@@ -46,7 +56,9 @@ module Pod
|
|
46
56
|
@build_headers = Sandbox::HeadersStore.new(sandbox, 'Private')
|
47
57
|
@file_accessors = []
|
48
58
|
@resource_bundle_targets = []
|
59
|
+
@test_native_targets = []
|
49
60
|
@dependent_targets = []
|
61
|
+
@test_dependent_targets = []
|
50
62
|
@build_config_cache = {}
|
51
63
|
end
|
52
64
|
|
@@ -133,7 +145,7 @@ module Pod
|
|
133
145
|
#
|
134
146
|
attr_accessor :file_accessors
|
135
147
|
|
136
|
-
# @return [Array<
|
148
|
+
# @return [Array<PBXNativeTarget>] the resource bundle targets belonging
|
137
149
|
# to this target.
|
138
150
|
attr_reader :resource_bundle_targets
|
139
151
|
|
@@ -157,7 +169,7 @@ module Pod
|
|
157
169
|
specs.map { |spec| spec.consumer(platform) }
|
158
170
|
end
|
159
171
|
|
160
|
-
# @return [Boolean] Whether the target uses Swift code
|
172
|
+
# @return [Boolean] Whether the target uses Swift code.
|
161
173
|
#
|
162
174
|
def uses_swift?
|
163
175
|
return @uses_swift if defined? @uses_swift
|
@@ -168,6 +180,52 @@ module Pod
|
|
168
180
|
end
|
169
181
|
end
|
170
182
|
|
183
|
+
# @return [Boolean] Whether the target has any tests specifications.
|
184
|
+
#
|
185
|
+
def contains_test_specifications?
|
186
|
+
specs.any?(&:test_specification?)
|
187
|
+
end
|
188
|
+
|
189
|
+
# @return [Array<Symbol>] All of the test supported types within this target.
|
190
|
+
#
|
191
|
+
def supported_test_types
|
192
|
+
specs.select(&:test_specification?).map(&:test_type).uniq
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns the corresponding native target to use based on the provided specification.
|
196
|
+
# This is used to figure out whether to add a source file into the library native target or any of the
|
197
|
+
# test native targets.
|
198
|
+
#
|
199
|
+
# @param [Specification] spec
|
200
|
+
# The specifcation to base from in order to find the native target.
|
201
|
+
#
|
202
|
+
# @return [PBXNativeTarget] the native target to use or `nil` if none is found.
|
203
|
+
#
|
204
|
+
def native_target_for_spec(spec)
|
205
|
+
return native_target unless spec.test_specification?
|
206
|
+
test_native_targets.find do |native_target|
|
207
|
+
native_target.symbol_type == product_type_for_test_type(spec.test_type)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns the corresponding native product type to use given the test type.
|
212
|
+
# This is primarily used when creating the native targets in order to produce the correct test bundle target
|
213
|
+
# based on the type of tests included.
|
214
|
+
#
|
215
|
+
# @param [Symbol] test_type
|
216
|
+
# The test type to map to provided by the test specification DSL.
|
217
|
+
#
|
218
|
+
# @return [Symbol] The native product type to use.
|
219
|
+
#
|
220
|
+
def product_type_for_test_type(test_type)
|
221
|
+
case test_type
|
222
|
+
when :unit
|
223
|
+
:unit_test_bundle
|
224
|
+
else
|
225
|
+
raise Informative, "Unknown test type `#{test_type}`."
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
171
229
|
# @return [Specification] The root specification for the target.
|
172
230
|
#
|
173
231
|
def root_spec
|
@@ -189,6 +247,15 @@ module Pod
|
|
189
247
|
"#{label}-#{bundle_name}"
|
190
248
|
end
|
191
249
|
|
250
|
+
# @param [Symbol] test_type
|
251
|
+
# The test type to use for producing the test label.
|
252
|
+
#
|
253
|
+
# @return [String] The derived name of the test target.
|
254
|
+
#
|
255
|
+
def test_target_label(test_type)
|
256
|
+
"#{label}-#{test_type.capitalize}-Tests"
|
257
|
+
end
|
258
|
+
|
192
259
|
# @return [Array<String>] The names of the Pods on which this target
|
193
260
|
# depends.
|
194
261
|
#
|
@@ -234,7 +301,7 @@ module Pod
|
|
234
301
|
|
235
302
|
if whitelists.empty?
|
236
303
|
@build_config_cache[key] = true
|
237
|
-
|
304
|
+
true
|
238
305
|
elsif whitelists.count == 1
|
239
306
|
@build_config_cache[key] = whitelists.first
|
240
307
|
whitelists.first
|
@@ -258,7 +325,7 @@ module Pod
|
|
258
325
|
|
259
326
|
if whitelists.empty?
|
260
327
|
@inhibit_warnings = false
|
261
|
-
|
328
|
+
false
|
262
329
|
elsif whitelists.count == 1
|
263
330
|
@inhibit_warnings = whitelists.first
|
264
331
|
whitelists.first
|
@@ -268,7 +335,7 @@ module Pod
|
|
268
335
|
'settings to inhibit warnings. CocoaPods does not currently ' \
|
269
336
|
'support different settings and will fall back to your preference ' \
|
270
337
|
'set in the root target definition.'
|
271
|
-
|
338
|
+
podfile.root_target_definitions.first.inhibits_warnings_for_pod?(root_spec.name)
|
272
339
|
end
|
273
340
|
end
|
274
341
|
|
data/lib/cocoapods/validator.rb
CHANGED
@@ -28,8 +28,12 @@ module Pod
|
|
28
28
|
# the Source URLs to use in creating a {Podfile}.
|
29
29
|
#
|
30
30
|
def initialize(spec_or_path, source_urls)
|
31
|
-
@source_urls = source_urls.map { |url| config.sources_manager.source_with_name_or_url(url) }.map(&:url)
|
32
31
|
@linter = Specification::Linter.new(spec_or_path)
|
32
|
+
@source_urls = if @linter.spec && @linter.spec.dependencies.empty?
|
33
|
+
[]
|
34
|
+
else
|
35
|
+
source_urls.map { |url| config.sources_manager.source_with_name_or_url(url) }.map(&:url)
|
36
|
+
end
|
33
37
|
end
|
34
38
|
|
35
39
|
#-------------------------------------------------------------------------#
|
@@ -68,7 +72,7 @@ module Pod
|
|
68
72
|
a_spec = spec
|
69
73
|
if spec && @only_subspec
|
70
74
|
subspec_name = @only_subspec.start_with?(spec.root.name) ? @only_subspec : "#{spec.root.name}/#{@only_subspec}"
|
71
|
-
a_spec = spec.subspec_by_name(subspec_name)
|
75
|
+
a_spec = spec.subspec_by_name(subspec_name, true, true)
|
72
76
|
@subspec_name = a_spec.name
|
73
77
|
end
|
74
78
|
|
@@ -142,15 +146,8 @@ module Pod
|
|
142
146
|
reasons << 'all results apply only to public specs, but you can use ' \
|
143
147
|
'`--private` to ignore them if linting the specification for a private pod'
|
144
148
|
end
|
145
|
-
|
146
|
-
|
147
|
-
'Swift 3.0 by default, if you are using a different version of ' \
|
148
|
-
'swift you can use a `.swift-version` file to set the version for ' \
|
149
|
-
"your Pod. For example to use Swift 2.3, run: \n" \
|
150
|
-
' `echo "2.3" > .swift-version`'
|
151
|
-
else
|
152
|
-
reasons.to_sentence
|
153
|
-
end
|
149
|
+
|
150
|
+
reasons.to_sentence
|
154
151
|
end
|
155
152
|
|
156
153
|
#-------------------------------------------------------------------------#
|
@@ -189,10 +186,14 @@ module Pod
|
|
189
186
|
#
|
190
187
|
attr_accessor :only_subspec
|
191
188
|
|
192
|
-
# @return [Bool] Whether the validator should validate all subspecs
|
189
|
+
# @return [Bool] Whether the validator should validate all subspecs.
|
193
190
|
#
|
194
191
|
attr_accessor :no_subspecs
|
195
192
|
|
193
|
+
# @return [Bool] Whether the validator should skip building and running tests.
|
194
|
+
#
|
195
|
+
attr_accessor :skip_tests
|
196
|
+
|
196
197
|
# @return [Bool] Whether frameworks should be used for the installation.
|
197
198
|
#
|
198
199
|
attr_accessor :use_frameworks
|
@@ -245,7 +246,7 @@ module Pod
|
|
245
246
|
# @return [Pathname] the temporary directory used by the linter.
|
246
247
|
#
|
247
248
|
def validation_dir
|
248
|
-
Pathname(Dir.
|
249
|
+
@validation_dir ||= Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{spec.name}"]))
|
249
250
|
end
|
250
251
|
|
251
252
|
# @return [String] the SWIFT_VERSION to use for validation.
|
@@ -290,6 +291,10 @@ module Pod
|
|
290
291
|
# Perform analysis for a given spec (or subspec)
|
291
292
|
#
|
292
293
|
def perform_extensive_analysis(spec)
|
294
|
+
if spec.test_specification?
|
295
|
+
error('spec', "Validating a test spec (`#{spec.name}`) is not supported.")
|
296
|
+
return false
|
297
|
+
end
|
293
298
|
validate_homepage(spec)
|
294
299
|
validate_screenshots(spec)
|
295
300
|
validate_social_media_url(spec)
|
@@ -304,9 +309,11 @@ module Pod
|
|
304
309
|
download_pod
|
305
310
|
check_file_patterns
|
306
311
|
install_pod
|
312
|
+
validate_dot_swift_version
|
307
313
|
add_app_project_import
|
308
314
|
validate_vendored_dynamic_frameworks
|
309
315
|
build_pod
|
316
|
+
test_pod unless skip_tests
|
310
317
|
ensure
|
311
318
|
tear_down_validation_environment
|
312
319
|
end
|
@@ -324,7 +331,7 @@ module Pod
|
|
324
331
|
# Recursively perform the extensive analysis on all subspecs
|
325
332
|
#
|
326
333
|
def perform_extensive_subspec_analysis(spec)
|
327
|
-
spec.subspecs.send(fail_fast ? :all? : :each) do |subspec|
|
334
|
+
spec.subspecs.reject(&:test_specification?).send(fail_fast ? :all? : :each) do |subspec|
|
328
335
|
@subspec_name = subspec.name
|
329
336
|
perform_extensive_analysis(subspec)
|
330
337
|
end
|
@@ -378,6 +385,17 @@ module Pod
|
|
378
385
|
validate_url(spec.documentation_url) if spec.documentation_url
|
379
386
|
end
|
380
387
|
|
388
|
+
def validate_dot_swift_version
|
389
|
+
if !used_swift_version.nil? && dot_swift_version.nil?
|
390
|
+
warning(:swift_version,
|
391
|
+
'The validator for Swift projects uses ' \
|
392
|
+
'Swift 3.0 by default, if you are using a different version of ' \
|
393
|
+
'swift you can use a `.swift-version` file to set the version for ' \
|
394
|
+
"your Pod. For example to use Swift 2.3, run: \n" \
|
395
|
+
' `echo "2.3" > .swift-version`')
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
381
399
|
def setup_validation_environment
|
382
400
|
validation_dir.rmtree if validation_dir.exist?
|
383
401
|
validation_dir.mkpath
|
@@ -401,10 +419,11 @@ module Pod
|
|
401
419
|
end
|
402
420
|
|
403
421
|
def download_pod
|
404
|
-
podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks)
|
422
|
+
podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, consumer.spec.test_specs.map(&:name))
|
405
423
|
sandbox = Sandbox.new(config.sandbox_root)
|
406
424
|
@installer = Installer.new(sandbox, podfile)
|
407
425
|
@installer.use_default_plugins = false
|
426
|
+
@installer.has_dependencies = !spec.dependencies.empty?
|
408
427
|
%i(prepare resolve_dependencies download_dependencies).each { |m| @installer.send(m) }
|
409
428
|
@file_accessor = @installer.pod_targets.flat_map(&:file_accessors).find { |fa| fa.spec.name == consumer.spec.name }
|
410
429
|
end
|
@@ -480,15 +499,13 @@ module Pod
|
|
480
499
|
# for all available platforms with xcodebuild.
|
481
500
|
#
|
482
501
|
def install_pod
|
483
|
-
%i(
|
484
|
-
verify_no_static_framework_transitive_dependencies
|
485
|
-
verify_framework_usage generate_pods_project integrate_user_project
|
502
|
+
%i(validate_targets generate_pods_project integrate_user_project
|
486
503
|
perform_post_install_actions).each { |m| @installer.send(m) }
|
487
504
|
|
488
505
|
deployment_target = spec.subspec_by_name(subspec_name).deployment_target(consumer.platform_name)
|
489
506
|
@installer.aggregate_targets.each do |target|
|
490
507
|
target.pod_targets.each do |pod_target|
|
491
|
-
next unless native_target = pod_target.native_target
|
508
|
+
next unless (native_target = pod_target.native_target)
|
492
509
|
native_target.build_configuration_list.build_configurations.each do |build_configuration|
|
493
510
|
(build_configuration.build_settings['OTHER_CFLAGS'] ||= '$(inherited)') << ' -Wincomplete-umbrella'
|
494
511
|
build_configuration.build_settings['SWIFT_VERSION'] = swift_version if pod_target.uses_swift?
|
@@ -529,28 +546,38 @@ module Pod
|
|
529
546
|
UI.warn "Skipping compilation with `xcodebuild' because it can't be found.\n".yellow
|
530
547
|
else
|
531
548
|
UI.message "\nBuilding with xcodebuild.\n".yellow do
|
532
|
-
|
549
|
+
scheme = if skip_import_validation?
|
550
|
+
@installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }.label
|
551
|
+
else
|
552
|
+
'App'
|
553
|
+
end
|
554
|
+
output = xcodebuild('build', scheme, 'Release')
|
533
555
|
UI.puts output
|
534
556
|
parsed_output = parse_xcodebuild_output(output)
|
535
|
-
parsed_output
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
# it's safe for us to do the same.
|
540
|
-
#
|
541
|
-
# For more details see https://github.com/CocoaPods/CocoaPods/issues/2394#issuecomment-56658587
|
542
|
-
#
|
543
|
-
if message.include?("'InputFile' should have")
|
544
|
-
next
|
545
|
-
end
|
557
|
+
translate_output_to_linter_messages(parsed_output)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
end
|
546
561
|
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
562
|
+
# Builds and runs all test sources associated with the current specification being validated.
|
563
|
+
#
|
564
|
+
# @note Xcode warnings are treaded as notes because the spec maintainer
|
565
|
+
# might not be the author of the library
|
566
|
+
#
|
567
|
+
# @return [void]
|
568
|
+
#
|
569
|
+
def test_pod
|
570
|
+
if !xcodebuild_available?
|
571
|
+
UI.warn "Skipping test validation with `xcodebuild' because it can't be found.\n".yellow
|
572
|
+
else
|
573
|
+
UI.message "\nTesting with xcodebuild.\n".yellow do
|
574
|
+
pod_target = @installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }
|
575
|
+
consumer.spec.test_specs.each do |test_spec|
|
576
|
+
scheme = pod_target.native_target_for_spec(test_spec)
|
577
|
+
output = xcodebuild('test', scheme, 'Debug')
|
578
|
+
UI.puts output
|
579
|
+
parsed_output = parse_xcodebuild_output(output)
|
580
|
+
translate_output_to_linter_messages(parsed_output)
|
554
581
|
end
|
555
582
|
end
|
556
583
|
end
|
@@ -670,6 +697,29 @@ module Pod
|
|
670
697
|
add_result(:note, *args)
|
671
698
|
end
|
672
699
|
|
700
|
+
def translate_output_to_linter_messages(parsed_output)
|
701
|
+
parsed_output.each do |message|
|
702
|
+
# Checking the error for `InputFile` is to work around an Xcode
|
703
|
+
# issue where linting would fail even though `xcodebuild` actually
|
704
|
+
# succeeds. Xcode.app also doesn't fail when this issue occurs, so
|
705
|
+
# it's safe for us to do the same.
|
706
|
+
#
|
707
|
+
# For more details see https://github.com/CocoaPods/CocoaPods/issues/2394#issuecomment-56658587
|
708
|
+
#
|
709
|
+
if message.include?("'InputFile' should have")
|
710
|
+
next
|
711
|
+
end
|
712
|
+
|
713
|
+
if message =~ /\S+:\d+:\d+: error:/
|
714
|
+
error('xcodebuild', message)
|
715
|
+
elsif message =~ /\S+:\d+:\d+: warning:/
|
716
|
+
warning('xcodebuild', message)
|
717
|
+
else
|
718
|
+
note('xcodebuild', message)
|
719
|
+
end
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
673
723
|
def shares_pod_target_xcscheme?(pod_target)
|
674
724
|
Pathname.new(@installer.pods_project.path + pod_target.label).exist?
|
675
725
|
end
|
@@ -719,13 +769,16 @@ module Pod
|
|
719
769
|
# @param [Bool] use_frameworks
|
720
770
|
# whether frameworks should be used for the installation
|
721
771
|
#
|
772
|
+
# @param [Array<String>] test_spec_names
|
773
|
+
# the test spec names to include in the podfile.
|
774
|
+
#
|
722
775
|
# @return [Podfile] a podfile that requires the specification on the
|
723
776
|
# current platform.
|
724
777
|
#
|
725
778
|
# @note The generated podfile takes into account whether the linter is
|
726
779
|
# in local mode.
|
727
780
|
#
|
728
|
-
def podfile_from_spec(platform_name, deployment_target, use_frameworks = true)
|
781
|
+
def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [])
|
729
782
|
name = subspec_name || spec.name
|
730
783
|
podspec = file.realpath
|
731
784
|
local = local?
|
@@ -741,6 +794,13 @@ module Pod
|
|
741
794
|
else
|
742
795
|
pod name, :podspec => podspec.to_s
|
743
796
|
end
|
797
|
+
test_spec_names.each do |test_spec_name|
|
798
|
+
if local
|
799
|
+
pod test_spec_name, :path => podspec.dirname.to_s
|
800
|
+
else
|
801
|
+
pod test_spec_name, :podspec => podspec.to_s
|
802
|
+
end
|
803
|
+
end
|
744
804
|
end
|
745
805
|
end
|
746
806
|
end
|
@@ -771,14 +831,9 @@ module Pod
|
|
771
831
|
# @return [String] Executes xcodebuild in the current working directory and
|
772
832
|
# returns its output (both STDOUT and STDERR).
|
773
833
|
#
|
774
|
-
def xcodebuild
|
834
|
+
def xcodebuild(action, scheme, configuration)
|
775
835
|
require 'fourflusher'
|
776
|
-
|
777
|
-
@installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }.label
|
778
|
-
else
|
779
|
-
'App'
|
780
|
-
end
|
781
|
-
command = %W(clean build -workspace #{File.join(validation_dir, 'App.xcworkspace')} -scheme #{scheme} -configuration Release)
|
836
|
+
command = %W(clean #{action} -workspace #{File.join(validation_dir, 'App.xcworkspace')} -scheme #{scheme} -configuration #{configuration})
|
782
837
|
case consumer.platform_name
|
783
838
|
when :osx, :macos
|
784
839
|
command += %w(CODE_SIGN_IDENTITY=)
|