cocoapods 1.7.5 → 1.8.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -11
  3. data/LICENSE +13 -8
  4. data/README.md +2 -1
  5. data/lib/cocoapods/command/init.rb +18 -16
  6. data/lib/cocoapods/command/install.rb +2 -1
  7. data/lib/cocoapods/command/lib/create.rb +1 -2
  8. data/lib/cocoapods/command/lib/lint.rb +12 -11
  9. data/lib/cocoapods/command/repo/add.rb +2 -2
  10. data/lib/cocoapods/command/repo/list.rb +7 -5
  11. data/lib/cocoapods/command/repo/push.rb +15 -12
  12. data/lib/cocoapods/command/setup.rb +2 -88
  13. data/lib/cocoapods/command/spec/lint.rb +10 -9
  14. data/lib/cocoapods/command/update.rb +5 -4
  15. data/lib/cocoapods/config.rb +9 -8
  16. data/lib/cocoapods/external_sources/path_source.rb +1 -1
  17. data/lib/cocoapods/gem_version.rb +1 -1
  18. data/lib/cocoapods/generator/embed_frameworks_script.rb +1 -1
  19. data/lib/cocoapods/generator/info_plist_file.rb +2 -2
  20. data/lib/cocoapods/installer.rb +32 -12
  21. data/lib/cocoapods/installer/analyzer.rb +132 -97
  22. data/lib/cocoapods/installer/analyzer/target_inspector.rb +6 -8
  23. data/lib/cocoapods/installer/installation_options.rb +4 -0
  24. data/lib/cocoapods/installer/pod_source_installer.rb +17 -1
  25. data/lib/cocoapods/installer/podfile_validator.rb +26 -6
  26. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +37 -27
  27. data/lib/cocoapods/installer/project_cache/project_cache_version.rb +1 -1
  28. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +3 -3
  29. data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +12 -6
  30. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +32 -8
  31. data/lib/cocoapods/installer/project_cache/target_metadata.rb +6 -2
  32. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +12 -0
  33. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +1 -1
  34. data/lib/cocoapods/installer/xcode/multi_pods_project_generator.rb +3 -1
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +2 -2
  36. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +18 -3
  37. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +53 -11
  38. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +92 -60
  39. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +66 -50
  40. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +12 -0
  41. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +6 -2
  42. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +2 -2
  43. data/lib/cocoapods/installer/xcode/target_validator.rb +30 -14
  44. data/lib/cocoapods/native_target_extension.rb +11 -5
  45. data/lib/cocoapods/open-uri.rb +1 -1
  46. data/lib/cocoapods/project.rb +13 -7
  47. data/lib/cocoapods/resolver.rb +63 -53
  48. data/lib/cocoapods/resolver/lazy_specification.rb +14 -5
  49. data/lib/cocoapods/sandbox.rb +35 -2
  50. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +3 -4
  51. data/lib/cocoapods/sources_manager.rb +72 -43
  52. data/lib/cocoapods/target.rb +7 -1
  53. data/lib/cocoapods/target/aggregate_target.rb +13 -8
  54. data/lib/cocoapods/target/build_settings.rb +33 -10
  55. data/lib/cocoapods/target/pod_target.rb +114 -30
  56. data/lib/cocoapods/user_interface/error_report.rb +9 -5
  57. data/lib/cocoapods/validator.rb +55 -11
  58. data/lib/cocoapods/version_metadata.rb +14 -1
  59. metadata +6 -7
  60. data/lib/cocoapods/command/spec/env_spec.rb +0 -53
@@ -112,7 +112,7 @@ module Pod
112
112
  regex = %r{
113
113
  ^(
114
114
  (\s* # Possible, but unlikely, space before include statement
115
- \#include\s+ # Include statement
115
+ \#include(\?)?\s+ # Include statement
116
116
  ['"] # Open quote
117
117
  (.*\/)? # Possible prefix to path
118
118
  #{Regexp.quote(target_config_path)} # The path should end in the target_config_path
@@ -13,7 +13,9 @@ module Pod
13
13
  # Generate container Pods.xcodeproj.
14
14
  container_project = create_container_project(aggregate_targets, sandbox.project_path)
15
15
 
16
- project_paths_by_pod_targets = pod_targets.group_by { |pod_target| sandbox.pod_target_project_path(pod_target.pod_name) }
16
+ project_paths_by_pod_targets = pod_targets.group_by do |pod_target|
17
+ sandbox.pod_target_project_path(pod_target.project_name)
18
+ end
17
19
  projects_by_pod_targets = Hash[project_paths_by_pod_targets.map do |project_path, pod_targets|
18
20
  project = create_pods_project(pod_targets, project_path, container_project)
19
21
  [project, pod_targets]
@@ -59,8 +59,8 @@ module Pod
59
59
  # Hit the cache
60
60
  is_local = sandbox.local?(pod_target.pod_name)
61
61
  cached_dependency = metadata_cache.target_label_by_metadata[pod_target.label]
62
- project.add_cached_pod_subproject(cached_dependency, is_local)
63
- Project.add_cached_dependency(aggregate_native_target, cached_dependency)
62
+ project.add_cached_pod_subproject(sandbox, cached_dependency, is_local)
63
+ Project.add_cached_dependency(sandbox, aggregate_native_target, cached_dependency)
64
64
  end
65
65
  end
66
66
  end
@@ -37,6 +37,10 @@ module Pod
37
37
  #
38
38
  attr_reader :add_main
39
39
 
40
+ # @return [Hash] Info.plist entries for the app host
41
+ #
42
+ attr_reader :info_plist_entries
43
+
40
44
  # Initialize a new instance
41
45
  #
42
46
  # @param [Sandbox] sandbox @see #sandbox
@@ -46,8 +50,9 @@ module Pod
46
50
  # @param [String] group_name @see #group_name
47
51
  # @param [String] app_target_label see #app_target_label
48
52
  # @param [Boolean] add_main see #add_main
53
+ # @param [Hash] info_plist_entries see #info_plist_entries
49
54
  #
50
- def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true)
55
+ def initialize(sandbox, project, platform, subgroup_name, group_name, app_target_label, add_main: true, info_plist_entries: {})
51
56
  @sandbox = sandbox
52
57
  @project = project
53
58
  @platform = platform
@@ -55,6 +60,7 @@ module Pod
55
60
  @group_name = group_name
56
61
  @app_target_label = app_target_label
57
62
  @add_main = add_main
63
+ @info_plist_entries = info_plist_entries
58
64
  target_group = project.pod_group(group_name)
59
65
  @group = target_group[subgroup_name] || target_group.new_group(subgroup_name)
60
66
  end
@@ -74,9 +80,8 @@ module Pod
74
80
 
75
81
  Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, @group, app_target_label) if add_main
76
82
  Pod::Generator::AppTargetHelper.add_launchscreen_storyboard(project, app_host_target, @group, deployment_target, app_target_label) if platform == :ios
77
- additional_entries = ADDITIONAL_INFO_PLIST_ENTRIES.merge(platform == :ios ? ADDITIONAL_IOS_INFO_PLIST_ENTRIES : {})
78
83
  create_info_plist_file_with_sandbox(sandbox, app_host_info_plist_path, app_host_target, '1.0.0', platform,
79
- :appl, additional_entries)
84
+ :appl, :additional_entries => additional_info_plist_entries)
80
85
  @group.new_file(app_host_info_plist_path)
81
86
  app_host_target
82
87
  end
@@ -104,6 +109,16 @@ module Pod
104
109
  ),
105
110
  }.freeze
106
111
 
112
+ # @return [Hash] the additional Info.plist entries to be included
113
+ #
114
+ def additional_info_plist_entries
115
+ result = {}
116
+ result.merge!(ADDITIONAL_INFO_PLIST_ENTRIES)
117
+ result.merge!(ADDITIONAL_IOS_INFO_PLIST_ENTRIES) if platform == :ios
118
+ result.merge!(info_plist_entries) if info_plist_entries
119
+ result
120
+ end
121
+
107
122
  # @return [Pathname] The absolute path of the Info.plist to use for an app host.
108
123
  #
109
124
  def app_host_info_plist_path
@@ -6,6 +6,10 @@ module Pod
6
6
  class PodTargetDependencyInstaller
7
7
  require 'cocoapods/native_target_extension.rb'
8
8
 
9
+ # @return [Sandbox] The sandbox used for this installation.
10
+ #
11
+ attr_reader :sandbox
12
+
9
13
  # @return [TargetInstallationResults] The target installation results for pod targets.
10
14
  #
11
15
  attr_reader :pod_target_installation_results
@@ -14,10 +18,6 @@ module Pod
14
18
  #
15
19
  attr_reader :metadata_cache
16
20
 
17
- # @return [Sandbox] The sandbox used for this installation.
18
- #
19
- attr_reader :sandbox
20
-
21
21
  # Initialize a new instance.
22
22
  #
23
23
  # @param [Sandbox] sandbox @see #sandbox
@@ -85,8 +85,8 @@ module Pod
85
85
  else
86
86
  # Hit the cache
87
87
  cached_dependency = metadata_cache.target_label_by_metadata[dependent_target.label]
88
- project.add_cached_pod_subproject(cached_dependency, is_local)
89
- Project.add_cached_dependency(native_target, cached_dependency)
88
+ project.add_cached_pod_subproject(sandbox, cached_dependency, is_local)
89
+ Project.add_cached_dependency(sandbox, native_target, cached_dependency)
90
90
  end
91
91
  end
92
92
  end
@@ -98,7 +98,7 @@ module Pod
98
98
  test_native_target.add_dependency(test_resource_bundle_target)
99
99
  end
100
100
 
101
- test_dependent_targets = pod_target.test_dependent_targets_by_spec_name.fetch(test_spec.name, []).unshift(pod_target).uniq
101
+ test_dependent_targets = pod_target.test_dependent_targets_by_spec_name.fetch(test_spec.name, []).+([pod_target]).uniq
102
102
  test_dependent_targets.each do |test_dependent_target|
103
103
  is_local = sandbox.local?(test_dependent_target.pod_name)
104
104
  if dependency_installation_result = pod_target_installation_results[test_dependent_target.name]
@@ -111,10 +111,52 @@ module Pod
111
111
  else
112
112
  # Hit the cache
113
113
  cached_dependency = metadata_cache.target_label_by_metadata[test_dependent_target.label]
114
- project.add_cached_pod_subproject(cached_dependency, is_local)
115
- Project.add_cached_dependency(test_native_target, cached_dependency)
114
+ project.add_cached_pod_subproject(sandbox, cached_dependency, is_local)
115
+ Project.add_cached_dependency(sandbox, test_native_target, cached_dependency)
116
+ end
117
+ end
118
+
119
+ if app_host_target_label = pod_target.app_host_target_label(test_spec)
120
+ app_host_pod_target_label, app_host_target_label = *app_host_target_label
121
+ wire_test_native_target_app_host(test_native_target, pod_target, pod_target_installation_results, project, metadata_cache, app_host_pod_target_label, app_host_target_label)
122
+ end
123
+ end
124
+ end
125
+
126
+ def wire_test_native_target_app_host(test_native_target, pod_target, pod_target_installation_results, project, metadata_cache, app_host_pod_target_label, app_host_target_label)
127
+ if dependency_installation_result = pod_target_installation_results[app_host_pod_target_label]
128
+ unless app_native_target = dependency_installation_result.app_host_target_labelled(app_host_target_label)
129
+ raise Informative, "Did not find target with label #{app_host_target_label} in the set of targets installed for #{app_host_pod_target_label}."
130
+ end
131
+
132
+ dependent_test_project = app_native_target.project
133
+ if dependent_test_project != project
134
+ project.add_subproject_reference(dependent_test_project, project.dependencies_group)
135
+ end
136
+
137
+ app_host_target_names = app_native_target.resolved_build_setting('PRODUCT_NAME', true)
138
+ test_native_target.build_configurations.each do |configuration|
139
+ app_host_target_name = app_host_target_names[configuration.name] || target.name
140
+ case test_native_target.symbol_type
141
+ when :unit_test_bundle
142
+ test_host = "$(BUILT_PRODUCTS_DIR)/#{app_host_target_name}.app/"
143
+ test_host << 'Contents/MacOS/' if pod_target.platform == :osx
144
+ test_host << app_host_target_name.to_s
145
+ configuration.build_settings['BUNDLE_LOADER'] = '$(TEST_HOST)'
146
+ configuration.build_settings['TEST_HOST'] = test_host
147
+ when :ui_test_bundle
148
+ configuration.build_settings['TEST_TARGET_NAME'] = app_host_target_name
116
149
  end
117
150
  end
151
+ target_attributes = project.root_object.attributes['TargetAttributes'] || {}
152
+ target_attributes[test_native_target.uuid.to_s] = { 'TestTargetID' => app_native_target.uuid.to_s }
153
+ project.root_object.attributes['TargetAttributes'] = target_attributes
154
+ test_native_target.add_dependency(app_native_target)
155
+ else
156
+ # Hit the cache
157
+ cached_dependency = metadata_cache.target_label_by_metadata[app_host_target_label]
158
+ project.add_cached_subproject_reference(sandbox, cached_dependency, project.dependencies_group)
159
+ Project.add_cached_dependency(sandbox, test_native_target, cached_dependency)
118
160
  end
119
161
  end
120
162
 
@@ -144,8 +186,8 @@ module Pod
144
186
  else
145
187
  # Hit the cache
146
188
  cached_dependency = metadata_cache.target_label_by_metadata[app_dependent_target.label]
147
- project.add_cached_pod_subproject(cached_dependency, is_local)
148
- Project.add_cached_dependency(native_target, cached_dependency)
189
+ project.add_cached_pod_subproject(sandbox, cached_dependency, is_local)
190
+ Project.add_cached_dependency(sandbox, native_target, cached_dependency)
149
191
  end
150
192
  end
151
193
  end
@@ -48,7 +48,7 @@ module Pod
48
48
  resource_bundle_targets = add_resources_bundle_targets(library_file_accessors).values.flatten
49
49
 
50
50
  test_native_targets = add_test_targets
51
- test_app_host_targets = add_test_app_host_targets(test_native_targets)
51
+ test_app_host_targets = add_test_app_host_targets
52
52
  test_resource_bundle_targets = add_resources_bundle_targets(test_file_accessors)
53
53
 
54
54
  app_native_targets = add_app_targets
@@ -72,8 +72,8 @@ module Pod
72
72
  end
73
73
 
74
74
  file_accessor.public_headers.map do |public_header|
75
- public_header = if header_mappings_dir
76
- public_header.relative_path_from(header_mappings_dir)
75
+ public_header = if header_mappings_dir(file_accessor)
76
+ public_header.relative_path_from(header_mappings_dir(file_accessor))
77
77
  else
78
78
  public_header.basename
79
79
  end
@@ -88,7 +88,7 @@ module Pod
88
88
 
89
89
  if target.build_as_framework?
90
90
  unless skip_info_plist?(native_target)
91
- create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
91
+ create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform, :additional_entries => target.info_plist_entries)
92
92
  end
93
93
  create_build_phase_to_symlink_header_folders(native_target)
94
94
  end
@@ -303,7 +303,7 @@ module Pod
303
303
 
304
304
  header_file_refs = project_file_references_array(headers, 'header')
305
305
  native_target.add_file_references(header_file_refs) do |build_file|
306
- add_header(build_file, public_headers, private_headers, native_target)
306
+ add_header(file_accessor, build_file, public_headers, private_headers, native_target)
307
307
  end
308
308
 
309
309
  other_file_refs = project_file_references_array(other_source_files, 'other source')
@@ -331,7 +331,9 @@ module Pod
331
331
  name = target.test_target_label(test_spec)
332
332
  platform_name = target.platform.name
333
333
  language = target.uses_swift_for_spec?(test_spec) ? :swift : :objc
334
- test_native_target = project.new_target(product_type, name, platform_name, deployment_target, nil, language)
334
+ test_native_target = project.new_target(product_type, name, platform_name,
335
+ target.deployment_target_for_non_library_spec(test_spec), nil,
336
+ language)
335
337
  test_native_target.product_reference.name = name
336
338
 
337
339
  target.user_build_configurations.each do |bc_name, type|
@@ -372,7 +374,9 @@ module Pod
372
374
  # Generate vanilla Info.plist for test target similar to the one Xcode generates for new test target.
373
375
  # This creates valid test bundle accessible at the runtime, allowing tests to load bundle resources
374
376
  # defined in podspec.
375
- create_info_plist_file(target.info_plist_path_for_spec(test_spec), test_native_target, '1.0', target.platform, :bndl)
377
+ additional_entries = spec_consumer.info_plist
378
+ path = target.info_plist_path_for_spec(test_spec)
379
+ create_info_plist_file(path, test_native_target, '1.0', target.platform, :bndl, :additional_entries => additional_entries)
376
380
 
377
381
  test_native_target
378
382
  end
@@ -381,32 +385,17 @@ module Pod
381
385
  # Adds the test app host targets for the library to the Pods project with the
382
386
  # appropriate build configurations.
383
387
  #
384
- # @param [Array<PBXNativeTarget>] test_native_targets
385
- # the test native targets that have been created to use as a lookup when linking the app host to.
386
- #
387
388
  # @return [Array<PBXNativeTarget>] the app host targets created.
388
389
  #
389
- def add_test_app_host_targets(test_native_targets)
390
- target.test_spec_consumers.select(&:requires_app_host?).group_by(&:test_type).map do |test_type, test_spec_consumers|
391
- platform = target.platform
392
- name = "AppHost-#{target.label}-#{test_type.capitalize}-Tests"
393
- app_host_target = AppHostInstaller.new(sandbox, project, platform, name, target.pod_name, name).install!
394
- # Wire test native targets to the generated app host.
395
- test_spec_consumers.each do |test_spec_consumer|
396
- test_native_target = test_native_target_from_spec(test_spec_consumer.spec, test_native_targets)
397
- test_native_target.build_configurations.each do |configuration|
398
- test_host = "$(BUILT_PRODUCTS_DIR)/#{app_host_target.name}.app/"
399
- test_host << 'Contents/MacOS/' if platform == :osx
400
- test_host << app_host_target.name.to_s
401
- configuration.build_settings['TEST_HOST'] = test_host
402
- end
403
- target_attributes = project.root_object.attributes['TargetAttributes'] || {}
404
- target_attributes[test_native_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s }
405
- project.root_object.attributes['TargetAttributes'] = target_attributes
406
- test_native_target.add_dependency(app_host_target)
407
- end
408
- app_host_target
390
+ def add_test_app_host_targets
391
+ target.test_spec_consumers.reject(&:requires_app_host?).select(&:app_host_name).each do |test_spec_consumer|
392
+ raise Informative, "`#{target.label}-#{test_spec_consumer.test_type}-Tests` manually specifies an app host but has not specified `requires_app_host = true`."
409
393
  end
394
+
395
+ target.test_spec_consumers.select(&:requires_app_host?).reject(&:app_host_name).group_by { |consumer| target.app_host_target_label(consumer.spec) }.
396
+ map do |(_, target_name), _|
397
+ AppHostInstaller.new(sandbox, project, target.platform, target_name, target.pod_name, target_name).install!
398
+ end
410
399
  end
411
400
 
412
401
  # Adds the app targets for the library to the Pods project with the
@@ -416,12 +405,15 @@ module Pod
416
405
  #
417
406
  def add_app_targets
418
407
  target.app_specs.map do |app_spec|
408
+ spec_consumer = app_spec.consumer(target.platform)
419
409
  spec_name = app_spec.parent.name
420
410
  subspec_name = target.subspec_label(app_spec)
421
411
  app_target_label = target.app_target_label(app_spec)
422
- platform = target.platform
412
+ platform = Platform.new(target.platform.symbolic_name, target.deployment_target_for_non_library_spec(app_spec))
413
+ info_plist_entries = spec_consumer.info_plist
423
414
  app_native_target = AppHostInstaller.new(sandbox, project, platform, subspec_name, spec_name,
424
- app_target_label, :add_main => false).install!
415
+ app_target_label, :add_main => false,
416
+ :info_plist_entries => info_plist_entries).install!
425
417
 
426
418
  app_native_target.product_reference.name = app_target_label
427
419
  target.user_build_configurations.each do |bc_name, type|
@@ -507,8 +499,11 @@ module Pod
507
499
  target.user_build_configurations.each do |bc_name, type|
508
500
  resource_bundle_target.add_build_configuration(bc_name, type)
509
501
  end
510
- resource_bundle_target.deployment_target = deployment_target
511
-
502
+ resource_bundle_target.deployment_target = if file_accessor.spec.non_library_specification?
503
+ target.deployment_target_for_non_library_spec(file_accessor.spec)
504
+ else
505
+ deployment_target
506
+ end
512
507
  # Create Info.plist file for bundle
513
508
  path = target.info_plist_path
514
509
  path.dirname.mkdir unless path.dirname.exist?
@@ -524,6 +519,10 @@ module Pod
524
519
  configuration.build_settings['CONFIGURATION_BUILD_DIR'] = target.configuration_build_dir('$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)')
525
520
  end
526
521
 
522
+ # Set the 'IBSC_MODULE' build settings for resource bundles so that Storyboards and Xibs can load
523
+ # classes from the parent module.
524
+ configuration.build_settings['IBSC_MODULE'] = target.product_module_name
525
+
527
526
  # Set the `SWIFT_VERSION` build setting for resource bundles that could have resources that get
528
527
  # compiled such as an `xcdatamodeld` file which has 'Swift' as its code generation language.
529
528
  if contains_compile_phase_refs && file_accessors.any? { |fa| target.uses_swift_for_spec?(fa.spec) }
@@ -608,16 +607,22 @@ module Pod
608
607
  def create_test_target_copy_resources_script(test_spec)
609
608
  path = target.copy_resources_script_path_for_spec(test_spec)
610
609
  pod_targets = target.dependent_targets_for_test_spec(test_spec)
610
+ host_target_spec_names = target.app_host_dependent_targets_for_spec(test_spec).flat_map do |pt|
611
+ pt.specs.map(&:name)
612
+ end.uniq
611
613
  resource_paths_by_config = target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
612
614
  resources_by_config[config] = pod_targets.flat_map do |pod_target|
613
615
  spec_paths_to_include = pod_target.library_specs.map(&:name)
616
+ spec_paths_to_include -= host_target_spec_names
614
617
  spec_paths_to_include << test_spec.name if pod_target == target
615
618
  pod_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
616
619
  end
617
620
  end
618
- generator = Generator::CopyResourcesScript.new(resource_paths_by_config, target.platform)
619
- update_changed_file(generator, path)
620
- add_file_to_support_group(path)
621
+ unless resource_paths_by_config.each_value.all?(&:empty?)
622
+ generator = Generator::CopyResourcesScript.new(resource_paths_by_config, target.platform)
623
+ update_changed_file(generator, path)
624
+ add_file_to_support_group(path)
625
+ end
621
626
  end
622
627
 
623
628
  # Creates a script that embeds the frameworks to the bundle of the test target.
@@ -630,16 +635,22 @@ module Pod
630
635
  def create_test_target_embed_frameworks_script(test_spec)
631
636
  path = target.embed_frameworks_script_path_for_spec(test_spec)
632
637
  pod_targets = target.dependent_targets_for_test_spec(test_spec)
638
+ host_target_spec_names = target.app_host_dependent_targets_for_spec(test_spec).flat_map do |pt|
639
+ pt.specs.map(&:name)
640
+ end.uniq
633
641
  framework_paths_by_config = target.user_build_configurations.keys.each_with_object({}) do |config, paths_by_config|
634
642
  paths_by_config[config] = pod_targets.flat_map do |pod_target|
635
643
  spec_paths_to_include = pod_target.library_specs.map(&:name)
644
+ spec_paths_to_include -= host_target_spec_names
636
645
  spec_paths_to_include << test_spec.name if pod_target == target
637
646
  pod_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
638
647
  end
639
648
  end
640
- generator = Generator::EmbedFrameworksScript.new(framework_paths_by_config)
641
- update_changed_file(generator, path)
642
- add_file_to_support_group(path)
649
+ unless framework_paths_by_config.each_value.all?(&:empty?)
650
+ generator = Generator::EmbedFrameworksScript.new(framework_paths_by_config)
651
+ update_changed_file(generator, path)
652
+ add_file_to_support_group(path)
653
+ end
643
654
  end
644
655
 
645
656
  # Generates the contents of the xcconfig file used for each app target type and saves it to disk.
@@ -684,9 +695,11 @@ module Pod
684
695
  pod_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
685
696
  end
686
697
  end
687
- generator = Generator::CopyResourcesScript.new(resource_paths_by_config, target.platform)
688
- update_changed_file(generator, path)
689
- add_file_to_support_group(path)
698
+ unless resource_paths_by_config.each_value.all?(&:empty?)
699
+ generator = Generator::CopyResourcesScript.new(resource_paths_by_config, target.platform)
700
+ update_changed_file(generator, path)
701
+ add_file_to_support_group(path)
702
+ end
690
703
  end
691
704
 
692
705
  # Creates a script that embeds the frameworks to the bundle of the app target.
@@ -706,9 +719,11 @@ module Pod
706
719
  pod_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
707
720
  end
708
721
  end
709
- generator = Generator::EmbedFrameworksScript.new(framework_paths_by_config)
710
- update_changed_file(generator, path)
711
- add_file_to_support_group(path)
722
+ unless framework_paths_by_config.each_value.all?(&:empty?)
723
+ generator = Generator::EmbedFrameworksScript.new(framework_paths_by_config)
724
+ update_changed_file(generator, path)
725
+ add_file_to_support_group(path)
726
+ end
712
727
  end
713
728
 
714
729
  # Manually add `libswiftSwiftOnoneSupport.dylib` as it seems there is an issue with tests that do not include it for Debug configurations.
@@ -736,13 +751,21 @@ module Pod
736
751
  # @return [void]
737
752
  #
738
753
  def create_build_phase_to_symlink_header_folders(native_target)
739
- return unless target.platform.name == :osx && header_mappings_dir
754
+ return unless target.platform.name == :osx && any_header_mapping_dirs?
740
755
 
741
756
  build_phase = native_target.new_shell_script_build_phase('Create Symlinks to Header Folders')
742
757
  build_phase.shell_script = <<-eos.strip_heredoc
743
- base="$CONFIGURATION_BUILD_DIR/$WRAPPER_NAME"
744
- ln -fs "$base/${PUBLIC_HEADERS_FOLDER_PATH\#$WRAPPER_NAME/}" "$base/${PUBLIC_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}"
745
- ln -fs "$base/${PRIVATE_HEADERS_FOLDER_PATH\#\$WRAPPER_NAME/}" "$base/${PRIVATE_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}"
758
+ cd "$CONFIGURATION_BUILD_DIR/$WRAPPER_NAME" || exit 1
759
+
760
+ public_path="${PUBLIC_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}"
761
+ if [ ! -f "$public_path" ]; then
762
+ ln -fs "${PUBLIC_HEADERS_FOLDER_PATH\#$WRAPPER_NAME/}" "$public_path"
763
+ fi
764
+
765
+ private_path="${PRIVATE_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}"
766
+ if [ ! -f "$private_path" ]; then
767
+ ln -fs "${PRIVATE_HEADERS_FOLDER_PATH\#\$WRAPPER_NAME/}" "$private_path"
768
+ fi
746
769
  eos
747
770
  end
748
771
 
@@ -868,20 +891,25 @@ module Pod
868
891
  def project_file_references_array(files, file_type)
869
892
  files.map do |sf|
870
893
  project.reference_for_path(sf).tap do |ref|
871
- raise Informative, "Unable to find #{file_type} ref for #{sf} for target #{target.name}." unless ref
894
+ raise Informative, "Unable to find #{file_type} ref for `#{sf.basename}` for target `#{target.name}`." unless ref
872
895
  end
873
896
  end
874
897
  end
875
898
 
876
- def header_mappings_dir
877
- return @header_mappings_dir if defined?(@header_mappings_dir)
878
- file_accessor = target.file_accessors.first
879
- @header_mappings_dir = if dir = file_accessor.spec_consumer.header_mappings_dir
880
- file_accessor.path_list.root + dir
881
- end
899
+ def any_header_mapping_dirs?
900
+ return @any_header_mapping_dirs if defined?(@any_header_mapping_dirs)
901
+ @any_header_mapping_dirs = target.file_accessors.any? { |fa| fa.spec_consumer.header_mappings_dir }
902
+ end
903
+
904
+ def header_mappings_dir(file_accessor)
905
+ @header_mappings_dirs ||= {}
906
+ return @header_mappings_dirs[file_accessor] if @header_mappings_dirs.key?(file_accessor)
907
+ @header_mappings_dirs[file_accessor] = if dir = file_accessor.spec_consumer.header_mappings_dir
908
+ file_accessor.path_list.root + dir
909
+ end
882
910
  end
883
911
 
884
- def add_header(build_file, public_headers, private_headers, native_target)
912
+ def add_header(file_accessor, build_file, public_headers, private_headers, native_target)
885
913
  file_ref = build_file.file_ref
886
914
  acl = if !target.build_as_framework? # Headers are already rooted at ${PODS_ROOT}/Headers/P*/[pod]/...
887
915
  'Project'
@@ -893,8 +921,12 @@ module Pod
893
921
  'Project'
894
922
  end
895
923
 
896
- if target.build_as_framework? && header_mappings_dir && acl != 'Project'
897
- relative_path = file_ref.real_path.relative_path_from(header_mappings_dir)
924
+ if target.build_as_framework? && any_header_mapping_dirs? && acl != 'Project'
925
+ relative_path = if mapping_dir = header_mappings_dir(file_accessor)
926
+ file_ref.real_path.relative_path_from(mapping_dir)
927
+ else
928
+ file_ref.real_path.relative_path_from(file_accessor.path_list.root)
929
+ end
898
930
  sub_dir = relative_path.dirname
899
931
  copy_phase_name = "Copy #{sub_dir} #{acl} Headers"
900
932
  copy_phase = native_target.copy_files_build_phases.find { |bp| bp.name == copy_phase_name } ||