cocoapods 1.9.0 → 1.10.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 (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