cocoapods-tt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cocoapods-tt/command/native/install.rb +56 -0
  3. data/lib/cocoapods-tt/command/native/update.rb +157 -0
  4. data/lib/cocoapods-tt/command/tt/make.rb +92 -0
  5. data/lib/cocoapods-tt/command/tt.rb +115 -0
  6. data/lib/cocoapods-tt/command.rb +1 -0
  7. data/lib/cocoapods-tt/gem_version.rb +3 -0
  8. data/lib/cocoapods-tt/native/command.rb +185 -0
  9. data/lib/cocoapods-tt/native/config.rb +366 -0
  10. data/lib/cocoapods-tt/native/core_overrides.rb +1 -0
  11. data/lib/cocoapods-tt/native/downloader/cache.rb +322 -0
  12. data/lib/cocoapods-tt/native/downloader/request.rb +86 -0
  13. data/lib/cocoapods-tt/native/downloader/response.rb +16 -0
  14. data/lib/cocoapods-tt/native/downloader.rb +192 -0
  15. data/lib/cocoapods-tt/native/executable.rb +247 -0
  16. data/lib/cocoapods-tt/native/external_sources/abstract_external_source.rb +205 -0
  17. data/lib/cocoapods-tt/native/external_sources/downloader_source.rb +30 -0
  18. data/lib/cocoapods-tt/native/external_sources/path_source.rb +55 -0
  19. data/lib/cocoapods-tt/native/external_sources/podspec_source.rb +54 -0
  20. data/lib/cocoapods-tt/native/external_sources.rb +57 -0
  21. data/lib/cocoapods-tt/native/gem_version.rb +5 -0
  22. data/lib/cocoapods-tt/native/generator/acknowledgements/markdown.rb +44 -0
  23. data/lib/cocoapods-tt/native/generator/acknowledgements/plist.rb +94 -0
  24. data/lib/cocoapods-tt/native/generator/acknowledgements.rb +107 -0
  25. data/lib/cocoapods-tt/native/generator/app_target_helper.rb +363 -0
  26. data/lib/cocoapods-tt/native/generator/bridge_support.rb +22 -0
  27. data/lib/cocoapods-tt/native/generator/constant.rb +19 -0
  28. data/lib/cocoapods-tt/native/generator/copy_dsyms_script.rb +56 -0
  29. data/lib/cocoapods-tt/native/generator/copy_resources_script.rb +223 -0
  30. data/lib/cocoapods-tt/native/generator/copy_xcframework_script.rb +227 -0
  31. data/lib/cocoapods-tt/native/generator/dummy_source.rb +31 -0
  32. data/lib/cocoapods-tt/native/generator/embed_frameworks_script.rb +196 -0
  33. data/lib/cocoapods-tt/native/generator/file_list.rb +39 -0
  34. data/lib/cocoapods-tt/native/generator/header.rb +103 -0
  35. data/lib/cocoapods-tt/native/generator/info_plist_file.rb +128 -0
  36. data/lib/cocoapods-tt/native/generator/module_map.rb +99 -0
  37. data/lib/cocoapods-tt/native/generator/prefix_header.rb +60 -0
  38. data/lib/cocoapods-tt/native/generator/script_phase_constants.rb +100 -0
  39. data/lib/cocoapods-tt/native/generator/umbrella_header.rb +46 -0
  40. data/lib/cocoapods-tt/native/hooks_manager.rb +132 -0
  41. data/lib/cocoapods-tt/native/installer/analyzer/analysis_result.rb +87 -0
  42. data/lib/cocoapods-tt/native/installer/analyzer/locking_dependency_analyzer.rb +103 -0
  43. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant.rb +87 -0
  44. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant_set.rb +175 -0
  45. data/lib/cocoapods-tt/native/installer/analyzer/podfile_dependency_cache.rb +55 -0
  46. data/lib/cocoapods-tt/native/installer/analyzer/sandbox_analyzer.rb +268 -0
  47. data/lib/cocoapods-tt/native/installer/analyzer/specs_state.rb +108 -0
  48. data/lib/cocoapods-tt/native/installer/analyzer/target_inspection_result.rb +58 -0
  49. data/lib/cocoapods-tt/native/installer/analyzer/target_inspector.rb +258 -0
  50. data/lib/cocoapods-tt/native/installer/analyzer.rb +1204 -0
  51. data/lib/cocoapods-tt/native/installer/base_install_hooks_context.rb +135 -0
  52. data/lib/cocoapods-tt/native/installer/installation_options.rb +195 -0
  53. data/lib/cocoapods-tt/native/installer/pod_source_installer.rb +224 -0
  54. data/lib/cocoapods-tt/native/installer/pod_source_preparer.rb +77 -0
  55. data/lib/cocoapods-tt/native/installer/podfile_validator.rb +168 -0
  56. data/lib/cocoapods-tt/native/installer/post_install_hooks_context.rb +9 -0
  57. data/lib/cocoapods-tt/native/installer/post_integrate_hooks_context.rb +9 -0
  58. data/lib/cocoapods-tt/native/installer/pre_install_hooks_context.rb +51 -0
  59. data/lib/cocoapods-tt/native/installer/pre_integrate_hooks_context.rb +9 -0
  60. data/lib/cocoapods-tt/native/installer/project_cache/project_cache.rb +11 -0
  61. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analysis_result.rb +53 -0
  62. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analyzer.rb +200 -0
  63. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_version.rb +43 -0
  64. data/lib/cocoapods-tt/native/installer/project_cache/project_installation_cache.rb +103 -0
  65. data/lib/cocoapods-tt/native/installer/project_cache/project_metadata_cache.rb +73 -0
  66. data/lib/cocoapods-tt/native/installer/project_cache/target_cache_key.rb +176 -0
  67. data/lib/cocoapods-tt/native/installer/project_cache/target_metadata.rb +74 -0
  68. data/lib/cocoapods-tt/native/installer/sandbox_dir_cleaner.rb +105 -0
  69. data/lib/cocoapods-tt/native/installer/sandbox_header_paths_installer.rb +45 -0
  70. data/lib/cocoapods-tt/native/installer/source_provider_hooks_context.rb +34 -0
  71. data/lib/cocoapods-tt/native/installer/target_uuid_generator.rb +34 -0
  72. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +179 -0
  73. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator.rb +815 -0
  74. data/lib/cocoapods-tt/native/installer/user_project_integrator.rb +280 -0
  75. data/lib/cocoapods-tt/native/installer/xcode/multi_pods_project_generator.rb +82 -0
  76. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +66 -0
  77. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb +192 -0
  78. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/app_host_installer.rb +154 -0
  79. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/file_references_installer.rb +329 -0
  80. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +195 -0
  81. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_installer.rb +1239 -0
  82. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_integrator.rb +312 -0
  83. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pods_project_writer.rb +90 -0
  84. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/project_generator.rb +120 -0
  85. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installation_result.rb +140 -0
  86. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer.rb +257 -0
  87. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer_helper.rb +110 -0
  88. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator.rb +291 -0
  89. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator_result.rb +54 -0
  90. data/lib/cocoapods-tt/native/installer/xcode/single_pods_project_generator.rb +38 -0
  91. data/lib/cocoapods-tt/native/installer/xcode/target_validator.rb +170 -0
  92. data/lib/cocoapods-tt/native/installer/xcode.rb +11 -0
  93. data/lib/cocoapods-tt/native/installer.rb +1044 -0
  94. data/lib/cocoapods-tt/native/native_target_extension.rb +60 -0
  95. data/lib/cocoapods-tt/native/open-uri.rb +33 -0
  96. data/lib/cocoapods-tt/native/podfile.rb +13 -0
  97. data/lib/cocoapods-tt/native/project.rb +544 -0
  98. data/lib/cocoapods-tt/native/resolver/lazy_specification.rb +88 -0
  99. data/lib/cocoapods-tt/native/resolver/resolver_specification.rb +41 -0
  100. data/lib/cocoapods-tt/native/resolver.rb +600 -0
  101. data/lib/cocoapods-tt/native/sandbox/file_accessor.rb +532 -0
  102. data/lib/cocoapods-tt/native/sandbox/headers_store.rb +163 -0
  103. data/lib/cocoapods-tt/native/sandbox/path_list.rb +242 -0
  104. data/lib/cocoapods-tt/native/sandbox/pod_dir_cleaner.rb +71 -0
  105. data/lib/cocoapods-tt/native/sandbox/podspec_finder.rb +23 -0
  106. data/lib/cocoapods-tt/native/sandbox.rb +470 -0
  107. data/lib/cocoapods-tt/native/sources_manager.rb +221 -0
  108. data/lib/cocoapods-tt/native/target/aggregate_target.rb +558 -0
  109. data/lib/cocoapods-tt/native/target/build_settings.rb +1385 -0
  110. data/lib/cocoapods-tt/native/target/pod_target.rb +1168 -0
  111. data/lib/cocoapods-tt/native/target.rb +378 -0
  112. data/lib/cocoapods-tt/native/user_interface/error_report.rb +204 -0
  113. data/lib/cocoapods-tt/native/user_interface/inspector_reporter.rb +102 -0
  114. data/lib/cocoapods-tt/native/user_interface.rb +463 -0
  115. data/lib/cocoapods-tt/native/validator.rb +1170 -0
  116. data/lib/cocoapods-tt/native/version_metadata.rb +26 -0
  117. data/lib/cocoapods-tt/native/xcode/framework_paths.rb +54 -0
  118. data/lib/cocoapods-tt/native/xcode/linkage_analyzer.rb +22 -0
  119. data/lib/cocoapods-tt/native/xcode/xcframework/xcframework_slice.rb +138 -0
  120. data/lib/cocoapods-tt/native/xcode/xcframework.rb +99 -0
  121. data/lib/cocoapods-tt/native/xcode.rb +7 -0
  122. data/lib/cocoapods-tt.rb +1 -0
  123. data/lib/cocoapods_plugin.rb +17 -0
  124. metadata +193 -0
@@ -0,0 +1,108 @@
1
+ require 'set'
2
+
3
+ module Pod
4
+ class Installer
5
+ class Analyzer
6
+ # This class represents the state of a collection of Pods.
7
+ #
8
+ # @note The names of the pods stored by this class are always the **root**
9
+ # name of the specification.
10
+ #
11
+ # @note The motivation for this class is to ensure that the names of the
12
+ # subspecs are added instead of the name of the Pods.
13
+ #
14
+ class SpecsState
15
+ # @return [Set<String>] the names of the pods that were added.
16
+ #
17
+ attr_reader :added
18
+
19
+ # @return [Set<String>] the names of the pods that were changed.
20
+ #
21
+ attr_reader :changed
22
+
23
+ # @return [Set<String>] the names of the pods that were deleted.
24
+ #
25
+ attr_reader :deleted
26
+
27
+ # @return [Set<String>] the names of the pods that were unchanged.
28
+ #
29
+ attr_reader :unchanged
30
+
31
+ # Initialize a new instance
32
+ #
33
+ # @param [Hash{Symbol=>String}] pods_by_state
34
+ # The name of the pods grouped by their state
35
+ # (`:added`, `:removed`, `:changed` or `:unchanged`).
36
+ #
37
+ def initialize(pods_by_state = nil)
38
+ @added = Set.new
39
+ @deleted = Set.new
40
+ @changed = Set.new
41
+ @unchanged = Set.new
42
+
43
+ if pods_by_state
44
+ {
45
+ :added => :added,
46
+ :changed => :changed,
47
+ :removed => :deleted,
48
+ :unchanged => :unchanged,
49
+ }.each do |state, spec_state|
50
+ Array(pods_by_state[state]).each do |name|
51
+ add_name(name, spec_state)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ # Displays the state of each pod.
58
+ #
59
+ # @return [void]
60
+ #
61
+ def print
62
+ states = %i(added deleted changed unchanged)
63
+ lines(states).each do |line|
64
+ UI.message(line, '', 2)
65
+ end
66
+ end
67
+
68
+ def to_s(states: %i(added deleted changed unchanged))
69
+ lines(states).join("\n")
70
+ end
71
+
72
+ # Adds the name of a Pod to the give state.
73
+ #
74
+ # @param [String] name
75
+ # the name of the Pod.
76
+ #
77
+ # @param [Symbol] state
78
+ # the state of the Pod.
79
+ #
80
+ # @return [void]
81
+ #
82
+ def add_name(name, state)
83
+ send(state) << Specification.root_name(name)
84
+ end
85
+
86
+ private
87
+
88
+ # @return [Array<String>] A description of changes for the given states,
89
+ # one per line
90
+ #
91
+ def lines(states)
92
+ prefixes = {
93
+ :added => 'A'.green,
94
+ :deleted => 'R'.red,
95
+ :changed => 'M'.yellow,
96
+ :unchanged => '-',
97
+ }
98
+
99
+ states.flat_map do |state|
100
+ send(state).sort.map do |pod|
101
+ prefixes[state.to_sym] + " #{pod}"
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,58 @@
1
+ module Pod
2
+ class Installer
3
+ class Analyzer
4
+ class TargetInspectionResult
5
+ # @return [TargetDefinition] the target definition, whose project was
6
+ # inspected
7
+ #
8
+ attr_reader :target_definition
9
+
10
+ # @return [Xcodeproj::Project] the user's Xcode project
11
+ #
12
+ attr_reader :project
13
+
14
+ # @return [Array<String>] the uuid of the user's targets
15
+ #
16
+ attr_reader :project_target_uuids
17
+
18
+ # @return [Hash{String=>Symbol}] A hash representing the user build
19
+ # configurations where each key corresponds to the name of a
20
+ # configuration and its value to its type (`:debug` or
21
+ # `:release`).
22
+ #
23
+ attr_reader :build_configurations
24
+
25
+ # @return [Platform] the platform of the user targets
26
+ #
27
+ attr_reader :platform
28
+
29
+ # @return [Array<String>] the architectures used by user's targets
30
+ #
31
+ attr_reader :archs
32
+
33
+ # @return [Pathname] the path to the root of the project containing the user target
34
+ #
35
+ attr_reader :client_root
36
+
37
+ # Initialize a new instance
38
+ #
39
+ # @param [TargetDefinition] target_definition @see #target_definition
40
+ # @param [Xcodeproj::Project] project @see #project
41
+ # @param [Array<String>] project_target_uuids @see #project_target_uuids
42
+ # @param [Hash{String=>Symbol}] build_configurations @see #build_configurations
43
+ # @param [Platform] platform @see #platform
44
+ # @param [Array<String>] archs @see #archs
45
+ #
46
+ def initialize(target_definition, project, project_target_uuids, build_configurations, platform, archs)
47
+ @target_definition = target_definition
48
+ @project = project
49
+ @project_target_uuids = project_target_uuids
50
+ @build_configurations = build_configurations
51
+ @platform = platform
52
+ @archs = archs
53
+ @client_root = Pathname.new(project.project_dir + project.root_object.project_dir_path).realpath
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,258 @@
1
+ require 'active_support/core_ext/array/conversions'
2
+
3
+ module Pod
4
+ class Installer
5
+ class Analyzer
6
+ class TargetInspector
7
+ PLATFORM_INFO_URL = 'https://guides.cocoapods.org/syntax/podfile.html#platform'.freeze
8
+
9
+ # @return [TargetDefinition] the target definition to inspect
10
+ #
11
+ attr_reader :target_definition
12
+
13
+ # @return [Pathname] the root of the CocoaPods installation where the
14
+ # Podfile is located
15
+ #
16
+ attr_reader :installation_root
17
+
18
+ # Initialize a new instance
19
+ #
20
+ # @param [TargetDefinition] target_definition
21
+ # @see #target_definition
22
+ #
23
+ # @param [Pathname] installation_root
24
+ # @see #installation_root
25
+ #
26
+ def initialize(target_definition, installation_root)
27
+ @target_definition = target_definition
28
+ @installation_root = installation_root
29
+ end
30
+
31
+ # Inspect the #target_definition
32
+ #
33
+ # @raise If no `user_project` is set
34
+ #
35
+ # @return [TargetInspectionResult] the result of the inspection of the target definition within the user project
36
+ #
37
+ def compute_results(user_project)
38
+ raise ArgumentError, 'Cannot compute results without a user project set' unless user_project
39
+
40
+ targets = compute_targets(user_project)
41
+ project_target_uuids = targets.map(&:uuid)
42
+ build_configurations = compute_build_configurations(targets)
43
+ platform = compute_platform(targets)
44
+ archs = compute_archs(targets)
45
+ swift_version = compute_swift_version_from_targets(targets)
46
+
47
+ result = TargetInspectionResult.new(target_definition, user_project, project_target_uuids,
48
+ build_configurations, platform, archs)
49
+ result.target_definition.swift_version = swift_version
50
+ result
51
+ end
52
+
53
+ # Returns the path of the user project that the #target_definition
54
+ # should integrate.
55
+ #
56
+ # @raise If the project is implicit and there are multiple projects.
57
+ #
58
+ # @raise If the path doesn't exits.
59
+ #
60
+ # @return [Pathname] the path of the user project.
61
+ #
62
+ def compute_project_path
63
+ if target_definition.user_project_path
64
+ path = installation_root + target_definition.user_project_path
65
+ path = "#{path}.xcodeproj" unless File.extname(path) == '.xcodeproj'
66
+ path = Pathname.new(path)
67
+ unless path.exist?
68
+ raise Informative, 'Unable to find the Xcode project ' \
69
+ "`#{path}` for the target `#{target_definition.label}`."
70
+ end
71
+ else
72
+ xcodeprojs = installation_root.children.select { |e| e.fnmatch('*.xcodeproj') }
73
+ if xcodeprojs.size == 1
74
+ path = xcodeprojs.first
75
+ else
76
+ raise Informative, 'Could not automatically select an Xcode project. ' \
77
+ "Specify one in your Podfile like so:\n\n" \
78
+ " project 'path/to/Project.xcodeproj'\n"
79
+ end
80
+ end
81
+ path
82
+ end
83
+
84
+ #-----------------------------------------------------------------------#
85
+
86
+ private
87
+
88
+ # Returns a list of the targets from the project of #target_definition
89
+ # that needs to be integrated.
90
+ #
91
+ # @note The method first looks if there is a target specified with
92
+ # the `link_with` option of the {TargetDefinition}. Otherwise
93
+ # it looks for the target that has the same name of the target
94
+ # definition. Finally if no target was found the first
95
+ # encountered target is returned (it is assumed to be the one
96
+ # to integrate in simple projects).
97
+ #
98
+ # @param [Xcodeproj::Project] user_project
99
+ # the user project
100
+ #
101
+ # @return [Array<PBXNativeTarget>]
102
+ #
103
+ def compute_targets(user_project)
104
+ native_targets = user_project.native_targets
105
+ target = native_targets.find { |t| t.name == target_definition.name.to_s }
106
+ unless target
107
+ found = native_targets.map { |t| "`#{t.name}`" }.to_sentence
108
+ raise Informative, "Unable to find a target named `#{target_definition.name}` in project `#{Pathname(user_project.path).basename}`, did find #{found}."
109
+ end
110
+ [target]
111
+ end
112
+
113
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
114
+ # #target_definition which needs to be integrated
115
+ #
116
+ # @return [Hash{String=>Symbol}] A hash representing the user build
117
+ # configurations where each key corresponds to the name of a
118
+ # configuration and its value to its type (`:debug` or `:release`).
119
+ #
120
+ def compute_build_configurations(user_targets)
121
+ if user_targets
122
+ user_targets.flat_map { |t| t.build_configurations.map(&:name) }.each_with_object({}) do |name, hash|
123
+ hash[name] = name == 'Debug' ? :debug : :release
124
+ end.merge(target_definition.build_configurations || {})
125
+ else
126
+ target_definition.build_configurations || {}
127
+ end
128
+ end
129
+
130
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
131
+ # #target_definition which needs to be integrated
132
+ #
133
+ # @return [Platform] The platform of the user's targets
134
+ #
135
+ # @note This resolves to the lowest deployment target across the user
136
+ # targets.
137
+ #
138
+ # @todo Is assigning the platform to the target definition the best way
139
+ # to go?
140
+ #
141
+ def compute_platform(user_targets)
142
+ return target_definition.platform if target_definition.platform
143
+ name = nil
144
+ deployment_target = nil
145
+
146
+ user_targets.each do |target|
147
+ name ||= target.platform_name
148
+ raise Informative, 'Targets with different platforms' unless name == target.platform_name
149
+ if !deployment_target || deployment_target > Version.new(target.deployment_target)
150
+ deployment_target = Version.new(target.deployment_target)
151
+ end
152
+ end
153
+
154
+ unless name
155
+ raise Informative,
156
+ "Unable to determine the platform for the `#{target_definition.name}` target."
157
+ end
158
+
159
+ UI.warn "Automatically assigning platform `#{Platform.string_name(name)}` with version `#{deployment_target}` " \
160
+ "on target `#{target_definition.name}` because no platform was specified. " \
161
+ "Please specify a platform for this target in your Podfile. See `#{PLATFORM_INFO_URL}`."
162
+
163
+ target_definition.set_platform(name, deployment_target)
164
+ Platform.new(name, deployment_target)
165
+ end
166
+
167
+ # Computes the architectures relevant for the user's targets.
168
+ #
169
+ # @param [Array<PBXNativeTarget] user_targets the user's targets of the project of
170
+ # #target_definition which needs to be integrated
171
+ #
172
+ # @return [Array<String>]
173
+ #
174
+ def compute_archs(user_targets)
175
+ user_targets.flat_map do |target|
176
+ Array(target.common_resolved_build_setting('ARCHS'))
177
+ end.compact.uniq.sort
178
+ end
179
+
180
+ # Checks if any of the targets for the {TargetDefinition} computed before
181
+ # by #compute_user_project_targets is recommended to be build as a framework
182
+ # due the presence of Swift source code in any of the source build phases.
183
+ #
184
+ # @param [TargetDefinition] target_definition
185
+ # the target definition
186
+ #
187
+ # @param [Array<PBXNativeTarget>] native_targets
188
+ # the targets which are checked for presence of Swift source code
189
+ #
190
+ # @return [Boolean] Whether the user project targets to integrate into
191
+ # uses Swift
192
+ #
193
+ def compute_recommends_frameworks(target_definition, native_targets)
194
+ file_predicate = nil
195
+ file_predicate = proc do |file_ref|
196
+ if file_ref.respond_to?(:last_known_file_type)
197
+ file_ref.last_known_file_type == 'sourcecode.swift'
198
+ elsif file_ref.respond_to?(:files)
199
+ file_ref.files.any?(&file_predicate)
200
+ else
201
+ false
202
+ end
203
+ end
204
+ target_definition.platform.supports_dynamic_frameworks? || native_targets.any? do |target|
205
+ target.source_build_phase.files.any? do |build_file|
206
+ file_predicate.call(build_file.file_ref)
207
+ end
208
+ end
209
+ end
210
+
211
+ # Compute the Swift version for the target build configurations. If more
212
+ # than one Swift version is defined for a given target, then it will raise.
213
+ #
214
+ # @param [Array<PBXNativeTarget>] targets
215
+ # the targets that are checked for Swift versions.
216
+ #
217
+ # @return [String] the targets Swift version or nil
218
+ #
219
+ def compute_swift_version_from_targets(targets)
220
+ versions_to_targets = targets.inject({}) do |memo, target|
221
+ # User project may have an xcconfig that specifies the `SWIFT_VERSION`.
222
+ # Xcodeproj handles that xcconfig either not being set or the file not being present on disk.
223
+ # After the first integration the xcconfig set is most probably
224
+ # the one that was generated from CocoaPods. See https://github.com/CocoaPods/CocoaPods/issues/7731 for
225
+ # more details.
226
+ versions = target.resolved_build_setting('SWIFT_VERSION', true).values
227
+ versions.each do |version|
228
+ memo[version] = [] if memo[version].nil?
229
+ memo[version] << target.name unless memo[version].include? target.name
230
+ end
231
+ memo
232
+ end
233
+
234
+ case versions_to_targets.count
235
+ when 0
236
+ nil
237
+ when 1
238
+ versions_to_targets.keys.first
239
+ else
240
+ target_version_pairs = versions_to_targets.map do |version_names, target_names|
241
+ target_names.map { |target_name| [target_name, version_names] }
242
+ end
243
+
244
+ sorted_pairs = target_version_pairs.flat_map { |i| i }.sort_by do |target_name, version_name|
245
+ "#{target_name} #{version_name}"
246
+ end
247
+
248
+ formatted_output = sorted_pairs.map do |target, version_name|
249
+ "#{target}: Swift #{version_name}"
250
+ end.join("\n")
251
+
252
+ raise Informative, "There may only be up to 1 unique SWIFT_VERSION per target. Found target(s) with multiple Swift versions:\n#{formatted_output}"
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end