cocoapods 1.9.1 → 1.10.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +292 -5
- data/README.md +2 -1
- data/lib/cocoapods/command/lib/lint.rb +12 -3
- data/lib/cocoapods/command/repo/push.rb +1 -1
- data/lib/cocoapods/command/repo/update.rb +11 -0
- data/lib/cocoapods/command/spec/lint.rb +12 -3
- data/lib/cocoapods/command.rb +12 -2
- data/lib/cocoapods/config.rb +17 -0
- data/lib/cocoapods/downloader/cache.rb +2 -2
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/app_target_helper.rb +10 -2
- data/lib/cocoapods/generator/copy_dsyms_script.rb +56 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +2 -14
- data/lib/cocoapods/generator/copy_xcframework_script.rb +245 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +125 -212
- data/lib/cocoapods/generator/script_phase_constants.rb +99 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +1 -1
- data/lib/cocoapods/installer/analyzer.rb +17 -8
- data/lib/cocoapods/installer/base_install_hooks_context.rb +135 -0
- data/lib/cocoapods/installer/installation_options.rb +5 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +2 -1
- data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -127
- data/lib/cocoapods/installer/post_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +4 -0
- data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +2 -1
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +132 -111
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +13 -27
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +5 -1
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +2 -1
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +8 -6
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +187 -61
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +61 -30
- data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -2
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +5 -7
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +45 -6
- data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +19 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
- data/lib/cocoapods/installer.rb +70 -3
- data/lib/cocoapods/sandbox/file_accessor.rb +10 -1
- data/lib/cocoapods/sources_manager.rb +2 -1
- data/lib/cocoapods/target/aggregate_target.rb +35 -0
- data/lib/cocoapods/target/build_settings.rb +94 -18
- data/lib/cocoapods/target/pod_target.rb +85 -11
- data/lib/cocoapods/target.rb +44 -2
- data/lib/cocoapods/user_interface/error_report.rb +1 -1
- data/lib/cocoapods/user_interface/inspector_reporter.rb +3 -10
- data/lib/cocoapods/validator.rb +38 -12
- data/lib/cocoapods/xcode/framework_paths.rb +1 -1
- data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +91 -4
- data/lib/cocoapods/xcode/xcframework.rb +17 -4
- data/lib/cocoapods.rb +3 -1
- metadata +31 -53
- data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -257
@@ -103,9 +103,9 @@ module Pod
|
|
103
103
|
end]
|
104
104
|
end
|
105
105
|
|
106
|
-
# @return [Hash{
|
106
|
+
# @return [Hash{Specification => (Specification,PodTarget)}] tuples of app specs and pod targets by test spec.
|
107
107
|
#
|
108
|
-
attr_accessor :
|
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
|
-
@
|
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.
|
189
|
-
[
|
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.
|
434
|
-
#
|
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.
|
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 =
|
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 =
|
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
|
data/lib/cocoapods/target.rb
CHANGED
@@ -43,6 +43,11 @@ module Pod
|
|
43
43
|
#
|
44
44
|
attr_reader :application_extension_api_only
|
45
45
|
|
46
|
+
# @return [Boolean] whether the target must be compiled with Swift's library
|
47
|
+
# evolution support, necessary for XCFrameworks.
|
48
|
+
#
|
49
|
+
attr_reader :build_library_for_distribution
|
50
|
+
|
46
51
|
# Initialize a new target
|
47
52
|
#
|
48
53
|
# @param [Sandbox] sandbox @see #sandbox
|
@@ -59,6 +64,7 @@ module Pod
|
|
59
64
|
@build_type = build_type
|
60
65
|
|
61
66
|
@application_extension_api_only = false
|
67
|
+
@build_library_for_distribution = false
|
62
68
|
@build_settings = create_build_settings
|
63
69
|
end
|
64
70
|
|
@@ -298,19 +304,55 @@ module Pod
|
|
298
304
|
support_files_dir + "#{label}-dummy.m"
|
299
305
|
end
|
300
306
|
|
301
|
-
#
|
302
|
-
#
|
307
|
+
# Mark the target as extension-only.
|
308
|
+
# Translates to APPLICATION_EXTENSION_API_ONLY = YES in the build settings.
|
303
309
|
#
|
304
310
|
def mark_application_extension_api_only
|
305
311
|
@application_extension_api_only = true
|
306
312
|
end
|
307
313
|
|
314
|
+
# Compiles the target with Swift's library evolution support, necessary to
|
315
|
+
# build XCFrameworks.
|
316
|
+
# Translates to BUILD_LIBRARY_FOR_DISTRIBUTION = YES in the build settings.
|
317
|
+
#
|
318
|
+
def mark_build_library_for_distribution
|
319
|
+
@build_library_for_distribution = true
|
320
|
+
end
|
321
|
+
|
308
322
|
# @return [Pathname] The absolute path of the prepare artifacts script.
|
309
323
|
#
|
324
|
+
# @deprecated
|
325
|
+
#
|
326
|
+
# @todo Remove in 2.0
|
327
|
+
#
|
310
328
|
def prepare_artifacts_script_path
|
311
329
|
support_files_dir + "#{label}-artifacts.sh"
|
312
330
|
end
|
313
331
|
|
332
|
+
# Returns an extension in the target that corresponds to the
|
333
|
+
# resource's input extension.
|
334
|
+
#
|
335
|
+
# @param [String] input_extension
|
336
|
+
# The input extension to map to.
|
337
|
+
#
|
338
|
+
# @return [String] The output extension.
|
339
|
+
#
|
340
|
+
def self.output_extension_for_resource(input_extension)
|
341
|
+
case input_extension
|
342
|
+
when '.storyboard' then '.storyboardc'
|
343
|
+
when '.xib' then '.nib'
|
344
|
+
when '.xcdatamodel' then '.mom'
|
345
|
+
when '.xcdatamodeld' then '.momd'
|
346
|
+
when '.xcmappingmodel' then '.cdm'
|
347
|
+
when '.xcassets' then '.car'
|
348
|
+
else input_extension
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def self.resource_extension_compilable?(input_extension)
|
353
|
+
output_extension_for_resource(input_extension) != input_extension && input_extension != '.xcassets'
|
354
|
+
end
|
355
|
+
|
314
356
|
#-------------------------------------------------------------------------#
|
315
357
|
|
316
358
|
private
|
@@ -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)}"
|
data/lib/cocoapods/validator.rb
CHANGED
@@ -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
|
@@ -433,7 +443,7 @@ module Pod
|
|
433
443
|
if !resp
|
434
444
|
warning('url', "There was a problem validating the URL #{url}.", true)
|
435
445
|
elsif !resp.success?
|
436
|
-
|
446
|
+
note('url', "The URL (#{url}) is not reachable.", true)
|
437
447
|
end
|
438
448
|
|
439
449
|
resp
|
@@ -546,6 +556,8 @@ module Pod
|
|
546
556
|
validation_dir.rmtree
|
547
557
|
end
|
548
558
|
|
559
|
+
# @return [String] The deployment targret of the library spec.
|
560
|
+
#
|
549
561
|
def deployment_target
|
550
562
|
deployment_target = spec.subspec_by_name(subspec_name).deployment_target(consumer.platform_name)
|
551
563
|
if consumer.platform_name == :ios && use_frameworks
|
@@ -557,7 +569,7 @@ module Pod
|
|
557
569
|
|
558
570
|
def download_pod
|
559
571
|
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)
|
572
|
+
podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks, test_spec_names, use_modular_headers, use_static_frameworks)
|
561
573
|
sandbox = Sandbox.new(config.sandbox_root)
|
562
574
|
@installer = Installer.new(sandbox, podfile)
|
563
575
|
@installer.use_default_plugins = false
|
@@ -584,7 +596,7 @@ module Pod
|
|
584
596
|
app_target = app_project.targets.first
|
585
597
|
pod_target = validation_pod_target
|
586
598
|
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') } }
|
599
|
+
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
600
|
Pod::Generator::AppTargetHelper.add_empty_swift_file(app_project, app_target) if @installer.pod_targets.any?(&:uses_swift?)
|
589
601
|
app_project.save
|
590
602
|
Xcodeproj::XCScheme.share_scheme(app_project.path, 'App')
|
@@ -701,7 +713,7 @@ module Pod
|
|
701
713
|
UI.warn "Skipping compilation with `xcodebuild` because target contains no sources.\n".yellow
|
702
714
|
else
|
703
715
|
if analyze
|
704
|
-
output = xcodebuild('analyze', scheme, 'Release')
|
716
|
+
output = xcodebuild('analyze', scheme, 'Release', :deployment_target => deployment_target)
|
705
717
|
find_output = Executable.execute_command('find', [validation_dir, '-name', '*.html'], false)
|
706
718
|
if find_output != ''
|
707
719
|
message = 'Static Analysis failed.'
|
@@ -710,7 +722,7 @@ module Pod
|
|
710
722
|
error('build_pod', message)
|
711
723
|
end
|
712
724
|
else
|
713
|
-
output = xcodebuild('build', scheme, 'Release')
|
725
|
+
output = xcodebuild('build', scheme, configuration ? configuration : 'Release', :deployment_target => deployment_target)
|
714
726
|
end
|
715
727
|
parsed_output = parse_xcodebuild_output(output)
|
716
728
|
translate_output_to_linter_messages(parsed_output)
|
@@ -732,12 +744,22 @@ module Pod
|
|
732
744
|
else
|
733
745
|
UI.message "\nTesting with `xcodebuild`.\n".yellow do
|
734
746
|
pod_target = validation_pod_target
|
735
|
-
consumer.spec.test_specs
|
747
|
+
all_test_specs = consumer.spec.test_specs
|
748
|
+
unless test_specs.nil?
|
749
|
+
test_spec_names = all_test_specs.map(&:base_name)
|
750
|
+
all_test_specs.select! { |test_spec| test_specs.include? test_spec.base_name }
|
751
|
+
test_specs.each do |test_spec|
|
752
|
+
unless test_spec_names.include? test_spec
|
753
|
+
UI.warn "Requested test spec `#{test_spec}` does not exist in the podspec. Existing test specs are `#{test_spec_names}`"
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
all_test_specs.each do |test_spec|
|
736
758
|
if !test_spec.supported_on_platform?(consumer.platform_name)
|
737
759
|
UI.warn "Skipping test spec `#{test_spec.name}` on platform `#{consumer.platform_name}` since it is not supported.\n".yellow
|
738
760
|
else
|
739
761
|
scheme = @installer.target_installation_results.first[pod_target.name].native_target_for_spec(test_spec)
|
740
|
-
output = xcodebuild('test', scheme, 'Debug')
|
762
|
+
output = xcodebuild('test', scheme, 'Debug', :deployment_target => test_spec.deployment_target(consumer.platform_name))
|
741
763
|
parsed_output = parse_xcodebuild_output(output)
|
742
764
|
translate_output_to_linter_messages(parsed_output)
|
743
765
|
end
|
@@ -953,7 +975,7 @@ module Pod
|
|
953
975
|
# @note The generated podfile takes into account whether the linter is
|
954
976
|
# in local mode.
|
955
977
|
#
|
956
|
-
def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false)
|
978
|
+
def podfile_from_spec(platform_name, deployment_target, use_frameworks = true, test_spec_names = [], use_modular_headers = false, use_static_frameworks = false)
|
957
979
|
name = subspec_name || spec.name
|
958
980
|
podspec = file.realpath
|
959
981
|
local = local?
|
@@ -963,12 +985,16 @@ module Pod
|
|
963
985
|
additional_path_pods = (include_podspecs ? Dir.glob(include_podspecs) : []) .select { |path| spec.name != Specification.from_file(path).name } - additional_podspec_pods
|
964
986
|
|
965
987
|
Pod::Podfile.new do
|
966
|
-
install! 'cocoapods', :deterministic_uuids => false
|
988
|
+
install! 'cocoapods', :deterministic_uuids => false, :warn_for_unused_master_specs_repo => false
|
967
989
|
# By default inhibit warnings for all pods, except the one being validated.
|
968
990
|
inhibit_all_warnings!
|
969
991
|
urls.each { |u| source(u) }
|
970
992
|
target 'App' do
|
971
|
-
|
993
|
+
if use_static_frameworks
|
994
|
+
use_frameworks!(:linkage => :static)
|
995
|
+
else
|
996
|
+
use_frameworks!(use_frameworks)
|
997
|
+
end
|
972
998
|
use_modular_headers! if use_modular_headers
|
973
999
|
platform(platform_name, deployment_target)
|
974
1000
|
if local
|
@@ -1016,7 +1042,7 @@ module Pod
|
|
1016
1042
|
l.include?('note: ') && (l !~ /expanded from macro/)
|
1017
1043
|
end
|
1018
1044
|
selected_lines.map do |l|
|
1019
|
-
new = l.gsub(%r{#{validation_dir}/Pods/}, '')
|
1045
|
+
new = l.force_encoding('UTF-8').gsub(%r{#{validation_dir}/Pods/}, '')
|
1020
1046
|
new.gsub!(/^ */, ' ')
|
1021
1047
|
end
|
1022
1048
|
end
|
@@ -1024,7 +1050,7 @@ module Pod
|
|
1024
1050
|
# @return [String] Executes xcodebuild in the current working directory and
|
1025
1051
|
# returns its output (both STDOUT and STDERR).
|
1026
1052
|
#
|
1027
|
-
def xcodebuild(action, scheme, configuration)
|
1053
|
+
def xcodebuild(action, scheme, configuration, deployment_target:)
|
1028
1054
|
require 'fourflusher'
|
1029
1055
|
command = %W(clean #{action} -workspace #{File.join(validation_dir, 'App.xcworkspace')} -scheme #{scheme} -configuration #{configuration})
|
1030
1056
|
case consumer.platform_name
|
@@ -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
|
7
|
+
# @return [Pathname] the path to the .framework or .a of this slice
|
6
8
|
#
|
7
9
|
attr_reader :path
|
8
10
|
|
@@ -22,28 +24,113 @@ module Pod
|
|
22
24
|
#
|
23
25
|
attr_reader :platform_variant
|
24
26
|
|
25
|
-
|
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 ||=
|
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
|
46
|
-
|
124
|
+
@binary_path ||= begin
|
125
|
+
case package_type
|
126
|
+
when :framework
|
127
|
+
path + name
|
128
|
+
when :library
|
129
|
+
path
|
130
|
+
else
|
131
|
+
raise Informative, "Invalid package type `#{package_type}`"
|
132
|
+
end
|
133
|
+
end
|
47
134
|
end
|
48
135
|
end
|
49
136
|
end
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
76
|
-
|
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
|
data/lib/cocoapods.rb
CHANGED
@@ -59,10 +59,12 @@ module Pod
|
|
59
59
|
autoload :Plist, 'cocoapods/generator/acknowledgements/plist'
|
60
60
|
autoload :BridgeSupport, 'cocoapods/generator/bridge_support'
|
61
61
|
autoload :Constant, 'cocoapods/generator/constant'
|
62
|
+
autoload :ScriptPhaseConstants, 'cocoapods/generator/script_phase_constants'
|
62
63
|
autoload :CopyResourcesScript, 'cocoapods/generator/copy_resources_script'
|
64
|
+
autoload :CopydSYMsScript, 'cocoapods/generator/copy_dsyms_script'
|
63
65
|
autoload :DummySource, 'cocoapods/generator/dummy_source'
|
64
66
|
autoload :EmbedFrameworksScript, 'cocoapods/generator/embed_frameworks_script'
|
65
|
-
autoload :
|
67
|
+
autoload :CopyXCFrameworksScript, 'cocoapods/generator/copy_xcframework_script'
|
66
68
|
autoload :FileList, 'cocoapods/generator/file_list'
|
67
69
|
autoload :Header, 'cocoapods/generator/header'
|
68
70
|
autoload :InfoPlistFile, 'cocoapods/generator/info_plist_file'
|