cocoapods 1.5.3 → 1.6.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +200 -0
  3. data/lib/cocoapods.rb +0 -1
  4. data/lib/cocoapods/command/init.rb +1 -1
  5. data/lib/cocoapods/command/install.rb +7 -0
  6. data/lib/cocoapods/command/lib/lint.rb +8 -1
  7. data/lib/cocoapods/command/outdated.rb +2 -7
  8. data/lib/cocoapods/command/repo/add.rb +1 -1
  9. data/lib/cocoapods/command/repo/list.rb +1 -1
  10. data/lib/cocoapods/command/repo/push.rb +17 -12
  11. data/lib/cocoapods/command/repo/remove.rb +1 -1
  12. data/lib/cocoapods/command/repo/update.rb +1 -1
  13. data/lib/cocoapods/command/setup.rb +1 -1
  14. data/lib/cocoapods/command/spec/create.rb +39 -39
  15. data/lib/cocoapods/command/spec/lint.rb +8 -1
  16. data/lib/cocoapods/config.rb +13 -2
  17. data/lib/cocoapods/downloader/cache.rb +1 -1
  18. data/lib/cocoapods/executable.rb +2 -2
  19. data/lib/cocoapods/external_sources.rb +7 -4
  20. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  23. data/lib/cocoapods/generator/acknowledgements/plist.rb +11 -0
  24. data/lib/cocoapods/generator/app_target_helper.rb +102 -16
  25. data/lib/cocoapods/generator/copy_resources_script.rb +6 -0
  26. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  27. data/lib/cocoapods/generator/embed_frameworks_script.rb +13 -2
  28. data/lib/cocoapods/generator/header.rb +1 -1
  29. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  30. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  31. data/lib/cocoapods/hooks_manager.rb +28 -17
  32. data/lib/cocoapods/installer.rb +103 -42
  33. data/lib/cocoapods/installer/analyzer.rb +362 -277
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +9 -6
  36. data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
  37. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
  38. data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
  39. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +24 -16
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  42. data/lib/cocoapods/installer/post_install_hooks_context.rb +71 -46
  43. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  44. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  45. data/lib/cocoapods/installer/user_project_integrator.rb +0 -2
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +38 -28
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +129 -119
  49. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +95 -0
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +12 -45
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +277 -169
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +31 -24
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +60 -69
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  57. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  58. data/lib/cocoapods/project.rb +14 -14
  59. data/lib/cocoapods/resolver.rb +38 -50
  60. data/lib/cocoapods/sandbox.rb +22 -38
  61. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  62. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  63. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  64. data/lib/cocoapods/sources_manager.rb +1 -1
  65. data/lib/cocoapods/target.rb +92 -37
  66. data/lib/cocoapods/target/aggregate_target.rb +140 -84
  67. data/lib/cocoapods/target/build_settings.rb +1076 -0
  68. data/lib/cocoapods/target/pod_target.rb +198 -294
  69. data/lib/cocoapods/user_interface.rb +5 -0
  70. data/lib/cocoapods/validator.rb +133 -41
  71. metadata +18 -18
  72. data/lib/cocoapods/generator/xcconfig.rb +0 -13
  73. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  74. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  75. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
@@ -1,71 +1,86 @@
1
1
  module Pod
2
2
  # Stores the information relative to the target used to compile a single Pod.
3
- # A pod can have one or more activated spec/subspecs.
3
+ # A pod can have one or more activated spec, subspecs and test specs.
4
4
  #
5
5
  class PodTarget < Target
6
- # @return [Array<Specification>] the spec and subspecs for the target.
6
+ # @return [Array<Specification>] the spec, subspecs and test specs of the target.
7
7
  #
8
8
  attr_reader :specs
9
9
 
10
+ # @return [Array<Specification>] All of the test specs within this target.
11
+ # Subset of #specs.
12
+ #
13
+ attr_reader :test_specs
14
+
15
+ # @return [Array<Specification>] All of the specs within this target that are not test specs.
16
+ # Subset of #specs.
17
+ #
18
+ attr_reader :non_test_specs
19
+
10
20
  # @return [Array<TargetDefinition>] the target definitions of the Podfile
11
21
  # that generated this target.
12
22
  #
13
23
  attr_reader :target_definitions
14
24
 
15
- # @return [HeadersStore] the header directory for the target.
25
+ # @return [Array<Sandbox::FileAccessor>] the file accessors for the
26
+ # specifications of this target.
16
27
  #
17
- attr_reader :build_headers
28
+ attr_reader :file_accessors
18
29
 
19
- # @return [String] used as suffix in the label
30
+ # @return [String] the suffix used for this target when deduplicated. May be `nil`.
20
31
  #
21
32
  # @note This affects the value returned by #configuration_build_dir
22
33
  # and accessors relying on this as #build_product_path.
23
34
  #
24
35
  attr_reader :scope_suffix
25
36
 
37
+ # @return [HeadersStore] the header directory for the target.
38
+ #
39
+ attr_reader :build_headers
40
+
26
41
  # @return [Array<PodTarget>] the targets that this target has a dependency
27
42
  # upon.
28
43
  #
29
44
  attr_accessor :dependent_targets
30
45
 
31
- # @return [Array<PodTarget>] the targets that this target has a test dependency
32
- # upon.
46
+ # @return [Hash{String=>Array<PodTarget>}] all target dependencies by test spec name.
33
47
  #
34
- attr_accessor :test_dependent_targets
48
+ attr_accessor :test_dependent_targets_by_spec_name
35
49
 
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.
50
+ # Initialize a new instance
38
51
  #
39
- attr_accessor :test_native_targets
40
-
41
- # @param [Array<Specification>] specs @see #specs
52
+ # @param [Sandbox] sandbox @see Target#sandbox
53
+ # @param [Boolean] host_requires_frameworks @see Target#host_requires_frameworks
54
+ # @param [Hash{String=>Symbol}] user_build_configurations @see Target#user_build_configurations
55
+ # @param [Array<String>] archs @see Target#archs
56
+ # @param [Platform] platform @see Target#platform
42
57
  # @param [Array<TargetDefinition>] target_definitions @see #target_definitions
43
- # @param [Sandbox] sandbox @see #sandbox
58
+ # @param [Array<Sandbox::FileAccessor>] file_accessors @see #file_accessors
44
59
  # @param [String] scope_suffix @see #scope_suffix
45
60
  #
46
- def initialize(specs, target_definitions, sandbox, scope_suffix = nil)
61
+ def initialize(sandbox, host_requires_frameworks, user_build_configurations, archs, platform, specs,
62
+ target_definitions, file_accessors = [], scope_suffix = nil)
63
+ super(sandbox, host_requires_frameworks, user_build_configurations, archs, platform)
47
64
  raise "Can't initialize a PodTarget without specs!" if specs.nil? || specs.empty?
48
65
  raise "Can't initialize a PodTarget without TargetDefinition!" if target_definitions.nil? || target_definitions.empty?
49
- raise "Can't initialize a PodTarget with only abstract TargetDefinitions" if target_definitions.all?(&:abstract?)
66
+ raise "Can't initialize a PodTarget with only abstract TargetDefinitions!" if target_definitions.all?(&:abstract?)
50
67
  raise "Can't initialize a PodTarget with an empty string scope suffix!" if scope_suffix == ''
51
- super()
52
68
  @specs = specs.dup.freeze
53
- @test_specs, @non_test_specs = @specs.partition(&:test_specification?)
54
69
  @target_definitions = target_definitions
55
- @sandbox = sandbox
70
+ @file_accessors = file_accessors
56
71
  @scope_suffix = scope_suffix
57
- @build_headers = Sandbox::HeadersStore.new(sandbox, 'Private', :private)
58
- @file_accessors = []
59
- @resource_bundle_targets = []
60
- @test_resource_bundle_targets = []
61
- @test_native_targets = []
72
+ @test_specs, @non_test_specs = @specs.partition(&:test_specification?)
73
+ @build_headers = Sandbox::HeadersStore.new(sandbox, 'Private', :private)
62
74
  @dependent_targets = []
63
- @test_dependent_targets = []
75
+ @test_dependent_targets_by_spec_name = {}
64
76
  @build_config_cache = {}
65
77
  end
66
78
 
79
+ # Scopes the current target based on the existing pod targets within the cache.
80
+ #
67
81
  # @param [Hash{Array => PodTarget}] cache
68
- # the cached PodTarget for a previously scoped (specs, target_definition)
82
+ # the cached target for a previously scoped target.
83
+ #
69
84
  # @return [Array<PodTarget>] a scoped copy for each target definition.
70
85
  #
71
86
  def scoped(cache = {})
@@ -74,13 +89,14 @@ module Pod
74
89
  if cache[cache_key]
75
90
  cache[cache_key]
76
91
  else
77
- target = PodTarget.new(specs, [target_definition], sandbox, target_definition.label)
78
- target.file_accessors = file_accessors
79
- target.user_build_configurations = user_build_configurations
80
- target.native_target = native_target
81
- target.archs = archs
92
+ target = PodTarget.new(sandbox, host_requires_frameworks, user_build_configurations, archs, platform, specs, [target_definition], file_accessors, target_definition.label)
82
93
  target.dependent_targets = dependent_targets.flat_map { |pt| pt.scoped(cache) }.select { |pt| pt.target_definitions == [target_definition] }
83
- target.host_requires_frameworks = host_requires_frameworks
94
+ target.test_dependent_targets_by_spec_name = Hash[test_dependent_targets_by_spec_name.map do |spec_name, test_pod_targets|
95
+ scoped_test_pod_targets = test_pod_targets.flat_map do |test_pod_target|
96
+ test_pod_target.scoped(cache).select { |pt| pt.target_definitions == [target_definition] }
97
+ end
98
+ [spec_name, scoped_test_pod_targets]
99
+ end]
84
100
  cache[cache_key] = target
85
101
  end
86
102
  end
@@ -96,7 +112,7 @@ module Pod
96
112
  end
97
113
  end
98
114
 
99
- # @return [String] the Swift version for the target. If the pod author has provided a swift version
115
+ # @return [String] the Swift version for the target. If the pod author has provided a Swift version
100
116
  # then that is the one returned, otherwise the Swift version is determined by the user
101
117
  # targets that include this pod target.
102
118
  #
@@ -110,32 +126,6 @@ module Pod
110
126
  root_spec.swift_version
111
127
  end
112
128
 
113
- # @note The deployment target for the pod target is the maximum of all
114
- # the deployment targets for the current platform of the target
115
- # (or the minimum required to support the current installation
116
- # strategy, if higher).
117
- #
118
- # @return [Platform] the platform for this target.
119
- #
120
- def platform
121
- @platform ||= begin
122
- platform_name = target_definitions.first.platform.name
123
- default = Podfile::TargetDefinition::PLATFORM_DEFAULTS[platform_name]
124
- deployment_target = specs.map do |spec|
125
- Version.new(spec.deployment_target(platform_name) || default)
126
- end.max
127
- if platform_name == :ios && requires_frameworks?
128
- minimum = Version.new('8.0')
129
- deployment_target = [deployment_target, minimum].max
130
- end
131
- Platform.new(platform_name, deployment_target)
132
- end
133
- end
134
-
135
- # @visibility private
136
- #
137
- attr_writer :platform
138
-
139
129
  # @return [Podfile] The podfile which declares the dependency.
140
130
  #
141
131
  def podfile
@@ -150,30 +140,15 @@ module Pod
150
140
  root_spec.module_name
151
141
  end
152
142
 
153
- # @return [Array<Sandbox::FileAccessor>] the file accessors for the
154
- # specifications of this target.
155
- #
156
- attr_accessor :file_accessors
157
-
158
- # @return [Array<PBXNativeTarget>] the resource bundle targets belonging
159
- # to this target.
160
- attr_reader :resource_bundle_targets
161
-
162
- # @return [Array<PBXNativeTarget>] the resource bundle test targets belonging
163
- # to this target.
164
- attr_reader :test_resource_bundle_targets
165
-
166
143
  # @return [Bool] Whether or not this target should be built.
167
144
  #
168
145
  # A target should not be built if it has no source files.
169
146
  #
170
147
  def should_build?
171
148
  return @should_build if defined? @should_build
172
-
173
- return @should_build = true if contains_script_phases?
174
-
175
- source_files = file_accessors.flat_map(&:source_files)
176
- source_files -= file_accessors.flat_map(&:headers)
149
+ accessors = file_accessors.reject { |fa| fa.spec.test_specification? }
150
+ source_files = accessors.flat_map(&:source_files)
151
+ source_files -= accessors.flat_map(&:headers)
177
152
  @should_build = !source_files.empty?
178
153
  end
179
154
 
@@ -184,17 +159,47 @@ module Pod
184
159
  specs.map { |spec| spec.consumer(platform) }
185
160
  end
186
161
 
187
- # @return [Boolean] Whether the target uses Swift code.
162
+ # @return [Array<Specification::Consumer>] the test specification consumers for
163
+ # the target.
164
+ #
165
+ def test_spec_consumers
166
+ test_specs.map { |test_spec| test_spec.consumer(platform) }
167
+ end
168
+
169
+ # @return [Boolean] Whether the target uses Swift code. This excludes source files from test specs.
188
170
  #
189
171
  def uses_swift?
190
172
  return @uses_swift if defined? @uses_swift
191
173
  @uses_swift = begin
192
- file_accessors.any? do |file_accessor|
174
+ file_accessors.reject { |a| a.spec.test_specification? }.any? do |file_accessor|
193
175
  file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
194
176
  end
195
177
  end
196
178
  end
197
179
 
180
+ # Checks whether a particular test specification uses Swift or not.
181
+ #
182
+ # @param [Specification] test_spec
183
+ # The test spec to query against.
184
+ #
185
+ # @return [Boolean] Whether the target uses Swift code within the requested test spec.
186
+ #
187
+ def uses_swift_for_test_spec?(test_spec)
188
+ @uses_swift_for_test_type ||= {}
189
+ return @uses_swift_for_test_type[test_spec.name] if @uses_swift_for_test_type.key?(test_spec.name)
190
+ @uses_swift_for_test_type[test_spec.name] = begin
191
+ file_accessors.select { |a| a.spec.test_specification? && a.spec == test_spec }.any? do |file_accessor|
192
+ file_accessor.source_files.any? { |sf| sf.extname == '.swift' }
193
+ end
194
+ end
195
+ end
196
+
197
+ # @return [Boolean] Whether the target should build a static framework.
198
+ #
199
+ def static_framework?
200
+ requires_frameworks? && root_spec.static_framework
201
+ end
202
+
198
203
  # @return [Boolean] Whether the target defines a "module"
199
204
  # (and thus will need a module map and umbrella header).
200
205
  #
@@ -204,7 +209,19 @@ module Pod
204
209
  def defines_module?
205
210
  return @defines_module if defined?(@defines_module)
206
211
  return @defines_module = true if uses_swift? || requires_frameworks?
207
- return @defines_module = true if target_definitions.any? { |td| td.build_pod_as_module?(pod_name) }
212
+
213
+ explicit_target_definitions = target_definitions.select { |td| td.dependencies.any? { |d| d.root_name == pod_name } }
214
+ tds_by_answer = explicit_target_definitions.group_by { |td| td.build_pod_as_module?(pod_name) }
215
+
216
+ if tds_by_answer.size > 1
217
+ UI.warn "Unable to determine whether to build `#{label}` as a module due to a conflict " \
218
+ "between the following target definitions:\n\t- #{tds_by_answer.map do |a, td|
219
+ "`#{td.to_sentence}` #{a ? "requires `#{label}` as a module" : "does not require `#{label}` as a module"}"
220
+ end.join("\n\t- ")}\n\n" \
221
+ "Defaulting to skip building `#{label}` as a module."
222
+ elsif tds_by_answer.keys.first == true || target_definitions.all? { |td| td.build_pod_as_module?(pod_name) }
223
+ return @defines_module = true
224
+ end
208
225
 
209
226
  @defines_module = non_test_specs.any? { |s| s.consumer(platform).pod_target_xcconfig['DEFINES_MODULE'] == 'YES' }
210
227
  end
@@ -221,113 +238,58 @@ module Pod
221
238
  !script_phases.empty?
222
239
  end
223
240
 
224
- # @return [Hash{Array => Specification}] a hash where the keys are the test native targets and the value
225
- # an array of all the test specs associated with this native target.
226
- #
227
- def test_specs_by_native_target
228
- test_specs.group_by { |test_spec| native_target_for_spec(test_spec) }
229
- end
230
-
231
241
  # @return [Boolean] Whether the target has any tests specifications.
232
242
  #
233
243
  def contains_test_specifications?
234
244
  !test_specs.empty?
235
245
  end
236
246
 
237
- # @return [Array<Specification>] All of the test specs within this target.
238
- #
239
- attr_reader :test_specs
240
-
241
- # @return [Array<Specification>] All of the specs within this target that are not test specs.
242
- #
243
- attr_reader :non_test_specs
244
-
245
- # @return [Array<Symbol>] All of the test supported types within this target.
246
- #
247
- def supported_test_types
248
- test_specs.map(&:test_type).uniq
249
- end
250
-
251
- # Returns the framework paths associated with this target. By default all paths include the framework paths
252
- # that are part of test specifications.
253
- #
254
- # @param [Boolean] include_test_spec_paths
255
- # Whether to include framework paths from test specifications or not.
256
- #
257
- # @return [Array<Hash{Symbol => [String]}>] The vendored and non vendored framework paths
258
- # this target depends upon.
259
- #
260
- def framework_paths(include_test_spec_paths = true)
261
- @framework_paths ||= {}
262
- return @framework_paths[include_test_spec_paths] if @framework_paths.key?(include_test_spec_paths)
263
- @framework_paths[include_test_spec_paths] = begin
264
- accessors = file_accessors
265
- accessors = accessors.reject { |a| a.spec.test_specification? } unless include_test_spec_paths
266
- frameworks = []
267
- accessors.flat_map(&:vendored_dynamic_artifacts).map do |framework_path|
268
- relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
269
- framework = { :name => framework_path.basename.to_s,
270
- :input_path => "${PODS_ROOT}/#{relative_path_to_sandbox}",
271
- :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{framework_path.basename}" }
272
- # Until this can be configured, assume the dSYM file uses the file name as the framework.
273
- # See https://github.com/CocoaPods/CocoaPods/issues/1698
274
- dsym_name = "#{framework_path.basename}.dSYM"
275
- dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
276
- if dsym_path.exist?
277
- framework[:dsym_name] = dsym_name
278
- framework[:dsym_input_path] = "${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
279
- framework[:dsym_output_path] = "${DWARF_DSYM_FOLDER_PATH}/#{dsym_name}"
247
+ # @return [Hash{String=>Array<Hash{Symbol=>String}>}] The vendored and non vendored framework paths this target
248
+ # depends upon keyed by spec name. For the root spec and subspecs the framework path of the target itself
249
+ # is included.
250
+ #
251
+ def framework_paths
252
+ @framework_paths ||= begin
253
+ file_accessors.each_with_object({}) do |file_accessor, hash|
254
+ frameworks = []
255
+ file_accessor.vendored_dynamic_artifacts.map do |framework_path|
256
+ relative_path_to_sandbox = framework_path.relative_path_from(sandbox.root)
257
+ framework = { :name => framework_path.basename.to_s,
258
+ :input_path => "${PODS_ROOT}/#{relative_path_to_sandbox}",
259
+ :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{framework_path.basename}" }
260
+ # Until this can be configured, assume the dSYM file uses the file name as the framework.
261
+ # See https://github.com/CocoaPods/CocoaPods/issues/1698
262
+ dsym_name = "#{framework_path.basename}.dSYM"
263
+ dsym_path = Pathname.new("#{framework_path.dirname}/#{dsym_name}")
264
+ if dsym_path.exist?
265
+ framework[:dsym_name] = dsym_name
266
+ framework[:dsym_input_path] = "${PODS_ROOT}/#{relative_path_to_sandbox}.dSYM"
267
+ framework[:dsym_output_path] = "${DWARF_DSYM_FOLDER_PATH}/#{dsym_name}"
268
+ end
269
+ frameworks << framework
280
270
  end
281
- frameworks << framework
282
- end
283
- if should_build? && requires_frameworks? && !static_framework?
284
- frameworks << { :name => product_name,
285
- :input_path => build_product_path('${BUILT_PRODUCTS_DIR}'),
286
- :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{product_name}" }
271
+ if !file_accessor.spec.test_specification? && should_build? && requires_frameworks? && !static_framework?
272
+ frameworks << { :name => product_name,
273
+ :input_path => build_product_path('${BUILT_PRODUCTS_DIR}'),
274
+ :output_path => "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{product_name}" }
275
+ end
276
+ hash[file_accessor.spec.name] = frameworks
287
277
  end
288
- frameworks
289
278
  end
290
279
  end
291
280
 
292
- # Returns the resource paths associated with this target. By default all paths include the resource paths
293
- # that are part of test specifications.
294
- #
295
- # @param [Boolean] include_test_spec_paths
296
- # Whether to include resource paths from test specifications or not.
297
- #
298
- # @return [Array<String>] The resource and resource bundle paths this target depends upon.
281
+ # @return [Hash{String=>Array<String>}] The resource and resource bundle paths this target depends upon keyed by
282
+ # spec name.
299
283
  #
300
- def resource_paths(include_test_spec_paths = true)
301
- @resource_paths ||= {}
302
- return @resource_paths[include_test_spec_paths] if @resource_paths.key?(include_test_spec_paths)
303
- @resource_paths[include_test_spec_paths] = begin
304
- accessors = file_accessors
305
- accessors = accessors.reject { |a| a.spec.test_specification? } unless include_test_spec_paths
306
- resource_paths = accessors.flat_map do |accessor|
307
- accessor.resources.flat_map { |res| "${PODS_ROOT}/#{res.relative_path_from(sandbox.project.path.dirname)}" }
284
+ def resource_paths
285
+ @resource_paths ||= begin
286
+ file_accessors.each_with_object({}) do |file_accessor, hash|
287
+ resource_paths = file_accessor.resources.map { |res| "${PODS_ROOT}/#{res.relative_path_from(sandbox.project.path.dirname)}" }
288
+ prefix = Pod::Target::BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE
289
+ prefix = configuration_build_dir unless file_accessor.spec.test_specification?
290
+ resource_bundle_paths = file_accessor.resource_bundles.keys.map { |name| "#{prefix}/#{name.shellescape}.bundle" }
291
+ hash[file_accessor.spec.name] = resource_paths + resource_bundle_paths
308
292
  end
309
- resource_bundles = accessors.flat_map do |accessor|
310
- prefix = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE
311
- prefix = configuration_build_dir unless accessor.spec.test_specification?
312
- accessor.resource_bundles.keys.map { |name| "#{prefix}/#{name.shellescape}.bundle" }
313
- end
314
- resource_paths + resource_bundles
315
- end
316
- end
317
-
318
- # Returns the corresponding native target to use based on the provided specification.
319
- # This is used to figure out whether to add a source file into the library native target or any of the
320
- # test native targets.
321
- #
322
- # @param [Specification] spec
323
- # The specification to base from in order to find the native target.
324
- #
325
- # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
326
- #
327
- def native_target_for_spec(spec)
328
- return native_target unless spec.test_specification?
329
- test_native_targets.find do |native_target|
330
- native_target.symbol_type == product_type_for_test_type(spec.test_type)
331
293
  end
332
294
  end
333
295
 
@@ -349,22 +311,6 @@ module Pod
349
311
  end
350
312
  end
351
313
 
352
- # Returns the corresponding test type given the product type.
353
- #
354
- # @param [Symbol] product_type
355
- # The product type to map to a test type.
356
- #
357
- # @return [Symbol] The native product type to use.
358
- #
359
- def test_type_for_product_type(product_type)
360
- case product_type
361
- when :unit_test_bundle
362
- :unit
363
- else
364
- raise Informative, "Unknown product type `#{product_type}`."
365
- end
366
- end
367
-
368
314
  # @return [Specification] The root specification for the target.
369
315
  #
370
316
  def root_spec
@@ -391,6 +337,12 @@ module Pod
391
337
  end
392
338
  end
393
339
 
340
+ # @return [Pathname] the absolute path of the prefix header file.
341
+ #
342
+ def prefix_header_path
343
+ support_files_dir + "#{label}-prefix.pch"
344
+ end
345
+
394
346
  # @param [String] bundle_name
395
347
  # The name of the bundle product, which is given by the +spec+.
396
348
  #
@@ -400,64 +352,49 @@ module Pod
400
352
  "#{label}-#{bundle_name}"
401
353
  end
402
354
 
403
- # @param [Symbol] test_type
404
- # The test type to use for producing the test label.
355
+ # @param [Specification] test_spec
356
+ # The test spec to use for producing the test label.
405
357
  #
406
358
  # @return [String] The derived name of the test target.
407
359
  #
408
- def test_target_label(test_type)
409
- "#{label}-#{test_type.capitalize}-Tests"
360
+ def test_target_label(test_spec)
361
+ "#{label}-#{test_spec.test_type.capitalize}-#{test_spec.name.split('/')[1..-1].join('-')}"
410
362
  end
411
363
 
412
- # @param [Symbol] test_type
413
- # The test type to use for producing the test label.
414
- #
415
- # @return [String] The label of the app host label to use given the platform and test type.
416
- #
417
- def app_host_label(test_type)
418
- "AppHost-#{Platform.string_name(platform.symbolic_name)}-#{test_type.capitalize}-Tests"
419
- end
420
-
421
- # @param [Symbol] test_type
422
- # The test type this embed frameworks script path is for.
364
+ # @param [Specification] test_spec
365
+ # The test spec this embed frameworks script path is for.
423
366
  #
424
367
  # @return [Pathname] The absolute path of the copy resources script for the given test type.
425
368
  #
426
- def copy_resources_script_path_for_test_type(test_type)
427
- support_files_dir + "#{test_target_label(test_type)}-resources.sh"
369
+ def copy_resources_script_path_for_test_spec(test_spec)
370
+ support_files_dir + "#{test_target_label(test_spec)}-resources.sh"
428
371
  end
429
372
 
430
- # @param [Symbol] test_type
431
- # The test type this embed frameworks script path is for.
373
+ # @param [Specification] test_spec
374
+ # The test spec this embed frameworks script path is for.
432
375
  #
433
376
  # @return [Pathname] The absolute path of the embed frameworks script for the given test type.
434
377
  #
435
- def embed_frameworks_script_path_for_test_type(test_type)
436
- support_files_dir + "#{test_target_label(test_type)}-frameworks.sh"
378
+ def embed_frameworks_script_path_for_test_spec(test_spec)
379
+ support_files_dir + "#{test_target_label(test_spec)}-frameworks.sh"
437
380
  end
438
381
 
439
- # @param [Symbol] test_type
440
- # The test type this Info.plist path is for.
382
+ # @param [Specification] test_spec
383
+ # The test spec this Info.plist path is for.
441
384
  #
442
385
  # @return [Pathname] The absolute path of the Info.plist for the given test type.
443
386
  #
444
- def info_plist_path_for_test_type(test_type)
445
- support_files_dir + "#{test_target_label(test_type)}-Info.plist"
387
+ def info_plist_path_for_test_spec(test_spec)
388
+ support_files_dir + "#{test_target_label(test_spec)}-Info.plist"
446
389
  end
447
390
 
448
- # @return [Pathname] the absolute path of the prefix header file.
449
- #
450
- def prefix_header_path
451
- support_files_dir + "#{label}-prefix.pch"
452
- end
453
-
454
- # @param [Symbol] test_type
455
- # The test type prefix header path is for.
391
+ # @param [Specification] test_spec
392
+ # The test spec this prefix header path is for.
456
393
  #
457
394
  # @return [Pathname] the absolute path of the prefix header file for the given test type.
458
395
  #
459
- def prefix_header_path_for_test_type(test_type)
460
- support_files_dir + "#{test_target_label(test_type)}-prefix.pch"
396
+ def prefix_header_path_for_test_spec(test_spec)
397
+ support_files_dir + "#{test_target_label(test_spec)}-prefix.pch"
461
398
  end
462
399
 
463
400
  # @return [Array<String>] The names of the Pods on which this target
@@ -473,72 +410,49 @@ module Pod
473
410
  # dependency upon.
474
411
  #
475
412
  def recursive_dependent_targets
476
- @recursive_dependent_targets ||= begin
477
- targets = dependent_targets.clone
478
-
479
- targets.each do |target|
480
- target.dependent_targets.each do |t|
481
- targets.push(t) unless t == self || targets.include?(t)
482
- end
483
- end
413
+ @recursive_dependent_targets ||= _add_recursive_dependent_targets(Set.new).delete(self).to_a
414
+ end
484
415
 
485
- targets
416
+ def _add_recursive_dependent_targets(set)
417
+ dependent_targets.each do |target|
418
+ target._add_recursive_dependent_targets(set) if set.add?(target)
486
419
  end
420
+
421
+ set
487
422
  end
423
+ protected :_add_recursive_dependent_targets
488
424
 
425
+ # @param [Specification] test_spec
426
+ # the test spec to scope dependencies for
427
+ #
489
428
  # @return [Array<PodTarget>] the recursive targets that this target has a
490
429
  # test dependency upon.
491
430
  #
492
- def recursive_test_dependent_targets
493
- @recursive_test_dependent_targets ||= begin
494
- targets = test_dependent_targets.clone
431
+ def recursive_test_dependent_targets(test_spec)
432
+ @recursive_test_dependent_targets ||= {}
433
+ @recursive_test_dependent_targets[test_spec] ||= _add_recursive_test_dependent_targets(test_spec, Set.new).to_a
434
+ end
495
435
 
496
- targets.each do |target|
497
- target.test_dependent_targets.each do |t|
498
- targets.push(t) unless t == self || targets.include?(t)
499
- end
500
- end
436
+ def _add_recursive_test_dependent_targets(test_spec, set)
437
+ raise ArgumentError, 'Must give a test spec' unless test_spec
438
+ return unless dependent_targets = test_dependent_targets_by_spec_name[test_spec.name]
501
439
 
502
- targets
440
+ dependent_targets.each do |target|
441
+ target._add_recursive_dependent_targets(set) if set.add?(target)
503
442
  end
504
- end
505
443
 
506
- # @return [Array<PodTarget>] the canonical list of dependent targets this target has a dependency upon.
507
- # This list includes the target itself as well as its recursive dependent and test dependent targets.
508
- #
509
- def all_dependent_targets
510
- [self, *recursive_dependent_targets, *recursive_test_dependent_targets].uniq
444
+ set
511
445
  end
446
+ private :_add_recursive_test_dependent_targets
512
447
 
513
- # Checks if the target should be included in the build configuration with
514
- # the given name of a given target definition.
448
+ # @param [Specification] test_spec
449
+ # the test spec to scope dependencies for
515
450
  #
516
- # @param [TargetDefinition] target_definition
517
- # The target definition to check.
518
- #
519
- # @param [String] configuration_name
520
- # The name of the build configuration.
451
+ # @return [Array<PodTarget>] the canonical list of dependent targets this target has a dependency upon.
452
+ # This list includes the target itself as well as its recursive dependent and test dependent targets.
521
453
  #
522
- def include_in_build_config?(target_definition, configuration_name)
523
- key = [target_definition.label, configuration_name]
524
- if @build_config_cache.key?(key)
525
- return @build_config_cache[key]
526
- end
527
-
528
- whitelists = target_definition_dependencies(target_definition).map do |dependency|
529
- target_definition.pod_whitelisted_for_configuration?(dependency.name, configuration_name)
530
- end.uniq
531
-
532
- if whitelists.empty?
533
- @build_config_cache[key] = true
534
- elsif whitelists.count == 1
535
- @build_config_cache[key] = whitelists.first
536
- else
537
- raise Informative, "The subspecs of `#{pod_name}` are linked to " \
538
- "different build configurations for the `#{target_definition}` " \
539
- 'target. CocoaPods does not currently support subspecs across ' \
540
- 'different build configurations.'
541
- end
454
+ def dependent_targets_for_test_spec(test_spec)
455
+ [self, *recursive_dependent_targets, *recursive_test_dependent_targets(test_spec)].uniq
542
456
  end
543
457
 
544
458
  # Checks if warnings should be inhibited for this pod.
@@ -574,7 +488,7 @@ module Pod
574
488
  #
575
489
  # @return [String] The absolute path to the configuration build dir
576
490
  #
577
- def configuration_build_dir(dir = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE)
491
+ def configuration_build_dir(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
578
492
  "#{dir}/#{label}"
579
493
  end
580
494
 
@@ -583,7 +497,7 @@ module Pod
583
497
  #
584
498
  # @return [String] The absolute path to the build product
585
499
  #
586
- def build_product_path(dir = Generator::XCConfig::XCConfigHelper::CONFIGURATION_BUILD_DIR_VARIABLE)
500
+ def build_product_path(dir = BuildSettings::CONFIGURATION_BUILD_DIR_VARIABLE)
587
501
  "#{configuration_build_dir(dir)}/#{product_name}"
588
502
  end
589
503
 
@@ -600,18 +514,18 @@ module Pod
600
514
  [version.major, version.minor, version.patch].join('.')
601
515
  end
602
516
 
603
- # @param [Boolean] include_test_dependent_targets
517
+ # @param [Boolean] include_dependent_targets_for_test_spec
604
518
  # whether to include header search paths for test dependent targets
605
519
  #
606
520
  # @return [Array<String>] The set of header search paths this target uses.
607
521
  #
608
- def header_search_paths(include_test_dependent_targets = false)
522
+ def header_search_paths(include_dependent_targets_for_test_spec: nil)
609
523
  header_search_paths = []
610
524
  header_search_paths.concat(build_headers.search_paths(platform, nil, false))
611
525
  header_search_paths.concat(sandbox.public_headers.search_paths(platform, pod_name, uses_modular_headers?))
612
526
  dependent_targets = recursive_dependent_targets
613
- dependent_targets += recursive_test_dependent_targets if include_test_dependent_targets
614
- dependent_targets.each do |dependent_target|
527
+ dependent_targets += recursive_test_dependent_targets(include_dependent_targets_for_test_spec) if include_dependent_targets_for_test_spec
528
+ dependent_targets.uniq.each do |dependent_target|
615
529
  header_search_paths.concat(sandbox.public_headers.search_paths(platform, dependent_target.pod_name, defines_module? && dependent_target.uses_modular_headers?(false)))
616
530
  end
617
531
  header_search_paths.uniq
@@ -636,18 +550,8 @@ module Pod
636
550
 
637
551
  private
638
552
 
639
- # @param [TargetDefinition] target_definition
640
- # The target definition to check.
641
- #
642
- # @return [Array<Dependency>] The dependency of the target definition for
643
- # this Pod. Return an empty array if the Pod is not a direct
644
- # dependency of the target definition but the dependency of one or
645
- # more Pods.
646
- #
647
- def target_definition_dependencies(target_definition)
648
- target_definition.dependencies.select do |dependency|
649
- Specification.root_name(dependency.name) == pod_name
650
- end
553
+ def create_build_settings
554
+ BuildSettings::PodTargetSettings.new(self)
651
555
  end
652
556
  end
653
557
  end