cocoapods 1.5.3 → 1.6.0.beta.1

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