cocoapods 1.9.0 → 1.10.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +226 -3
  3. data/README.md +2 -1
  4. data/lib/cocoapods.rb +3 -1
  5. data/lib/cocoapods/command.rb +12 -2
  6. data/lib/cocoapods/command/lib/lint.rb +12 -3
  7. data/lib/cocoapods/command/repo/push.rb +1 -1
  8. data/lib/cocoapods/command/repo/update.rb +11 -0
  9. data/lib/cocoapods/command/spec/lint.rb +12 -3
  10. data/lib/cocoapods/config.rb +17 -0
  11. data/lib/cocoapods/downloader/cache.rb +2 -2
  12. data/lib/cocoapods/gem_version.rb +1 -1
  13. data/lib/cocoapods/generator/app_target_helper.rb +10 -2
  14. data/lib/cocoapods/generator/copy_dsyms_script.rb +56 -0
  15. data/lib/cocoapods/generator/copy_resources_script.rb +2 -14
  16. data/lib/cocoapods/generator/copy_xcframework_script.rb +245 -0
  17. data/lib/cocoapods/generator/embed_frameworks_script.rb +125 -212
  18. data/lib/cocoapods/generator/script_phase_constants.rb +99 -0
  19. data/lib/cocoapods/installer.rb +70 -3
  20. data/lib/cocoapods/installer/analyzer.rb +17 -8
  21. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +1 -1
  22. data/lib/cocoapods/installer/base_install_hooks_context.rb +135 -0
  23. data/lib/cocoapods/installer/installation_options.rb +5 -0
  24. data/lib/cocoapods/installer/pod_source_installer.rb +2 -1
  25. data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -127
  26. data/lib/cocoapods/installer/post_integrate_hooks_context.rb +9 -0
  27. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +2 -1
  28. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +132 -111
  29. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +45 -6
  30. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +13 -27
  31. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +2 -1
  32. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +4 -4
  33. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +175 -58
  34. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +61 -30
  35. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -2
  36. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +5 -7
  37. data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +19 -0
  38. data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
  39. data/lib/cocoapods/sources_manager.rb +2 -1
  40. data/lib/cocoapods/target.rb +44 -2
  41. data/lib/cocoapods/target/aggregate_target.rb +35 -0
  42. data/lib/cocoapods/target/build_settings.rb +85 -18
  43. data/lib/cocoapods/target/pod_target.rb +85 -11
  44. data/lib/cocoapods/user_interface/error_report.rb +1 -1
  45. data/lib/cocoapods/user_interface/inspector_reporter.rb +3 -10
  46. data/lib/cocoapods/validator.rb +32 -8
  47. data/lib/cocoapods/xcode/framework_paths.rb +1 -1
  48. data/lib/cocoapods/xcode/xcframework.rb +17 -4
  49. data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +81 -3
  50. metadata +31 -53
  51. data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -253
@@ -103,9 +103,9 @@ module Pod
103
103
  end]
104
104
  end
105
105
 
106
- # @return [Hash{String => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec name.
106
+ # @return [Hash{Specification => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec.
107
107
  #
108
- attr_accessor :test_app_hosts_by_spec_name
108
+ attr_accessor :test_app_hosts_by_spec
109
109
 
110
110
  # @return [Hash{String => BuildSettings}] the test spec build settings for this target.
111
111
  #
@@ -153,7 +153,7 @@ module Pod
153
153
  self.dependent_targets = []
154
154
  self.test_dependent_targets_by_spec_name = Hash[test_specs.map { |ts| [ts.name, []] }]
155
155
  self.app_dependent_targets_by_spec_name = Hash[app_specs.map { |as| [as.name, []] }]
156
- @test_app_hosts_by_spec_name = {}
156
+ @test_app_hosts_by_spec = {}
157
157
  @build_config_cache = {}
158
158
  @test_spec_build_settings_by_config = create_test_build_settings_by_config
159
159
  @app_spec_build_settings_by_config = create_app_build_settings_by_config
@@ -171,7 +171,7 @@ module Pod
171
171
  cache_key = [specs, target_definition]
172
172
  cache[cache_key] ||= begin
173
173
  target = PodTarget.new(sandbox, build_type, user_build_configurations, archs, platform, specs,
174
- [target_definition], file_accessors, target_definition.label)
174
+ [target_definition], file_accessors, target_definition.label, swift_version)
175
175
  scope_dependent_targets = ->(dependent_targets) do
176
176
  dependent_targets.flat_map do |pod_target|
177
177
  pod_target.scoped(cache).select { |pt| pt.target_definitions == [target_definition] }
@@ -185,8 +185,8 @@ module Pod
185
185
  target.app_dependent_targets_by_spec_name_by_config = Hash[app_dependent_targets_by_spec_name_by_config.map do |spec_name, app_pod_targets_by_config|
186
186
  [spec_name, Hash[app_pod_targets_by_config.map { |k, v| [k, scope_dependent_targets[v]] }]]
187
187
  end]
188
- target.test_app_hosts_by_spec_name = Hash[test_app_hosts_by_spec_name.map do |spec_name, (app_host_spec, app_pod_target)|
189
- [spec_name, [app_host_spec, app_pod_target.scoped(cache).find { |pt| pt.target_definitions == [target_definition] }]]
188
+ target.test_app_hosts_by_spec = Hash[test_app_hosts_by_spec.map do |spec, (app_host_spec, app_pod_target)|
189
+ [spec, [app_host_spec, app_pod_target.scoped(cache).find { |pt| pt.target_definitions == [target_definition] }]]
190
190
  end]
191
191
  target
192
192
  end
@@ -430,13 +430,22 @@ module Pod
430
430
  end
431
431
 
432
432
  # @return [Hash{String=>Array<String>}] The resource and resource bundle paths this target depends upon keyed by
433
- # spec name. Resources for app specs and test specs are directly added to “Copy Bundle Resources” phase
434
- # from the generated targets for frameworks, but not libraries. Therefore they are not part of the resource paths.
433
+ # spec name. Resource (not resource bundles) paths can vary depending on the type of spec:
434
+ # - App specs _always_ get their resource paths added to "Copy Bundle Resources" phase from
435
+ # [PodTargetInstaller] therefore their resource paths are never included here.
436
+ # - Test specs may have their resource paths added to "Copy Bundle Resources" if the target itself is
437
+ # built as a framework, which is again checked and handled by PodTargetInstaller. If that is true then
438
+ # the resource paths are not included, otherwise they are included and handled via the CocoaPods copy
439
+ # resources script phase.
440
+ # - Library specs _do not_ have per-configuration CocoaPods copy resources script phase and their resource
441
+ # paths will be added to "Copy Bundle Resources" phase if the target is built as a framework because
442
+ # it supports it. We always include the resource paths for library specs because they are also
443
+ # integrated to the user target.
435
444
  #
436
445
  def resource_paths
437
446
  @resource_paths ||= begin
438
447
  file_accessors.each_with_object({}) do |file_accessor, hash|
439
- resource_paths = if file_accessor.spec.non_library_specification? && build_as_framework?
448
+ resource_paths = if file_accessor.spec.app_specification? || (file_accessor.spec.test_specification? && build_as_framework?)
440
449
  []
441
450
  else
442
451
  file_accessor.resources.map do |res|
@@ -582,7 +591,7 @@ module Pod
582
591
  # app host, and the second item is the target name of the app host
583
592
  #
584
593
  def app_host_target_label(test_spec)
585
- app_spec, app_target = test_app_hosts_by_spec_name[test_spec.name]
594
+ app_spec, app_target = test_app_hosts_by_spec[test_spec]
586
595
 
587
596
  if app_spec
588
597
  [app_target.name, app_target.app_target_label(app_spec)]
@@ -601,7 +610,7 @@ module Pod
601
610
  #
602
611
  def app_host_dependent_targets_for_spec(spec, configuration: nil)
603
612
  return [] unless spec.test_specification? && spec.consumer(platform).test_type == :unit
604
- app_host_info = test_app_hosts_by_spec_name[spec.name]
613
+ app_host_info = test_app_hosts_by_spec[spec]
605
614
  if app_host_info.nil?
606
615
  []
607
616
  else
@@ -684,11 +693,33 @@ module Pod
684
693
  support_files_dir + "#{non_library_spec_label(spec)}-frameworks-output-files.xcfilelist"
685
694
  end
686
695
 
696
+ # @return [Pathname] The absolute path of the copy xcframeworks script.
697
+ #
698
+ def copy_xcframeworks_script_path
699
+ support_files_dir + "#{label}-xcframeworks.sh"
700
+ end
701
+
702
+ # @return [String] The path of the copy xcframeworks input files file list
703
+ #
704
+ def copy_xcframeworks_script_input_files_path
705
+ support_files_dir + "#{label}-xcframeworks-input-files.xcfilelist"
706
+ end
707
+
708
+ # @return [String] The path of the copy xcframeworks output files file list
709
+ #
710
+ def copy_xcframeworks_script_output_files_path
711
+ support_files_dir + "#{label}-xcframeworks-output-files.xcfilelist"
712
+ end
713
+
687
714
  # @param [Specification] spec
688
715
  # The spec this script path is for.
689
716
  #
690
717
  # @return [Pathname] The absolute path of the prepare artifacts script for the given spec.
691
718
  #
719
+ # @deprecated
720
+ #
721
+ # @todo Remove in 2.0
722
+ #
692
723
  def prepare_artifacts_script_path_for_spec(spec)
693
724
  support_files_dir + "#{non_library_spec_label(spec)}-artifacts.sh"
694
725
  end
@@ -698,6 +729,10 @@ module Pod
698
729
  #
699
730
  # @return [Pathname] The absolute path of the prepare artifacts script input file list for the given spec.
700
731
  #
732
+ # @deprecated
733
+ #
734
+ # @todo Remove in 2.0
735
+ #
701
736
  def prepare_artifacts_script_input_files_path_for_spec(spec)
702
737
  support_files_dir + "#{non_library_spec_label(spec)}-artifacts-input-files.xcfilelist"
703
738
  end
@@ -707,10 +742,32 @@ module Pod
707
742
  #
708
743
  # @return [Pathname] The absolute path of the prepare artifacts script output file list for the given spec.
709
744
  #
745
+ # @deprecated
746
+ #
747
+ # @todo Remove in 2.0
748
+ #
710
749
  def prepare_artifacts_script_output_files_path_for_spec(spec)
711
750
  support_files_dir + "#{non_library_spec_label(spec)}-artifacts-output-files.xcfilelist"
712
751
  end
713
752
 
753
+ # @return [Pathname] The absolute path of the copy dSYMs script.
754
+ #
755
+ def copy_dsyms_script_path
756
+ support_files_dir + "#{label}-copy-dsyms.sh"
757
+ end
758
+
759
+ # @return [Pathname] The absolute path of the copy dSYM script phase input file list.
760
+ #
761
+ def copy_dsyms_script_input_files_path
762
+ support_files_dir + "#{label}-copy-dsyms-input-files.xcfilelist"
763
+ end
764
+
765
+ # @return [Pathname] The absolute path of the copy dSYM script phase output file list.
766
+ #
767
+ def copy_dsyms_script_output_files_path
768
+ support_files_dir + "#{label}-copy-dsyms-output-files.xcfilelist"
769
+ end
770
+
714
771
  # @param [Specification] spec
715
772
  # The spec this Info.plist path is for.
716
773
  #
@@ -1065,5 +1122,22 @@ module Pod
1065
1122
  end
1066
1123
  mappings
1067
1124
  end
1125
+
1126
+ # @!group Deprecated APIs
1127
+ # ----------------------------------------------------------------------- #
1128
+
1129
+ public
1130
+
1131
+ # @deprecated Use `test_app_hosts_by_spec` instead.
1132
+ #
1133
+ # @todo Remove in 2.0
1134
+ #
1135
+ # @return [Hash{String => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec name.
1136
+ #
1137
+ def test_app_hosts_by_spec_name
1138
+ Hash[test_app_hosts_by_spec.map do |spec, value|
1139
+ [spec.name, value]
1140
+ end]
1141
+ end
1068
1142
  end
1069
1143
  end
@@ -31,7 +31,7 @@ module Pod
31
31
  ### Error
32
32
 
33
33
  ```
34
- #{exception.class} - #{exception.message}
34
+ #{exception.class} - #{exception.message.force_encoding('UTF-8')}
35
35
  #{exception.backtrace.join("\n") if exception.backtrace}
36
36
  ```
37
37
 
@@ -1,3 +1,4 @@
1
+ require 'addressable'
1
2
  require 'uri'
2
3
 
3
4
  module Pod
@@ -8,8 +9,6 @@ module Pod
8
9
  # Called just as the investigation has begun.
9
10
  # Lets the user know that it's looking for an issue.
10
11
  #
11
- # @param [query] String unused
12
- #
13
12
  # @param [GhInspector::Inspector] inspector
14
13
  # The current inspector
15
14
  #
@@ -25,9 +24,6 @@ module Pod
25
24
  # @param [GhInspector::InspectionReport] report
26
25
  # Report a list of the issues
27
26
  #
28
- # @param [GhInspector::Inspector] inspector
29
- # The current inspector
30
- #
31
27
  # @return [void]
32
28
  #
33
29
  def inspector_successfully_received_report(report, _)
@@ -41,9 +37,6 @@ module Pod
41
37
 
42
38
  # Called once the report has been received, but when there are no issues found.
43
39
  #
44
- # @param [GhInspector::InspectionReport] report
45
- # An empty report
46
- #
47
40
  # @param [GhInspector::Inspector] inspector
48
41
  # The current inspector
49
42
  #
@@ -68,7 +61,7 @@ module Pod
68
61
  # @return [void]
69
62
  #
70
63
  def inspector_could_not_create_report(error, query, inspector)
71
- safe_query = URI.escape query
64
+ safe_query = Addressable::URI.escape query
72
65
  UI.puts 'Could not access the GitHub API, you may have better luck via the website.'
73
66
  UI.puts "https://github.com/#{inspector.repo_owner}/#{inspector.repo_name}/search?q=#{safe_query}&type=Issues&utf8=✓"
74
67
  UI.puts "Error: #{error.name}"
@@ -77,7 +70,7 @@ module Pod
77
70
  private
78
71
 
79
72
  def print_issue_full(issue)
80
- safe_url = URI.escape issue.html_url
73
+ safe_url = Addressable::URI.escape issue.html_url
81
74
  UI.puts " - #{issue.title}"
82
75
  UI.puts " #{safe_url} [#{issue.state}] [#{issue.comments} comment#{issue.comments == 1 ? '' : 's'}]"
83
76
  UI.puts " #{pretty_date(issue.updated_at)}"
@@ -241,6 +241,10 @@ module Pod
241
241
  #
242
242
  attr_accessor :skip_tests
243
243
 
244
+ # @return [Array<String>] List of test_specs to run. If nil, all tests are run (unless skip_tests is specified).
245
+ #
246
+ attr_accessor :test_specs
247
+
244
248
  # @return [Bool] Whether the validator should run Xcode Static Analysis.
245
249
  #
246
250
  attr_accessor :analyze
@@ -253,6 +257,10 @@ module Pod
253
257
  #
254
258
  attr_accessor :use_modular_headers
255
259
 
260
+ # @return [Boolean] Whether static frameworks should be used for the installation.
261
+ #
262
+ attr_accessor :use_static_frameworks
263
+
256
264
  # @return [Boolean] Whether attributes that affect only public sources
257
265
  # Bool be skipped.
258
266
  #
@@ -271,6 +279,8 @@ module Pod
271
279
  attr_accessor :skip_import_validation
272
280
  alias_method :skip_import_validation?, :skip_import_validation
273
281
 
282
+ attr_accessor :configuration
283
+
274
284
  #-------------------------------------------------------------------------#
275
285
 
276
286
  # !@group Lint results
@@ -557,7 +567,7 @@ module Pod
557
567
 
558
568
  def download_pod
559
569
  test_spec_names = consumer.spec.test_specs.select { |ts| ts.supported_on_platform?(consumer.platform_name) }.map(&:name)
560
- podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers)
570
+ podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers, use_static_frameworks)
561
571
  sandbox = Sandbox.new(config.sandbox_root)
562
572
  @installer = Installer.new(sandbox, podfile)
563
573
  @installer.use_default_plugins = false
@@ -584,7 +594,7 @@ module Pod
584
594
  app_target = app_project.targets.first
585
595
  pod_target = validation_pod_target
586
596
  Pod::Generator::AppTargetHelper.add_app_project_import(app_project, app_target, pod_target, consumer.platform_name)
587
- Pod::Generator::AppTargetHelper.add_xctest_search_paths(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
597
+ Pod::Generator::AppTargetHelper.add_xctest_search_paths(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') || c.weak_frameworks.include?('XCTest') } }
588
598
  Pod::Generator::AppTargetHelper.add_empty_swift_file(app_project, app_target) if @installer.pod_targets.any?(&:uses_swift?)
589
599
  app_project.save
590
600
  Xcodeproj::XCScheme.share_scheme(app_project.path, 'App')
@@ -710,7 +720,7 @@ module Pod
710
720
  error('build_pod', message)
711
721
  end
712
722
  else
713
- output = xcodebuild('build', scheme, 'Release')
723
+ output = xcodebuild('build', scheme, configuration ? configuration : 'Release')
714
724
  end
715
725
  parsed_output = parse_xcodebuild_output(output)
716
726
  translate_output_to_linter_messages(parsed_output)
@@ -732,7 +742,17 @@ module Pod
732
742
  else
733
743
  UI.message "\nTesting with `xcodebuild`.\n".yellow do
734
744
  pod_target = validation_pod_target
735
- consumer.spec.test_specs.each do |test_spec|
745
+ all_test_specs = consumer.spec.test_specs
746
+ unless test_specs.nil?
747
+ test_spec_names = all_test_specs.map(&:base_name)
748
+ all_test_specs.select! { |test_spec| test_specs.include? test_spec.base_name }
749
+ test_specs.each do |test_spec|
750
+ unless test_spec_names.include? test_spec
751
+ UI.warn "Requested test spec `#{test_spec}` does not exist in the podspec. Existing test specs are `#{test_spec_names}`"
752
+ end
753
+ end
754
+ end
755
+ all_test_specs.each do |test_spec|
736
756
  if !test_spec.supported_on_platform?(consumer.platform_name)
737
757
  UI.warn "Skipping test spec `#{test_spec.name}` on platform `#{consumer.platform_name}` since it is not supported.\n".yellow
738
758
  else
@@ -953,7 +973,7 @@ module Pod
953
973
  # @note The generated podfile takes into account whether the linter is
954
974
  # in local mode.
955
975
  #
956
- def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false)
976
+ def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false, use_static_frameworks = false)
957
977
  name = subspec_name || spec.name
958
978
  podspec = file.realpath
959
979
  local = local?
@@ -963,12 +983,16 @@ module Pod
963
983
  additional_path_pods = (include_podspecs ? Dir.glob(include_podspecs) : []) .select { |path| spec.name != Specification.from_file(path).name } - additional_podspec_pods
964
984
 
965
985
  Pod::Podfile.new do
966
- install! 'cocoapods', :deterministic_uuids => false
986
+ install! 'cocoapods', :deterministic_uuids => false, :warn_for_unused_master_specs_repo => false
967
987
  # By default inhibit warnings for all pods, except the one being validated.
968
988
  inhibit_all_warnings!
969
989
  urls.each { |u| source(u) }
970
990
  target 'App' do
971
- use_frameworks!(use_frameworks)
991
+ if use_static_frameworks
992
+ use_frameworks!(:linkage => :static)
993
+ else
994
+ use_frameworks!(use_frameworks)
995
+ end
972
996
  use_modular_headers! if use_modular_headers
973
997
  platform(platform_name, deployment_target)
974
998
  if local
@@ -1016,7 +1040,7 @@ module Pod
1016
1040
  l.include?('note: ') && (l !~ /expanded from macro/)
1017
1041
  end
1018
1042
  selected_lines.map do |l|
1019
- new = l.gsub(%r{#{validation_dir}/Pods/}, '')
1043
+ new = l.force_encoding('UTF-8').gsub(%r{#{validation_dir}/Pods/}, '')
1020
1044
  new.gsub!(/^ */, ' ')
1021
1045
  end
1022
1046
  end
@@ -9,7 +9,7 @@ module Pod
9
9
  #
10
10
  attr_reader :dsym_path
11
11
 
12
- # @return [Array, Nil] the bcsymbolmap files path array, if one exists
12
+ # @return [Array<String>, Nil] the bcsymbolmap files path array, if one exists
13
13
  #
14
14
  attr_reader :bcsymbolmap_paths
15
15
 
@@ -52,13 +52,22 @@ module Pod
52
52
  # @return [Boolean] true if any slices use dynamic linkage
53
53
  #
54
54
  def includes_dynamic_slices?
55
- slices.any? { |slice| Xcode::LinkageAnalyzer.dynamic_binary?(slice.binary_path) }
55
+ build_type.dynamic?
56
56
  end
57
57
 
58
58
  # @return [Boolean] true if any slices use dynamic linkage
59
59
  #
60
60
  def includes_static_slices?
61
- slices.any? { |slice| !Xcode::LinkageAnalyzer.dynamic_binary?(slice.binary_path) }
61
+ build_type.static?
62
+ end
63
+
64
+ # @return [Pod::BuildType] the build type of the contained slices
65
+ #
66
+ # @note As CocoaPods does not support mixed packaging nor linkage for xcframework slices,
67
+ # we pick the first slice and assume all are the same
68
+ #
69
+ def build_type
70
+ @build_type ||= slices.first.build_type
62
71
  end
63
72
 
64
73
  private
@@ -71,10 +80,14 @@ module Pod
71
80
  archs = library['SupportedArchitectures']
72
81
  platform_name = library['SupportedPlatform']
73
82
  platform_variant = library['SupportedPlatformVariant']
83
+ headers = library['HeadersPath']
74
84
 
75
- slice_path = path.join(identifier).join(relative_path)
76
- XCFramework::Slice.new(slice_path, identifier, archs, platform_name, platform_variant)
85
+ slice_root = path.join(identifier)
86
+ slice_path = slice_root.join(relative_path)
87
+ headers = slice_root.join(headers) unless headers.nil?
88
+ XCFramework::Slice.new(slice_path, identifier, archs, platform_name, :platform_variant => platform_variant, :headers => headers)
77
89
  end
90
+ raise Informative, "XCFramework at #{path} does not contain any frameworks or libraries." if slices.empty?
78
91
  end
79
92
  end
80
93
  end
@@ -1,8 +1,10 @@
1
+ require 'cocoapods/xcode/linkage_analyzer'
2
+
1
3
  module Pod
2
4
  module Xcode
3
5
  class XCFramework
4
6
  class Slice
5
- # @return [Pathname] the path to the .framework root of this framework slice
7
+ # @return [Pathname] the path to the .framework or .a of this slice
6
8
  #
7
9
  attr_reader :path
8
10
 
@@ -22,24 +24,100 @@ module Pod
22
24
  #
23
25
  attr_reader :platform_variant
24
26
 
25
- def initialize(path, identifier, archs, platform, platform_variant = nil)
27
+ # @return [Pathname] the path to the headers
28
+ #
29
+ attr_reader :headers
30
+
31
+ def initialize(path, identifier, archs, platform, platform_variant: nil, headers: path.join('Headers'))
26
32
  @path = path
27
33
  @identifier = identifier
28
34
  @supported_archs = archs
29
35
  @platform = Pod::Platform.new(platform)
30
36
  @platform_variant = platform_variant.to_sym unless platform_variant.nil?
37
+ @headers = headers
31
38
  end
32
39
 
33
40
  # @return [String] the name of the framework
34
41
  #
35
42
  def name
36
- @name ||= File.basename(path, '.framework')
43
+ @name ||= begin
44
+ case package_type
45
+ when :framework
46
+ File.basename(path, '.framework')
47
+ when :library
48
+ result = File.basename(path, '.a').gsub(/^lib/, '')
49
+ result[0] = result.downcase[0]
50
+ result
51
+ else
52
+ raise Informative, "Invalid package type `#{package_type}`"
53
+ end
54
+ end
37
55
  end
38
56
 
57
+ # @return [Boolean] true if this is a slice built for simulator
58
+ #
39
59
  def simulator_variant?
40
60
  @platform_variant == :simulator
41
61
  end
42
62
 
63
+ # @return [Symbol] the package type of the slice - either :framework or :library
64
+ #
65
+ def package_type
66
+ @package_type ||= begin
67
+ ext = File.extname(path)
68
+ case ext
69
+ when '.framework'
70
+ :framework
71
+ when '.a'
72
+ :library
73
+ else
74
+ raise Informative, "Invalid XCFramework slice type `#{ext}`"
75
+ end
76
+ end
77
+ end
78
+
79
+ # @return [Boolean] true if this slice is a framework, not a library
80
+ #
81
+ def framework?
82
+ build_type.framework?
83
+ end
84
+
85
+ # @return [Boolean] true if this slice is a library, not a framework
86
+ #
87
+ def library?
88
+ build_type.library?
89
+ end
90
+
91
+ # @return [Boolean] true if this slice contains a statically-linked binary
92
+ #
93
+ def static?
94
+ build_type.static?
95
+ end
96
+
97
+ # @return [Boolean] true if this slice contains a dynamically-linked binary
98
+ #
99
+ def dynamic?
100
+ build_type.dynamic?
101
+ end
102
+
103
+ # @return [BuildType] the build type of the binary
104
+ #
105
+ def build_type
106
+ @build_type ||= begin
107
+ linkage = Xcode::LinkageAnalyzer.dynamic_binary?(binary_path) ? :dynamic : :static
108
+ ext = File.extname(path)
109
+ packaging = case ext
110
+ when '.framework'
111
+ :framework
112
+ when '.a'
113
+ :library
114
+ else
115
+ raise Informative, "Invalid XCFramework slice type `#{ext}`"
116
+ end
117
+ BuildType.new(:linkage => linkage, :packaging => packaging)
118
+ end
119
+ end
120
+
43
121
  # @return [Pathname] the path to the bundled binary
44
122
  #
45
123
  def binary_path