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