cocoapods 1.5.2 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
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