pod-builder-y 2.3.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 (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE.txt +13 -0
  5. data/README.md +385 -0
  6. data/Rakefile +2 -0
  7. data/bin/console +16 -0
  8. data/bin/setup +8 -0
  9. data/exe/pod_builder_y +406 -0
  10. data/lib/core_ext/string.rb +5 -0
  11. data/lib/pod_builder/analyze.rb +59 -0
  12. data/lib/pod_builder/analyzer.rb +16 -0
  13. data/lib/pod_builder/command.rb +14 -0
  14. data/lib/pod_builder/command/build.rb +228 -0
  15. data/lib/pod_builder/command/build_all.rb +15 -0
  16. data/lib/pod_builder/command/clean.rb +75 -0
  17. data/lib/pod_builder/command/deintegrate.rb +101 -0
  18. data/lib/pod_builder/command/generate_lldbinit.rb +128 -0
  19. data/lib/pod_builder/command/generate_podspec.rb +22 -0
  20. data/lib/pod_builder/command/info.rb +18 -0
  21. data/lib/pod_builder/command/init.rb +148 -0
  22. data/lib/pod_builder/command/install_sources.rb +79 -0
  23. data/lib/pod_builder/command/none.rb +16 -0
  24. data/lib/pod_builder/command/restore_all.rb +33 -0
  25. data/lib/pod_builder/command/switch.rb +224 -0
  26. data/lib/pod_builder/command/sync_podfile.rb +34 -0
  27. data/lib/pod_builder/command/update.rb +43 -0
  28. data/lib/pod_builder/configuration.rb +300 -0
  29. data/lib/pod_builder/core.rb +222 -0
  30. data/lib/pod_builder/info.rb +90 -0
  31. data/lib/pod_builder/install.rb +505 -0
  32. data/lib/pod_builder/licenses.rb +73 -0
  33. data/lib/pod_builder/podfile.rb +700 -0
  34. data/lib/pod_builder/podfile/pre_actions_swizzles.rb +84 -0
  35. data/lib/pod_builder/podfile_cp.rb +99 -0
  36. data/lib/pod_builder/podfile_item.rb +530 -0
  37. data/lib/pod_builder/podspec.rb +269 -0
  38. data/lib/pod_builder/rome/post_install.rb +446 -0
  39. data/lib/pod_builder/rome/pre_install.rb +6 -0
  40. data/lib/pod_builder/templates/build_podfile.template +70 -0
  41. data/lib/pod_builder/templates/build_podspec.template +19 -0
  42. data/lib/pod_builder/version.rb +4 -0
  43. data/pod-builder.gemspec +37 -0
  44. metadata +240 -0
@@ -0,0 +1,84 @@
1
+ require 'xcodeproj'
2
+ require 'pod_builder/core'
3
+ require 'digest'
4
+
5
+ class Pod::Generator::FileList
6
+ alias_method :swz_initialize, :initialize
7
+
8
+ def initialize(paths)
9
+ paths.uniq!
10
+ swz_initialize(paths)
11
+ end
12
+ end
13
+
14
+ class Pod::Generator::CopyXCFrameworksScript
15
+ alias_method :swz_initialize, :initialize
16
+
17
+ def initialize(xcframeworks, sandbox_root, platform)
18
+ xcframeworks.uniq! { |t| t.path }
19
+ swz_initialize(xcframeworks, sandbox_root, platform)
20
+ end
21
+ end
22
+
23
+ class Pod::Generator::EmbedFrameworksScript
24
+ alias_method :swz_initialize, :initialize
25
+
26
+ def initialize(*args)
27
+ raise "Unsupported CocoaPods version" if (args.count == 0 || args.count > 2)
28
+
29
+ frameworks_by_config = args[0]
30
+ frameworks_by_config.keys.each do |key|
31
+ items = frameworks_by_config[key]
32
+ items.uniq! { |t| t.source_path }
33
+ frameworks_by_config[key] = items
34
+ end
35
+
36
+ if args.count == 2
37
+ # CocoaPods 1.10.0 and newer
38
+ xcframeworks_by_config = args[1]
39
+ xcframeworks_by_config.keys.each do |key|
40
+ items = xcframeworks_by_config[key]
41
+ items.uniq! { |t| t.path }
42
+ xcframeworks_by_config[key] = items
43
+ end
44
+ end
45
+
46
+ swz_initialize(*args)
47
+ end
48
+ end
49
+
50
+ class Pod::Generator::CopyResourcesScript
51
+ alias_method :swz_initialize, :initialize
52
+
53
+ def initialize(resources_by_config, platform)
54
+ resources_by_config.keys.each do |key|
55
+ items = resources_by_config[key]
56
+ items.uniq!
57
+
58
+ colliding_resources = items.group_by { |t| File.basename(t) }.values.select { |t| t.count > 1 }
59
+
60
+ unless colliding_resources.empty?
61
+ message = ""
62
+ colliding_resources.each do |resources|
63
+ resources.map! { |t| File.expand_path(t.gsub("${PODS_ROOT}", "#{Dir.pwd}/Pods")) }
64
+ # check that files are identical.
65
+ # For files with paths that are resolved (e.g containing ${PODS_ROOT}) we use the file hash
66
+ # we fallback to the filename for the others
67
+ hashes = resources.map { |t| File.exists?(t) ? Digest::MD5.hexdigest(File.read(t)) : File.basename(t) }
68
+ if hashes.uniq.count > 1
69
+ message += resources.join("\n") + "\n"
70
+ end
71
+ end
72
+
73
+ unless message.empty?
74
+ message = "\n\nThe following resources have the same name and will collide once copied into application bundle:\n" + message
75
+ raise message
76
+ end
77
+ end
78
+
79
+ resources_by_config[key] = items
80
+ end
81
+
82
+ swz_initialize(resources_by_config, platform)
83
+ end
84
+ end
@@ -0,0 +1,99 @@
1
+ require 'cocoapods/podfile.rb'
2
+
3
+ module Pod
4
+ class Podfile
5
+ class TargetDefinition
6
+ def pb_to_s(all_buildable_items, indent_level = 0, parent_pods = [])
7
+ indentation = " " * indent_level
8
+ target_s = "#{indentation}target '#{self.name}' do\n"
9
+
10
+ child_indentation = " " * (indent_level + 1)
11
+
12
+ explicit_deps = self.dependencies.map { |t| all_buildable_items.detect { |u| u.name == t.name } }.compact
13
+
14
+ pod_entries = []
15
+ prebuild_entries = []
16
+ self.dependencies.each do |dep|
17
+ if podfile_item = all_buildable_items.detect { |t| t.name == dep.name }
18
+ is_prebuilt = all_buildable_items.select { |t| t.root_name == dep.root_name}.all?(&:is_prebuilt)
19
+ if File.exist?(podfile_item.prebuilt_podspec_path) && !is_prebuilt
20
+ prebuild_entries.push(podfile_item)
21
+ else
22
+ pod_entries.push(podfile_item)
23
+ end
24
+
25
+ non_explicit_dependencies = podfile_item.recursive_dependencies(all_buildable_items) - explicit_deps
26
+ non_explicit_dependencies_root_names = non_explicit_dependencies.map(&:root_name).uniq.filter { |t| t != podfile_item.root_name }
27
+ non_explicit_dependencies = non_explicit_dependencies_root_names.map { |x|
28
+ if item = all_buildable_items.detect { |t| x == t.name }
29
+ item
30
+ else
31
+ item = all_buildable_items.detect { |t| x == t.root_name }
32
+ end
33
+ }.compact
34
+
35
+ non_explicit_dependencies.each do |dep|
36
+ dep_item = all_buildable_items.detect { |x| x.name == dep.name }
37
+
38
+ is_prebuilt = all_buildable_items.select { |t| t.root_name == dep.root_name}.all?(&:is_prebuilt)
39
+ if File.exist?(dep_item.prebuilt_podspec_path) && !is_prebuilt
40
+ prebuild_entries.push(dep_item)
41
+ else
42
+ pod_entries.push(dep_item)
43
+ end
44
+
45
+ explicit_deps.push(dep)
46
+ end
47
+ end
48
+ end
49
+
50
+ prebuild_entries = prebuild_entries.uniq.sort_by { |t| t.name }
51
+ pod_entries = pod_entries.uniq.sort_by { |t| t.name }
52
+
53
+ # Don't include inherited pods
54
+ prebuild_entries.reject! { |t| parent_pods.include?(t) }
55
+ pod_entries.reject! { |t| parent_pods.include?(t) }
56
+
57
+ prebuild_entries.each do |pod|
58
+ target_s += "#{child_indentation}#{pod.prebuilt_entry(false, false)}\n"
59
+ end
60
+ pod_entries.each do |pod|
61
+ target_s += "#{child_indentation}#{pod.entry(true, false)}\n"
62
+ end
63
+
64
+ if self.children.count > 0
65
+ target_s += "\n"
66
+ target_s += @children.map { |t| t.pb_to_s(all_buildable_items, indent_level + 1, parent_pods + pod_entries + prebuild_entries) }.join("\n\n")
67
+ end
68
+
69
+ target_s += "#{indentation}end\n"
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ module Pod
76
+ class Podfile
77
+ def pb_to_s(all_buildable_items)
78
+ initial_targets = root_target_definitions.first.children
79
+
80
+ platform = @current_target_definition.platform
81
+
82
+ podfile_s = "platform :#{platform.to_sym}, '#{platform.deployment_target.to_s}'\n\n"
83
+ podfile_s += initial_targets.map { |t| t.pb_to_s(all_buildable_items) }.join("\n\n")
84
+
85
+ return podfile_s
86
+ end
87
+ end
88
+ end
89
+
90
+ class PodfileCP
91
+ def self.podfile_path_transform(path)
92
+ prebuilt_prefix = PodBuilder::prebuiltpath.gsub(PodBuilder::project_path, "")[1..] + "/"
93
+ if path.start_with?(prebuilt_prefix)
94
+ return path
95
+ else
96
+ return PodBuilder::Podfile.podfile_path_transform(path)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,530 @@
1
+ # This class is the model that PodBuilder uses for every pod spec. The model is instantiated
2
+ # from Pod::Specification
3
+
4
+ module PodBuilder
5
+ class PodfileItem
6
+ # @return [String] The git repo
7
+ #
8
+ attr_reader :repo
9
+
10
+ # @return [String] The git branch
11
+ #
12
+ attr_reader :branch
13
+
14
+ # @return [String] A checksum for the spec
15
+ #
16
+ attr_reader :checksum
17
+
18
+ # @return [String] Matches @name unless for subspecs were it stores the name of the root pod
19
+ #
20
+ attr_reader :root_name
21
+
22
+ # @return [String] The name of the pod, which might be the subspec name if appicable
23
+ #
24
+ attr_reader :name
25
+
26
+ # @return [String] The pinned tag of the pod, if any
27
+ #
28
+ attr_reader :tag
29
+
30
+ # @return [String] The pinned version of the pod, if any
31
+ #
32
+ attr_reader :version
33
+
34
+ # @return Array<[String]> The available versions of the pod
35
+ #
36
+ attr_reader :available_versions
37
+
38
+ # @return [String] Local path, if any
39
+ #
40
+ attr_accessor :path
41
+
42
+ # @return [String] Local podspec path, if any
43
+ #
44
+ attr_accessor :podspec_path
45
+
46
+ # @return [String] The pinned commit of the pod, if any
47
+ #
48
+ attr_reader :commit
49
+
50
+ # @return [String] The module name
51
+ #
52
+ attr_reader :module_name
53
+
54
+ # @return [String] The swift version if applicable
55
+ #
56
+ attr_reader :swift_version
57
+
58
+ # @return [Array<String>] The pod's dependency names, if any. Use dependencies() to get the [Array<PodfileItem>]
59
+ #
60
+ attr_reader :dependency_names
61
+
62
+ # @return [Array<String>] The pod's external dependency names (excluding subspecs), if any
63
+ #
64
+ attr_reader :external_dependency_names
65
+
66
+ # @return [Bool] True if the pod is shipped as a static binary
67
+ #
68
+ attr_reader :is_static
69
+
70
+ # @return [Array<Hash>] The pod's xcconfig configuration
71
+ #
72
+ attr_reader :xcconfig
73
+
74
+ # @return [Bool] Is external pod
75
+ #
76
+ attr_accessor :is_external
77
+
78
+ # @return [String] Header directory name
79
+ #
80
+ attr_accessor :header_dir
81
+
82
+ # @return [String] The pod's build configuration
83
+ #
84
+ attr_accessor :build_configuration
85
+
86
+ # @return [String] The pod's vendored frameworks
87
+ #
88
+ attr_accessor :vendored_frameworks
89
+
90
+ # @return [String] The pod's vendored libraries
91
+ #
92
+ attr_accessor :vendored_libraries
93
+
94
+ # @return [String] Framweworks the pod needs to link to
95
+ #
96
+ attr_accessor :frameworks
97
+
98
+ # @return [String] Weak framweworks the pod needs to link to
99
+ #
100
+ attr_accessor :weak_frameworks
101
+
102
+ # @return [String] Libraries the pod needs to link to
103
+ #
104
+ attr_accessor :libraries
105
+
106
+ # @return [String] source_files
107
+ #
108
+ attr_accessor :source_files
109
+
110
+ # @return [String] license
111
+ #
112
+ attr_accessor :license
113
+
114
+ # @return [String] summary
115
+ #
116
+ attr_accessor :summary
117
+
118
+ # @return [Hash] source
119
+ #
120
+ attr_accessor :source
121
+
122
+ # @return [Hash] authors
123
+ #
124
+ attr_accessor :authors
125
+
126
+ # @return [String] homepage
127
+ #
128
+ attr_accessor :homepage
129
+
130
+ # @return [Array<String>] Default subspecs
131
+ #
132
+ attr_accessor :default_subspecs
133
+
134
+ # @return [Bool] Defines module
135
+ #
136
+ attr_accessor :defines_module
137
+
138
+ # Initialize a new instance
139
+ #
140
+ # @param [Specification] spec
141
+ #
142
+ # @param [Hash] checkout_options
143
+ #
144
+ def initialize(spec, all_specs, checkout_options, supported_platforms)
145
+ @name = spec.name
146
+ @root_name = spec.name.split("/").first
147
+
148
+ @checksum = spec.checksum
149
+
150
+ checkout_options_keys = [@root_name, @name]
151
+
152
+ if opts_key = checkout_options_keys.detect { |x| checkout_options.has_key?(x) }
153
+ @repo = checkout_options[opts_key][:git]
154
+ @tag = checkout_options[opts_key][:tag]
155
+ @commit = checkout_options[opts_key][:commit]
156
+ @path = checkout_options[opts_key][:path]
157
+ @podspec_path = checkout_options[opts_key][:podspec]
158
+ @branch = checkout_options[opts_key][:branch]
159
+ @is_external = true
160
+ else
161
+ @repo = spec.root.source[:git]
162
+ @tag = spec.root.source[:tag]
163
+ @commit = spec.root.source[:commit]
164
+ @is_external = false
165
+ end
166
+
167
+ @defines_module = nil # nil is not specified
168
+ if override = spec.attributes_hash.dig("pod_target_xcconfig", "DEFINES_MODULE")
169
+ @defines_module = (override == "YES")
170
+ end
171
+
172
+ @vendored_frameworks = extract_vendored_frameworks(spec, all_specs)
173
+ @vendored_libraries = extract_vendored_libraries(spec, all_specs)
174
+
175
+ @frameworks = []
176
+ @weak_frameworks = []
177
+ @libraries = []
178
+
179
+ @frameworks += extract_array(spec, "framework")
180
+ @frameworks += extract_array(spec, "frameworks")
181
+
182
+ @weak_frameworks += extract_array(spec, "weak_framework")
183
+ @weak_frameworks += extract_array(spec, "weak_frameworks")
184
+
185
+ @libraries += extract_array(spec, "library")
186
+ @libraries += extract_array(spec, "libraries")
187
+
188
+ @header_dir = spec.attributes_hash["header_dir"]
189
+
190
+ @version = spec.root.version.version
191
+ @available_versions = spec.respond_to?(:spec_source) ? spec.spec_source.versions(@root_name)&.map(&:to_s) : [@version]
192
+
193
+ @swift_version = spec.root.swift_version&.to_s
194
+ @module_name = spec.root.module_name
195
+
196
+ @default_subspecs = extract_array(spec, "default_subspecs")
197
+ if default_subspec = spec.attributes_hash["default_subspec"]
198
+ @default_subspecs.push(default_subspec)
199
+ end
200
+
201
+ if @name == @root_name && @default_subspecs.empty?
202
+ @default_subspecs += all_specs.select { |t| t.name.include?("/") && t.name.split("/").first == @root_name }.map { |t| t.name.split("/").last }
203
+ end
204
+
205
+ @dependency_names = spec.attributes_hash.fetch("dependencies", {}).keys + default_subspecs.map { |t| "#{@root_name}/#{t}" }
206
+ supported_platforms.each do |platform|
207
+ @dependency_names += (spec.attributes_hash.dig(platform, "dependencies") || {}).keys
208
+ end
209
+ @dependency_names.uniq!
210
+
211
+ @external_dependency_names = @dependency_names.select { |t| !t.start_with?(root_name) }
212
+
213
+ @is_static = spec.root.attributes_hash["static_framework"] || false
214
+ @xcconfig = spec.root.attributes_hash["xcconfig"] || {}
215
+
216
+ if spec.attributes_hash.has_key?("script_phases")
217
+ Configuration.skip_pods += [name, root_name]
218
+ Configuration.skip_pods.uniq!
219
+ puts "Will skip '#{root_name}' which defines script_phase in podspec".blue
220
+ end
221
+
222
+ default_subspecs_specs ||= begin
223
+ subspecs = all_specs.select { |t| t.name.split("/").first == @root_name }
224
+ subspecs.select { |t| @default_subspecs.include?(t.name.split("/").last) }
225
+ end
226
+ root_spec = all_specs.detect { |t| t.name == @root_name } || spec
227
+ @source_files = source_files_from([spec, root_spec] + default_subspecs_specs)
228
+
229
+ @build_configuration = spec.root.attributes_hash.dig("pod_target_xcconfig", "prebuild_configuration") || "release"
230
+ @build_configuration.downcase!
231
+
232
+ default_license = "MIT"
233
+ @license = spec.root.attributes_hash.fetch("license", {"type"=>"#{default_license}"})["type"] || default_license
234
+ @summary = spec.root.attributes_hash.fetch("summary", "A summary for #{@name}")
235
+ @source = spec.root.attributes_hash.fetch("source", { "git"=>"https://github.com/Subito-it/PodBuilder.git" })
236
+ @authors = spec.root.attributes_hash.fetch("authors", {"PodBuilder"=>"pod@podbuilder.com"})
237
+ @homepage = spec.root.attributes_hash.fetch("homepage", "https://github.com/Subito-it/PodBuilder")
238
+ end
239
+
240
+ def pod_specification(all_poditems, parent_spec = nil)
241
+ spec_raw = {}
242
+
243
+ spec_raw["name"] = @name
244
+ spec_raw["module_name"] = @module_name
245
+
246
+ spec_raw["source"] = {}
247
+ if repo = @repo
248
+ spec_raw["source"]["git"] = repo
249
+ end
250
+ if tag = @tag
251
+ spec_raw["source"]["tag"] = tag
252
+ end
253
+ if commit = @commit
254
+ spec_raw["source"]["commit"] = commit
255
+ end
256
+
257
+ spec_raw["version"] = @version
258
+ if swift_version = @swift_version
259
+ spec_raw["swift_version"] = swift_version
260
+ end
261
+
262
+ spec_raw["static_framework"] = is_static
263
+
264
+ spec_raw["frameworks"] = @frameworks
265
+ spec_raw["libraries"] = @libraries
266
+
267
+ spec_raw["xcconfig"] = @xcconfig
268
+
269
+ spec_raw["dependencies"] = @dependency_names.map { |x| [x, []] }.to_h
270
+
271
+ spec = Pod::Specification.from_hash(spec_raw, parent_spec)
272
+ all_subspec_items = all_poditems.select { |x| x.is_subspec && x.root_name == @name }
273
+ spec.subspecs = all_subspec_items.map { |x| x.pod_specification(all_poditems, spec) }
274
+
275
+ return spec
276
+ end
277
+
278
+ def inspect
279
+ return "#{@name} repo=#{@repo} pinned=#{@tag || @commit} is_static=#{@is_static} deps=#{@dependencies || "[]"}"
280
+ end
281
+
282
+ def to_s
283
+ return @name
284
+ end
285
+
286
+ def dependencies(available_pods)
287
+ return available_pods.select { |x| @dependency_names.include?(x.name) }
288
+ end
289
+
290
+ def recursive_dependencies(available_pods)
291
+ names = [name]
292
+
293
+ deps = []
294
+ last_count = -1
295
+ while deps.count != last_count do
296
+ last_count = deps.count
297
+
298
+ updated_names = []
299
+ names.each do |name|
300
+ if pod = available_pods.detect { |t| t.name == name }
301
+ deps.push(pod)
302
+ updated_names += pod.dependency_names
303
+ end
304
+ end
305
+
306
+ names = updated_names.uniq
307
+
308
+ deps.uniq!
309
+ end
310
+
311
+ root_names = deps.map(&:root_name).uniq
312
+
313
+ # We need to build all other common subspecs to properly build the item
314
+ # Ex.
315
+ # PodA depends on DepA/subspec1
316
+ # PodB depends on DepA/subspec2
317
+ #
318
+ # When building PodA we need to build both DepA subspecs because they might
319
+ # contain different code
320
+ deps += available_pods.select { |t| root_names.include?(t.root_name) && t.root_name != t.name }
321
+
322
+ deps.uniq!
323
+
324
+ return deps
325
+ end
326
+
327
+ # @return [Bool] True if it's a pod that doesn't provide source code (is already shipped as a prebuilt pod)
328
+ #
329
+ def is_prebuilt
330
+ if Configuration.force_prebuild_pods.include?(@root_name) || Configuration.force_prebuild_pods.include?(@name)
331
+ return false
332
+ end
333
+
334
+ # We treat pods to skip like prebuilt ones
335
+ if Configuration.skip_pods.include?(@root_name) || Configuration.skip_pods.include?(@name)
336
+ return true
337
+ end
338
+
339
+ # Podspecs aren't always properly written (source_file key is often used instead of header_files)
340
+ # Therefore it can become tricky to understand which pods are already precompiled by boxing a .framework or .a
341
+ embedded_as_vendored = vendored_frameworks.map { |x| File.basename(x) }.include?("#{module_name}.framework")
342
+ embedded_as_static_lib = vendored_libraries.map { |x| File.basename(x) }.include?("lib#{module_name}.a")
343
+
344
+ only_headers = (source_files.count > 0 && @source_files.all? { |x| x.end_with?(".h") })
345
+ no_sources = (@source_files.count == 0 || only_headers) && (@vendored_frameworks + @vendored_libraries).count > 0
346
+
347
+ if !no_sources && !only_headers
348
+ return false
349
+ else
350
+ return (no_sources || only_headers || embedded_as_static_lib || embedded_as_vendored)
351
+ end
352
+ end
353
+
354
+ # @return [Bool] True if it's a subspec
355
+ #
356
+ def is_subspec
357
+ @root_name != @name
358
+ end
359
+
360
+ # @return [Bool] True if it's a development pod
361
+ #
362
+ def is_development_pod
363
+ @path != nil
364
+ end
365
+
366
+ # @return [String] The podfile entry
367
+ #
368
+ def entry(include_version = true, include_pb_entry = true)
369
+ e = "pod '#{@name}'"
370
+
371
+ unless include_version
372
+ return e
373
+ end
374
+
375
+ if is_external
376
+ if @path
377
+ e += ", :path => '#{@path}'"
378
+ elsif @podspec_path
379
+ e += ", :podspec => '#{@podspec_path}'"
380
+ else
381
+ if @repo
382
+ e += ", :git => '#{@repo}'"
383
+ end
384
+ if @tag
385
+ e += ", :tag => '#{@tag}'"
386
+ end
387
+ if @commit
388
+ e += ", :commit => '#{@commit}'"
389
+ end
390
+ if @branch
391
+ e += ", :branch => '#{@branch}'"
392
+ end
393
+ end
394
+ else
395
+ e += ", '=#{@version}'"
396
+ end
397
+
398
+ if include_pb_entry && !is_prebuilt
399
+ prebuilt_info_path = PodBuilder::prebuiltpath("#{root_name}/#{Configuration::prebuilt_info_filename}")
400
+ if File.exist?(prebuilt_info_path)
401
+ data = JSON.parse(File.read(prebuilt_info_path))
402
+ swift_version = data["swift_version"]
403
+ is_static = data["is_static"] || false
404
+
405
+ e += "#{prebuilt_marker()} is<#{is_static}>"
406
+ if swift_version
407
+ e += " sv<#{swift_version}>"
408
+ end
409
+ else
410
+ e += prebuilt_marker()
411
+ end
412
+ end
413
+
414
+ return e
415
+ end
416
+
417
+ def podspec_name
418
+ return name.gsub("/", "_")
419
+ end
420
+
421
+ def prebuilt_rel_path
422
+ return "#{module_name}.framework"
423
+ end
424
+
425
+ def prebuilt_podspec_path(absolute_path = true)
426
+ podspec_path = PodBuilder::prebuiltpath("#{@root_name}/#{@root_name}.podspec")
427
+ if absolute_path
428
+ return podspec_path
429
+ else
430
+ pod_path = Pathname.new(podspec_path).relative_path_from(Pathname.new(PodBuilder::basepath)).to_s
431
+ end
432
+ end
433
+
434
+ def prebuilt_entry(include_pb_entry = true, absolute_path = false)
435
+ podspec_dirname = File.dirname(prebuilt_podspec_path(absolute_path = absolute_path))
436
+
437
+ entry = "pod '#{name}', :path => '#{podspec_dirname}'"
438
+
439
+ if include_pb_entry && !is_prebuilt
440
+ entry += prebuilt_marker()
441
+ end
442
+
443
+ return entry
444
+ end
445
+
446
+ def prebuilt_marker
447
+ return " # pb<#{name}>"
448
+ end
449
+
450
+ def has_subspec(named)
451
+ unless !is_subspec
452
+ return false
453
+ end
454
+
455
+ return named.split("/").first == name
456
+ end
457
+
458
+ def has_common_spec(named)
459
+ return root_name == named.split("/").first
460
+ end
461
+
462
+ private
463
+
464
+ def extract_vendored_frameworks(spec, all_specs)
465
+ items = []
466
+
467
+ supported_platforms = spec.available_platforms.flatten.map(&:name).map(&:to_s)
468
+ items += [spec.attributes_hash["vendored_frameworks"]]
469
+ items += [spec.attributes_hash["vendored_framework"]]
470
+
471
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_frameworks"] }
472
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_framework"] }
473
+
474
+ return items.flatten.uniq.compact
475
+ end
476
+
477
+ def extract_vendored_libraries(spec, all_specs)
478
+ items = []
479
+
480
+ supported_platforms = spec.available_platforms.flatten.map(&:name).map(&:to_s)
481
+
482
+ items += [spec.attributes_hash["vendored_libraries"]]
483
+ items += [spec.attributes_hash["vendored_library"]]
484
+
485
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_libraries"] }
486
+ items += supported_platforms.map { |x| spec.attributes_hash.fetch(x, {})["vendored_library"] }
487
+
488
+ return items.flatten.uniq.compact
489
+ end
490
+
491
+ def extract_array(spec, key)
492
+ element = spec.attributes_hash.fetch(key, [])
493
+ if element.instance_of? String
494
+ element = [element]
495
+ end
496
+
497
+ return element
498
+ end
499
+
500
+ def source_files_from_string(source)
501
+ # Transform source file entries
502
+ # "Networking{Response,Request}*.{h,m}" -> ["NetworkingResponse*.h", "NetworkingResponse*.m", "NetworkingRequest*.h", "NetworkingRequest*.m"]
503
+ files = []
504
+ if source.is_a? String
505
+ matches = source.match(/(.*){(.*)}(.*)/)
506
+ if matches&.size == 4
507
+ res = matches[2].split(",").map { |t| "#{matches[1]}#{t}#{matches[3]}" }
508
+ if res.any? { |t| t.include?("{") }
509
+ return res.map { |t| source_files_from_string(t) }.flatten
510
+ end
511
+
512
+ return res
513
+ end
514
+
515
+ return source.split(",")
516
+ else
517
+ if source.any? { |t| t.include?("{") }
518
+ return source.map { |t| source_files_from_string(t) }.flatten
519
+ end
520
+
521
+ return source
522
+ end
523
+ end
524
+
525
+ def source_files_from(specs)
526
+ files = specs.map { |t| t.attributes_hash.fetch("source_files", []) }.flatten
527
+ return source_files_from_string(files).uniq
528
+ end
529
+ end
530
+ end