cocoapods 1.6.2 → 1.7.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -7
  3. data/README.md +9 -9
  4. data/lib/cocoapods.rb +2 -0
  5. data/lib/cocoapods/command.rb +1 -1
  6. data/lib/cocoapods/command/init.rb +2 -12
  7. data/lib/cocoapods/command/install.rb +3 -0
  8. data/lib/cocoapods/command/lib/create.rb +1 -1
  9. data/lib/cocoapods/command/lib/lint.rb +5 -1
  10. data/lib/cocoapods/command/list.rb +3 -5
  11. data/lib/cocoapods/command/repo.rb +1 -0
  12. data/lib/cocoapods/command/repo/add.rb +4 -5
  13. data/lib/cocoapods/command/repo/add_cdn.rb +58 -0
  14. data/lib/cocoapods/command/repo/list.rb +5 -6
  15. data/lib/cocoapods/command/repo/push.rb +6 -5
  16. data/lib/cocoapods/command/spec/create.rb +12 -12
  17. data/lib/cocoapods/command/spec/lint.rb +1 -1
  18. data/lib/cocoapods/command/update.rb +3 -0
  19. data/lib/cocoapods/config.rb +1 -0
  20. data/lib/cocoapods/executable.rb +32 -7
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/app_target_helper.rb +1 -1
  23. data/lib/cocoapods/generator/embed_frameworks_script.rb +13 -0
  24. data/lib/cocoapods/generator/file_list.rb +39 -0
  25. data/lib/cocoapods/generator/module_map.rb +1 -1
  26. data/lib/cocoapods/installer.rb +188 -46
  27. data/lib/cocoapods/installer/analyzer.rb +64 -39
  28. data/lib/cocoapods/installer/analyzer/pod_variant.rb +14 -9
  29. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +11 -2
  30. data/lib/cocoapods/installer/installation_options.rb +70 -44
  31. data/lib/cocoapods/installer/pod_source_installer.rb +9 -4
  32. data/lib/cocoapods/installer/podfile_validator.rb +9 -0
  33. data/lib/cocoapods/installer/post_install_hooks_context.rb +5 -2
  34. data/lib/cocoapods/installer/project_cache/project_cache.rb +11 -0
  35. data/lib/cocoapods/installer/project_cache/project_cache_analysis_result.rb +53 -0
  36. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +156 -0
  37. data/lib/cocoapods/installer/project_cache/project_cache_version.rb +43 -0
  38. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +77 -0
  39. data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +63 -0
  40. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +134 -0
  41. data/lib/cocoapods/installer/project_cache/target_metadata.rb +70 -0
  42. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +89 -0
  43. data/lib/cocoapods/installer/sandbox_header_paths_installer.rb +45 -0
  44. data/lib/cocoapods/installer/target_uuid_generator.rb +32 -0
  45. data/lib/cocoapods/installer/user_project_integrator.rb +8 -6
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +128 -63
  47. data/lib/cocoapods/installer/xcode.rb +3 -0
  48. data/lib/cocoapods/installer/xcode/multi_pods_project_generator.rb +72 -0
  49. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +102 -218
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +75 -0
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +1 -1
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +29 -17
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +31 -65
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +155 -0
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +265 -110
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +70 -43
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/pods_project_writer.rb +75 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +119 -0
  59. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +44 -7
  60. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +5 -7
  61. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +32 -0
  62. data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +35 -0
  63. data/lib/cocoapods/installer/xcode/single_pods_project_generator.rb +38 -0
  64. data/lib/cocoapods/installer/xcode/target_validator.rb +32 -25
  65. data/lib/cocoapods/native_target_extension.rb +54 -0
  66. data/lib/cocoapods/open-uri.rb +1 -1
  67. data/lib/cocoapods/podfile.rb +13 -0
  68. data/lib/cocoapods/project.rb +88 -10
  69. data/lib/cocoapods/resolver.rb +11 -8
  70. data/lib/cocoapods/resolver/resolver_specification.rb +7 -7
  71. data/lib/cocoapods/sandbox.rb +38 -9
  72. data/lib/cocoapods/sandbox/file_accessor.rb +21 -0
  73. data/lib/cocoapods/sandbox/headers_store.rb +18 -3
  74. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -14
  75. data/lib/cocoapods/sources_manager.rb +11 -3
  76. data/lib/cocoapods/target.rb +67 -7
  77. data/lib/cocoapods/target/aggregate_target.rb +70 -8
  78. data/lib/cocoapods/target/build_settings.rb +124 -65
  79. data/lib/cocoapods/target/build_type.rb +139 -0
  80. data/lib/cocoapods/target/framework_paths.rb +12 -7
  81. data/lib/cocoapods/target/pod_target.rb +322 -65
  82. data/lib/cocoapods/user_interface.rb +2 -2
  83. data/lib/cocoapods/user_interface/error_report.rb +3 -0
  84. data/lib/cocoapods/user_interface/inspector_reporter.rb +1 -1
  85. data/lib/cocoapods/validator.rb +74 -39
  86. data/lib/cocoapods/version_metadata.rb +7 -0
  87. metadata +30 -6
@@ -10,18 +10,19 @@ module Pod
10
10
  #
11
11
  attr_reader :target_installation_result
12
12
 
13
- # @return [InstallationOptions] the installation options from the Podfile.
13
+ # @return [Boolean] whether to use input/output paths for build phase scripts
14
14
  #
15
- attr_reader :installation_options
15
+ attr_reader :use_input_output_paths
16
+ alias use_input_output_paths? use_input_output_paths
16
17
 
17
18
  # Initialize a new instance
18
19
  #
19
20
  # @param [TargetInstallationResult] target_installation_result @see #target_installation_result
20
- # @param [InstallationOptions] installation_options @see #installation_options
21
+ # @param [Boolean] use_input_output_paths @see #use_input_output_paths
21
22
  #
22
- def initialize(target_installation_result, installation_options)
23
+ def initialize(target_installation_result, use_input_output_paths: true)
23
24
  @target_installation_result = target_installation_result
24
- @installation_options = installation_options
25
+ @use_input_output_paths = use_input_output_paths
25
26
  end
26
27
 
27
28
  # Integrates the pod target.
@@ -30,15 +31,12 @@ module Pod
30
31
  #
31
32
  def integrate!
32
33
  UI.section(integration_message) do
33
- target_installation_result.test_specs_by_native_target.each do |test_native_target, test_specs|
34
- test_specs.each do |test_spec|
35
- add_embed_frameworks_script_phase(test_native_target, test_spec)
36
- add_copy_resources_script_phase(test_native_target, test_spec)
37
- end
38
- UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(test_specs), test_native_target)
34
+ target_installation_result.non_library_specs_by_native_target.each do |native_target, spec|
35
+ add_embed_frameworks_script_phase(native_target, spec)
36
+ add_copy_resources_script_phase(native_target, spec)
37
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(spec), native_target)
39
38
  end
40
- specs = target.non_test_specs
41
- UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(specs), target_installation_result.native_target)
39
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(target.library_specs), target_installation_result.native_target)
42
40
  end
43
41
  end
44
42
 
@@ -57,48 +55,77 @@ module Pod
57
55
  #
58
56
  # @return [void]
59
57
  #
60
- def add_copy_resources_script_phase(native_target, test_spec)
61
- script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
62
- input_paths = []
63
- output_paths = []
64
- unless installation_options.disable_input_output_paths?
65
- resource_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
66
- spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
67
- spec_paths_to_include << test_spec.name if dependent_target == target
58
+ def add_copy_resources_script_phase(native_target, spec)
59
+ script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_spec(spec).relative_path_from(target.sandbox.root)}"
60
+
61
+ input_paths_by_config = {}
62
+ output_paths_by_config = {}
63
+ if use_input_output_paths
64
+ dependent_targets = if spec.test_specification?
65
+ target.dependent_targets_for_test_spec(spec)
66
+ else
67
+ target.dependent_targets_for_app_spec(spec)
68
+ end
69
+ resource_paths = dependent_targets.flat_map do |dependent_target|
70
+ spec_paths_to_include = dependent_target.library_specs.map(&:name)
71
+ spec_paths_to_include << spec.name if dependent_target == target
68
72
  dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
69
- end
73
+ end.uniq
74
+
70
75
  unless resource_paths.empty?
71
- resource_paths_flattened = resource_paths.flatten.uniq
72
- input_paths = [script_path, *resource_paths_flattened]
73
- output_paths = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths_flattened)
76
+ input_file_list_path = target.copy_resources_script_input_files_path_for_spec(spec)
77
+ input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
78
+ input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
79
+ input_paths_by_config[input_paths_key] = [script_path] + resource_paths
80
+
81
+ output_file_list_path = target.copy_resources_script_output_files_path_for_spec(spec)
82
+ output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
83
+ output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
84
+ output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths)
74
85
  end
75
86
  end
76
- UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
77
- UserProjectIntegrator::TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
87
+
88
+ UserProjectIntegrator::TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
78
89
  end
79
90
 
80
91
  # Find or create a 'Embed Pods Frameworks' Copy Files Build Phase
81
92
  #
82
93
  # @return [void]
83
94
  #
84
- def add_embed_frameworks_script_phase(native_target, test_spec)
85
- script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
86
- input_paths = []
87
- output_paths = []
88
- unless installation_options.disable_input_output_paths?
89
- framework_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
90
- spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
91
- spec_paths_to_include << test_spec.name if dependent_target == target
92
- dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
93
- end
95
+ def add_embed_frameworks_script_phase(native_target, spec)
96
+ script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_spec(spec).relative_path_from(target.sandbox.root)}"
97
+
98
+ input_paths_by_config = {}
99
+ output_paths_by_config = {}
100
+ if use_input_output_paths?
101
+ dependent_targets = if spec.test_specification?
102
+ target.dependent_targets_for_test_spec(spec)
103
+ else
104
+ target.dependent_targets_for_app_spec(spec)
105
+ end
106
+ framework_paths = dependent_targets.flat_map do |dependent_target|
107
+ spec_paths_to_include = dependent_target.library_specs.map(&:name)
108
+ spec_paths_to_include << spec.name if dependent_target == target
109
+ dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact
110
+ end.uniq
111
+
94
112
  unless framework_paths.empty?
95
- input_paths = [script_path, *framework_paths.flat_map { |fw| [fw.source_path, fw.dsym_path] }.compact]
96
- output_paths = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
113
+ input_file_list_path = target.embed_frameworks_script_input_files_path_for_spec(spec)
114
+ input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
115
+ input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
116
+ input_paths = input_paths_by_config[input_paths_key] = [script_path]
117
+ framework_paths.each do |path|
118
+ input_paths.concat(path.all_paths)
119
+ end
120
+
121
+ output_file_list_path = target.embed_frameworks_script_output_files_path_for_spec(spec)
122
+ output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
123
+ output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
124
+ output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
97
125
  end
98
126
  end
99
127
 
100
- UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
101
- UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
128
+ UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
102
129
  end
103
130
 
104
131
  # @return [String] the message that should be displayed for the target
@@ -114,13 +141,13 @@ module Pod
114
141
  target_installation_result.target
115
142
  end
116
143
 
117
- # @param [Array<Specification] specs
144
+ # @param [Specification, Array<Specification>] specs
118
145
  # the specs to return script phrases from.
119
146
  #
120
147
  # @return [Array<Hash<Symbol=>String>] an array of all combined script phases from the specs.
121
148
  #
122
149
  def script_phases_for_specs(specs)
123
- specs.flat_map { |spec| spec.consumer(target.platform).script_phases }
150
+ Array(specs).flat_map { |spec| spec.consumer(target.platform).script_phases }
124
151
  end
125
152
  end
126
153
  end
@@ -0,0 +1,75 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectWriter
5
+ # @return [Sandbox] sandbox
6
+ # The Pods sandbox instance.
7
+ #
8
+ attr_reader :sandbox
9
+
10
+ # @return [Array<Project>] projects
11
+ # The list project to write.
12
+ #
13
+ attr_reader :projects
14
+
15
+ # @return [Hash<String, TargetInstallationResult>] pod_target_installation_results
16
+ # Hash of pod target name to installation results.
17
+ #
18
+ attr_reader :pod_target_installation_results
19
+
20
+ # @return [InstallationOptions] installation_options
21
+ #
22
+ attr_reader :installation_options
23
+
24
+ # Initialize a new instance
25
+ #
26
+ # @param [Sandbox] sandbox @see #sandbox
27
+ # @param [Project] projects @see #project
28
+ # @param [Hash<String, TargetInstallationResult>] pod_target_installation_results @see #pod_target_installation_results
29
+ # @param [InstallationOptions] installation_options @see #installation_options
30
+ #
31
+ def initialize(sandbox, projects, pod_target_installation_results, installation_options)
32
+ @sandbox = sandbox
33
+ @projects = projects
34
+ @pod_target_installation_results = pod_target_installation_results
35
+ @installation_options = installation_options
36
+ end
37
+
38
+ def write!
39
+ cleanup_projects(projects)
40
+
41
+ projects.each do |project|
42
+ UI.message "- Writing Xcode project file to #{UI.path project.path}" do
43
+ library_product_types = [:framework, :dynamic_library, :static_library]
44
+ results_by_native_target = Hash[pod_target_installation_results.map do |_, result|
45
+ [result.native_target, result]
46
+ end]
47
+ project.recreate_user_schemes(false) do |scheme, target|
48
+ next unless target.respond_to?(:symbol_type)
49
+ next unless library_product_types.include? target.symbol_type
50
+ installation_result = results_by_native_target[target]
51
+ next unless installation_result
52
+ installation_result.test_native_targets.each do |test_native_target|
53
+ scheme.add_test_target(test_native_target)
54
+ end
55
+ end
56
+ project.save
57
+ end
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ # Cleans up projects before writing.
64
+ #
65
+ def cleanup_projects(projects)
66
+ projects.each do |project|
67
+ [project.pods, project.support_files_group,
68
+ project.development_pods, project.dependencies_group].each { |group| group.remove_from_project if group.empty? }
69
+ project.sort(:groups_position => :below)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,119 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ # Responsible for creating and preparing a Pod::Project instance
5
+ #
6
+ class ProjectGenerator
7
+ # @return [Sandbox] sandbox
8
+ # The Pods sandbox instance.
9
+ #
10
+ attr_reader :sandbox
11
+
12
+ # @return [String] path
13
+ # Path of the project.
14
+ #
15
+ attr_reader :path
16
+
17
+ # @return [Array<PodTarget>] pod_targets
18
+ # Array of pod targets this project includes.
19
+ #
20
+ attr_reader :pod_targets
21
+
22
+ # @return [Hash{String=>Symbol}] A hash representing all the user build
23
+ # configurations across all integration targets. Each key
24
+ # corresponds to the name of a configuration and its value to
25
+ # its type (`:debug` or `:release`).
26
+ #
27
+ attr_reader :build_configurations
28
+
29
+ # @return [Array<Platform>] The list of all platforms this project supports.
30
+ #
31
+ attr_reader :platforms
32
+
33
+ # @return [String] Object version for the Xcode project.
34
+ #
35
+ attr_reader :object_version
36
+
37
+ # @return [String] Path to the Podfile included in the project.
38
+ #
39
+ attr_reader :podfile_path
40
+
41
+ # @return [Bool] Bool indicating if this project is a pod target subproject.
42
+ # Used by `generate_multiple_pod_projects` installation option.
43
+ #
44
+ attr_reader :pod_target_subproject
45
+
46
+ # Initialize a new instance
47
+ #
48
+ # @param [Sandbox] sandbox @see #sandbox
49
+ # @param [String] path @see #path
50
+ # @param [Array<PodTarget>] pod_targets @see #pod_targets
51
+ # @param [Hash{String=>Symbol}] build_configurations @see #build_configurations
52
+ # @param [Array<Platform>] platforms @see #platforms
53
+ # @param [String] object_version @see #object_version
54
+ # @param [String] podfile_path @see #podfile_path
55
+ #
56
+ def initialize(sandbox, path, pod_targets, build_configurations, platforms,
57
+ object_version, podfile_path = nil, pod_target_subproject: false)
58
+ @sandbox = sandbox
59
+ @path = path
60
+ @pod_targets = pod_targets
61
+ @build_configurations = build_configurations
62
+ @platforms = platforms
63
+ @object_version = object_version
64
+ @podfile_path = podfile_path
65
+ @pod_target_subproject = pod_target_subproject
66
+ end
67
+
68
+ public
69
+
70
+ # @return [Project] Generated and prepared project.
71
+ #
72
+ def generate!
73
+ project = create_project(path, object_version, pod_target_subproject)
74
+ prepare(sandbox, project, pod_targets, build_configurations, platforms, podfile_path)
75
+ project
76
+ end
77
+
78
+ private
79
+
80
+ def create_project(path, object_version, pod_target_subproject)
81
+ object_version ||= Xcodeproj::Constants::DEFAULT_OBJECT_VERSION
82
+ Pod::Project.new(path, false, object_version, :pod_target_subproject => pod_target_subproject)
83
+ end
84
+
85
+ def prepare(sandbox, project, pod_targets, build_configurations, platforms, podfile_path)
86
+ UI.message "- Creating #{project.project_name} project" do
87
+ build_configurations.each do |name, type|
88
+ project.add_build_configuration(name, type)
89
+ end
90
+ # Reset symroot just in case the user has added a new build configuration other than 'Debug' or 'Release'.
91
+ project.symroot = Pod::Project::LEGACY_BUILD_ROOT
92
+ pod_names = pod_targets.map(&:pod_name).uniq
93
+ pod_names.each do |pod_name|
94
+ local = sandbox.local?(pod_name)
95
+ path = sandbox.pod_dir(pod_name)
96
+ was_absolute = sandbox.local_path_was_absolute?(pod_name)
97
+ project.add_pod_group(pod_name, path, local, was_absolute)
98
+ end
99
+ if podfile_path
100
+ project.add_podfile(podfile_path)
101
+ end
102
+ osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min
103
+ ios_deployment_target = platforms.select { |p| p.name == :ios }.map(&:deployment_target).min
104
+ watchos_deployment_target = platforms.select { |p| p.name == :watchos }.map(&:deployment_target).min
105
+ tvos_deployment_target = platforms.select { |p| p.name == :tvos }.map(&:deployment_target).min
106
+ project.build_configurations.each do |build_configuration|
107
+ build_configuration.build_settings['MACOSX_DEPLOYMENT_TARGET'] = osx_deployment_target.to_s if osx_deployment_target
108
+ build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target.to_s if ios_deployment_target
109
+ build_configuration.build_settings['WATCHOS_DEPLOYMENT_TARGET'] = watchos_deployment_target.to_s if watchos_deployment_target
110
+ build_configuration.build_settings['TVOS_DEPLOYMENT_TARGET'] = tvos_deployment_target.to_s if tvos_deployment_target
111
+ build_configuration.build_settings['STRIP_INSTALLED_PRODUCT'] = 'NO'
112
+ build_configuration.build_settings['CLANG_ENABLE_OBJC_ARC'] = 'YES'
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -38,6 +38,18 @@ module Pod
38
38
  #
39
39
  attr_reader :test_app_host_targets
40
40
 
41
+ # @return [Array<PBXNativeTarget>] app_native_targets
42
+ # The app native targets that were produced for this target. Can be empty if there were no app
43
+ # native targets created (e.g. no app specs present).
44
+ #
45
+ attr_reader :app_native_targets
46
+
47
+ # @return [Hash{String=>Array<PBXNativeTarget>}] app_resource_bundle_targets
48
+ # The app resource bundle targets that were produced for this target keyed by app spec name.
49
+ # Can be empty if the target had no resource bundles for any apps.
50
+ #
51
+ attr_reader :app_resource_bundle_targets
52
+
41
53
  # Initialize a new instance
42
54
  #
43
55
  # @param [Target] target @see #target
@@ -46,15 +58,20 @@ module Pod
46
58
  # @param [Array<PBXNativeTarget>] test_native_targets @see #test_native_targets
47
59
  # @param [Hash{String=>Array<PBXNativeTarget>}] test_resource_bundle_targets @see #test_resource_bundle_targets
48
60
  # @param [Array<PBXNativeTarget>] test_app_host_targets @see #test_app_host_targets
61
+ # @param [Array<PBXNativeTarget>] app_native_targets @see #app_native_targets
62
+ # @param [Hash{String=>Array<PBXNativeTarget>}] app_resource_bundle_targets @see #app_resource_bundle_targets
49
63
  #
50
64
  def initialize(target, native_target, resource_bundle_targets = [], test_native_targets = [],
51
- test_resource_bundle_targets = {}, test_app_host_targets = [])
65
+ test_resource_bundle_targets = {}, test_app_host_targets = [],
66
+ app_native_targets = [], app_resource_bundle_targets = {})
52
67
  @target = target
53
68
  @native_target = native_target
54
69
  @resource_bundle_targets = resource_bundle_targets
55
70
  @test_native_targets = test_native_targets
56
71
  @test_resource_bundle_targets = test_resource_bundle_targets
57
72
  @test_app_host_targets = test_app_host_targets
73
+ @app_native_targets = app_native_targets
74
+ @app_resource_bundle_targets = app_resource_bundle_targets
58
75
  end
59
76
 
60
77
  # Returns the corresponding native target to use based on the provided specification.
@@ -65,20 +82,34 @@ module Pod
65
82
  # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
66
83
  #
67
84
  def native_target_for_spec(spec)
68
- return native_target unless spec.test_specification?
69
- test_native_target_from_spec(spec)
85
+ return native_target if spec.library_specification?
86
+ return test_native_target_from_spec(spec) if spec.test_specification?
87
+ return app_native_target_from_spec(spec) if spec.app_specification?
70
88
  end
71
89
 
72
90
  # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the test native targets and the value
73
- # an array of all the test specs associated with this native target.
91
+ # is the test spec associated with this native target.
74
92
  #
75
93
  def test_specs_by_native_target
76
- test_specs_by_native_target = target.test_specs.group_by do |test_spec|
77
- test_native_target_from_spec(test_spec)
78
- end
94
+ test_specs_by_native_target = Hash[target.test_specs.map { |spec| [test_native_target_from_spec(spec), spec] }]
79
95
  test_specs_by_native_target.delete_if { |k, _| k.nil? }
80
96
  end
81
97
 
98
+ # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the app native targets and the value
99
+ # is the app spec associated with this native target.
100
+ #
101
+ def app_specs_by_native_target
102
+ app_specs_by_native_target = Hash[target.app_specs.map { |spec| [app_native_target_from_spec(spec), spec] }]
103
+ app_specs_by_native_target.delete_if { |k, _| k.nil? }
104
+ end
105
+
106
+ # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the native targets and the value
107
+ # is the non-library spec associated with this native target.
108
+ #
109
+ def non_library_specs_by_native_target
110
+ test_specs_by_native_target.merge(app_specs_by_native_target)
111
+ end
112
+
82
113
  private
83
114
 
84
115
  def test_native_target_from_spec(spec)
@@ -86,6 +117,12 @@ module Pod
86
117
  test_native_target.name == target.test_target_label(spec)
87
118
  end
88
119
  end
120
+
121
+ def app_native_target_from_spec(spec)
122
+ app_native_targets.find do |app_native_target|
123
+ app_native_target.name == target.app_target_label(spec)
124
+ end
125
+ end
89
126
  end
90
127
  end
91
128
  end