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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +13 -0
- data/README.md +385 -0
- data/Rakefile +2 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/exe/pod_builder_y +406 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/pod_builder/analyze.rb +59 -0
- data/lib/pod_builder/analyzer.rb +16 -0
- data/lib/pod_builder/command.rb +14 -0
- data/lib/pod_builder/command/build.rb +228 -0
- data/lib/pod_builder/command/build_all.rb +15 -0
- data/lib/pod_builder/command/clean.rb +75 -0
- data/lib/pod_builder/command/deintegrate.rb +101 -0
- data/lib/pod_builder/command/generate_lldbinit.rb +128 -0
- data/lib/pod_builder/command/generate_podspec.rb +22 -0
- data/lib/pod_builder/command/info.rb +18 -0
- data/lib/pod_builder/command/init.rb +148 -0
- data/lib/pod_builder/command/install_sources.rb +79 -0
- data/lib/pod_builder/command/none.rb +16 -0
- data/lib/pod_builder/command/restore_all.rb +33 -0
- data/lib/pod_builder/command/switch.rb +224 -0
- data/lib/pod_builder/command/sync_podfile.rb +34 -0
- data/lib/pod_builder/command/update.rb +43 -0
- data/lib/pod_builder/configuration.rb +300 -0
- data/lib/pod_builder/core.rb +222 -0
- data/lib/pod_builder/info.rb +90 -0
- data/lib/pod_builder/install.rb +505 -0
- data/lib/pod_builder/licenses.rb +73 -0
- data/lib/pod_builder/podfile.rb +700 -0
- data/lib/pod_builder/podfile/pre_actions_swizzles.rb +84 -0
- data/lib/pod_builder/podfile_cp.rb +99 -0
- data/lib/pod_builder/podfile_item.rb +530 -0
- data/lib/pod_builder/podspec.rb +269 -0
- data/lib/pod_builder/rome/post_install.rb +446 -0
- data/lib/pod_builder/rome/pre_install.rb +6 -0
- data/lib/pod_builder/templates/build_podfile.template +70 -0
- data/lib/pod_builder/templates/build_podspec.template +19 -0
- data/lib/pod_builder/version.rb +4 -0
- data/pod-builder.gemspec +37 -0
- 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
|