xcocoapods 1.5.3
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +6303 -0
- data/LICENSE +28 -0
- data/README.md +80 -0
- data/bin/pod +56 -0
- data/bin/sandbox-pod +168 -0
- data/lib/cocoapods.rb +73 -0
- data/lib/cocoapods/command.rb +175 -0
- data/lib/cocoapods/command/cache.rb +28 -0
- data/lib/cocoapods/command/cache/clean.rb +90 -0
- data/lib/cocoapods/command/cache/list.rb +69 -0
- data/lib/cocoapods/command/env.rb +66 -0
- data/lib/cocoapods/command/init.rb +128 -0
- data/lib/cocoapods/command/install.rb +45 -0
- data/lib/cocoapods/command/ipc.rb +19 -0
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -0
- data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
- data/lib/cocoapods/command/ipc/repl.rb +51 -0
- data/lib/cocoapods/command/ipc/spec.rb +29 -0
- data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
- data/lib/cocoapods/command/lib.rb +11 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +121 -0
- data/lib/cocoapods/command/list.rb +39 -0
- data/lib/cocoapods/command/options/project_directory.rb +36 -0
- data/lib/cocoapods/command/options/repo_update.rb +34 -0
- data/lib/cocoapods/command/outdated.rb +140 -0
- data/lib/cocoapods/command/repo.rb +29 -0
- data/lib/cocoapods/command/repo/add.rb +103 -0
- data/lib/cocoapods/command/repo/lint.rb +82 -0
- data/lib/cocoapods/command/repo/list.rb +93 -0
- data/lib/cocoapods/command/repo/push.rb +281 -0
- data/lib/cocoapods/command/repo/remove.rb +36 -0
- data/lib/cocoapods/command/repo/update.rb +28 -0
- data/lib/cocoapods/command/setup.rb +103 -0
- data/lib/cocoapods/command/spec.rb +112 -0
- data/lib/cocoapods/command/spec/cat.rb +51 -0
- data/lib/cocoapods/command/spec/create.rb +283 -0
- data/lib/cocoapods/command/spec/edit.rb +87 -0
- data/lib/cocoapods/command/spec/env_spec.rb +53 -0
- data/lib/cocoapods/command/spec/lint.rb +137 -0
- data/lib/cocoapods/command/spec/which.rb +43 -0
- data/lib/cocoapods/command/update.rb +101 -0
- data/lib/cocoapods/config.rb +347 -0
- data/lib/cocoapods/core_overrides.rb +1 -0
- data/lib/cocoapods/downloader.rb +190 -0
- data/lib/cocoapods/downloader/cache.rb +233 -0
- data/lib/cocoapods/downloader/request.rb +86 -0
- data/lib/cocoapods/downloader/response.rb +16 -0
- data/lib/cocoapods/executable.rb +222 -0
- data/lib/cocoapods/external_sources.rb +57 -0
- data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods/external_sources/path_source.rb +55 -0
- data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods/gem_version.rb +5 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods/generator/app_target_helper.rb +244 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/constant.rb +19 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
- data/lib/cocoapods/generator/dummy_source.rb +31 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
- data/lib/cocoapods/generator/header.rb +103 -0
- data/lib/cocoapods/generator/info_plist_file.rb +116 -0
- data/lib/cocoapods/generator/module_map.rb +99 -0
- data/lib/cocoapods/generator/prefix_header.rb +60 -0
- data/lib/cocoapods/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods/hooks_manager.rb +132 -0
- data/lib/cocoapods/installer.rb +703 -0
- data/lib/cocoapods/installer/analyzer.rb +972 -0
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
- data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
- data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
- data/lib/cocoapods/installer/installation_options.rb +158 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
- data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods/installer/podfile_validator.rb +139 -0
- data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
- data/lib/cocoapods/installer/xcode.rb +8 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
- data/lib/cocoapods/open-uri.rb +33 -0
- data/lib/cocoapods/project.rb +414 -0
- data/lib/cocoapods/resolver.rb +585 -0
- data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
- data/lib/cocoapods/sandbox.rb +404 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
- data/lib/cocoapods/sandbox/headers_store.rb +146 -0
- data/lib/cocoapods/sandbox/path_list.rb +220 -0
- data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
- data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods/sources_manager.rb +157 -0
- data/lib/cocoapods/target.rb +261 -0
- data/lib/cocoapods/target/aggregate_target.rb +338 -0
- data/lib/cocoapods/target/build_settings.rb +1075 -0
- data/lib/cocoapods/target/pod_target.rb +559 -0
- data/lib/cocoapods/user_interface.rb +459 -0
- data/lib/cocoapods/user_interface/error_report.rb +187 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/validator.rb +981 -0
- metadata +533 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
module Pod
|
|
2
|
+
class Installer
|
|
3
|
+
class UserProjectIntegrator
|
|
4
|
+
class TargetIntegrator
|
|
5
|
+
# Configures an user target to use the CocoaPods xcconfigs which allow
|
|
6
|
+
# lo link against the Pods.
|
|
7
|
+
#
|
|
8
|
+
class XCConfigIntegrator
|
|
9
|
+
# Integrates the user target.
|
|
10
|
+
#
|
|
11
|
+
# @param [Target::AggregateTarget] pod_bundle
|
|
12
|
+
# The Pods bundle.
|
|
13
|
+
#
|
|
14
|
+
# @param [Array<PBXNativeTarget>] targets
|
|
15
|
+
# The native targets associated which should be integrated
|
|
16
|
+
# with the Pod bundle.
|
|
17
|
+
#
|
|
18
|
+
def self.integrate(pod_bundle, targets)
|
|
19
|
+
targets.each do |target|
|
|
20
|
+
target.build_configurations.each do |config|
|
|
21
|
+
set_target_xcconfig(pod_bundle, target, config)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# @!group Integration steps
|
|
29
|
+
#-------------------------------------------------------------------#
|
|
30
|
+
|
|
31
|
+
# Creates a file reference to the xcconfig generated by
|
|
32
|
+
# CocoaPods (if needed) and sets it as the base configuration of
|
|
33
|
+
# build configuration of the user target.
|
|
34
|
+
#
|
|
35
|
+
# @param [Target::AggregateTarget] pod_bundle
|
|
36
|
+
# The Pods bundle.
|
|
37
|
+
#
|
|
38
|
+
# @param [PBXNativeTarget] target
|
|
39
|
+
# The native target.
|
|
40
|
+
#
|
|
41
|
+
# @param [Xcodeproj::XCBuildConfiguration] config
|
|
42
|
+
# The build configuration.
|
|
43
|
+
#
|
|
44
|
+
def self.set_target_xcconfig(pod_bundle, target, config)
|
|
45
|
+
path = pod_bundle.xcconfig_relative_path(config.name)
|
|
46
|
+
group = config.project['Pods'] || config.project.new_group('Pods')
|
|
47
|
+
file_ref = group.files.find { |f| f.path == path }
|
|
48
|
+
existing = config.base_configuration_reference
|
|
49
|
+
|
|
50
|
+
set_base_configuration_reference = ->() do
|
|
51
|
+
file_ref ||= group.new_file(path)
|
|
52
|
+
config.base_configuration_reference = file_ref
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if existing && existing != file_ref
|
|
56
|
+
if existing.real_path.to_path.start_with?(pod_bundle.sandbox.root.to_path << '/')
|
|
57
|
+
set_base_configuration_reference.call
|
|
58
|
+
elsif !xcconfig_includes_target_xcconfig?(config.base_configuration_reference, path)
|
|
59
|
+
unless existing_config_is_identical_to_pod_config?(existing.real_path, pod_bundle.xcconfig_path(config.name))
|
|
60
|
+
UI.warn 'CocoaPods did not set the base configuration of your ' \
|
|
61
|
+
'project because your project already has a custom ' \
|
|
62
|
+
'config set. In order for CocoaPods integration to work at ' \
|
|
63
|
+
'all, please either set the base configurations of the target ' \
|
|
64
|
+
"`#{target.name}` to `#{path}` or include the `#{path}` in your " \
|
|
65
|
+
"build configuration (#{UI.path(existing.real_path)})."
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
elsif config.base_configuration_reference.nil? || file_ref.nil?
|
|
69
|
+
set_base_configuration_reference.call
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# @!group Private helpers
|
|
76
|
+
#-------------------------------------------------------------------#
|
|
77
|
+
|
|
78
|
+
# Prints a warning informing the user that a build configuration of
|
|
79
|
+
# the integrated target is overriding the CocoaPods build settings.
|
|
80
|
+
#
|
|
81
|
+
# @param [Target::AggregateTarget] pod_bundle
|
|
82
|
+
# The Pods bundle.
|
|
83
|
+
#
|
|
84
|
+
# @param [XcodeProj::PBXNativeTarget] target
|
|
85
|
+
# The native target.
|
|
86
|
+
#
|
|
87
|
+
# @param [Xcodeproj::XCBuildConfiguration] config
|
|
88
|
+
# The build configuration.
|
|
89
|
+
#
|
|
90
|
+
# @param [String] key
|
|
91
|
+
# The key of the overridden build setting.
|
|
92
|
+
#
|
|
93
|
+
def self.print_override_warning(pod_bundle, target, config, key)
|
|
94
|
+
actions = [
|
|
95
|
+
'Use the `$(inherited)` flag, or',
|
|
96
|
+
'Remove the build settings from the target.',
|
|
97
|
+
]
|
|
98
|
+
message = "The `#{target.name} [#{config.name}]` " \
|
|
99
|
+
"target overrides the `#{key}` build setting defined in " \
|
|
100
|
+
"`#{pod_bundle.xcconfig_relative_path(config.name)}'. " \
|
|
101
|
+
'This can lead to problems with the CocoaPods installation'
|
|
102
|
+
UI.warn(message, actions)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Naively checks to see if a given PBXFileReference imports a given
|
|
106
|
+
# path.
|
|
107
|
+
#
|
|
108
|
+
# @param [PBXFileReference] base_config_ref
|
|
109
|
+
# A file reference to an `.xcconfig` file.
|
|
110
|
+
#
|
|
111
|
+
# @param [String] target_config_path
|
|
112
|
+
# The path to check for.
|
|
113
|
+
#
|
|
114
|
+
SILENCE_WARNINGS_STRING = '// @COCOAPODS_SILENCE_WARNINGS@ //'
|
|
115
|
+
def self.xcconfig_includes_target_xcconfig?(base_config_ref, target_config_path)
|
|
116
|
+
return unless base_config_ref && base_config_ref.real_path.file?
|
|
117
|
+
regex = %r{
|
|
118
|
+
^(
|
|
119
|
+
(\s* # Possible, but unlikely, space before include statement
|
|
120
|
+
\#include\s+ # Include statement
|
|
121
|
+
['"] # Open quote
|
|
122
|
+
(.*\/)? # Possible prefix to path
|
|
123
|
+
#{Regexp.quote(target_config_path)} # The path should end in the target_config_path
|
|
124
|
+
['"] # Close quote
|
|
125
|
+
)
|
|
126
|
+
|
|
|
127
|
+
(#{Regexp.quote(SILENCE_WARNINGS_STRING)}) # Token to treat xcconfig as good and silence pod install warnings
|
|
128
|
+
)
|
|
129
|
+
}x
|
|
130
|
+
base_config_ref.real_path.readlines.find { |line| line =~ regex }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Checks to see if the config files at two paths exist and are identical
|
|
134
|
+
#
|
|
135
|
+
# @param The existing config path
|
|
136
|
+
#
|
|
137
|
+
# @param The pod config path
|
|
138
|
+
#
|
|
139
|
+
def self.existing_config_is_identical_to_pod_config?(existing_config_path, pod_config_path)
|
|
140
|
+
existing_config_path.file? && (!pod_config_path.file? || FileUtils.compare_file(existing_config_path, pod_config_path))
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
module Pod
|
|
2
|
+
class Installer
|
|
3
|
+
class Xcode
|
|
4
|
+
# The {PodsProjectGenerator} handles generation of the 'Pods/Pods.xcodeproj'
|
|
5
|
+
#
|
|
6
|
+
class PodsProjectGenerator
|
|
7
|
+
require 'cocoapods/installer/xcode/pods_project_generator/target_installer_helper'
|
|
8
|
+
require 'cocoapods/installer/xcode/pods_project_generator/pod_target_integrator'
|
|
9
|
+
require 'cocoapods/installer/xcode/pods_project_generator/target_installer'
|
|
10
|
+
require 'cocoapods/installer/xcode/pods_project_generator/target_installation_result'
|
|
11
|
+
require 'cocoapods/installer/xcode/pods_project_generator/pod_target_installer'
|
|
12
|
+
require 'cocoapods/installer/xcode/pods_project_generator/file_references_installer'
|
|
13
|
+
require 'cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer'
|
|
14
|
+
require 'cocoapods/installer/xcode/pods_project_generator/app_host_installer'
|
|
15
|
+
|
|
16
|
+
# @return [Sandbox] The sandbox where the Pods should be installed.
|
|
17
|
+
#
|
|
18
|
+
attr_reader :sandbox
|
|
19
|
+
|
|
20
|
+
# @return [Pod::Project] the `Pods/Pods.xcodeproj` project.
|
|
21
|
+
#
|
|
22
|
+
attr_reader :project
|
|
23
|
+
|
|
24
|
+
# @return [Array<AggregateTarget>] The model representations of an
|
|
25
|
+
# aggregation of pod targets generated for a target definition
|
|
26
|
+
# in the Podfile.
|
|
27
|
+
#
|
|
28
|
+
attr_reader :aggregate_targets
|
|
29
|
+
|
|
30
|
+
# @return [Array<PodTarget>] The model representations of pod targets.
|
|
31
|
+
#
|
|
32
|
+
attr_reader :pod_targets
|
|
33
|
+
|
|
34
|
+
# @return [Analyzer] the analyzer which provides the information about what
|
|
35
|
+
# needs to be installed.
|
|
36
|
+
#
|
|
37
|
+
attr_reader :analysis_result
|
|
38
|
+
|
|
39
|
+
# @return [InstallationOptions] the installation options from the Podfile.
|
|
40
|
+
#
|
|
41
|
+
attr_reader :installation_options
|
|
42
|
+
|
|
43
|
+
# @return [Config] the global CocoaPods configuration.
|
|
44
|
+
#
|
|
45
|
+
attr_reader :config
|
|
46
|
+
|
|
47
|
+
# Initialize a new instance
|
|
48
|
+
#
|
|
49
|
+
# @param [Sandbox] sandbox @see #sandbox
|
|
50
|
+
# @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
|
|
51
|
+
# @param [Array<PodTarget>] pod_targets @see #pod_targets
|
|
52
|
+
# @param [Analyzer] analysis_result @see #analysis_result
|
|
53
|
+
# @param [InstallationOptions] installation_options @see #installation_options
|
|
54
|
+
# @param [Config] config @see #config
|
|
55
|
+
#
|
|
56
|
+
def initialize(sandbox, aggregate_targets, pod_targets, analysis_result, installation_options, config)
|
|
57
|
+
@sandbox = sandbox
|
|
58
|
+
@aggregate_targets = aggregate_targets
|
|
59
|
+
@pod_targets = pod_targets
|
|
60
|
+
@analysis_result = analysis_result
|
|
61
|
+
@installation_options = installation_options
|
|
62
|
+
@config = config
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def generate!
|
|
66
|
+
prepare
|
|
67
|
+
install_file_references
|
|
68
|
+
@target_installation_results = install_targets
|
|
69
|
+
integrate_targets(@target_installation_results.pod_target_installation_results)
|
|
70
|
+
app_hosts_by_host_key = install_app_hosts
|
|
71
|
+
wire_target_dependencies(@target_installation_results, app_hosts_by_host_key)
|
|
72
|
+
@target_installation_results
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def write
|
|
76
|
+
UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do
|
|
77
|
+
project.pods.remove_from_project if project.pods.empty?
|
|
78
|
+
project.development_pods.remove_from_project if project.development_pods.empty?
|
|
79
|
+
project.sort(:groups_position => :below)
|
|
80
|
+
if installation_options.deterministic_uuids?
|
|
81
|
+
UI.message('- Generating deterministic UUIDs') { project.predictabilize_uuids }
|
|
82
|
+
end
|
|
83
|
+
library_product_types = [:framework, :dynamic_library, :static_library]
|
|
84
|
+
|
|
85
|
+
pod_target_installation_results = @target_installation_results.pod_target_installation_results
|
|
86
|
+
results_by_native_target = Hash[pod_target_installation_results.map do |_, result|
|
|
87
|
+
[result.native_target, result]
|
|
88
|
+
end]
|
|
89
|
+
project.recreate_user_schemes(false) do |scheme, target|
|
|
90
|
+
next unless target.respond_to?(:symbol_type)
|
|
91
|
+
next unless library_product_types.include? target.symbol_type
|
|
92
|
+
installation_result = results_by_native_target[target]
|
|
93
|
+
next unless installation_result
|
|
94
|
+
installation_result.test_native_targets.each do |test_native_target|
|
|
95
|
+
scheme.add_test_target(test_native_target)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
project.save
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Shares schemes of development Pods.
|
|
103
|
+
#
|
|
104
|
+
# @return [void]
|
|
105
|
+
#
|
|
106
|
+
def share_development_pod_schemes
|
|
107
|
+
development_pod_targets.select(&:should_build?).each do |pod_target|
|
|
108
|
+
next unless share_scheme_for_development_pod?(pod_target.pod_name)
|
|
109
|
+
Xcodeproj::XCScheme.share_scheme(project.path, pod_target.label)
|
|
110
|
+
if pod_target.contains_test_specifications?
|
|
111
|
+
pod_target.supported_test_types.each do |test_type|
|
|
112
|
+
Xcodeproj::XCScheme.share_scheme(project.path, pod_target.test_target_label(test_type))
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
AppHostKey = Struct.new(:test_type, :platform)
|
|
121
|
+
InstallationResults = Struct.new(:pod_target_installation_results, :aggregate_target_installation_results)
|
|
122
|
+
|
|
123
|
+
def create_project
|
|
124
|
+
if object_version = aggregate_targets.map(&:user_project).compact.map { |p| p.object_version.to_i }.min
|
|
125
|
+
Pod::Project.new(sandbox.project_path, false, object_version)
|
|
126
|
+
else
|
|
127
|
+
Pod::Project.new(sandbox.project_path)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Creates the Pods project from scratch if it doesn't exists.
|
|
132
|
+
#
|
|
133
|
+
# @return [void]
|
|
134
|
+
#
|
|
135
|
+
# @todo Clean and modify the project if it exists.
|
|
136
|
+
#
|
|
137
|
+
def prepare
|
|
138
|
+
UI.message '- Creating Pods project' do
|
|
139
|
+
@project = create_project
|
|
140
|
+
analysis_result.all_user_build_configurations.each do |name, type|
|
|
141
|
+
@project.add_build_configuration(name, type)
|
|
142
|
+
end
|
|
143
|
+
# Reset symroot just in case the user has added a new build configuration other than 'Debug' or 'Release'.
|
|
144
|
+
@project.symroot = Pod::Project::LEGACY_BUILD_ROOT
|
|
145
|
+
|
|
146
|
+
pod_names = pod_targets.map(&:pod_name).uniq
|
|
147
|
+
pod_names.each do |pod_name|
|
|
148
|
+
local = sandbox.local?(pod_name)
|
|
149
|
+
path = sandbox.pod_dir(pod_name)
|
|
150
|
+
was_absolute = sandbox.local_path_was_absolute?(pod_name)
|
|
151
|
+
@project.add_pod_group(pod_name, path, local, was_absolute)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
if config.podfile_path
|
|
155
|
+
@project.add_podfile(config.podfile_path)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
sandbox.project = @project
|
|
159
|
+
platforms = aggregate_targets.map(&:platform)
|
|
160
|
+
osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min
|
|
161
|
+
ios_deployment_target = platforms.select { |p| p.name == :ios }.map(&:deployment_target).min
|
|
162
|
+
watchos_deployment_target = platforms.select { |p| p.name == :watchos }.map(&:deployment_target).min
|
|
163
|
+
tvos_deployment_target = platforms.select { |p| p.name == :tvos }.map(&:deployment_target).min
|
|
164
|
+
@project.build_configurations.each do |build_configuration|
|
|
165
|
+
build_configuration.build_settings['MACOSX_DEPLOYMENT_TARGET'] = osx_deployment_target.to_s if osx_deployment_target
|
|
166
|
+
build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target.to_s if ios_deployment_target
|
|
167
|
+
build_configuration.build_settings['WATCHOS_DEPLOYMENT_TARGET'] = watchos_deployment_target.to_s if watchos_deployment_target
|
|
168
|
+
build_configuration.build_settings['TVOS_DEPLOYMENT_TARGET'] = tvos_deployment_target.to_s if tvos_deployment_target
|
|
169
|
+
build_configuration.build_settings['STRIP_INSTALLED_PRODUCT'] = 'NO'
|
|
170
|
+
build_configuration.build_settings['CLANG_ENABLE_OBJC_ARC'] = 'YES'
|
|
171
|
+
build_configuration.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
|
|
172
|
+
build_configuration.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def install_file_references
|
|
178
|
+
installer = FileReferencesInstaller.new(sandbox, pod_targets, project)
|
|
179
|
+
installer.install!
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def install_targets
|
|
183
|
+
UI.message '- Installing targets' do
|
|
184
|
+
umbrella_headers_by_dir = pod_targets.map do |pod_target|
|
|
185
|
+
next unless pod_target.should_build? && pod_target.defines_module?
|
|
186
|
+
pod_target.umbrella_header_path
|
|
187
|
+
end.compact.group_by(&:dirname)
|
|
188
|
+
|
|
189
|
+
pod_target_installation_results = Hash[pod_targets.sort_by(&:name).map do |pod_target|
|
|
190
|
+
umbrella_headers_in_header_dir = umbrella_headers_by_dir[pod_target.module_map_path.dirname]
|
|
191
|
+
target_installer = PodTargetInstaller.new(sandbox, @project, pod_target, umbrella_headers_in_header_dir)
|
|
192
|
+
[pod_target.name, target_installer.install!]
|
|
193
|
+
end]
|
|
194
|
+
|
|
195
|
+
# Hook up system framework dependencies for the pod targets that were just installed.
|
|
196
|
+
pod_target_installation_result_values = pod_target_installation_results.values.compact
|
|
197
|
+
unless pod_target_installation_result_values.empty?
|
|
198
|
+
add_system_framework_dependencies(pod_target_installation_result_values)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
aggregate_target_installation_results = Hash[aggregate_targets.sort_by(&:name).map do |target|
|
|
202
|
+
target_installer = AggregateTargetInstaller.new(sandbox, @project, target)
|
|
203
|
+
[target.name, target_installer.install!]
|
|
204
|
+
end]
|
|
205
|
+
|
|
206
|
+
InstallationResults.new(pod_target_installation_results, aggregate_target_installation_results)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def install_app_hosts
|
|
211
|
+
pod_target_with_test_specs = pod_targets.reject do |pod_target|
|
|
212
|
+
pod_target.test_specs.empty? || pod_target.test_spec_consumers.none?(&:requires_app_host?)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
return if pod_target_with_test_specs.empty?
|
|
216
|
+
|
|
217
|
+
UI.message '- Installing app hosts' do
|
|
218
|
+
app_host_keys = pod_target_with_test_specs.flat_map do |pod_target|
|
|
219
|
+
pod_target.supported_test_types.flat_map do |test_type|
|
|
220
|
+
AppHostKey.new(test_type, pod_target.platform)
|
|
221
|
+
end.uniq
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
app_host_keys_by_test_type = app_host_keys.group_by do |app_host_key|
|
|
225
|
+
[app_host_key.test_type, app_host_key.platform.symbolic_name]
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
app_host_keys_by_test_type.map do |(test_type, platform_symbol), keys|
|
|
229
|
+
deployment_target = keys.map { |k| k.platform.deployment_target }.max
|
|
230
|
+
platform = Platform.new(platform_symbol, deployment_target)
|
|
231
|
+
AppHostKey.new(test_type, platform)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
Hash[app_host_keys.map do |app_host_key|
|
|
235
|
+
[app_host_key, AppHostInstaller.new(sandbox, project, app_host_key.platform, app_host_key.test_type).install!]
|
|
236
|
+
end]
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def integrate_targets(pod_target_installation_results)
|
|
241
|
+
pod_installations_to_integrate = pod_target_installation_results.values.select do |pod_target_installation_result|
|
|
242
|
+
pod_target = pod_target_installation_result.target
|
|
243
|
+
!pod_target_installation_result.test_native_targets.empty? || pod_target.contains_script_phases?
|
|
244
|
+
end
|
|
245
|
+
unless pod_installations_to_integrate.empty?
|
|
246
|
+
UI.message '- Integrating targets' do
|
|
247
|
+
pod_installations_to_integrate.each do |pod_target_installation_result|
|
|
248
|
+
PodTargetIntegrator.new(pod_target_installation_result).integrate!
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def add_system_framework_dependencies(pod_target_installation_results)
|
|
255
|
+
sorted_installation_results = pod_target_installation_results.sort_by do |pod_target_installation_result|
|
|
256
|
+
pod_target_installation_result.target.name
|
|
257
|
+
end
|
|
258
|
+
sorted_installation_results.each do |target_installation_result|
|
|
259
|
+
pod_target = target_installation_result.target
|
|
260
|
+
next unless pod_target.should_build?
|
|
261
|
+
next if !pod_target.requires_frameworks? || pod_target.static_framework?
|
|
262
|
+
pod_target.file_accessors.each do |file_accessor|
|
|
263
|
+
native_target = target_installation_result.native_target_for_spec(file_accessor.spec)
|
|
264
|
+
add_system_frameworks_to_native_target(native_target, file_accessor)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Adds a target dependency for each pod spec to each aggregate target and
|
|
270
|
+
# links the pod targets among each other.
|
|
271
|
+
#
|
|
272
|
+
# @param [Array[Hash{String=>TargetInstallationResult}]] target_installation_results
|
|
273
|
+
# the installation results that were produced when all targets were installed. This includes
|
|
274
|
+
# pod target installation results and aggregate target installation results.
|
|
275
|
+
#
|
|
276
|
+
# @param [Hash{AppHostKey=>Array<PBXNativeTarget>}] app_hosts_by_host_key
|
|
277
|
+
# the app hosts by test type that were installed in #install_app_hosts
|
|
278
|
+
#
|
|
279
|
+
# @return [void]
|
|
280
|
+
#
|
|
281
|
+
def wire_target_dependencies(target_installation_results, app_hosts_by_host_key)
|
|
282
|
+
frameworks_group = project.frameworks_group
|
|
283
|
+
pod_target_installation_results_hash = target_installation_results.pod_target_installation_results
|
|
284
|
+
aggregate_target_installation_results_hash = target_installation_results.aggregate_target_installation_results
|
|
285
|
+
|
|
286
|
+
# Wire up aggregate targets
|
|
287
|
+
aggregate_target_installation_results_hash.values.each do |aggregate_target_installation_result|
|
|
288
|
+
aggregate_target = aggregate_target_installation_result.target
|
|
289
|
+
aggregate_native_target = aggregate_target_installation_result.native_target
|
|
290
|
+
is_app_extension = !(aggregate_target.user_targets.map(&:symbol_type) &
|
|
291
|
+
[:app_extension, :watch_extension, :watch2_extension, :tv_extension, :messages_extension]).empty?
|
|
292
|
+
is_app_extension ||= aggregate_target.user_targets.any? { |ut| ut.common_resolved_build_setting('APPLICATION_EXTENSION_API_ONLY') == 'YES' }
|
|
293
|
+
configure_app_extension_api_only_to_native_target(aggregate_native_target) if is_app_extension
|
|
294
|
+
# Wire up dependencies that are part of inherit search paths for this aggregate target.
|
|
295
|
+
aggregate_target.search_paths_aggregate_targets.each do |search_paths_target|
|
|
296
|
+
aggregate_native_target.add_dependency(aggregate_target_installation_results_hash[search_paths_target.name].native_target)
|
|
297
|
+
end
|
|
298
|
+
# Wire up all pod target dependencies to aggregate target.
|
|
299
|
+
aggregate_target.pod_targets.each do |pod_target|
|
|
300
|
+
pod_target_native_target = pod_target_installation_results_hash[pod_target.name].native_target
|
|
301
|
+
aggregate_native_target.add_dependency(pod_target_native_target)
|
|
302
|
+
configure_app_extension_api_only_to_native_target(pod_target_native_target) if is_app_extension
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Wire up pod targets
|
|
307
|
+
pod_target_installation_results_hash.values.each do |pod_target_installation_result|
|
|
308
|
+
pod_target = pod_target_installation_result.target
|
|
309
|
+
native_target = pod_target_installation_result.native_target
|
|
310
|
+
# First, wire up all resource bundles.
|
|
311
|
+
pod_target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
|
|
312
|
+
native_target.add_dependency(resource_bundle_target)
|
|
313
|
+
if pod_target.requires_frameworks? && pod_target.should_build?
|
|
314
|
+
native_target.add_resources([resource_bundle_target.product_reference])
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
# Wire up all dependencies to this pod target, if any.
|
|
318
|
+
dependent_targets = pod_target.dependent_targets
|
|
319
|
+
dependent_targets.each do |dependent_target|
|
|
320
|
+
native_target.add_dependency(pod_target_installation_results_hash[dependent_target.name].native_target)
|
|
321
|
+
add_framework_file_reference_to_native_target(native_target, pod_target, dependent_target, frameworks_group)
|
|
322
|
+
end
|
|
323
|
+
# Wire up test native targets.
|
|
324
|
+
unless pod_target_installation_result.test_native_targets.empty?
|
|
325
|
+
pod_target_installation_result.test_specs_by_native_target.each do |test_native_target, test_specs|
|
|
326
|
+
test_dependent_targets = test_specs.flat_map { |s| pod_target.test_dependent_targets_by_spec_name[s.name] }.compact.unshift(pod_target).uniq
|
|
327
|
+
test_dependent_targets.each do |test_dependent_target|
|
|
328
|
+
dependency_installation_result = pod_target_installation_results_hash[test_dependent_target.name]
|
|
329
|
+
dependency_installation_result.test_resource_bundle_targets.values.flatten.each do |test_resource_bundle_target|
|
|
330
|
+
test_native_target.add_dependency(test_resource_bundle_target)
|
|
331
|
+
end
|
|
332
|
+
test_native_target.add_dependency(dependency_installation_result.native_target)
|
|
333
|
+
add_framework_file_reference_to_native_target(test_native_target, pod_target, test_dependent_target, frameworks_group)
|
|
334
|
+
# Wire app host dependencies to test native target
|
|
335
|
+
if pod_target.test_spec_consumers.any?(&:requires_app_host?)
|
|
336
|
+
pod_target.supported_test_types.each do |test_type|
|
|
337
|
+
app_host_target = app_hosts_by_host_key[AppHostKey.new(test_type, pod_target.platform)]
|
|
338
|
+
test_native_target.add_dependency(app_host_target)
|
|
339
|
+
configure_app_host_to_native_target(app_host_target, test_native_target)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# @param [String] pod The root name of the development pod.
|
|
349
|
+
#
|
|
350
|
+
# @return [Bool] whether the scheme for the given development pod should be
|
|
351
|
+
# shared.
|
|
352
|
+
#
|
|
353
|
+
def share_scheme_for_development_pod?(pod)
|
|
354
|
+
case dev_pods_to_share = installation_options.share_schemes_for_development_pods
|
|
355
|
+
when TrueClass, FalseClass, NilClass
|
|
356
|
+
dev_pods_to_share
|
|
357
|
+
when Array
|
|
358
|
+
dev_pods_to_share.any? { |dev_pod| dev_pod === pod } # rubocop:disable Style/CaseEquality
|
|
359
|
+
else
|
|
360
|
+
raise Informative, 'Unable to handle share_schemes_for_development_pods ' \
|
|
361
|
+
"being set to #{dev_pods_to_share.inspect} -- please set it to true, " \
|
|
362
|
+
'false, or an array of pods to share schemes for.'
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# @return [Array<Library>] The targets of the development pods generated by
|
|
367
|
+
# the installation process.
|
|
368
|
+
#
|
|
369
|
+
def development_pod_targets
|
|
370
|
+
pod_targets.select do |pod_target|
|
|
371
|
+
sandbox.local?(pod_target.pod_name)
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
#------------------------------------------------------------------------#
|
|
376
|
+
|
|
377
|
+
# @! group Private Helpers
|
|
378
|
+
|
|
379
|
+
def add_system_frameworks_to_native_target(native_target, file_accessor)
|
|
380
|
+
file_accessor.spec_consumer.frameworks.each do |framework|
|
|
381
|
+
native_target.add_system_framework(framework)
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def add_framework_file_reference_to_native_target(native_target, pod_target, dependent_target, frameworks_group)
|
|
386
|
+
if pod_target.should_build? && pod_target.requires_frameworks? && !pod_target.static_framework? && dependent_target.should_build?
|
|
387
|
+
product_ref = frameworks_group.files.find { |f| f.path == dependent_target.product_name } ||
|
|
388
|
+
frameworks_group.new_product_ref_for_target(dependent_target.product_basename, dependent_target.product_type)
|
|
389
|
+
native_target.frameworks_build_phase.add_file_reference(product_ref, true)
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
# Sets the APPLICATION_EXTENSION_API_ONLY build setting to YES for all
|
|
394
|
+
# configurations of the given native target.
|
|
395
|
+
#
|
|
396
|
+
def configure_app_extension_api_only_to_native_target(native_target)
|
|
397
|
+
native_target.build_configurations.each do |config|
|
|
398
|
+
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def configure_app_host_to_native_target(app_host_target, test_native_target)
|
|
403
|
+
test_native_target.build_configurations.each do |configuration|
|
|
404
|
+
test_host = "$(BUILT_PRODUCTS_DIR)/#{app_host_target.name}.app/"
|
|
405
|
+
test_host << 'Contents/MacOS/' if app_host_target.platform_name == :osx
|
|
406
|
+
test_host << app_host_target.name.to_s
|
|
407
|
+
configuration.build_settings['TEST_HOST'] = test_host
|
|
408
|
+
end
|
|
409
|
+
target_attributes = project.root_object.attributes['TargetAttributes'] || {}
|
|
410
|
+
target_attributes[test_native_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s }
|
|
411
|
+
project.root_object.attributes['TargetAttributes'] = target_attributes
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|