cocoapods-core 0.17.0.rc1
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/LICENSE +20 -0
- data/README.md +36 -0
- data/lib/cocoapods-core/core_ui.rb +19 -0
- data/lib/cocoapods-core/dependency.rb +295 -0
- data/lib/cocoapods-core/gem_version.rb +6 -0
- data/lib/cocoapods-core/lockfile.rb +440 -0
- data/lib/cocoapods-core/platform.rb +171 -0
- data/lib/cocoapods-core/podfile/dsl.rb +459 -0
- data/lib/cocoapods-core/podfile/target_definition.rb +503 -0
- data/lib/cocoapods-core/podfile.rb +345 -0
- data/lib/cocoapods-core/requirement.rb +15 -0
- data/lib/cocoapods-core/source/validator.rb +183 -0
- data/lib/cocoapods-core/source.rb +284 -0
- data/lib/cocoapods-core/specification/consumer.rb +356 -0
- data/lib/cocoapods-core/specification/dsl/attribute.rb +245 -0
- data/lib/cocoapods-core/specification/dsl/attribute_support.rb +76 -0
- data/lib/cocoapods-core/specification/dsl/deprecations.rb +47 -0
- data/lib/cocoapods-core/specification/dsl/platform_proxy.rb +67 -0
- data/lib/cocoapods-core/specification/dsl.rb +1110 -0
- data/lib/cocoapods-core/specification/linter.rb +436 -0
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +152 -0
- data/lib/cocoapods-core/specification/set/presenter.rb +229 -0
- data/lib/cocoapods-core/specification/set/statistics.rb +277 -0
- data/lib/cocoapods-core/specification/set.rb +171 -0
- data/lib/cocoapods-core/specification/yaml.rb +60 -0
- data/lib/cocoapods-core/specification.rb +592 -0
- data/lib/cocoapods-core/standard_error.rb +84 -0
- data/lib/cocoapods-core/vendor/dependency.rb +264 -0
- data/lib/cocoapods-core/vendor/requirement.rb +208 -0
- data/lib/cocoapods-core/vendor/version.rb +333 -0
- data/lib/cocoapods-core/vendor.rb +56 -0
- data/lib/cocoapods-core/version.rb +99 -0
- data/lib/cocoapods-core/yaml_converter.rb +202 -0
- data/lib/cocoapods-core.rb +23 -0
- metadata +154 -0
@@ -0,0 +1,440 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# The Lockfile stores information about the pods that were installed by
|
4
|
+
# CocoaPods.
|
5
|
+
#
|
6
|
+
# It is used in combination with the Podfile to resolve the exact version of
|
7
|
+
# the Pods that should be installed (i.e. to prevent `pod install` from
|
8
|
+
# upgrading dependencies).
|
9
|
+
#
|
10
|
+
# Moreover it is used as a manifest of an installation to detect which Pods
|
11
|
+
# need to be installed or removed.
|
12
|
+
#
|
13
|
+
class Lockfile
|
14
|
+
|
15
|
+
# TODO The symbols should be converted to a String and back to symbol
|
16
|
+
# when reading (EXTERNAL SOURCES Download options)
|
17
|
+
|
18
|
+
# @return [String] the hash used to initialize the Lockfile.
|
19
|
+
#
|
20
|
+
attr_reader :internal_data
|
21
|
+
|
22
|
+
# @param [Hash] hash
|
23
|
+
# a hash representation of the Lockfile.
|
24
|
+
#
|
25
|
+
def initialize(hash)
|
26
|
+
@internal_data = hash
|
27
|
+
end
|
28
|
+
|
29
|
+
# Loads a lockfile form the given path.
|
30
|
+
#
|
31
|
+
# @note This method returns nil if the given path doesn't exists.
|
32
|
+
#
|
33
|
+
# @raise If there is a syntax error loading the YAML data.
|
34
|
+
#
|
35
|
+
# @param [Pathname] path
|
36
|
+
# the path where the lockfile is serialized.
|
37
|
+
#
|
38
|
+
# @return [Lockfile] a new lockfile.
|
39
|
+
#
|
40
|
+
def self.from_file(path)
|
41
|
+
return nil unless path.exist?
|
42
|
+
begin
|
43
|
+
hash = YAML.load(File.open(path))
|
44
|
+
rescue Exception => e
|
45
|
+
raise StandardError, "Podfile.lock syntax error: #{e.inspect}"
|
46
|
+
end
|
47
|
+
lockfile = Lockfile.new(hash)
|
48
|
+
lockfile.defined_in_file = path
|
49
|
+
lockfile
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String] the file where the Lockfile is serialized.
|
53
|
+
#
|
54
|
+
attr_accessor :defined_in_file
|
55
|
+
|
56
|
+
# @return [String] a string representation suitable for UI output.
|
57
|
+
#
|
58
|
+
def to_s
|
59
|
+
"Podfile.lock"
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [String] a string representation suitable for debugging.
|
63
|
+
#
|
64
|
+
def inspect
|
65
|
+
"#<#{self.class}>"
|
66
|
+
end
|
67
|
+
|
68
|
+
#-------------------------------------------------------------------------#
|
69
|
+
|
70
|
+
# !@group Accessing the Data
|
71
|
+
|
72
|
+
public
|
73
|
+
|
74
|
+
# @return [Array<String>] the names of the installed Pods.
|
75
|
+
#
|
76
|
+
def pod_names
|
77
|
+
generate_pod_names_and_versions unless @pod_names
|
78
|
+
@pod_names
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the version of the given Pod.
|
82
|
+
#
|
83
|
+
# @param [name] The name of the Pod (root name of the specification).
|
84
|
+
#
|
85
|
+
# @return [Version] The version of the pod.
|
86
|
+
#
|
87
|
+
# @return [Nil] If there is no version stored for the given name.
|
88
|
+
#
|
89
|
+
def version(pod_name)
|
90
|
+
version = pod_versions[pod_name]
|
91
|
+
return version if version
|
92
|
+
pod_name = pod_versions.keys.find { |name| Specification.root_name(name) == pod_name }
|
93
|
+
pod_versions[pod_name]
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns the checksum for the given Pod.
|
97
|
+
#
|
98
|
+
# @param [name] The name of the Pod (root name of the specification).
|
99
|
+
#
|
100
|
+
# @return [String] The checksum of the specification for the given Pod.
|
101
|
+
#
|
102
|
+
# @return [Nil] If there is no checksum stored for the given name.
|
103
|
+
#
|
104
|
+
def checksum(name)
|
105
|
+
checksum_data[name]
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [Array<Dependency>] the dependencies of the Podfile used for the
|
109
|
+
# last installation.
|
110
|
+
#
|
111
|
+
# @note It includes only the dependencies explicitly required in the
|
112
|
+
# podfile and not those triggered by the Resolver.
|
113
|
+
#
|
114
|
+
def dependencies
|
115
|
+
unless @dependencies
|
116
|
+
data = internal_data['DEPENDENCIES'] || []
|
117
|
+
@dependencies = data.map do |string|
|
118
|
+
dep = Dependency.from_string(string)
|
119
|
+
dep.external_source = external_sources_data[dep.root_name]
|
120
|
+
dep
|
121
|
+
end
|
122
|
+
end
|
123
|
+
@dependencies
|
124
|
+
end
|
125
|
+
|
126
|
+
# Generates a dependency that requires the exact version of the Pod with the
|
127
|
+
# given name.
|
128
|
+
#
|
129
|
+
# @param [String] name
|
130
|
+
# the name of the Pod
|
131
|
+
#
|
132
|
+
# @note The generated dependencies are by the Installer to prevent the
|
133
|
+
# Resolver from upgrading a Pod during an installation.
|
134
|
+
#
|
135
|
+
# @raise If there is no version stored for the given name.
|
136
|
+
#
|
137
|
+
# @return [Dependency] the generated dependency.
|
138
|
+
#
|
139
|
+
def dependency_to_lock_pod_named(name)
|
140
|
+
dep = dependencies.find { |d| d.name == name || d.root_name == name }
|
141
|
+
version = version(name)
|
142
|
+
|
143
|
+
unless dep
|
144
|
+
raise StandardError, "Attempt to lock the `#{name}` Pod without an known dependency."
|
145
|
+
end
|
146
|
+
|
147
|
+
unless version
|
148
|
+
raise StandardError, "Attempt to lock the `#{name}` Pod without an known version."
|
149
|
+
end
|
150
|
+
|
151
|
+
locked_dependency = dep.dup
|
152
|
+
locked_dependency.specific_version = version
|
153
|
+
locked_dependency
|
154
|
+
end
|
155
|
+
|
156
|
+
#--------------------------------------#
|
157
|
+
|
158
|
+
# !@group Accessing the internal data.
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
# @return [Array<String, Hash{String => Array[String]}>] the pods installed
|
163
|
+
# and their dependencies.
|
164
|
+
#
|
165
|
+
def generate_pod_names_and_versions
|
166
|
+
@pod_names = []
|
167
|
+
@pod_versions = {}
|
168
|
+
|
169
|
+
return unless pods = internal_data['PODS']
|
170
|
+
pods.each do |pod|
|
171
|
+
pod = pod.keys.first unless pod.is_a?(String)
|
172
|
+
name, version = Spec.name_and_version_from_string(pod)
|
173
|
+
@pod_names << name
|
174
|
+
@pod_versions[name] = version
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# @return [Hash{String => Hash}] a hash where the name of the pods are the
|
179
|
+
# keys and the values are the external source hash the dependency
|
180
|
+
# that required the pod.
|
181
|
+
#
|
182
|
+
def external_sources_data
|
183
|
+
@external_sources_data ||= internal_data["EXTERNAL SOURCES"] || {}
|
184
|
+
end
|
185
|
+
|
186
|
+
# @return [Hash{String => Version}] a Hash containing the name of the root
|
187
|
+
# specification of the installed Pods as the keys and their
|
188
|
+
# corresponding {Version} as the values.
|
189
|
+
#
|
190
|
+
def pod_versions
|
191
|
+
generate_pod_names_and_versions unless @pod_versions
|
192
|
+
@pod_versions
|
193
|
+
end
|
194
|
+
|
195
|
+
# @return [Hash{String => Version}] A Hash containing the checksums of the
|
196
|
+
# specification by the name of their root.
|
197
|
+
#
|
198
|
+
def checksum_data
|
199
|
+
internal_data['SPEC CHECKSUMS'] || {}
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
#-------------------------------------------------------------------------#
|
204
|
+
|
205
|
+
# !@group Comparison with a Podfile
|
206
|
+
|
207
|
+
public
|
208
|
+
|
209
|
+
# Analyzes the {Lockfile} and detects any changes applied to the {Podfile}
|
210
|
+
# since the last installation.
|
211
|
+
#
|
212
|
+
# For each Pod, it detects one state among the following:
|
213
|
+
#
|
214
|
+
# - added: Pods that weren't present in the Podfile.
|
215
|
+
# - changed: Pods that were present in the Podfile but changed:
|
216
|
+
# - Pods whose version is not compatible anymore with Podfile,
|
217
|
+
# - Pods that changed their head or external options.
|
218
|
+
# - removed: Pods that were removed form the Podfile.
|
219
|
+
# - unchanged: Pods that are still compatible with Podfile.
|
220
|
+
#
|
221
|
+
# @param [Podfile] podfile
|
222
|
+
# the podfile that should be analyzed.
|
223
|
+
#
|
224
|
+
# @return [Hash{Symbol=>Array[Strings]}] a hash where pods are grouped
|
225
|
+
# by the state in which they are.
|
226
|
+
#
|
227
|
+
# @todo Why do we look for compatibility instead of just comparing if the
|
228
|
+
# two dependencies are equal?
|
229
|
+
#
|
230
|
+
def detect_changes_with_podfile(podfile)
|
231
|
+
result = {}
|
232
|
+
[ :added, :changed, :removed, :unchanged ].each { |k| result[k] = [] }
|
233
|
+
|
234
|
+
installed_deps = dependencies.map { |d| dependency_to_lock_pod_named(d.name) }
|
235
|
+
all_dep_names = (dependencies + podfile.dependencies).map(&:name).uniq
|
236
|
+
all_dep_names.each do |name|
|
237
|
+
installed_dep = installed_deps.find { |d| d.name == name }
|
238
|
+
podfile_dep = podfile.dependencies.find { |d| d.name == name }
|
239
|
+
|
240
|
+
if installed_dep.nil? then key = :added
|
241
|
+
elsif podfile_dep.nil? then key = :removed
|
242
|
+
elsif podfile_dep.compatible?(installed_dep ) then key = :unchanged
|
243
|
+
else key = :changed
|
244
|
+
end
|
245
|
+
result[key] << name
|
246
|
+
end
|
247
|
+
result
|
248
|
+
end
|
249
|
+
|
250
|
+
#-------------------------------------------------------------------------#
|
251
|
+
|
252
|
+
# !@group Serialization
|
253
|
+
|
254
|
+
public
|
255
|
+
|
256
|
+
# Writes the Lockfile to the given path.
|
257
|
+
#
|
258
|
+
# @param [Pathname] path
|
259
|
+
# the path where the lockfile should be saved.
|
260
|
+
#
|
261
|
+
# @return [void]
|
262
|
+
#
|
263
|
+
def write_to_disk(path)
|
264
|
+
path.dirname.mkpath unless path.dirname.exist?
|
265
|
+
File.open(path, 'w') {|f| f.write(to_yaml) }
|
266
|
+
self.defined_in_file = path
|
267
|
+
end
|
268
|
+
|
269
|
+
# @return [Hash{String=>Array,Hash,String}] a hash reppresentation of the
|
270
|
+
# Lockfile.
|
271
|
+
#
|
272
|
+
# @example Output
|
273
|
+
#
|
274
|
+
# {
|
275
|
+
# 'PODS' => [ { BananaLib (1.0) => [monkey (< 1.0.9, ~> 1.0.1)] },
|
276
|
+
# "JSONKit (1.4)",
|
277
|
+
# "monkey (1.0.8)"]
|
278
|
+
# 'DEPENDENCIES' => [ "BananaLib (~> 1.0)",
|
279
|
+
# "JSONKit (from `path/JSONKit.podspec`)" ],
|
280
|
+
# 'EXTERNAL SOURCES' => { "JSONKit" => { :podspec => path/JSONKit.podspec } },
|
281
|
+
# 'SPEC CHECKSUMS' => { "BananaLib" => "439d9f683377ecf4a27de43e8cf3bce6be4df97b",
|
282
|
+
# "JSONKit", "92ae5f71b77c8dec0cd8d0744adab79d38560949" },
|
283
|
+
# 'COCOAPODS' => "0.17.0"
|
284
|
+
# }
|
285
|
+
#
|
286
|
+
#
|
287
|
+
def to_hash
|
288
|
+
hash = {}
|
289
|
+
internal_data.each do |key, value|
|
290
|
+
hash[key] = value unless value.empty?
|
291
|
+
end
|
292
|
+
hash
|
293
|
+
end
|
294
|
+
|
295
|
+
# @return [String] the YAML representation of the Lockfile, used for
|
296
|
+
# serialization.
|
297
|
+
#
|
298
|
+
# @note Empty root keys are discarded.
|
299
|
+
#
|
300
|
+
# @note The YAML string is prettified.
|
301
|
+
#
|
302
|
+
def to_yaml
|
303
|
+
keys_hint = [
|
304
|
+
"PODS",
|
305
|
+
"DEPENDENCIES",
|
306
|
+
"EXTERNAL SOURCES",
|
307
|
+
"SPEC CHECKSUMS",
|
308
|
+
"COCOAPODS"
|
309
|
+
]
|
310
|
+
YAMLConverter.convert_hash(to_hash, keys_hint, "\n\n")
|
311
|
+
end
|
312
|
+
|
313
|
+
#-------------------------------------------------------------------------#
|
314
|
+
|
315
|
+
class << self
|
316
|
+
|
317
|
+
# !@group Generation
|
318
|
+
|
319
|
+
public
|
320
|
+
|
321
|
+
# Generates a hash representation of the Lockfile generated from a given
|
322
|
+
# Podfile and the list of resolved Specifications. This representation is
|
323
|
+
# suitable for serialization.
|
324
|
+
#
|
325
|
+
# @param [Podfile] podfile
|
326
|
+
# the podfile that should be used to generate the lockfile.
|
327
|
+
#
|
328
|
+
# @param [Array<Specification>] specs
|
329
|
+
# an array containing the podspec that were generated by
|
330
|
+
# resolving the given podfile.
|
331
|
+
#
|
332
|
+
# @return [Lockfile] a new lockfile.
|
333
|
+
#
|
334
|
+
def generate(podfile, specs)
|
335
|
+
hash = {
|
336
|
+
'PODS' => generate_pods_data(podfile, specs),
|
337
|
+
'DEPENDENCIES' => generate_dependencies_data(podfile),
|
338
|
+
'EXTERNAL SOURCES' => generate_external_sources_data(podfile),
|
339
|
+
'SPEC CHECKSUMS' => generate_checksums(specs),
|
340
|
+
'COCOAPODS' => CORE_VERSION
|
341
|
+
}
|
342
|
+
Lockfile.new(hash)
|
343
|
+
end
|
344
|
+
|
345
|
+
#--------------------------------------#
|
346
|
+
|
347
|
+
private
|
348
|
+
|
349
|
+
# !@group Private helpers
|
350
|
+
|
351
|
+
# Generates the list of the installed Pods and their dependencies.
|
352
|
+
#
|
353
|
+
# @note The dependencies of iOS and OS X version of the same pod are
|
354
|
+
# merged.
|
355
|
+
#
|
356
|
+
# @todo Specifications should be stored per platform, otherwise they
|
357
|
+
# list dependencies which actually might not be used.
|
358
|
+
#
|
359
|
+
# @return [Array<Hash,String>] the generated data.
|
360
|
+
#
|
361
|
+
# @example Output
|
362
|
+
# [ {"BananaLib (1.0)"=>["monkey (< 1.0.9, ~> 1.0.1)"]},
|
363
|
+
# "monkey (1.0.8)" ]
|
364
|
+
#
|
365
|
+
#
|
366
|
+
def generate_pods_data(podfile, specs)
|
367
|
+
pod_and_deps = specs.map do |spec|
|
368
|
+
[spec.to_s, spec.all_dependencies.map(&:to_s).sort]
|
369
|
+
end.uniq
|
370
|
+
|
371
|
+
tmp = {}
|
372
|
+
pod_and_deps.each do |name, deps|
|
373
|
+
if tmp[name]
|
374
|
+
tmp[name].concat(deps).uniq!
|
375
|
+
else
|
376
|
+
tmp[name] = deps
|
377
|
+
end
|
378
|
+
end
|
379
|
+
pod_and_deps = tmp.sort_by(&:first).map do |name, deps|
|
380
|
+
deps.empty? ? name : { name => deps }
|
381
|
+
end
|
382
|
+
pod_and_deps
|
383
|
+
end
|
384
|
+
|
385
|
+
# Generates the list of the dependencies of the Podfile.
|
386
|
+
#
|
387
|
+
# @example Output
|
388
|
+
# [ "BananaLib (~> 1.0)",
|
389
|
+
# "JSONKit (from `path/JSONKit.podspec')" ]
|
390
|
+
#
|
391
|
+
# @return [Array] the generated data.
|
392
|
+
#
|
393
|
+
def generate_dependencies_data(podfile)
|
394
|
+
podfile.dependencies.map{ |d| d.to_s }.sort
|
395
|
+
end
|
396
|
+
|
397
|
+
# Generates the information of the external sources.
|
398
|
+
#
|
399
|
+
# @example Output
|
400
|
+
# { "JSONKit"=>{:podspec=>"path/JSONKit.podspec"} }
|
401
|
+
#
|
402
|
+
# @return [Hash] a hash where the keys are the names of the pods and
|
403
|
+
# the values store the external source hashes of each
|
404
|
+
# dependency.
|
405
|
+
#
|
406
|
+
# @todo The downloader should generate an external source hash that
|
407
|
+
# should be store for dependencies in head mode and for those
|
408
|
+
# with external source.
|
409
|
+
#
|
410
|
+
def generate_external_sources_data(podfile)
|
411
|
+
deps = podfile.dependencies.select(&:external?)
|
412
|
+
deps = deps.sort { |d, other| d.name <=> other.name}
|
413
|
+
sources = {}
|
414
|
+
deps.each { |d| sources[d.root_name] = d.external_source }
|
415
|
+
sources
|
416
|
+
end
|
417
|
+
|
418
|
+
# Generates the relative to the checksum of the specifications.
|
419
|
+
#
|
420
|
+
# @example Output
|
421
|
+
# {
|
422
|
+
# "BananaLib"=>"9906b267592664126923875ce2c8d03824372c79",
|
423
|
+
# "JSONKit"=>"92ae5f71b77c8dec0cd8d0744adab79d38560949"
|
424
|
+
# }
|
425
|
+
#
|
426
|
+
# @return [Hash] a hash where the keys are the names of the root
|
427
|
+
# specifications and the values are the SHA1 digest of the
|
428
|
+
# podspec file.
|
429
|
+
#
|
430
|
+
def generate_checksums(specs)
|
431
|
+
checksums = {}
|
432
|
+
specs.select { |spec| !spec.defined_in_file.nil? }.each do |spec|
|
433
|
+
checksums[spec.root.name] = spec.checksum
|
434
|
+
end
|
435
|
+
checksums
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# A Platform describes an SDK name and deployment target.
|
4
|
+
#
|
5
|
+
class Platform
|
6
|
+
|
7
|
+
# @return [Symbol, String] the name of the SDK represented by the platform.
|
8
|
+
#
|
9
|
+
def name
|
10
|
+
@symbolic_name
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Version] the deployment target of the platform.
|
14
|
+
#
|
15
|
+
attr_reader :deployment_target
|
16
|
+
|
17
|
+
# Constructs a platform from either another platform or by
|
18
|
+
# specifying the symbolic name and optionally the deployment target.
|
19
|
+
#
|
20
|
+
# @overload initialize(name, deployment_target)
|
21
|
+
#
|
22
|
+
# @param [Symbol, String] name
|
23
|
+
# the name of platform.
|
24
|
+
#
|
25
|
+
# @param [String, Version] deployment_target
|
26
|
+
# the optional deployment.
|
27
|
+
#
|
28
|
+
# @note If the deployment target is not provided a default deployment
|
29
|
+
# target will not be assigned.
|
30
|
+
#
|
31
|
+
# @example Initialization with symbol
|
32
|
+
#
|
33
|
+
# Platform.new(:ios)
|
34
|
+
# Platform.new(:ios, '4.3')
|
35
|
+
#
|
36
|
+
# @overload initialize(platform)
|
37
|
+
#
|
38
|
+
# @param [Platform] platform
|
39
|
+
# Another {Platform}.
|
40
|
+
#
|
41
|
+
# @example Initialization with another platform
|
42
|
+
#
|
43
|
+
# platform = Platform.new(:ios)
|
44
|
+
# Platform.new(platform)
|
45
|
+
#
|
46
|
+
def initialize(input, target = nil)
|
47
|
+
if input.is_a? Platform
|
48
|
+
@symbolic_name = input.name
|
49
|
+
@deployment_target = input.deployment_target
|
50
|
+
else
|
51
|
+
@symbolic_name = input.to_sym
|
52
|
+
target = target[:deployment_target] if target.is_a?(Hash)
|
53
|
+
@deployment_target = Version.create(target)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convenience method to initialize an iOS platform.
|
58
|
+
#
|
59
|
+
# @return [Platform] an iOS platform.
|
60
|
+
#
|
61
|
+
def self.ios
|
62
|
+
new :ios
|
63
|
+
end
|
64
|
+
|
65
|
+
# Convenience method to initialize an OS X platform.
|
66
|
+
#
|
67
|
+
# @return [Platform] an OS X platform.
|
68
|
+
#
|
69
|
+
def self.osx
|
70
|
+
new :osx
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks if a platform is equivalent to another one or to a symbol
|
74
|
+
# representation.
|
75
|
+
#
|
76
|
+
# @param [Platform, Symbol] other
|
77
|
+
# the other platform to check.
|
78
|
+
#
|
79
|
+
# @note If a symbol is passed the comparison does not take into account
|
80
|
+
# the deployment target.
|
81
|
+
#
|
82
|
+
# @return [Boolean] whether two platforms are the equivalent.
|
83
|
+
#
|
84
|
+
def ==(other)
|
85
|
+
if other.is_a?(Symbol)
|
86
|
+
@symbolic_name == other
|
87
|
+
else
|
88
|
+
(name == other.name) && (deployment_target == other.deployment_target)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Checks whether a platform supports another one.
|
93
|
+
#
|
94
|
+
# In the context of operating system SDKs, a platform supports another
|
95
|
+
# one if they have the same name and the other platform has a minor or
|
96
|
+
# equal deployment target.
|
97
|
+
#
|
98
|
+
# @return [Bool] whether the platform supports another platform.
|
99
|
+
#
|
100
|
+
def supports?(other)
|
101
|
+
other = Platform.new(other)
|
102
|
+
if other.deployment_target && deployment_target
|
103
|
+
(other.name == name) && (other.deployment_target <= deployment_target)
|
104
|
+
else
|
105
|
+
other.name == name
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [String] a string representation that includes the deployment
|
110
|
+
# target.
|
111
|
+
#
|
112
|
+
def to_s
|
113
|
+
s = self.class.string_name(@symbolic_name)
|
114
|
+
s << " #{deployment_target}" if deployment_target
|
115
|
+
s
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [String] the debug representation.
|
119
|
+
#
|
120
|
+
def inspect
|
121
|
+
"#<#{self.class.name} name=#{name.inspect} " \
|
122
|
+
"deployment_target=#{deployment_target.inspect}>"
|
123
|
+
end
|
124
|
+
|
125
|
+
# @return [Symbol] a symbol representing the name of the platform.
|
126
|
+
#
|
127
|
+
def to_sym
|
128
|
+
name
|
129
|
+
end
|
130
|
+
|
131
|
+
# Compares the platform first by name and the by deployment_target for
|
132
|
+
# sorting.
|
133
|
+
#
|
134
|
+
# @param [Platform] other
|
135
|
+
# The other platform to compare.
|
136
|
+
#
|
137
|
+
# @return [Fixnum] -1, 0, or +1 depending on whether the receiver is less
|
138
|
+
# than, equal to, or greater than other.
|
139
|
+
#
|
140
|
+
def <=> other
|
141
|
+
name_sort = self.name.to_s <=> other.name.to_s
|
142
|
+
if name_sort.zero?
|
143
|
+
self.deployment_target <=> other.deployment_target
|
144
|
+
else
|
145
|
+
name_sort
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [Bool] whether the platform requires legacy architectures for
|
150
|
+
# iOS.
|
151
|
+
#
|
152
|
+
def requires_legacy_ios_archs?
|
153
|
+
(name == :ios) && deployment_target && (deployment_target < Version.new("4.3"))
|
154
|
+
end
|
155
|
+
|
156
|
+
# Converts the symbolic name of a platform to a string name suitable to be
|
157
|
+
# presented to the user.
|
158
|
+
#
|
159
|
+
# @param [Symbol] symbolic_name
|
160
|
+
# the symbolic name of a platform.
|
161
|
+
#
|
162
|
+
# @return [String] The string that describes the name of the given symbol.
|
163
|
+
#
|
164
|
+
def self.string_name(symbolic_name)
|
165
|
+
case symbolic_name
|
166
|
+
when :ios then 'iOS'
|
167
|
+
when :osx then 'OS X'
|
168
|
+
else symbolic_name end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|