cocoapods 1.5.2 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +365 -1
- data/bin/pod +1 -1
- data/lib/cocoapods/command/cache/clean.rb +1 -1
- data/lib/cocoapods/command/init.rb +4 -2
- data/lib/cocoapods/command/install.rb +7 -0
- data/lib/cocoapods/command/lib/lint.rb +8 -1
- data/lib/cocoapods/command/outdated.rb +4 -9
- data/lib/cocoapods/command/repo/add.rb +1 -1
- data/lib/cocoapods/command/repo/list.rb +1 -1
- data/lib/cocoapods/command/repo/push.rb +17 -12
- data/lib/cocoapods/command/repo/remove.rb +1 -1
- data/lib/cocoapods/command/repo/update.rb +1 -1
- data/lib/cocoapods/command/setup.rb +1 -1
- data/lib/cocoapods/command/spec/create.rb +39 -39
- data/lib/cocoapods/command/spec/lint.rb +8 -1
- data/lib/cocoapods/command.rb +3 -1
- data/lib/cocoapods/config.rb +13 -2
- data/lib/cocoapods/downloader/cache.rb +1 -1
- data/lib/cocoapods/executable.rb +3 -3
- data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
- data/lib/cocoapods/external_sources.rb +7 -4
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +13 -2
- data/lib/cocoapods/generator/app_target_helper.rb +141 -17
- data/lib/cocoapods/generator/copy_resources_script.rb +14 -3
- data/lib/cocoapods/generator/dummy_source.rb +14 -5
- data/lib/cocoapods/generator/embed_frameworks_script.rb +37 -20
- data/lib/cocoapods/generator/header.rb +1 -1
- data/lib/cocoapods/generator/info_plist_file.rb +12 -4
- data/lib/cocoapods/generator/prefix_header.rb +2 -2
- data/lib/cocoapods/hooks_manager.rb +28 -17
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +14 -6
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
- data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +27 -14
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
- data/lib/cocoapods/installer/analyzer.rb +391 -284
- data/lib/cocoapods/installer/installation_options.rb +2 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
- data/lib/cocoapods/installer/post_install_hooks_context.rb +72 -47
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
- data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +69 -29
- data/lib/cocoapods/installer/user_project_integrator.rb +6 -4
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +104 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +23 -50
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +296 -177
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +51 -33
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +62 -69
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +130 -122
- data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
- data/lib/cocoapods/installer.rb +140 -63
- data/lib/cocoapods/project.rb +16 -14
- data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
- data/lib/cocoapods/resolver.rb +79 -98
- data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
- data/lib/cocoapods/sandbox/headers_store.rb +9 -8
- data/lib/cocoapods/sandbox/path_list.rb +5 -8
- data/lib/cocoapods/sandbox.rb +31 -43
- data/lib/cocoapods/sources_manager.rb +1 -1
- data/lib/cocoapods/target/aggregate_target.rb +143 -85
- data/lib/cocoapods/target/build_settings.rb +1124 -0
- data/lib/cocoapods/target/framework_paths.rb +36 -0
- data/lib/cocoapods/target/pod_target.rb +198 -295
- data/lib/cocoapods/target.rb +92 -37
- data/lib/cocoapods/user_interface.rb +5 -0
- data/lib/cocoapods/validator.rb +149 -44
- data/lib/cocoapods.rb +0 -1
- metadata +31 -23
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
- data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
- data/lib/cocoapods/generator/xcconfig.rb +0 -13
@@ -19,43 +19,62 @@ module Pod
|
|
19
19
|
autoload :TargetInspectionResult, 'cocoapods/installer/analyzer/target_inspection_result'
|
20
20
|
autoload :TargetInspector, 'cocoapods/installer/analyzer/target_inspector'
|
21
21
|
|
22
|
-
# @return [
|
22
|
+
# @return [String] The version of iOS which requires binaries with only 64-bit architectures
|
23
|
+
#
|
24
|
+
IOS_64_BIT_ONLY_VERSION = Version.new('11.0')
|
25
|
+
|
26
|
+
# @return [Integer] The Xcode object version until which 64-bit architectures should be manually specified
|
27
|
+
#
|
28
|
+
# Xcode 10 will automatically select the correct architectures based on deployment target
|
29
|
+
IOS_64_BIT_ONLY_PROJECT_VERSION = 50
|
30
|
+
|
31
|
+
# @return [Sandbox] The sandbox to use for this analysis.
|
23
32
|
#
|
24
33
|
attr_reader :sandbox
|
25
34
|
|
26
|
-
# @return [Podfile] The Podfile specification that contains the
|
27
|
-
# information of the Pods that should be installed.
|
35
|
+
# @return [Podfile] The Podfile specification that contains the information of the Pods that should be installed.
|
28
36
|
#
|
29
37
|
attr_reader :podfile
|
30
38
|
|
31
|
-
# @return [Lockfile] The Lockfile that stores the information about the
|
32
|
-
# Pods previously installed on any machine.
|
39
|
+
# @return [Lockfile] The Lockfile, if available, that stores the information about the Pods previously installed.
|
33
40
|
#
|
34
41
|
attr_reader :lockfile
|
35
42
|
|
36
|
-
# @return [Array<Source>] Sources provided by plugins
|
43
|
+
# @return [Array<Source>] Sources provided by plugins or `nil`.
|
37
44
|
#
|
38
45
|
attr_reader :plugin_sources
|
39
46
|
|
47
|
+
# @return [Bool] Whether the analysis has dependencies and thus sources must be configured.
|
48
|
+
#
|
49
|
+
# @note This is used by the `pod lib lint` command to prevent update of specs when not needed.
|
50
|
+
#
|
51
|
+
attr_reader :has_dependencies
|
52
|
+
alias_method :has_dependencies?, :has_dependencies
|
53
|
+
|
54
|
+
# @return [Hash, Boolean, nil] Pods that have been requested to be updated or true if all Pods should be updated.
|
55
|
+
# This can be false if no pods should be updated.
|
56
|
+
#
|
57
|
+
attr_reader :pods_to_update
|
58
|
+
|
40
59
|
# Initialize a new instance
|
41
60
|
#
|
42
|
-
# @param [Sandbox]
|
43
|
-
# @param [Podfile]
|
44
|
-
# @param [Lockfile]
|
45
|
-
# @param [Array<Source>] plugin_sources
|
61
|
+
# @param [Sandbox] sandbox @see #sandbox
|
62
|
+
# @param [Podfile] podfile @see #podfile
|
63
|
+
# @param [Lockfile] lockfile @see #lockfile
|
64
|
+
# @param [Array<Source>] plugin_sources @see #plugin_sources
|
65
|
+
# @param [Boolean] has_dependencies @see #has_dependencies
|
66
|
+
# @param [Hash, Boolean, nil] pods_to_update @see #pods_to_update
|
46
67
|
#
|
47
|
-
def initialize(sandbox, podfile, lockfile = nil, plugin_sources = nil
|
68
|
+
def initialize(sandbox, podfile, lockfile = nil, plugin_sources = nil, has_dependencies = true,
|
69
|
+
pods_to_update = false)
|
48
70
|
@sandbox = sandbox
|
49
71
|
@podfile = podfile
|
50
72
|
@lockfile = lockfile
|
51
73
|
@plugin_sources = plugin_sources
|
52
|
-
|
53
|
-
@
|
54
|
-
@allow_pre_downloads = true
|
55
|
-
@has_dependencies = true
|
56
|
-
@test_pod_target_analyzer_cache = {}
|
57
|
-
@test_pod_target_key = Struct.new(:name, :pod_targets)
|
74
|
+
@has_dependencies = has_dependencies
|
75
|
+
@pods_to_update = pods_to_update
|
58
76
|
@podfile_dependency_cache = PodfileDependencyCache.from_podfile(podfile)
|
77
|
+
@result = nil
|
59
78
|
end
|
60
79
|
|
61
80
|
# Performs the analysis.
|
@@ -70,124 +89,124 @@ module Pod
|
|
70
89
|
# @return [AnalysisResult]
|
71
90
|
#
|
72
91
|
def analyze(allow_fetches = true)
|
92
|
+
return @result if @result
|
73
93
|
validate_podfile!
|
74
94
|
validate_lockfile_version!
|
75
|
-
@result = AnalysisResult.new
|
76
|
-
@result.podfile_dependency_cache = @podfile_dependency_cache
|
77
95
|
if installation_options.integrate_targets?
|
78
|
-
|
96
|
+
target_inspections = inspect_targets_to_integrate
|
79
97
|
else
|
80
98
|
verify_platforms_specified!
|
99
|
+
target_inspections = {}
|
81
100
|
end
|
82
|
-
|
101
|
+
podfile_state = generate_podfile_state
|
83
102
|
|
84
103
|
store_existing_checkout_options
|
85
|
-
|
104
|
+
if allow_fetches == :outdated
|
105
|
+
# special-cased -- we're only really resolving for outdated, rather than doing a full analysis
|
106
|
+
elsif allow_fetches == true
|
107
|
+
fetch_external_sources(podfile_state)
|
108
|
+
elsif !dependencies_to_fetch(podfile_state).all?(&:local?)
|
109
|
+
raise Informative, 'Cannot analyze without fetching dependencies since the sandbox is not up-to-date. Run `pod install` to ensure all dependencies have been fetched.' \
|
110
|
+
"\n The missing dependencies are:\n \t#{dependencies_to_fetch(podfile_state).reject(&:local?).join("\n \t")}"
|
111
|
+
end
|
86
112
|
|
87
|
-
|
88
|
-
resolver_specs_by_target = resolve_dependencies
|
113
|
+
locked_dependencies = generate_version_locking_dependencies(podfile_state)
|
114
|
+
resolver_specs_by_target = resolve_dependencies(locked_dependencies)
|
89
115
|
validate_platforms(resolver_specs_by_target)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
116
|
+
specifications = generate_specifications(resolver_specs_by_target)
|
117
|
+
targets = generate_targets(resolver_specs_by_target, target_inspections)
|
118
|
+
pod_targets = calculate_pod_targets(targets)
|
119
|
+
sandbox_state = generate_sandbox_state(specifications)
|
120
|
+
specs_by_target = resolver_specs_by_target.each_with_object({}) do |rspecs_by_target, hash|
|
94
121
|
hash[rspecs_by_target[0]] = rspecs_by_target[1].map(&:spec)
|
95
122
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
123
|
+
specs_by_source = Hash[resolver_specs_by_target.values.flatten(1).group_by(&:source).map do |source, specs|
|
124
|
+
[source, specs.map(&:spec).uniq]
|
125
|
+
end]
|
126
|
+
sources.each { |s| specs_by_source[s] ||= [] }
|
127
|
+
@result = AnalysisResult.new(podfile_state, specs_by_target, specs_by_source, specifications, sandbox_state,
|
128
|
+
targets, pod_targets, @podfile_dependency_cache)
|
99
129
|
end
|
100
130
|
|
101
|
-
|
102
|
-
|
103
|
-
# @return [Bool] Whether an installation should be performed or this
|
104
|
-
# CocoaPods project is already up to date.
|
131
|
+
# Updates the git source repositories.
|
105
132
|
#
|
106
|
-
def
|
107
|
-
|
108
|
-
|
133
|
+
def update_repositories
|
134
|
+
sources.each do |source|
|
135
|
+
if source.git?
|
136
|
+
config.sources_manager.update(source.name, true)
|
137
|
+
else
|
138
|
+
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
139
|
+
end
|
140
|
+
end
|
141
|
+
@specs_updated = true
|
109
142
|
end
|
110
143
|
|
111
|
-
#
|
112
|
-
# the analysis result to check for changes
|
144
|
+
# Returns the sources used to query for specifications.
|
113
145
|
#
|
114
|
-
#
|
146
|
+
# When no explicit Podfile sources or plugin sources are defined, this defaults to the master spec repository.
|
115
147
|
#
|
116
|
-
|
117
|
-
|
118
|
-
needing_install = state.added + state.changed + state.deleted
|
119
|
-
!needing_install.empty?
|
120
|
-
end
|
121
|
-
|
122
|
-
# @param [AnalysisResult] analysis_result
|
123
|
-
# the analysis result to check for changes
|
124
|
-
#
|
125
|
-
# @return [Bool] Whether the sandbox is in synch with the lockfile.
|
148
|
+
# @return [Array<Source>] the sources to be used in finding specifications, as specified by the podfile or all
|
149
|
+
# sources.
|
126
150
|
#
|
127
|
-
def
|
128
|
-
|
129
|
-
|
130
|
-
|
151
|
+
def sources
|
152
|
+
@sources ||= begin
|
153
|
+
sources = podfile.sources
|
154
|
+
plugin_sources = @plugin_sources || []
|
155
|
+
|
156
|
+
# Add any sources specified using the :source flag on individual dependencies.
|
157
|
+
dependency_sources = podfile_dependencies.map(&:podspec_repo).compact
|
158
|
+
all_dependencies_have_sources = dependency_sources.count == podfile_dependencies.count
|
159
|
+
|
160
|
+
if all_dependencies_have_sources
|
161
|
+
sources = dependency_sources
|
162
|
+
elsif has_dependencies? && sources.empty? && plugin_sources.empty?
|
163
|
+
sources = ['https://github.com/CocoaPods/Specs.git']
|
164
|
+
else
|
165
|
+
sources += dependency_sources
|
166
|
+
end
|
167
|
+
|
168
|
+
result = sources.uniq.map do |source_url|
|
169
|
+
config.sources_manager.find_or_create_source_with_url(source_url)
|
170
|
+
end
|
171
|
+
unless plugin_sources.empty?
|
172
|
+
result.insert(0, *plugin_sources)
|
173
|
+
end
|
174
|
+
result
|
175
|
+
end
|
131
176
|
end
|
132
177
|
|
133
178
|
#-----------------------------------------------------------------------#
|
134
179
|
|
135
|
-
|
180
|
+
private
|
136
181
|
|
137
|
-
#
|
138
|
-
# updated or true if all Pods should be updated
|
139
|
-
#
|
140
|
-
attr_accessor :update
|
182
|
+
# @!group Configuration
|
141
183
|
|
142
184
|
# @return [Bool] Whether the version of the dependencies which did not
|
143
185
|
# change in the Podfile should be locked.
|
144
186
|
#
|
145
187
|
def update_mode?
|
146
|
-
|
188
|
+
pods_to_update != nil
|
147
189
|
end
|
148
190
|
|
149
191
|
# @return [Symbol] Whether and how the dependencies in the Podfile
|
150
192
|
# should be updated.
|
151
193
|
#
|
152
194
|
def update_mode
|
153
|
-
if !
|
195
|
+
if !pods_to_update
|
154
196
|
:none
|
155
|
-
elsif
|
197
|
+
elsif pods_to_update == true
|
156
198
|
:all
|
157
|
-
elsif !
|
199
|
+
elsif !pods_to_update[:pods].nil?
|
158
200
|
:selected
|
159
201
|
end
|
160
202
|
end
|
161
203
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
# @note This flag should not be used in installations.
|
166
|
-
#
|
167
|
-
# @note This is used by the `pod outdated` command to prevent
|
168
|
-
# modification of the sandbox in the resolution process.
|
169
|
-
#
|
170
|
-
attr_accessor :allow_pre_downloads
|
171
|
-
alias_method :allow_pre_downloads?, :allow_pre_downloads
|
172
|
-
|
173
|
-
# @return [Bool] Whether the analysis has dependencies and thus
|
174
|
-
# sources must be configured.
|
175
|
-
#
|
176
|
-
# @note This is used by the `pod lib lint` command to prevent
|
177
|
-
# update of specs when not needed.
|
178
|
-
#
|
179
|
-
attr_accessor :has_dependencies
|
180
|
-
alias_method :has_dependencies?, :has_dependencies
|
204
|
+
def podfile_dependencies
|
205
|
+
@podfile_dependency_cache.podfile_dependencies
|
206
|
+
end
|
181
207
|
|
182
208
|
#-----------------------------------------------------------------------#
|
183
209
|
|
184
|
-
private
|
185
|
-
|
186
|
-
# @return [Bool] Whether the analysis has updated sources repositories.
|
187
|
-
#
|
188
|
-
attr_accessor :specs_updated
|
189
|
-
alias_method :specs_updated?, :specs_updated
|
190
|
-
|
191
210
|
def validate_podfile!
|
192
211
|
validator = Installer::PodfileValidator.new(podfile, @podfile_dependency_cache)
|
193
212
|
validator.validate
|
@@ -223,8 +242,7 @@ module Pod
|
|
223
242
|
# the name of the Pod (root name of the dependencies) and doesn't
|
224
243
|
# group them by target definition.
|
225
244
|
#
|
226
|
-
# @
|
227
|
-
# be marked as added.
|
245
|
+
# @return [SpecState]
|
228
246
|
#
|
229
247
|
def generate_podfile_state
|
230
248
|
if lockfile
|
@@ -232,34 +250,17 @@ module Pod
|
|
232
250
|
UI.section 'Finding Podfile changes' do
|
233
251
|
pods_by_state = lockfile.detect_changes_with_podfile(podfile)
|
234
252
|
pods_state = SpecsState.new(pods_by_state)
|
235
|
-
pods_state.print
|
253
|
+
pods_state.print if config.verbose?
|
236
254
|
end
|
237
255
|
pods_state
|
238
256
|
else
|
239
257
|
state = SpecsState.new
|
240
|
-
state.added.merge(
|
258
|
+
state.added.merge(podfile_dependencies.map(&:root_name))
|
241
259
|
state
|
242
260
|
end
|
243
261
|
end
|
244
262
|
|
245
|
-
|
246
|
-
|
247
|
-
# Updates the git source repositories.
|
248
|
-
#
|
249
|
-
def update_repositories
|
250
|
-
sources.each do |source|
|
251
|
-
if source.git?
|
252
|
-
config.sources_manager.update(source.name, true)
|
253
|
-
else
|
254
|
-
UI.message "Skipping `#{source.name}` update because the repository is not a git source repository."
|
255
|
-
end
|
256
|
-
end
|
257
|
-
@specs_updated = true
|
258
|
-
end
|
259
|
-
|
260
|
-
private
|
261
|
-
|
262
|
-
# Copies the pod_targets of any of the app embedded aggregate targets into
|
263
|
+
# Copies the pod targets of any of the app embedded aggregate targets into
|
263
264
|
# their potential host aggregate target, if that potential host aggregate target's
|
264
265
|
# user_target hosts any of the app embedded aggregate targets' user_targets
|
265
266
|
#
|
@@ -273,13 +274,17 @@ module Pod
|
|
273
274
|
# targets are considered, otherwise, all other types are have
|
274
275
|
# their pods copied to their host targets as well (extensions, etc.)
|
275
276
|
#
|
276
|
-
|
277
|
-
|
278
|
-
|
277
|
+
# @return [Hash{String=>Array<PodTarget>}] the additional pod targets to include to the host
|
278
|
+
# keyed by their configuration.
|
279
|
+
#
|
280
|
+
def embedded_target_pod_targets_by_host(aggregate_target, embedded_aggregate_targets, libraries_only)
|
281
|
+
return {} if aggregate_target.requires_host_target?
|
279
282
|
aggregate_user_target_uuids = Set.new(aggregate_target.user_targets.map(&:uuid))
|
283
|
+
embedded_pod_targets_by_build_config = Hash.new([].freeze)
|
280
284
|
embedded_aggregate_targets.each do |embedded_aggregate_target|
|
281
285
|
# Skip non libraries in library-only mode
|
282
286
|
next if libraries_only && !embedded_aggregate_target.library?
|
287
|
+
next if aggregate_target.search_paths_aggregate_targets.include?(embedded_aggregate_target)
|
283
288
|
next unless embedded_aggregate_target.user_targets.any? do |embedded_user_target|
|
284
289
|
# You have to ask the host target's project for the host targets of
|
285
290
|
# the embedded target, as opposed to asking user_project for the
|
@@ -290,11 +295,18 @@ module Pod
|
|
290
295
|
host_target_uuids = Set.new(aggregate_target.user_project.host_targets_for_embedded_target(embedded_user_target).map(&:uuid))
|
291
296
|
!aggregate_user_target_uuids.intersection(host_target_uuids).empty?
|
292
297
|
end
|
293
|
-
|
294
|
-
|
295
|
-
|
298
|
+
embedded_aggregate_target.user_build_configurations.keys.each do |configuration_name|
|
299
|
+
pod_target_names = Set.new(aggregate_target.pod_targets_for_build_configuration(configuration_name).map(&:name))
|
300
|
+
embedded_pod_targets = embedded_aggregate_target.pod_targets_for_build_configuration(configuration_name).select do |pod_target|
|
301
|
+
if !pod_target_names.include?(pod_target.name) &&
|
302
|
+
aggregate_target.pod_targets.none? { |aggregate_pod_target| (pod_target.specs - aggregate_pod_target.specs).empty? }
|
303
|
+
pod_target.name
|
304
|
+
end
|
305
|
+
end
|
306
|
+
embedded_pod_targets_by_build_config[configuration_name] = embedded_pod_targets
|
296
307
|
end
|
297
308
|
end
|
309
|
+
embedded_pod_targets_by_build_config
|
298
310
|
end
|
299
311
|
|
300
312
|
# Raises an error if there are embedded targets in the Podfile, but
|
@@ -384,13 +396,22 @@ module Pod
|
|
384
396
|
# mapping of targets to resolved specs (containing information about test usage)
|
385
397
|
# aggregate targets
|
386
398
|
#
|
399
|
+
# @param [Array<TargetInspection>] target_inspections
|
400
|
+
# the user target inspections used to construct the aggregate and pod targets.
|
401
|
+
#
|
387
402
|
# @return [Array<AggregateTarget>] the list of aggregate targets generated.
|
388
403
|
#
|
389
|
-
def generate_targets(resolver_specs_by_target)
|
404
|
+
def generate_targets(resolver_specs_by_target, target_inspections)
|
390
405
|
resolver_specs_by_target = resolver_specs_by_target.reject { |td, _| td.abstract? }
|
391
|
-
pod_targets = generate_pod_targets(resolver_specs_by_target)
|
406
|
+
pod_targets = generate_pod_targets(resolver_specs_by_target, target_inspections)
|
392
407
|
aggregate_targets = resolver_specs_by_target.keys.map do |target_definition|
|
393
|
-
generate_target(target_definition, pod_targets, resolver_specs_by_target)
|
408
|
+
generate_target(target_definition, target_inspections, pod_targets, resolver_specs_by_target)
|
409
|
+
end
|
410
|
+
aggregate_targets.each do |target|
|
411
|
+
search_paths_aggregate_targets = aggregate_targets.select do |aggregate_target|
|
412
|
+
target.target_definition.targets_to_inherit_search_paths.include?(aggregate_target.target_definition)
|
413
|
+
end
|
414
|
+
target.search_paths_aggregate_targets.concat(search_paths_aggregate_targets).freeze
|
394
415
|
end
|
395
416
|
if installation_options.integrate_targets?
|
396
417
|
# Copy embedded target pods that cannot have their pods embedded as frameworks to
|
@@ -399,21 +420,20 @@ module Pod
|
|
399
420
|
analyze_host_targets_in_podfile(aggregate_targets, embedded_targets)
|
400
421
|
|
401
422
|
use_frameworks_embedded_targets, non_use_frameworks_embedded_targets = embedded_targets.partition(&:requires_frameworks?)
|
402
|
-
aggregate_targets.
|
423
|
+
aggregate_targets = aggregate_targets.map do |aggregate_target|
|
403
424
|
# For targets that require frameworks, we always have to copy their pods to their
|
404
425
|
# host targets because those frameworks will all be loaded from the host target's bundle
|
405
|
-
|
426
|
+
embedded_pod_targets = embedded_target_pod_targets_by_host(aggregate_target, use_frameworks_embedded_targets, false)
|
406
427
|
|
407
428
|
# For targets that don't require frameworks, we only have to consider library-type
|
408
429
|
# targets because their host targets will still need to link their pods
|
409
|
-
|
430
|
+
embedded_pod_targets.merge!(embedded_target_pod_targets_by_host(aggregate_target, non_use_frameworks_embedded_targets, true))
|
431
|
+
|
432
|
+
next aggregate_target if embedded_pod_targets.empty?
|
433
|
+
aggregate_target.merge_embedded_pod_targets(embedded_pod_targets)
|
410
434
|
end
|
411
435
|
end
|
412
|
-
aggregate_targets
|
413
|
-
target.search_paths_aggregate_targets.concat(aggregate_targets.select do |aggregate_target|
|
414
|
-
target.target_definition.targets_to_inherit_search_paths.include?(aggregate_target.target_definition)
|
415
|
-
end).freeze
|
416
|
-
end
|
436
|
+
aggregate_targets
|
417
437
|
end
|
418
438
|
|
419
439
|
# Setup the aggregate target for a single user target
|
@@ -421,6 +441,9 @@ module Pod
|
|
421
441
|
# @param [TargetDefinition] target_definition
|
422
442
|
# the target definition for the user target.
|
423
443
|
#
|
444
|
+
# @param [Hash{TargetDefinition => TargetInspectionResult}] target_inspections
|
445
|
+
# the user target inspections used to construct the aggregate and pod targets.
|
446
|
+
#
|
424
447
|
# @param [Array<PodTarget>] pod_targets
|
425
448
|
# the pod targets, which were generated.
|
426
449
|
#
|
@@ -429,30 +452,44 @@ module Pod
|
|
429
452
|
#
|
430
453
|
# @return [AggregateTarget]
|
431
454
|
#
|
432
|
-
def generate_target(target_definition, pod_targets, resolver_specs_by_target)
|
433
|
-
target = AggregateTarget.new(target_definition, sandbox)
|
434
|
-
target.host_requires_frameworks |= target_definition.uses_frameworks?
|
435
|
-
|
455
|
+
def generate_target(target_definition, target_inspections, pod_targets, resolver_specs_by_target)
|
436
456
|
if installation_options.integrate_targets?
|
437
|
-
target_inspection =
|
457
|
+
target_inspection = target_inspections[target_definition]
|
438
458
|
raise "missing inspection: #{target_definition.name}" unless target_inspection
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
459
|
+
target_requires_64_bit = Analyzer.requires_64_bit_archs?(target_definition.platform, target_inspection.project.object_version)
|
460
|
+
user_project = target_inspection.project
|
461
|
+
client_root = target_inspection.client_root
|
462
|
+
user_target_uuids = target_inspection.project_target_uuids
|
463
|
+
user_build_configurations = target_inspection.build_configurations
|
464
|
+
archs = target_requires_64_bit ? ['$(ARCHS_STANDARD_64_BIT)'] : target_inspection.archs
|
444
465
|
else
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
466
|
+
target_requires_64_bit = Analyzer.requires_64_bit_archs?(target_definition.platform, nil)
|
467
|
+
user_project = nil
|
468
|
+
client_root = config.installation_root.realpath
|
469
|
+
user_target_uuids = []
|
470
|
+
user_build_configurations = target_definition.build_configurations || Target::DEFAULT_BUILD_CONFIGURATIONS
|
471
|
+
archs = target_requires_64_bit ? ['$(ARCHS_STANDARD_64_BIT)'] : []
|
451
472
|
end
|
473
|
+
platform = target_definition.platform
|
474
|
+
build_configurations = user_build_configurations.keys.concat(target_definition.all_whitelisted_configurations).uniq
|
475
|
+
pod_targets_for_build_configuration = filter_pod_targets_for_target_definition(target_definition, pod_targets,
|
476
|
+
resolver_specs_by_target,
|
477
|
+
build_configurations)
|
478
|
+
AggregateTarget.new(sandbox, target_definition.uses_frameworks?, user_build_configurations, archs, platform,
|
479
|
+
target_definition, client_root, user_project, user_target_uuids,
|
480
|
+
pod_targets_for_build_configuration)
|
481
|
+
end
|
452
482
|
|
453
|
-
|
454
|
-
|
455
|
-
|
483
|
+
# @return [Array<PodTarget>] The model representations of pod targets.
|
484
|
+
#
|
485
|
+
def calculate_pod_targets(aggregate_targets)
|
486
|
+
aggregate_target_pod_targets = aggregate_targets.flat_map(&:pod_targets).uniq
|
487
|
+
test_dependent_targets = aggregate_target_pod_targets.flat_map do |pod_target|
|
488
|
+
pod_target.test_specs.flat_map do |test_spec|
|
489
|
+
pod_target.recursive_test_dependent_targets(test_spec)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
(aggregate_target_pod_targets + test_dependent_targets).uniq
|
456
493
|
end
|
457
494
|
|
458
495
|
# Returns a filtered list of pod targets that should or should not be part of the target definition. Pod targets
|
@@ -467,14 +504,48 @@ module Pod
|
|
467
504
|
# @param [Hash{Podfile::TargetDefinition => Array<ResolvedSpecification>}] resolver_specs_by_target
|
468
505
|
# the resolved specifications grouped by target.
|
469
506
|
#
|
470
|
-
# @
|
507
|
+
# @param [Array<String>] build_configurations
|
508
|
+
# The list of all build configurations the targets will be built for.
|
471
509
|
#
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
510
|
+
# @return [Hash<String => Array<PodTarget>>]
|
511
|
+
# the filtered list of pod targets, grouped by build configuration.
|
512
|
+
#
|
513
|
+
def filter_pod_targets_for_target_definition(target_definition, pod_targets, resolver_specs_by_target, build_configurations)
|
514
|
+
pod_targets_by_build_config = Hash.new([].freeze)
|
515
|
+
build_configurations.each { |config| pod_targets_by_build_config[config] = [] }
|
516
|
+
|
517
|
+
pod_targets.each do |pod_target|
|
518
|
+
next unless pod_target.target_definitions.include?(target_definition)
|
519
|
+
next unless resolver_specs_by_target[target_definition].any? do |resolver_spec|
|
520
|
+
!resolver_spec.used_by_tests_only? && pod_target.specs.include?(resolver_spec.spec)
|
521
|
+
end
|
522
|
+
|
523
|
+
pod_name = pod_target.pod_name
|
524
|
+
|
525
|
+
dependencies = @podfile_dependency_cache.target_definition_dependencies(target_definition).select do |dependency|
|
526
|
+
Specification.root_name(dependency.name) == pod_name
|
527
|
+
end
|
528
|
+
|
529
|
+
build_configurations.each do |configuration_name|
|
530
|
+
whitelists = dependencies.map do |dependency|
|
531
|
+
target_definition.pod_whitelisted_for_configuration?(dependency.name, configuration_name)
|
532
|
+
end.uniq
|
533
|
+
|
534
|
+
case whitelists
|
535
|
+
when [], [true] then nil
|
536
|
+
when [false] then next
|
537
|
+
else
|
538
|
+
raise Informative, "The subspecs of `#{pod_name}` are linked to " \
|
539
|
+
"different build configurations for the `#{target_definition}` " \
|
540
|
+
'target. CocoaPods does not currently support subspecs across ' \
|
541
|
+
'different build configurations.'
|
542
|
+
end
|
543
|
+
|
544
|
+
pod_targets_by_build_config[configuration_name] << pod_target
|
545
|
+
end
|
477
546
|
end
|
547
|
+
|
548
|
+
pod_targets_by_build_config
|
478
549
|
end
|
479
550
|
|
480
551
|
# Setup the pod targets for an aggregate target. Deduplicates resulting
|
@@ -484,9 +555,12 @@ module Pod
|
|
484
555
|
# @param [Hash{Podfile::TargetDefinition => Array<ResolvedSpecification>}] resolver_specs_by_target
|
485
556
|
# the resolved specifications grouped by target.
|
486
557
|
#
|
558
|
+
# @param [Hash{TargetDefinition => TargetInspectionResult}] target_inspections
|
559
|
+
# the user target inspections used to construct the aggregate and pod targets.
|
560
|
+
#
|
487
561
|
# @return [Array<PodTarget>]
|
488
562
|
#
|
489
|
-
def generate_pod_targets(resolver_specs_by_target)
|
563
|
+
def generate_pod_targets(resolver_specs_by_target, target_inspections)
|
490
564
|
if installation_options.deduplicate_targets?
|
491
565
|
distinct_targets = resolver_specs_by_target.each_with_object({}) do |dependency, hash|
|
492
566
|
target_definition, dependent_specs = *dependency
|
@@ -503,7 +577,7 @@ module Pod
|
|
503
577
|
pod_targets = distinct_targets.flat_map do |_root, target_definitions_by_variant|
|
504
578
|
suffixes = PodVariantSet.new(target_definitions_by_variant.keys).scope_suffixes
|
505
579
|
target_definitions_by_variant.flat_map do |variant, target_definitions|
|
506
|
-
generate_pod_target(target_definitions, variant.specs + variant.test_specs, :scope_suffix => suffixes[variant])
|
580
|
+
generate_pod_target(target_definitions, target_inspections, variant.specs + variant.test_specs, :scope_suffix => suffixes[variant])
|
507
581
|
end
|
508
582
|
end
|
509
583
|
|
@@ -514,28 +588,32 @@ module Pod
|
|
514
588
|
hash[name] = values.sort_by { |pt| pt.specs.count }
|
515
589
|
end
|
516
590
|
pod_targets.each do |target|
|
517
|
-
all_specs = all_resolver_specs.
|
518
|
-
dependencies =
|
519
|
-
test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs).group_by(&:root)
|
520
|
-
test_dependencies.delete_if { |k| dependencies.key? k }
|
591
|
+
all_specs = all_resolver_specs.group_by(&:name)
|
592
|
+
dependencies = dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
|
521
593
|
target.dependent_targets = filter_dependencies(dependencies, pod_targets_by_name, target)
|
522
|
-
target.
|
594
|
+
target.test_dependent_targets_by_spec_name = target.test_specs.each_with_object({}) do |test_spec, hash|
|
595
|
+
test_dependencies = dependencies_for_specs([test_spec], target.platform, all_specs).group_by(&:root)
|
596
|
+
test_dependencies.delete_if { |k| dependencies.key? k }
|
597
|
+
hash[test_spec.name] = filter_dependencies(test_dependencies, pod_targets_by_name, target)
|
598
|
+
end
|
523
599
|
end
|
524
600
|
else
|
525
601
|
dedupe_cache = {}
|
526
602
|
resolver_specs_by_target.flat_map do |target_definition, specs|
|
527
603
|
grouped_specs = specs.group_by(&:root).values.uniq
|
528
604
|
pod_targets = grouped_specs.flat_map do |pod_specs|
|
529
|
-
generate_pod_target([target_definition], pod_specs.map(&:spec)).scoped(dedupe_cache)
|
605
|
+
generate_pod_target([target_definition], target_inspections, pod_specs.map(&:spec)).scoped(dedupe_cache)
|
530
606
|
end
|
531
607
|
|
532
608
|
pod_targets.each do |target|
|
533
|
-
all_specs = specs.map(&:spec).
|
534
|
-
dependencies =
|
535
|
-
test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs).group_by(&:root)
|
536
|
-
test_dependencies.delete_if { |k| dependencies.key? k }
|
609
|
+
all_specs = specs.map(&:spec).group_by(&:name)
|
610
|
+
dependencies = dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
|
537
611
|
target.dependent_targets = pod_targets.reject { |t| dependencies[t.root_spec].nil? }
|
538
|
-
target.
|
612
|
+
target.test_dependent_targets_by_spec_name = target.test_specs.each_with_object({}) do |test_spec, hash|
|
613
|
+
test_dependencies = dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
|
614
|
+
test_dependencies.delete_if { |k| dependencies.key? k }
|
615
|
+
hash[test_spec.name] = pod_targets.reject { |t| test_dependencies[t.root_spec].nil? }
|
616
|
+
end
|
539
617
|
end
|
540
618
|
end
|
541
619
|
end
|
@@ -552,7 +630,7 @@ module Pod
|
|
552
630
|
end
|
553
631
|
end
|
554
632
|
|
555
|
-
# Returns the specs upon which the given specs
|
633
|
+
# Returns the specs upon which the given specs _directly_ depend.
|
556
634
|
#
|
557
635
|
# @note: This is implemented in the analyzer, because we don't have to
|
558
636
|
# care about the requirements after dependency resolution.
|
@@ -563,37 +641,36 @@ module Pod
|
|
563
641
|
# @param [Platform] platform
|
564
642
|
# The platform for which the dependencies should be returned.
|
565
643
|
#
|
566
|
-
# @param [
|
644
|
+
# @param [Hash<String, Specification>] all_specs
|
567
645
|
# All specifications which are installed alongside.
|
568
646
|
#
|
569
647
|
# @return [Array<Specification>]
|
570
648
|
#
|
571
|
-
def
|
649
|
+
def dependencies_for_specs(specs, platform, all_specs)
|
572
650
|
return [] if specs.empty? || all_specs.empty?
|
573
651
|
|
574
652
|
dependent_specs = Set.new
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
true
|
653
|
+
|
654
|
+
specs.each do |s|
|
655
|
+
s.dependencies(platform).each do |dep|
|
656
|
+
all_specs[dep.name].each do |spec|
|
657
|
+
dependent_specs << spec
|
581
658
|
end
|
582
|
-
dependent_specs << match if match
|
583
659
|
end
|
584
660
|
end
|
585
661
|
|
586
|
-
|
587
|
-
|
588
|
-
dependent_specs.union transitive_dependencies_for_specs(dependent_specs, platform, remaining_specs)
|
662
|
+
dependent_specs - specs
|
589
663
|
end
|
590
664
|
|
591
665
|
# Create a target for each spec group
|
592
666
|
#
|
593
|
-
# @param [
|
594
|
-
# the aggregate target
|
667
|
+
# @param [Array<TargetDefinition>] target_definitions
|
668
|
+
# the target definitions of the aggregate target
|
595
669
|
#
|
596
|
-
# @param [
|
670
|
+
# @param [Hash{TargetDefinition => TargetInspectionResult}] target_inspections
|
671
|
+
# the user target inspections used to construct the aggregate and pod targets.
|
672
|
+
#
|
673
|
+
# @param [Array<Specification>] specs
|
597
674
|
# the specifications of an equal root.
|
598
675
|
#
|
599
676
|
# @param [String] scope_suffix
|
@@ -601,22 +678,71 @@ module Pod
|
|
601
678
|
#
|
602
679
|
# @return [PodTarget]
|
603
680
|
#
|
604
|
-
def generate_pod_target(target_definitions,
|
605
|
-
|
606
|
-
|
607
|
-
|
681
|
+
def generate_pod_target(target_definitions, target_inspections, specs, scope_suffix: nil)
|
682
|
+
object_version = target_inspections.values.map { |ti| ti.project.object_version }.min
|
683
|
+
target_requires_64_bit = target_definitions.all? { |td| Analyzer.requires_64_bit_archs?(td.platform, object_version) }
|
608
684
|
if installation_options.integrate_targets?
|
609
|
-
target_inspections =
|
610
|
-
|
611
|
-
|
685
|
+
target_inspections = target_inspections.select { |t, _| target_definitions.include?(t) }.values
|
686
|
+
user_build_configurations = target_inspections.map(&:build_configurations).reduce({}, &:merge)
|
687
|
+
archs = if target_requires_64_bit
|
688
|
+
['$(ARCHS_STANDARD_64_BIT)']
|
689
|
+
else
|
690
|
+
target_inspections.flat_map(&:archs).compact.uniq.sort
|
691
|
+
end
|
612
692
|
else
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
693
|
+
user_build_configurations = {}
|
694
|
+
archs = target_requires_64_bit ? ['$(ARCHS_STANDARD_64_BIT)'] : []
|
695
|
+
end
|
696
|
+
host_requires_frameworks = target_definitions.any?(&:uses_frameworks?)
|
697
|
+
platform = determine_platform(specs, target_definitions, host_requires_frameworks)
|
698
|
+
file_accessors = create_file_accessors(specs, platform)
|
699
|
+
PodTarget.new(sandbox, host_requires_frameworks, user_build_configurations, archs, platform, specs,
|
700
|
+
target_definitions, file_accessors, scope_suffix)
|
701
|
+
end
|
702
|
+
|
703
|
+
# Creates the file accessors for a given pod.
|
704
|
+
#
|
705
|
+
# @param [Array<Specification>] specs
|
706
|
+
# the specs to map each file accessor to.
|
707
|
+
#
|
708
|
+
# @param [Platform] platform
|
709
|
+
# the platform to use when generating each file accessor.
|
710
|
+
#
|
711
|
+
# @return [Array<FileAccessor>]
|
712
|
+
#
|
713
|
+
def create_file_accessors(specs, platform)
|
714
|
+
name = specs.first.name
|
715
|
+
pod_root = sandbox.pod_dir(name)
|
716
|
+
path_list = Sandbox::PathList.new(pod_root)
|
717
|
+
specs.map do |spec|
|
718
|
+
Sandbox::FileAccessor.new(path_list, spec.consumer(platform))
|
617
719
|
end
|
720
|
+
end
|
618
721
|
|
619
|
-
|
722
|
+
# Calculates and returns the platform to use for the given list of specs and target definitions.
|
723
|
+
#
|
724
|
+
# @param [Array<Specification>] specs
|
725
|
+
# the specs to inspect and calculate the platform for.
|
726
|
+
#
|
727
|
+
# @param [Array<TargetDefinition>] target_definitions
|
728
|
+
# the target definitions these specs are part of.
|
729
|
+
#
|
730
|
+
# @param [Boolean] host_requires_frameworks
|
731
|
+
# whether the platform is calculated for a target that needs to be packaged as a framework.
|
732
|
+
#
|
733
|
+
# @return [Platform]
|
734
|
+
#
|
735
|
+
def determine_platform(specs, target_definitions, host_requires_frameworks)
|
736
|
+
platform_name = target_definitions.first.platform.name
|
737
|
+
default = Podfile::TargetDefinition::PLATFORM_DEFAULTS[platform_name]
|
738
|
+
deployment_target = specs.map do |spec|
|
739
|
+
Version.new(spec.deployment_target(platform_name) || default)
|
740
|
+
end.max
|
741
|
+
if platform_name == :ios && host_requires_frameworks
|
742
|
+
minimum = Version.new('8.0')
|
743
|
+
deployment_target = [deployment_target, minimum].max
|
744
|
+
end
|
745
|
+
Platform.new(platform_name, deployment_target)
|
620
746
|
end
|
621
747
|
|
622
748
|
# Generates dependencies that require the specific version of the Pods
|
@@ -626,21 +752,25 @@ module Pod
|
|
626
752
|
# is in update mode, to prevent it from upgrading the Pods that weren't
|
627
753
|
# changed in the {Podfile}.
|
628
754
|
#
|
755
|
+
# @param [SpecState] podfile_state
|
756
|
+
# the state of the podfile for which dependencies have or have not changed, added, deleted or updated.
|
757
|
+
#
|
629
758
|
# @return [Molinillo::DependencyGraph<Dependency>] the dependencies
|
630
759
|
# generated by the lockfile that prevent the resolver to update
|
631
760
|
# a Pod.
|
632
761
|
#
|
633
|
-
def generate_version_locking_dependencies
|
762
|
+
def generate_version_locking_dependencies(podfile_state)
|
634
763
|
if update_mode == :all || !lockfile
|
635
764
|
LockingDependencyAnalyzer.unlocked_dependency_graph
|
636
765
|
else
|
637
|
-
|
638
|
-
|
639
|
-
local_pod_names =
|
640
|
-
pods_to_unlock = local_pod_names.
|
641
|
-
sandbox.specification(pod_name)
|
766
|
+
deleted_and_changed = podfile_state.changed + podfile_state.deleted
|
767
|
+
deleted_and_changed += pods_to_update[:pods] if update_mode == :selected
|
768
|
+
local_pod_names = podfile_dependencies.select(&:local?).map(&:root_name)
|
769
|
+
pods_to_unlock = local_pod_names.to_set.delete_if do |pod_name|
|
770
|
+
next unless sandbox_specification = sandbox.specification(pod_name)
|
771
|
+
sandbox_specification.checksum == lockfile.checksum(pod_name)
|
642
772
|
end
|
643
|
-
LockingDependencyAnalyzer.generate_version_locking_dependencies(lockfile,
|
773
|
+
LockingDependencyAnalyzer.generate_version_locking_dependencies(lockfile, deleted_and_changed, pods_to_unlock)
|
644
774
|
end
|
645
775
|
end
|
646
776
|
|
@@ -659,25 +789,25 @@ module Pod
|
|
659
789
|
# compatible with the version reported by the podspec of the
|
660
790
|
# external source the resolver will raise.
|
661
791
|
#
|
662
|
-
# @
|
792
|
+
# @param [SpecState] podfile_state
|
793
|
+
# the state of the podfile for which dependencies have or have not changed, added, deleted or updated.
|
663
794
|
#
|
664
|
-
#
|
795
|
+
# @return [void]
|
665
796
|
#
|
666
|
-
def fetch_external_sources
|
667
|
-
return unless allow_pre_downloads?
|
668
|
-
|
797
|
+
def fetch_external_sources(podfile_state)
|
669
798
|
verify_no_pods_with_different_sources!
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
799
|
+
deps = dependencies_to_fetch(podfile_state)
|
800
|
+
pods = pods_to_fetch(podfile_state)
|
801
|
+
return if deps.empty?
|
802
|
+
UI.section 'Fetching external sources' do
|
803
|
+
deps.sort.each do |dependency|
|
804
|
+
fetch_external_source(dependency, !pods.include?(dependency.root_name))
|
675
805
|
end
|
676
806
|
end
|
677
807
|
end
|
678
808
|
|
679
809
|
def verify_no_pods_with_different_sources!
|
680
|
-
deps_with_different_sources =
|
810
|
+
deps_with_different_sources = podfile_dependencies.group_by(&:root_name).
|
681
811
|
select { |_root_name, dependencies| dependencies.map(&:external_source).uniq.count > 1 }
|
682
812
|
deps_with_different_sources.each do |root_name, dependencies|
|
683
813
|
raise Informative, 'There are multiple dependencies with different ' \
|
@@ -687,28 +817,26 @@ module Pod
|
|
687
817
|
end
|
688
818
|
|
689
819
|
def fetch_external_source(dependency, use_lockfile_options)
|
690
|
-
checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
|
691
|
-
|
692
|
-
ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file)
|
820
|
+
source = if use_lockfile_options && lockfile && checkout_options = lockfile.checkout_options_for_pod_named(dependency.root_name)
|
821
|
+
ExternalSources.from_params(checkout_options, dependency, podfile.defined_in_file, installation_options.clean?)
|
693
822
|
else
|
694
|
-
ExternalSources.from_dependency(dependency, podfile.defined_in_file)
|
695
|
-
|
696
|
-
source.can_cache = installation_options.clean?
|
823
|
+
ExternalSources.from_dependency(dependency, podfile.defined_in_file, installation_options.clean?)
|
824
|
+
end
|
697
825
|
source.fetch(sandbox)
|
698
826
|
end
|
699
827
|
|
700
|
-
def dependencies_to_fetch
|
828
|
+
def dependencies_to_fetch(podfile_state)
|
701
829
|
@deps_to_fetch ||= begin
|
702
830
|
deps_to_fetch = []
|
703
|
-
deps_with_external_source =
|
831
|
+
deps_with_external_source = podfile_dependencies.select(&:external_source)
|
704
832
|
|
705
833
|
if update_mode == :all
|
706
834
|
deps_to_fetch = deps_with_external_source
|
707
835
|
else
|
708
|
-
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) }
|
709
|
-
deps_to_fetch_if_needed = deps_with_external_source.select { |dep|
|
836
|
+
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch(podfile_state).include?(dep.root_name) }
|
837
|
+
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| podfile_state.unchanged.include?(dep.root_name) }
|
710
838
|
deps_to_fetch += deps_to_fetch_if_needed.select do |dep|
|
711
|
-
sandbox.
|
839
|
+
sandbox.specification_path(dep.root_name).nil? ||
|
712
840
|
!dep.external_source[:path].nil? ||
|
713
841
|
!sandbox.pod_dir(dep.root_name).directory? ||
|
714
842
|
checkout_requires_update?(dep)
|
@@ -725,15 +853,15 @@ module Pod
|
|
725
853
|
locked_checkout_options != sandbox_checkout_options
|
726
854
|
end
|
727
855
|
|
728
|
-
def pods_to_fetch
|
856
|
+
def pods_to_fetch(podfile_state)
|
729
857
|
@pods_to_fetch ||= begin
|
730
|
-
pods_to_fetch =
|
858
|
+
pods_to_fetch = podfile_state.added + podfile_state.changed
|
731
859
|
if update_mode == :selected
|
732
|
-
pods_to_fetch +=
|
860
|
+
pods_to_fetch += pods_to_update[:pods]
|
733
861
|
elsif update_mode == :all
|
734
|
-
pods_to_fetch +=
|
862
|
+
pods_to_fetch += podfile_state.unchanged + podfile_state.deleted
|
735
863
|
end
|
736
|
-
pods_to_fetch +=
|
864
|
+
pods_to_fetch += podfile_dependencies.
|
737
865
|
select { |dep| Hash(dep.external_source).key?(:podspec) && sandbox.specification_path(dep.root_name).nil? }.
|
738
866
|
map(&:root_name)
|
739
867
|
pods_to_fetch
|
@@ -741,7 +869,7 @@ module Pod
|
|
741
869
|
end
|
742
870
|
|
743
871
|
def store_existing_checkout_options
|
744
|
-
|
872
|
+
podfile_dependencies.select(&:external_source).each do |dep|
|
745
873
|
if checkout_options = lockfile && lockfile.checkout_options_for_pod_named(dep.root_name)
|
746
874
|
sandbox.store_checkout_source(dep.root_name, checkout_options)
|
747
875
|
end
|
@@ -767,8 +895,8 @@ module Pod
|
|
767
895
|
# @return [Hash{TargetDefinition => Array<Spec>}] the specifications
|
768
896
|
# grouped by target.
|
769
897
|
#
|
770
|
-
def resolve_dependencies
|
771
|
-
duplicate_dependencies =
|
898
|
+
def resolve_dependencies(locked_dependencies)
|
899
|
+
duplicate_dependencies = podfile_dependencies.group_by(&:name).
|
772
900
|
select { |_name, dependencies| dependencies.count > 1 }
|
773
901
|
duplicate_dependencies.each do |name, dependencies|
|
774
902
|
UI.warn "There are duplicate dependencies on `#{name}` in #{UI.path podfile.defined_in_file}:\n\n" \
|
@@ -777,7 +905,7 @@ module Pod
|
|
777
905
|
|
778
906
|
resolver_specs_by_target = nil
|
779
907
|
UI.section "Resolving dependencies of #{UI.path(podfile.defined_in_file) || 'Podfile'}" do
|
780
|
-
resolver = Resolver.new(sandbox, podfile, locked_dependencies, sources, specs_updated
|
908
|
+
resolver = Pod::Resolver.new(sandbox, podfile, locked_dependencies, sources, @specs_updated)
|
781
909
|
resolver_specs_by_target = resolver.resolve
|
782
910
|
resolver_specs_by_target.values.flatten(1).map(&:spec).each(&:validate_cocoapods_version)
|
783
911
|
end
|
@@ -787,7 +915,7 @@ module Pod
|
|
787
915
|
# Warns for any specification that is incompatible with its target.
|
788
916
|
#
|
789
917
|
# @param [Hash{TargetDefinition => Array<Spec>}] resolver_specs_by_target
|
790
|
-
# the specifications grouped by target.
|
918
|
+
# the resolved specifications grouped by target.
|
791
919
|
#
|
792
920
|
# @return [Hash{TargetDefinition => Array<Spec>}] the specifications
|
793
921
|
# grouped by target.
|
@@ -807,6 +935,9 @@ module Pod
|
|
807
935
|
|
808
936
|
# Returns the list of all the resolved specifications.
|
809
937
|
#
|
938
|
+
# @param [Hash{TargetDefinition => Array<Spec>}] resolver_specs_by_target
|
939
|
+
# the resolved specifications grouped by target.
|
940
|
+
#
|
810
941
|
# @return [Array<Specification>] the list of the specifications.
|
811
942
|
#
|
812
943
|
def generate_specifications(resolver_specs_by_target)
|
@@ -819,70 +950,46 @@ module Pod
|
|
819
950
|
# @return [SpecsState] the representation of the state of the manifest
|
820
951
|
# specifications.
|
821
952
|
#
|
822
|
-
def generate_sandbox_state
|
953
|
+
def generate_sandbox_state(specifications)
|
823
954
|
sandbox_state = nil
|
824
955
|
UI.section 'Comparing resolved specification to the sandbox manifest' do
|
825
|
-
sandbox_analyzer = SandboxAnalyzer.new(sandbox,
|
956
|
+
sandbox_analyzer = SandboxAnalyzer.new(sandbox, specifications, update_mode?)
|
826
957
|
sandbox_state = sandbox_analyzer.analyze
|
827
958
|
sandbox_state.print
|
828
959
|
end
|
829
960
|
sandbox_state
|
830
961
|
end
|
831
962
|
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
@sources ||= begin
|
857
|
-
sources = podfile.sources
|
858
|
-
plugin_sources = @plugin_sources || []
|
859
|
-
|
860
|
-
# Add any sources specified using the :source flag on individual dependencies.
|
861
|
-
dependency_sources = @podfile_dependency_cache.podfile_dependencies.map(&:podspec_repo).compact
|
862
|
-
all_dependencies_have_sources = dependency_sources.count == @podfile_dependency_cache.podfile_dependencies.count
|
863
|
-
|
864
|
-
if all_dependencies_have_sources
|
865
|
-
sources = dependency_sources
|
866
|
-
elsif has_dependencies? && sources.empty? && plugin_sources.empty?
|
867
|
-
sources = ['https://github.com/CocoaPods/Specs.git']
|
868
|
-
else
|
869
|
-
sources += dependency_sources
|
870
|
-
end
|
871
|
-
|
872
|
-
result = sources.uniq.map do |source_url|
|
873
|
-
config.sources_manager.find_or_create_source_with_url(source_url)
|
874
|
-
end
|
875
|
-
unless plugin_sources.empty?
|
876
|
-
result.insert(0, *plugin_sources)
|
963
|
+
class << self
|
964
|
+
# @param [Platform] platform
|
965
|
+
# The platform to build against
|
966
|
+
#
|
967
|
+
# @param [String, Nil] object_version
|
968
|
+
# The user project's object version, or nil if not available
|
969
|
+
#
|
970
|
+
# @return [Boolean] Whether the platform requires 64-bit architectures
|
971
|
+
#
|
972
|
+
def requires_64_bit_archs?(platform, object_version)
|
973
|
+
return false unless platform
|
974
|
+
case platform.name
|
975
|
+
when :osx
|
976
|
+
true
|
977
|
+
when :ios
|
978
|
+
if (version = object_version)
|
979
|
+
platform.deployment_target >= IOS_64_BIT_ONLY_VERSION && version.to_i < IOS_64_BIT_ONLY_PROJECT_VERSION
|
980
|
+
else
|
981
|
+
platform.deployment_target >= IOS_64_BIT_ONLY_VERSION
|
982
|
+
end
|
983
|
+
when :watchos
|
984
|
+
false
|
985
|
+
when :tvos
|
986
|
+
false
|
877
987
|
end
|
878
|
-
result
|
879
988
|
end
|
880
989
|
end
|
881
990
|
|
882
991
|
#-----------------------------------------------------------------------#
|
883
992
|
|
884
|
-
private
|
885
|
-
|
886
993
|
# @!group Analysis sub-steps
|
887
994
|
|
888
995
|
# Checks whether the platform is specified if not integrating
|