cocoapods 1.6.0.beta.1 → 1.6.0.beta.2

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -4
  3. data/lib/cocoapods/command/cache/clean.rb +1 -1
  4. data/lib/cocoapods/command/init.rb +3 -1
  5. data/lib/cocoapods/command/outdated.rb +2 -2
  6. data/lib/cocoapods/executable.rb +1 -1
  7. data/lib/cocoapods/gem_version.rb +1 -1
  8. data/lib/cocoapods/generator/acknowledgements/plist.rb +3 -3
  9. data/lib/cocoapods/generator/app_target_helper.rb +2 -4
  10. data/lib/cocoapods/generator/copy_resources_script.rb +8 -3
  11. data/lib/cocoapods/generator/embed_frameworks_script.rb +24 -18
  12. data/lib/cocoapods/installer.rb +37 -21
  13. data/lib/cocoapods/installer/analyzer.rb +19 -13
  14. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +5 -0
  15. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +5 -0
  16. data/lib/cocoapods/installer/installation_options.rb +2 -0
  17. data/lib/cocoapods/installer/pod_source_installer.rb +1 -1
  18. data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -1
  19. data/lib/cocoapods/installer/user_project_integrator.rb +6 -2
  20. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +42 -12
  21. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +2 -4
  22. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +14 -5
  23. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +12 -6
  24. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +22 -11
  25. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +29 -18
  26. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  27. data/lib/cocoapods/project.rb +2 -0
  28. data/lib/cocoapods/resolver.rb +42 -49
  29. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  30. data/lib/cocoapods/sandbox.rb +21 -17
  31. data/lib/cocoapods/target/aggregate_target.rb +3 -1
  32. data/lib/cocoapods/target/build_settings.rb +35 -12
  33. data/lib/cocoapods/target/framework_paths.rb +36 -0
  34. data/lib/cocoapods/target/pod_target.rb +16 -17
  35. data/lib/cocoapods/validator.rb +18 -5
  36. metadata +18 -10
@@ -10,12 +10,18 @@ module Pod
10
10
  #
11
11
  attr_reader :target_installation_result
12
12
 
13
+ # @return [InstallationOptions] the installation options from the Podfile.
14
+ #
15
+ attr_reader :installation_options
16
+
13
17
  # Initialize a new instance
14
18
  #
15
19
  # @param [TargetInstallationResult] target_installation_result @see #target_installation_result
20
+ # @param [InstallationOptions] installation_options @see #installation_options
16
21
  #
17
- def initialize(target_installation_result)
22
+ def initialize(target_installation_result, installation_options)
18
23
  @target_installation_result = target_installation_result
24
+ @installation_options = installation_options
19
25
  end
20
26
 
21
27
  # Integrates the pod target.
@@ -53,17 +59,19 @@ module Pod
53
59
  #
54
60
  def add_copy_resources_script_phase(native_target, test_spec)
55
61
  script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
56
- resource_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
57
- spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
58
- spec_paths_to_include << test_spec.name if dependent_target == target
59
- dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
60
- end
61
62
  input_paths = []
62
63
  output_paths = []
63
- unless resource_paths.empty?
64
- resource_paths_flattened = resource_paths.flatten.uniq
65
- input_paths = [script_path, *resource_paths_flattened]
66
- output_paths = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths_flattened)
64
+ unless installation_options.disable_input_output_paths?
65
+ resource_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
66
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
67
+ spec_paths_to_include << test_spec.name if dependent_target == target
68
+ dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
69
+ end
70
+ unless resource_paths.empty?
71
+ resource_paths_flattened = resource_paths.flatten.uniq
72
+ input_paths = [script_path, *resource_paths_flattened]
73
+ output_paths = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths_flattened)
74
+ end
67
75
  end
68
76
  UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
69
77
  UserProjectIntegrator::TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
@@ -75,17 +83,20 @@ module Pod
75
83
  #
76
84
  def add_embed_frameworks_script_phase(native_target, test_spec)
77
85
  script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
78
- framework_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
79
- spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
80
- spec_paths_to_include << test_spec.name if dependent_target == target
81
- dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
82
- end
83
86
  input_paths = []
84
87
  output_paths = []
85
- unless framework_paths.empty?
86
- input_paths = [script_path, *framework_paths.flat_map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.compact]
87
- output_paths = framework_paths.flat_map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.compact
88
+ unless installation_options.disable_input_output_paths?
89
+ framework_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
90
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
91
+ spec_paths_to_include << test_spec.name if dependent_target == target
92
+ dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
93
+ end
94
+ unless framework_paths.empty?
95
+ input_paths = [script_path, *framework_paths.flat_map { |fw| [fw.source_path, fw.dsym_path] }.compact]
96
+ output_paths = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
97
+ end
88
98
  end
99
+
89
100
  UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
90
101
  UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
91
102
  end
@@ -112,7 +112,7 @@ module Pod
112
112
  end.compact
113
113
 
114
114
  unless error_messages.empty?
115
- raise Informative, "Unable to determine Swift version for the following pods:\n\n #{error_messages.join('\n')}"
115
+ raise Informative, "Unable to determine Swift version for the following pods:\n\n#{error_messages.join("\n")}"
116
116
  end
117
117
  end
118
118
 
@@ -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
@@ -1,5 +1,4 @@
1
1
  require 'molinillo'
2
- require 'cocoapods/resolver/lazy_specification'
3
2
 
4
3
  module Pod
5
4
  class NoSpecFoundError < Informative
@@ -12,43 +11,8 @@ module Pod
12
11
  # by target for a given Podfile.
13
12
  #
14
13
  class Resolver
15
- # A small container that wraps a resolved specification for a given target definition. Additional metadata
16
- # is included here such as if the specification is only used by tests.
17
- #
18
- class ResolverSpecification
19
- # @return [Specification] the specification that was resolved
20
- #
21
- attr_reader :spec
22
-
23
- # @return [Source] the spec repo source the specification came from
24
- #
25
- attr_reader :source
26
-
27
- # @return [Bool] whether this resolved specification is only used by tests.
28
- #
29
- attr_reader :used_by_tests_only
30
- alias used_by_tests_only? used_by_tests_only
31
-
32
- def initialize(spec, used_by_tests_only, source)
33
- @spec = spec
34
- @used_by_tests_only = used_by_tests_only
35
- @source = source
36
- end
37
-
38
- def name
39
- spec.name
40
- end
41
-
42
- def root
43
- spec.root
44
- end
45
-
46
- def ==(other)
47
- self.class == other &&
48
- spec == other.spec &&
49
- used_by_tests_only == other.test_only
50
- end
51
- end
14
+ require 'cocoapods/resolver/lazy_specification'
15
+ require 'cocoapods/resolver/resolver_specification'
52
16
 
53
17
  include Pod::Installer::InstallationOptions::Mixin
54
18
 
@@ -97,7 +61,11 @@ module Pod
97
61
  @specs_updated = specs_updated
98
62
  @podfile_dependency_cache = podfile_dependency_cache
99
63
  @platforms_by_dependency = Hash.new { |h, k| h[k] = [] }
64
+
100
65
  @cached_sets = {}
66
+ @podfile_requirements_by_root_name = @podfile_dependency_cache.podfile_dependencies.group_by(&:root_name).each_value { |a| a.map!(&:requirement) }
67
+ @search = {}
68
+ @validated_platforms = Set.new
101
69
  end
102
70
 
103
71
  #-------------------------------------------------------------------------#
@@ -167,11 +135,11 @@ module Pod
167
135
  # @param [Dependency] dependency the dependency that is being searched for.
168
136
  #
169
137
  def search_for(dependency)
170
- @search ||= {}
171
138
  @search[dependency] ||= begin
172
139
  locked_requirement = requirement_for_locked_pod_named(dependency.name)
173
- additional_requirements = Array(locked_requirement)
174
- specifications_for_dependency(dependency, additional_requirements)
140
+ podfile_deps = Array(@podfile_requirements_by_root_name[dependency.root_name])
141
+ podfile_deps << locked_requirement if locked_requirement
142
+ specifications_for_dependency(dependency, podfile_deps)
175
143
  end
176
144
  @search[dependency].dup
177
145
  end
@@ -238,7 +206,7 @@ module Pod
238
206
  end
239
207
 
240
208
  def valid_possibility_version_for_root_name?(requirement, activated, spec)
241
- prerelease_requirement = requirement.prerelease? || requirement.external_source || !spec.version.prerelease?
209
+ return true if prerelease_requirement = requirement.prerelease? || requirement.external_source || !spec.version.prerelease?
242
210
 
243
211
  activated.each do |vertex|
244
212
  next unless vertex.payload
@@ -381,7 +349,7 @@ module Pod
381
349
  #
382
350
  def find_cached_set(dependency)
383
351
  name = dependency.root_name
384
- unless cached_sets[name]
352
+ cached_sets[name] ||= begin
385
353
  if dependency.external_source
386
354
  spec = sandbox.specification(name)
387
355
  unless spec
@@ -392,12 +360,13 @@ module Pod
392
360
  else
393
361
  set = create_set_from_sources(dependency)
394
362
  end
395
- cached_sets[name] = set
363
+
396
364
  unless set
397
365
  raise Molinillo::NoSuchDependencyError.new(dependency) # rubocop:disable Style/RaiseArgs
398
366
  end
367
+
368
+ set
399
369
  end
400
- cached_sets[name]
401
370
  end
402
371
 
403
372
  # @return [Requirement, Nil]
@@ -426,8 +395,11 @@ module Pod
426
395
  # @return [Source::Aggregate] The aggregate of the {#sources}.
427
396
  #
428
397
  def aggregate_for_dependency(dependency)
398
+ sources_manager = Config.instance.sources_manager
429
399
  if dependency && dependency.podspec_repo
430
- return Config.instance.sources_manager.aggregate_for_dependency(dependency)
400
+ sources_manager.aggregate_for_dependency(dependency)
401
+ elsif (locked_vertex = @locked_dependencies.vertex_named(dependency.name)) && (locked_dependency = locked_vertex.payload) && locked_dependency.podspec_repo
402
+ sources_manager.aggregate_for_dependency(locked_dependency)
431
403
  else
432
404
  @aggregate ||= Source::Aggregate.new(sources)
433
405
  end
@@ -441,6 +413,7 @@ module Pod
441
413
  #
442
414
  def validate_platform(spec, target)
443
415
  return unless target_platform = target.platform
416
+ return unless @validated_platforms.add?([spec.object_id, target_platform])
444
417
  unless spec.available_platforms.any? { |p| target_platform.to_sym == p.to_sym }
445
418
  raise Informative, "The platform of the target `#{target.name}` " \
446
419
  "(#{target.platform}) is not compatible with `#{spec}`, which does " \
@@ -509,6 +482,17 @@ module Pod
509
482
  end
510
483
  end,
511
484
  )
485
+ when Molinillo::NoSuchDependencyError
486
+ message += <<-EOS
487
+
488
+
489
+ You have either:
490
+ * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
491
+ * mistyped the name or version.
492
+ * not added the source repo that hosts the Podspec to your Podfile.
493
+
494
+ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
495
+ EOS
512
496
  end
513
497
  raise type.new(message).tap { |e| e.set_backtrace(error.backtrace) }
514
498
  end
@@ -569,17 +553,26 @@ module Pod
569
553
  end
570
554
  end
571
555
 
556
+ EdgeAndPlatform = Struct.new(:edge, :target_platform)
557
+ private_constant :EdgeAndPlatform
558
+
572
559
  # Whether the given `edge` should be followed to find dependencies for the
573
560
  # given `target_platform`.
574
561
  #
575
562
  # @return [Bool]
576
563
  #
577
564
  def edge_is_valid_for_target_platform?(edge, target_platform)
578
- requirement_name = edge.requirement.name
565
+ @edge_validity ||= Hash.new do |hash, edge_and_platform|
566
+ e = edge_and_platform.edge
567
+ platform = edge_and_platform.target_platform
568
+ requirement_name = e.requirement.name
579
569
 
580
- edge.origin.payload.all_dependencies(target_platform).any? do |dep|
581
- dep.name == requirement_name
570
+ hash[edge_and_platform] = e.origin.payload.all_dependencies(platform).any? do |dep|
571
+ dep.name == requirement_name
572
+ end
582
573
  end
574
+
575
+ @edge_validity[EdgeAndPlatform.new(edge, target_platform)]
583
576
  end
584
577
  end
585
578
  end
@@ -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
@@ -254,25 +254,29 @@ module Pod
254
254
  file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
255
255
  output_path = specifications_root + file_name
256
256
 
257
- case podspec
258
- when String
259
- output_path.open('w') { |f| f.puts(podspec) }
260
- when Pathname
261
- unless podspec.exist?
262
- raise Informative, "No podspec found for `#{name}` in #{podspec}"
257
+ spec =
258
+ case podspec
259
+ when String
260
+ output_path.open('w') { |f| f.puts(podspec) }
261
+ Specification.from_file(output_path)
262
+ when Pathname
263
+ unless podspec.exist?
264
+ raise Informative, "No podspec found for `#{name}` in #{podspec}"
265
+ end
266
+ FileUtils.copy(podspec, output_path)
267
+ Specification.from_file(podspec)
268
+ when Specification
269
+ raise ArgumentError, 'can only store Specification objects as json' unless json
270
+ output_path.open('w') { |f| f.puts(podspec.to_pretty_json) }
271
+ podspec.dup
272
+ else
273
+ raise ArgumentError, "Unknown type for podspec: #{podspec.inspect}"
263
274
  end
264
- spec = Specification.from_file(podspec)
265
- FileUtils.copy(podspec, output_path)
266
- when Specification
267
- raise ArgumentError, 'can only store Specification objects as json' unless json
268
- output_path.open('w') { |f| f.puts(podspec.to_pretty_json) }
269
- spec = podspec.dup
270
- else
271
- raise ArgumentError, "Unknown type for podspec: #{podspec.inspect}"
272
- end
273
275
 
274
- spec ||= Specification.from_file(output_path)
275
- spec.defined_in_file ||= output_path
276
+ # we force the file to be the file in the sandbox, so specs that have been serialized to
277
+ # json maintain a consistent checksum.
278
+ # this is safe to do because `spec` is always a clean instance
279
+ spec.defined_in_file = output_path
276
280
 
277
281
  unless spec.name == name
278
282
  raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
@@ -1,3 +1,5 @@
1
+ require 'cocoapods/target/framework_paths'
2
+
1
3
  module Pod
2
4
  # Stores the information relative to the target used to cluster the targets
3
5
  # of the single Pods. The client targets will then depend on this one.
@@ -222,7 +224,7 @@ module Pod
222
224
  !framework_paths_by_config.values.all?(&:empty?)
223
225
  end
224
226
 
225
- # @return [Hash{String => Array<Hash{Symbol => [String]}>}] The vendored dynamic artifacts and framework target
227
+ # @return [Hash{String => Array<FrameworkPaths>}] The vendored dynamic artifacts and framework target
226
228
  # input and output paths grouped by config
227
229
  #
228
230
  def framework_paths_by_config
@@ -552,7 +552,7 @@ module Pod
552
552
 
553
553
  # @return [Array<String>]
554
554
  define_build_settings_method :weak_frameworks_to_import, :memoized => true, :sorted => true, :uniqued => true do
555
- []
555
+ spec_consumers.flat_map(&:weak_frameworks)
556
556
  end
557
557
 
558
558
  # @return [Array<String>]
@@ -564,6 +564,12 @@ module Pod
564
564
  paths
565
565
  end
566
566
 
567
+ # @return [String]
568
+ define_build_settings_method :framework_header_search_path, :memoized => true do
569
+ return unless target.requires_frameworks?
570
+ "#{target.build_product_path}/Headers"
571
+ end
572
+
567
573
  # @return [Array<String>]
568
574
  define_build_settings_method :vendored_framework_search_paths, :memoized => true do
569
575
  file_accessors.flat_map(&:vendored_frameworks).map { |f| File.join '${PODS_ROOT}', f.dirname.relative_path_from(target.sandbox.root) }
@@ -690,6 +696,11 @@ module Pod
690
696
  target.header_search_paths(:include_dependent_targets_for_test_spec => test_spec)
691
697
  end
692
698
 
699
+ # @return [Array<String>]
700
+ define_build_settings_method :public_header_search_paths, :memoized => true, :sorted => true do
701
+ target.header_search_paths(:include_dependent_targets_for_test_spec => test_xcconfig?, :include_private_headers => false)
702
+ end
703
+
693
704
  #-------------------------------------------------------------------------#
694
705
 
695
706
  # @!group Swift
@@ -907,6 +918,12 @@ module Pod
907
918
  paths.concat target.sandbox.public_headers.search_paths(target.platform)
908
919
  end
909
920
 
921
+ # Make frameworks headers discoverable with any syntax (quotes,
922
+ # brackets, @import, etc.)
923
+ paths.concat pod_targets.
924
+ select { |pt| pt.requires_frameworks? && pt.should_build? }.
925
+ map { |pt| pt.build_settings.framework_header_search_path }
926
+
910
927
  paths.concat target.search_paths_aggregate_targets.flat_map { |at| at.build_settings(configuration_name).header_search_paths }
911
928
 
912
929
  paths
@@ -915,18 +932,24 @@ module Pod
915
932
  # @return [Array<String>]
916
933
  define_build_settings_method :other_cflags, :build_setting => true, :memoized => true do
917
934
  flags = super()
918
- flags +
919
- header_search_paths.flat_map { |p| ['-isystem', p] } +
920
- framework_header_paths_for_iquote.flat_map { |p| ['-iquote', p] }
921
- end
922
935
 
923
- # @return [Array<String>]
924
- define_build_settings_method :framework_header_paths_for_iquote, :memoized => true, :sorted => true, :uniqued => true do
925
- paths = pod_targets.
926
- select { |pt| pt.should_build? && pt.requires_frameworks? }.
927
- map { |pt| "#{pt.build_product_path}/Headers" }
928
- paths.concat target.search_paths_aggregate_targets.flat_map { |at| at.build_settings(configuration_name).framework_header_paths_for_iquote }
929
- paths
936
+ pod_targets_inhibiting_warnings = pod_targets.select(&:inhibit_warnings?)
937
+
938
+ silenced_headers = []
939
+ silenced_frameworks = []
940
+ pod_targets_inhibiting_warnings.each do |pt|
941
+ if pt.requires_frameworks? && pt.should_build?
942
+ silenced_headers.append pt.build_settings.framework_header_search_path
943
+ else
944
+ silenced_headers.concat pt.build_settings.public_header_search_paths
945
+ end
946
+ silenced_frameworks.concat pt.build_settings.framework_search_paths_to_import
947
+ end
948
+
949
+ flags += silenced_headers.uniq.flat_map { |p| ['-isystem', p] }
950
+ flags += silenced_frameworks.uniq.flat_map { |p| ['-iframework', p] }
951
+
952
+ flags
930
953
  end
931
954
 
932
955
  # @return [Array<String>]