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.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +365 -1
  3. data/bin/pod +1 -1
  4. data/lib/cocoapods/command/cache/clean.rb +1 -1
  5. data/lib/cocoapods/command/init.rb +4 -2
  6. data/lib/cocoapods/command/install.rb +7 -0
  7. data/lib/cocoapods/command/lib/lint.rb +8 -1
  8. data/lib/cocoapods/command/outdated.rb +4 -9
  9. data/lib/cocoapods/command/repo/add.rb +1 -1
  10. data/lib/cocoapods/command/repo/list.rb +1 -1
  11. data/lib/cocoapods/command/repo/push.rb +17 -12
  12. data/lib/cocoapods/command/repo/remove.rb +1 -1
  13. data/lib/cocoapods/command/repo/update.rb +1 -1
  14. data/lib/cocoapods/command/setup.rb +1 -1
  15. data/lib/cocoapods/command/spec/create.rb +39 -39
  16. data/lib/cocoapods/command/spec/lint.rb +8 -1
  17. data/lib/cocoapods/command.rb +3 -1
  18. data/lib/cocoapods/config.rb +13 -2
  19. data/lib/cocoapods/downloader/cache.rb +1 -1
  20. data/lib/cocoapods/executable.rb +3 -3
  21. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  22. data/lib/cocoapods/external_sources.rb +7 -4
  23. data/lib/cocoapods/gem_version.rb +1 -1
  24. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  25. data/lib/cocoapods/generator/acknowledgements/plist.rb +13 -2
  26. data/lib/cocoapods/generator/app_target_helper.rb +141 -17
  27. data/lib/cocoapods/generator/copy_resources_script.rb +14 -3
  28. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  29. data/lib/cocoapods/generator/embed_frameworks_script.rb +37 -20
  30. data/lib/cocoapods/generator/header.rb +1 -1
  31. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  32. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  33. data/lib/cocoapods/hooks_manager.rb +28 -17
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +14 -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 +27 -14
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/analyzer.rb +391 -284
  42. data/lib/cocoapods/installer/installation_options.rb +2 -0
  43. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  44. data/lib/cocoapods/installer/post_install_hooks_context.rb +72 -47
  45. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  46. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +69 -29
  49. data/lib/cocoapods/installer/user_project_integrator.rb +6 -4
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +104 -0
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +23 -50
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +296 -177
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +51 -33
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +62 -69
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +130 -122
  59. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  60. data/lib/cocoapods/installer.rb +140 -63
  61. data/lib/cocoapods/project.rb +16 -14
  62. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  63. data/lib/cocoapods/resolver.rb +79 -98
  64. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  65. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  66. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  67. data/lib/cocoapods/sandbox.rb +31 -43
  68. data/lib/cocoapods/sources_manager.rb +1 -1
  69. data/lib/cocoapods/target/aggregate_target.rb +143 -85
  70. data/lib/cocoapods/target/build_settings.rb +1124 -0
  71. data/lib/cocoapods/target/framework_paths.rb +36 -0
  72. data/lib/cocoapods/target/pod_target.rb +198 -295
  73. data/lib/cocoapods/target.rb +92 -37
  74. data/lib/cocoapods/user_interface.rb +5 -0
  75. data/lib/cocoapods/validator.rb +149 -44
  76. data/lib/cocoapods.rb +0 -1
  77. metadata +31 -23
  78. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  79. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  80. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
  81. data/lib/cocoapods/generator/xcconfig.rb +0 -13
@@ -61,17 +61,18 @@ module Pod
61
61
 
62
62
  # Initialize a new instance
63
63
  #
64
- # @param [Sandbox] sandbox @see sandbox
65
- # @param [Podfile] podfile @see podfile
66
- # @param [Lockfile] lockfile @see lockfile
64
+ # @param [Sandbox] sandbox @see #sandbox
65
+ # @param [Podfile] podfile @see #podfile
66
+ # @param [Lockfile] lockfile @see #lockfile
67
67
  #
68
68
  def initialize(sandbox, podfile, lockfile = nil)
69
- @sandbox = sandbox
70
- @podfile = podfile
69
+ @sandbox = sandbox || raise(ArgumentError, 'Missing required argument `sandbox`')
70
+ @podfile = podfile || raise(ArgumentError, 'Missing required argument `podfile`')
71
71
  @lockfile = lockfile
72
72
 
73
73
  @use_default_plugins = true
74
74
  @has_dependencies = true
75
+ @pod_installers = []
75
76
  end
76
77
 
77
78
  # @return [Hash, Boolean, nil] Pods that have been requested to be
@@ -97,6 +98,25 @@ module Pod
97
98
  attr_accessor :use_default_plugins
98
99
  alias_method :use_default_plugins?, :use_default_plugins
99
100
 
101
+ # @return [Boolean] Whether installation should verify that there are no
102
+ # Podfile or Lockfile changes. Defaults to false.
103
+ #
104
+ attr_accessor :deployment
105
+ alias_method :deployment?, :deployment
106
+
107
+ #-------------------------------------------------------------------------#
108
+
109
+ private
110
+
111
+ # @return [Array<PodSourceInstaller>] the pod installers created
112
+ # while installing pod targets
113
+ #
114
+ attr_reader :pod_installers
115
+
116
+ #-------------------------------------------------------------------------#
117
+
118
+ public
119
+
100
120
  # Installs the Pods.
101
121
  #
102
122
  # The installation process is mostly linear with a few minor complications
@@ -155,12 +175,17 @@ module Pod
155
175
  validate_build_configurations
156
176
  clean_sandbox
157
177
  end
178
+
179
+ UI.section 'Verifying no changes' do
180
+ verify_no_podfile_changes!
181
+ verify_no_lockfile_changes!
182
+ end if deployment?
183
+
158
184
  analyzer
159
185
  end
160
186
 
161
187
  def download_dependencies
162
188
  UI.section 'Downloading dependencies' do
163
- create_file_accessors
164
189
  install_pod_sources
165
190
  run_podfile_pre_install_hooks
166
191
  clean_pod_sources
@@ -174,14 +199,14 @@ module Pod
174
199
  private
175
200
 
176
201
  def create_generator
177
- Xcode::PodsProjectGenerator.new(aggregate_targets, sandbox, pod_targets, analysis_result, installation_options, config)
202
+ Xcode::PodsProjectGenerator.new(sandbox, aggregate_targets, pod_targets, analysis_result, installation_options, config)
178
203
  end
179
204
 
180
205
  # Generate the 'Pods/Pods.xcodeproj' project.
181
206
  #
182
207
  def generate_pods_project(generator = create_generator)
183
208
  UI.section 'Generating Pods project' do
184
- generator.generate!
209
+ @target_installation_results = generator.generate!
185
210
  @pods_project = generator.project
186
211
  run_podfile_post_install_hooks
187
212
  generator.write
@@ -201,13 +226,14 @@ module Pod
201
226
  #
202
227
  attr_reader :analysis_result
203
228
 
204
- # @return [Pod::Project] the `Pods/Pods.xcodeproj` project.
229
+ # @return [Array<Hash{String, TargetInstallationResult}>] the installation results produced by the pods project
230
+ # generator
205
231
  #
206
- attr_reader :pods_project
232
+ attr_reader :target_installation_results
207
233
 
208
- # @return [Array<String>] The Pods that should be installed.
234
+ # @return [Pod::Project] the `Pods/Pods.xcodeproj` project.
209
235
  #
210
- attr_reader :names_of_pods_to_install
236
+ attr_reader :pods_project
211
237
 
212
238
  # @return [Array<AggregateTarget>] The model representations of an
213
239
  # aggregation of pod targets generated for a target definition
@@ -218,13 +244,9 @@ module Pod
218
244
  # @return [Array<PodTarget>] The model representations of pod targets
219
245
  # generated as result of the analyzer.
220
246
  #
221
- def pod_targets
222
- aggregate_target_pod_targets = aggregate_targets.flat_map(&:pod_targets)
223
- test_dependent_targets = aggregate_target_pod_targets.flat_map(&:test_dependent_targets)
224
- (aggregate_target_pod_targets + test_dependent_targets).uniq
225
- end
247
+ attr_reader :pod_targets
226
248
 
227
- # @return [Array<Specification>] The specifications that where installed.
249
+ # @return [Array<Specification>] The specifications that were installed.
228
250
  #
229
251
  attr_accessor :installed_specs
230
252
 
@@ -236,18 +258,19 @@ module Pod
236
258
 
237
259
  # Performs the analysis.
238
260
  #
261
+ # @param [Analyzer] analyzer the analyzer to use for analysis
262
+ #
239
263
  # @return [void]
240
264
  #
241
265
  def analyze(analyzer = create_analyzer)
242
- analyzer.update = update
243
266
  @analysis_result = analyzer.analyze
244
- @aggregate_targets = analyzer.result.targets
267
+ @aggregate_targets = @analysis_result.targets
268
+ @pod_targets = @analysis_result.pod_targets
245
269
  end
246
270
 
247
271
  def create_analyzer(plugin_sources = nil)
248
- Analyzer.new(sandbox, podfile, lockfile, plugin_sources).tap do |analyzer|
272
+ Analyzer.new(sandbox, podfile, lockfile, plugin_sources, has_dependencies?, update).tap do |analyzer|
249
273
  analyzer.installation_options = installation_options
250
- analyzer.has_dependencies = has_dependencies?
251
274
  end
252
275
  end
253
276
 
@@ -302,11 +325,26 @@ module Pod
302
325
  end
303
326
  end
304
327
 
305
- # @return [void] In this step we create the file accessors for the pod
306
- # targets.
328
+ # @raise [Informative] If there are any Podfile changes
307
329
  #
308
- def create_file_accessors
309
- sandbox.create_file_accessors(pod_targets)
330
+ def verify_no_podfile_changes!
331
+ return unless analysis_result.podfile_needs_install?
332
+
333
+ changed_state = analysis_result.podfile_state.to_s(:states => %i(added deleted changed))
334
+ raise Informative, "There were changes to the podfile in deployment mode:\n#{changed_state}"
335
+ end
336
+
337
+ # @raise [Informative] If there are any Lockfile changes
338
+ #
339
+ def verify_no_lockfile_changes!
340
+ new_lockfile = generate_lockfile
341
+ return if new_lockfile == lockfile
342
+
343
+ diff = Xcodeproj::Differ.hash_diff(lockfile.to_hash, new_lockfile.to_hash, :key_1 => 'Old Lockfile', :key_2 => 'New Lockfile')
344
+ pretty_diff = YAMLHelper.convert_hash(diff, Lockfile::HASH_KEY_ORDER, "\n\n")
345
+ pretty_diff.gsub!(':diff:', 'diff:'.yellow)
346
+
347
+ raise Informative, "There were changes to the lockfile in deployment mode:\n#{pretty_diff}"
310
348
  end
311
349
 
312
350
  # Downloads, installs the documentation and cleans the sources of the Pods
@@ -327,7 +365,7 @@ module Pod
327
365
  current_repo = analysis_result.specs_by_source.detect { |key, values| break key if values.map(&:name).include?(spec.name) }
328
366
  current_repo &&= current_repo.url || current_repo.name
329
367
  previous_spec_repo = sandbox.manifest.spec_repo(spec.name)
330
- has_changed_repo = !previous_spec_repo.nil? && current_repo && (current_repo != previous_spec_repo)
368
+ has_changed_repo = !previous_spec_repo.nil? && current_repo && !current_repo.casecmp(previous_spec_repo).zero?
331
369
  title = "Installing #{spec.name} #{spec.version}"
332
370
  title << " (was #{previous_version} and source changed to `#{current_repo}` from `#{previous_spec_repo}`)" if has_changed_version && has_changed_repo
333
371
  title << " (was #{previous_version})" if has_changed_version && !has_changed_repo
@@ -347,22 +385,36 @@ module Pod
347
385
  end
348
386
 
349
387
  def create_pod_installer(pod_name)
350
- specs_by_platform = {}
351
- pod_targets.each do |pod_target|
352
- if pod_target.root_spec.name == pod_name
353
- specs_by_platform[pod_target.platform] ||= []
354
- specs_by_platform[pod_target.platform].concat(pod_target.specs)
355
- end
388
+ specs_by_platform = specs_for_pod(pod_name)
389
+
390
+ if specs_by_platform.empty?
391
+ requiring_targets = pod_targets.select { |pt| pt.recursive_dependent_targets.any? { |dt| dt.pod_name == pod_name } }
392
+ message = "Could not install '#{pod_name}' pod"
393
+ message += ", dependended upon by #{requiring_targets.to_sentence}" unless requiring_targets.empty?
394
+ message += '. There is either no platform to build for, or no target to build.'
395
+ raise StandardError, message
356
396
  end
357
397
 
358
- raise Informative, "Could not install '#{pod_name}' pod. There is no target that supports it." if specs_by_platform.empty?
359
-
360
- @pod_installers ||= []
361
398
  pod_installer = PodSourceInstaller.new(sandbox, specs_by_platform, :can_cache => installation_options.clean?)
362
- @pod_installers << pod_installer
399
+ pod_installers << pod_installer
363
400
  pod_installer
364
401
  end
365
402
 
403
+ # The specifications matching the specified pod name
404
+ #
405
+ # @param [String] pod_name the name of the pod
406
+ #
407
+ # @return [Hash{Platform => Array<Specification>}] the specifications grouped by platform
408
+ #
409
+ def specs_for_pod(pod_name)
410
+ pod_targets.each_with_object({}) do |pod_target, hash|
411
+ if pod_target.root_spec.name == pod_name
412
+ hash[pod_target.platform] ||= []
413
+ hash[pod_target.platform].concat(pod_target.specs)
414
+ end
415
+ end
416
+ end
417
+
366
418
  # Install the Pods. If the resolver indicated that a Pod should be
367
419
  # installed and it exits, it is removed and then reinstalled. In any case if
368
420
  # the Pod doesn't exits it is installed.
@@ -377,21 +429,16 @@ module Pod
377
429
 
378
430
  # Cleans the sources of the Pods if the config instructs to do so.
379
431
  #
380
- # @todo Why the @pod_installers might be empty?
381
432
  #
382
433
  def clean_pod_sources
383
434
  return unless installation_options.clean?
384
- return unless @pod_installers
385
- @pod_installers.each(&:clean!)
435
+ pod_installers.each(&:clean!)
386
436
  end
387
437
 
388
438
  # Unlocks the sources of the Pods.
389
439
  #
390
- # @todo Why the @pod_installers might be empty?
391
- #
392
440
  def unlock_pod_sources
393
- return unless @pod_installers
394
- @pod_installers.each do |installer|
441
+ pod_installers.each do |installer|
395
442
  pod_target = pod_targets.find { |target| target.pod_name == installer.name }
396
443
  installer.unlock_files!(pod_target.file_accessors)
397
444
  end
@@ -399,12 +446,9 @@ module Pod
399
446
 
400
447
  # Locks the sources of the Pods if the config instructs to do so.
401
448
  #
402
- # @todo Why the @pod_installers might be empty?
403
- #
404
449
  def lock_pod_sources
405
450
  return unless installation_options.lock_pod_sources?
406
- return unless @pod_installers
407
- @pod_installers.each do |installer|
451
+ pod_installers.each do |installer|
408
452
  pod_target = pod_targets.find { |target| target.pod_name == installer.name }
409
453
  installer.lock_files!(pod_target.file_accessors)
410
454
  end
@@ -429,11 +473,9 @@ module Pod
429
473
  # @return [void]
430
474
  #
431
475
  def perform_post_install_actions
432
- unlock_pod_sources
433
476
  run_plugins_post_install_hooks
434
477
  warn_for_deprecations
435
478
  warn_for_installed_script_phases
436
- lock_pod_sources
437
479
  print_post_install_message
438
480
  end
439
481
 
@@ -451,13 +493,26 @@ module Pod
451
493
  # Runs the registered callbacks for the plugins post install hooks.
452
494
  #
453
495
  def run_plugins_post_install_hooks
454
- context = PostInstallHooksContext.generate(sandbox, aggregate_targets)
455
- HooksManager.run(:post_install, context, plugins)
496
+ # This short-circuits because unlocking pod sources is expensive
497
+ if any_plugin_post_install_hooks?
498
+ unlock_pod_sources
499
+
500
+ context = PostInstallHooksContext.generate(sandbox, aggregate_targets)
501
+ HooksManager.run(:post_install, context, plugins)
502
+ end
503
+
504
+ lock_pod_sources
505
+ end
506
+
507
+ # @return [Boolean] whether there are any plugin post-install hooks to run
508
+ #
509
+ def any_plugin_post_install_hooks?
510
+ HooksManager.hooks_to_run(:post_install, plugins).any?
456
511
  end
457
512
 
458
513
  # Runs the registered callbacks for the source provider plugin hooks.
459
514
  #
460
- # @return [void]
515
+ # @return [Array<Pod::Source>] the plugin sources
461
516
  #
462
517
  def run_source_provider_hooks
463
518
  context = SourceProviderHooksContext.generate
@@ -550,16 +605,20 @@ module Pod
550
605
  end
551
606
  end
552
607
 
553
- # Writes the Podfile and the lock files.
608
+ # @return [Lockfile] The lockfile to write to disk.
554
609
  #
555
- # @todo Pass the checkout options to the Lockfile.
610
+ def generate_lockfile
611
+ external_source_pods = analysis_result.podfile_dependency_cache.podfile_dependencies.select(&:external_source).map(&:root_name).uniq
612
+ checkout_options = sandbox.checkout_sources.select { |root_name, _| external_source_pods.include? root_name }
613
+ Lockfile.generate(podfile, analysis_result.specifications, checkout_options, analysis_result.specs_by_source)
614
+ end
615
+
616
+ # Writes the Podfile and the lock files.
556
617
  #
557
618
  # @return [void]
558
619
  #
559
620
  def write_lockfiles
560
- external_source_pods = analysis_result.podfile_dependency_cache.podfile_dependencies.select(&:external_source).map(&:root_name).uniq
561
- checkout_options = sandbox.checkout_sources.select { |root_name, _| external_source_pods.include? root_name }
562
- @lockfile = Lockfile.generate(podfile, analysis_result.specifications, checkout_options, analysis_result.specs_by_source)
621
+ @lockfile = generate_lockfile
563
622
 
564
623
  UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do
565
624
  @lockfile.write_to_disk(config.lockfile_path)
@@ -579,11 +638,6 @@ module Pod
579
638
  #
580
639
  # @return [void]
581
640
  #
582
- # @todo [#397] The libraries should be cleaned and the re-added on every
583
- # installation. Maybe a clean_user_project phase should be added.
584
- # In any case it appears to be a good idea store target definition
585
- # information in the lockfile.
586
- #
587
641
  def integrate_user_project
588
642
  UI.section "Integrating client #{'project'.pluralize(aggregate_targets.map(&:user_project_path).uniq.count)}" do
589
643
  installation_root = config.installation_root
@@ -684,5 +738,28 @@ module Pod
684
738
  end
685
739
 
686
740
  #-------------------------------------------------------------------------#
741
+
742
+ public
743
+
744
+ # @!group Convenience Methods
745
+
746
+ def self.targets_from_sandbox(sandbox, podfile, lockfile)
747
+ raise Informative, 'You must run `pod install` to be able to generate target information' unless lockfile
748
+
749
+ new(sandbox, podfile, lockfile).instance_exec do
750
+ plugin_sources = run_source_provider_hooks
751
+ analyzer = create_analyzer(plugin_sources)
752
+ analyze(analyzer)
753
+ if analysis_result.podfile_needs_install?
754
+ raise Pod::Informative, 'The Podfile has changed, you must run `pod install`'
755
+ elsif analysis_result.sandbox_needs_install?
756
+ raise Pod::Informative, 'The `Pods` directory is out-of-date, you must run `pod install`'
757
+ end
758
+
759
+ aggregate_targets
760
+ end
761
+ end
762
+
763
+ #-------------------------------------------------------------------------#
687
764
  end
688
765
  end
@@ -8,9 +8,22 @@ module Pod
8
8
  # through the installation process.
9
9
  #
10
10
  class Project < Xcodeproj::Project
11
+ # @return [PBXGroup] The group for the support files of the aggregate
12
+ # targets.
13
+ #
14
+ attr_reader :support_files_group
15
+
16
+ # @return [PBXGroup] The group for the Pods.
17
+ #
18
+ attr_reader :pods
19
+
20
+ # @return [PBXGroup] The group for Development Pods.
21
+ #
22
+ attr_reader :development_pods
23
+
11
24
  # Initialize a new instance
12
25
  #
13
- # @param [Pathname, String] path @see path
26
+ # @param [Pathname, String] path @see #path
14
27
  # @param [Bool] skip_initialization
15
28
  # Whether the project should be initialized from scratch.
16
29
  # @param [Int] object_version
@@ -27,19 +40,6 @@ module Pod
27
40
  self.symroot = LEGACY_BUILD_ROOT
28
41
  end
29
42
 
30
- # @return [PBXGroup] The group for the support files of the aggregate
31
- # targets.
32
- #
33
- attr_reader :support_files_group
34
-
35
- # @return [PBXGroup] The group for the Pods.
36
- #
37
- attr_reader :pods
38
-
39
- # @return [PBXGroup] The group for Development Pods.
40
- #
41
- attr_reader :development_pods
42
-
43
43
  # Generates a list of new UUIDs that created objects can be assigned.
44
44
  #
45
45
  # @note Overridden to generate UUIDs in a much faster way, since we don't need to check for collisions
@@ -252,6 +252,8 @@ module Pod
252
252
  file_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
253
253
  file_ref.explicit_file_type = 'text.script.ruby'
254
254
  file_ref.last_known_file_type = 'text'
255
+ file_ref.tab_width = '2'
256
+ file_ref.indent_width = '2'
255
257
  end
256
258
 
257
259
  # Adds a new build configuration to the project and populates it with
@@ -0,0 +1,41 @@
1
+ module Pod
2
+ class Resolver
3
+ # A small container that wraps a resolved specification for a given target definition. Additional metadata
4
+ # is included here such as if the specification is only used by tests.
5
+ #
6
+ class ResolverSpecification
7
+ # @return [Specification] the specification that was resolved
8
+ #
9
+ attr_reader :spec
10
+
11
+ # @return [Source] the spec repo source the specification came from
12
+ #
13
+ attr_reader :source
14
+
15
+ # @return [Bool] whether this resolved specification is only used by tests.
16
+ #
17
+ attr_reader :used_by_tests_only
18
+ alias used_by_tests_only? used_by_tests_only
19
+
20
+ def initialize(spec, used_by_tests_only, source)
21
+ @spec = spec
22
+ @used_by_tests_only = used_by_tests_only
23
+ @source = source
24
+ end
25
+
26
+ def name
27
+ spec.name
28
+ end
29
+
30
+ def root
31
+ spec.root
32
+ end
33
+
34
+ def ==(other)
35
+ self.class == other.class &&
36
+ spec == other.spec &&
37
+ used_by_tests_only? == other.used_by_tests_only?
38
+ end
39
+ end
40
+ end
41
+ end