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