pod-builder-y 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
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