cocoapods-core 0.17.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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,503 @@
|
|
1
|
+
module Pod
|
2
|
+
class Podfile
|
3
|
+
|
4
|
+
# The TargetDefinition stores the information of a CocoaPods static
|
5
|
+
# library. The target definition can be linked with one or more targets of
|
6
|
+
# the user project.
|
7
|
+
#
|
8
|
+
# Target definitions can be nested and by default inherit the dependencies
|
9
|
+
# of the parent.
|
10
|
+
#
|
11
|
+
class TargetDefinition
|
12
|
+
|
13
|
+
# @return [String, Symbol] the name of the target definition.
|
14
|
+
#
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
# @return [TargetDefinition, Podfile] the parent target definition or the
|
18
|
+
# Podfile if the receiver is root.
|
19
|
+
#
|
20
|
+
attr_reader :parent
|
21
|
+
|
22
|
+
# @param [String, Symbol]
|
23
|
+
# name @see name
|
24
|
+
#
|
25
|
+
# @param [TargetDefinition] parent
|
26
|
+
# @see parent
|
27
|
+
#
|
28
|
+
# @option options [Bool] :exclusive
|
29
|
+
# @see exclusive?
|
30
|
+
#
|
31
|
+
def initialize(name, parent, internal_hash = {})
|
32
|
+
@name = name
|
33
|
+
@parent = parent
|
34
|
+
@internal_hash = internal_hash
|
35
|
+
@children = []
|
36
|
+
|
37
|
+
if parent.is_a?(TargetDefinition)
|
38
|
+
parent.children << self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Array<TargetDefinition>] the children target definitions.
|
43
|
+
#
|
44
|
+
attr_reader :children
|
45
|
+
|
46
|
+
# @return [Array<TargetDefinition>] the targets definition descending
|
47
|
+
# from this one.
|
48
|
+
#
|
49
|
+
def recursive_children
|
50
|
+
(children + children.map(&:recursive_children)).flatten
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Bool] Whether the target definition is root.
|
54
|
+
#
|
55
|
+
def root?
|
56
|
+
parent.is_a?(Podfile) || parent.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [TargetDefinition] The root target definition.
|
60
|
+
#
|
61
|
+
def root
|
62
|
+
if root?
|
63
|
+
self
|
64
|
+
else
|
65
|
+
parent.root
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [Podfile] The podfile that contains the specification for this
|
70
|
+
# target definition.
|
71
|
+
#
|
72
|
+
def podfile
|
73
|
+
root.parent
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Array<Dependency>] The list of the dependencies of the target
|
77
|
+
# definition including the inherited ones.
|
78
|
+
#
|
79
|
+
def dependencies
|
80
|
+
non_inherited_dependencies + ((exclusive? || parent.nil?) ? [] : parent.dependencies)
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Array] The list of the dependencies of the target definition,
|
84
|
+
# excluding inherited ones.
|
85
|
+
#
|
86
|
+
def non_inherited_dependencies
|
87
|
+
pod_dependencies.concat(podspec_dependencies)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [Bool] Whether the target definition has at least one
|
91
|
+
# dependency, excluding inherited ones.
|
92
|
+
#
|
93
|
+
def empty?
|
94
|
+
non_inherited_dependencies.empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
# @return [String] The label of the target definition according to its
|
98
|
+
# name.
|
99
|
+
#
|
100
|
+
def label
|
101
|
+
if root? && name == :default
|
102
|
+
"Pods"
|
103
|
+
elsif exclusive? || parent.nil?
|
104
|
+
"Pods-#{name}"
|
105
|
+
else
|
106
|
+
"#{parent.label}-#{name}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [String] A string representation suitable for UI.
|
111
|
+
#
|
112
|
+
def to_s
|
113
|
+
"`#{label}` target definition"
|
114
|
+
end
|
115
|
+
|
116
|
+
# @return [String] A string representation suitable for debug.
|
117
|
+
#
|
118
|
+
def inspect
|
119
|
+
"#<#{self.class} label=#{label}>"
|
120
|
+
end
|
121
|
+
|
122
|
+
#-----------------------------------------------------------------------#
|
123
|
+
|
124
|
+
public
|
125
|
+
|
126
|
+
# @!group Attributes
|
127
|
+
|
128
|
+
# Returns whether the target definition should inherit the dependencies
|
129
|
+
# of the parent.
|
130
|
+
#
|
131
|
+
# @note A target is always `exclusive` if it is root.
|
132
|
+
#
|
133
|
+
# @note A target is always `exclusive` if the `platform` does
|
134
|
+
# not match the parent's `platform`.
|
135
|
+
#
|
136
|
+
# @return [Bool] whether is exclusive.
|
137
|
+
#
|
138
|
+
def exclusive?
|
139
|
+
if root?
|
140
|
+
true
|
141
|
+
else
|
142
|
+
get_hash_value('exclusive') || ( platform && parent && parent.platform != platform )
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Sets whether the target definition is exclusive.
|
147
|
+
#
|
148
|
+
# @param [Bool] flag
|
149
|
+
# Whether the definition is exclusive.
|
150
|
+
#
|
151
|
+
# @return [void]
|
152
|
+
#
|
153
|
+
def exclusive=(flag)
|
154
|
+
set_hash_value('exclusive', flag)
|
155
|
+
end
|
156
|
+
|
157
|
+
#--------------------------------------#
|
158
|
+
|
159
|
+
# @return [Array<String>] the list of the names of the Xcode targets with
|
160
|
+
# which this target definition should be linked with.
|
161
|
+
#
|
162
|
+
def link_with
|
163
|
+
get_hash_value('link_with')
|
164
|
+
end
|
165
|
+
|
166
|
+
# Sets the client targets that should be integrated by this definition.
|
167
|
+
#
|
168
|
+
# @param [Array<String>] targets
|
169
|
+
# The list of the targets names.
|
170
|
+
#
|
171
|
+
# @return [void]
|
172
|
+
#
|
173
|
+
def link_with=(targets)
|
174
|
+
set_hash_value('link_with', Array(targets).map(&:to_s))
|
175
|
+
end
|
176
|
+
|
177
|
+
#--------------------------------------#
|
178
|
+
|
179
|
+
# @return [String] the path of the project this target definition should
|
180
|
+
# link with.
|
181
|
+
#
|
182
|
+
def user_project_path
|
183
|
+
path = get_hash_value('user_project_path')
|
184
|
+
if path
|
185
|
+
File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj"
|
186
|
+
else
|
187
|
+
parent.user_project_path unless root?
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Sets the path of the user project this target definition should link
|
192
|
+
# with.
|
193
|
+
#
|
194
|
+
# @param [String] path
|
195
|
+
# The path of the project.
|
196
|
+
#
|
197
|
+
# @return [void]
|
198
|
+
#
|
199
|
+
def user_project_path=(path)
|
200
|
+
set_hash_value('user_project_path', path)
|
201
|
+
end
|
202
|
+
|
203
|
+
#--------------------------------------#
|
204
|
+
|
205
|
+
# @return [Hash{String => symbol}] A hash where the keys are the name of
|
206
|
+
# the build configurations and the values a symbol that
|
207
|
+
# represents their type (`:debug` or `:release`).
|
208
|
+
#
|
209
|
+
def build_configurations
|
210
|
+
get_hash_value('build_configurations') || (parent.build_configurations unless root?)
|
211
|
+
end
|
212
|
+
|
213
|
+
# Sets the build configurations for this target.
|
214
|
+
#
|
215
|
+
# @return [Hash{String => Symbol}] hash
|
216
|
+
# A hash where the keys are the name of the build configurations
|
217
|
+
# and the values the type.
|
218
|
+
#
|
219
|
+
# @return [void]
|
220
|
+
#
|
221
|
+
def build_configurations=(hash)
|
222
|
+
set_hash_value('build_configurations', hash) unless hash.empty?
|
223
|
+
end
|
224
|
+
|
225
|
+
#--------------------------------------#
|
226
|
+
|
227
|
+
# @return [Bool] whether the target definition should silence all the
|
228
|
+
# warnings with a compiler flag.
|
229
|
+
#
|
230
|
+
def inhibit_all_warnings?
|
231
|
+
get_hash_value('inhibit_all_warnings') || (parent.inhibit_all_warnings? unless root?)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Sets whether the target definition should inhibit the warnings during
|
235
|
+
# compilation.
|
236
|
+
#
|
237
|
+
# @param [Bool] flag
|
238
|
+
# Whether the warnings should be suppressed.
|
239
|
+
#
|
240
|
+
# @return [void]
|
241
|
+
#
|
242
|
+
def inhibit_all_warnings=(flag)
|
243
|
+
set_hash_value('inhibit_all_warnings', flag)
|
244
|
+
end
|
245
|
+
|
246
|
+
#--------------------------------------#
|
247
|
+
|
248
|
+
# @return [Platform] the platform of the target definition.
|
249
|
+
#
|
250
|
+
# @note If no deployment target has been specified a default value is
|
251
|
+
# provided.
|
252
|
+
#
|
253
|
+
def platform
|
254
|
+
name_or_hash = get_hash_value('platform')
|
255
|
+
if name_or_hash
|
256
|
+
if name_or_hash.is_a?(Hash)
|
257
|
+
name = name_or_hash.keys.first.to_sym
|
258
|
+
target = name_or_hash.values.first
|
259
|
+
else
|
260
|
+
name = name_or_hash.to_sym
|
261
|
+
end
|
262
|
+
target ||= (name == :ios ? '4.3' : '10.6')
|
263
|
+
Platform.new(name, target)
|
264
|
+
else
|
265
|
+
parent.platform unless root?
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Sets the platform of the target definition.
|
270
|
+
#
|
271
|
+
# @param [Symbol] name
|
272
|
+
# The name of the platform.
|
273
|
+
#
|
274
|
+
# @param [String] target
|
275
|
+
# The deployment target of the platform.
|
276
|
+
#
|
277
|
+
# @raise When the name of the platform is unsupported.
|
278
|
+
#
|
279
|
+
# @return [void]
|
280
|
+
#
|
281
|
+
def set_platform(name, target = nil)
|
282
|
+
unless [:ios, :osx].include?(name)
|
283
|
+
raise StandardError, "Unsupported platform `#{name}`. Platform must be `:ios` or `:osx`."
|
284
|
+
end
|
285
|
+
|
286
|
+
if target
|
287
|
+
value = {name.to_s => target}
|
288
|
+
else
|
289
|
+
value = name.to_s
|
290
|
+
end
|
291
|
+
set_hash_value('platform', value)
|
292
|
+
end
|
293
|
+
|
294
|
+
#--------------------------------------#
|
295
|
+
|
296
|
+
# Stores the dependency for a Pod with the given name.
|
297
|
+
#
|
298
|
+
# @param [String] name
|
299
|
+
# The name of the Pod
|
300
|
+
#
|
301
|
+
# @param [Array<String, Hash>] requirements
|
302
|
+
# The requirements and the options of the dependency.
|
303
|
+
#
|
304
|
+
# @note The dependencies are stored as an array. To simplify the YAML
|
305
|
+
# representation if they have requirements they are represented
|
306
|
+
# as a Hash, otherwise only the String of the name is added to
|
307
|
+
# the array.
|
308
|
+
#
|
309
|
+
# @todo This needs urgently a rename.
|
310
|
+
#
|
311
|
+
# @return [void]
|
312
|
+
#
|
313
|
+
def store_pod(name, *requirements)
|
314
|
+
if requirements && !requirements.empty?
|
315
|
+
pod = { name => requirements }
|
316
|
+
else
|
317
|
+
pod = name
|
318
|
+
end
|
319
|
+
get_hash_value('dependencies', []) << pod
|
320
|
+
end
|
321
|
+
|
322
|
+
#--------------------------------------#
|
323
|
+
|
324
|
+
# Stores the podspec whose dependencies should be included by the
|
325
|
+
# target.
|
326
|
+
#
|
327
|
+
# @param [Hash] options
|
328
|
+
# The options used to find the podspec (either by name or by
|
329
|
+
# path). If nil the podspec is auto-detected (i.e. the first one
|
330
|
+
# in the folder of the Podfile)
|
331
|
+
#
|
332
|
+
# @note The storage of this information is optimized for YAML
|
333
|
+
# readability.
|
334
|
+
#
|
335
|
+
# @todo This needs urgently a rename.
|
336
|
+
#
|
337
|
+
# @return [void]
|
338
|
+
#
|
339
|
+
def store_podspec(options = nil)
|
340
|
+
if options
|
341
|
+
unless options.keys.all? { |key| [:name, :path].include?(key) }
|
342
|
+
raise StandardError, "Unrecognized options for the podspec method `#{options}`"
|
343
|
+
end
|
344
|
+
get_hash_value('podspecs', []) << options
|
345
|
+
else
|
346
|
+
get_hash_value('podspecs', []) << { :autodetect => true }
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
#-----------------------------------------------------------------------#
|
351
|
+
|
352
|
+
public
|
353
|
+
|
354
|
+
# @!group Representations
|
355
|
+
|
356
|
+
# @return [Array] The keys used by the hash representation of the
|
357
|
+
# target definition.
|
358
|
+
#
|
359
|
+
HASH_KEYS = [
|
360
|
+
'platform',
|
361
|
+
'podspecs',
|
362
|
+
'exclusive',
|
363
|
+
'link_with',
|
364
|
+
'inhibit_all_warnings',
|
365
|
+
'user_project_path',
|
366
|
+
'build_configurations',
|
367
|
+
'dependencies',
|
368
|
+
'children'
|
369
|
+
].freeze
|
370
|
+
|
371
|
+
# @return [Hash] The hash representation of the target definition.
|
372
|
+
#
|
373
|
+
def to_hash
|
374
|
+
hash = internal_hash.dup
|
375
|
+
unless children.empty?
|
376
|
+
hash['children'] = Hash[children.map { |child| [child.name, child.to_hash] }]
|
377
|
+
end
|
378
|
+
hash
|
379
|
+
end
|
380
|
+
|
381
|
+
# Configures a new target definition from the given hash.
|
382
|
+
#
|
383
|
+
# @param [Hash] the hash which contains the information of the
|
384
|
+
# Podfile.
|
385
|
+
#
|
386
|
+
# @return [TargetDefinition] the new target definition
|
387
|
+
#
|
388
|
+
def self.from_hash(name, hash, parent)
|
389
|
+
internal_hash = hash.dup
|
390
|
+
children_hashes = internal_hash.delete('children') || {}
|
391
|
+
definition = TargetDefinition.new(name, parent, internal_hash)
|
392
|
+
children_hashes.each do |child_name, child_hash|
|
393
|
+
TargetDefinition.from_hash(child_name, child_hash, definition)
|
394
|
+
end
|
395
|
+
definition
|
396
|
+
end
|
397
|
+
|
398
|
+
#-----------------------------------------------------------------------#
|
399
|
+
|
400
|
+
private
|
401
|
+
|
402
|
+
# @!group Private helpers
|
403
|
+
|
404
|
+
# @return [Array<TargetDefinition>]
|
405
|
+
#
|
406
|
+
attr_writer :children
|
407
|
+
|
408
|
+
# @return [Hash] The hash which store the attributes of the target
|
409
|
+
# definition.
|
410
|
+
#
|
411
|
+
attr_accessor :internal_hash
|
412
|
+
|
413
|
+
# Set a value in the internal hash of the target definition for the given
|
414
|
+
# key.
|
415
|
+
#
|
416
|
+
# @param [String] key
|
417
|
+
# The key for which to store the value.
|
418
|
+
#
|
419
|
+
# @param [Object] value
|
420
|
+
# The value to store.
|
421
|
+
#
|
422
|
+
# @raise If the key is not recognized.
|
423
|
+
#
|
424
|
+
# @return [void]
|
425
|
+
#
|
426
|
+
def set_hash_value(key, value)
|
427
|
+
raise StandardError, "Unsupported hash key `#{key}`" unless HASH_KEYS.include?(key)
|
428
|
+
internal_hash[key] = value
|
429
|
+
end
|
430
|
+
|
431
|
+
# Returns the value for the given key in the internal hash of the target
|
432
|
+
# definition.
|
433
|
+
#
|
434
|
+
# @param [String] key
|
435
|
+
# The key for which the value is needed.
|
436
|
+
#
|
437
|
+
# @param [Object] base_value
|
438
|
+
# The value to set if they key is nil. Useful for collections.
|
439
|
+
#
|
440
|
+
# @raise If the key is not recognized.
|
441
|
+
#
|
442
|
+
# @return [Object] The value for the key.
|
443
|
+
#
|
444
|
+
def get_hash_value(key, base_value = nil)
|
445
|
+
raise StandardError, "Unsupported hash key `#{key}`" unless HASH_KEYS.include?(key)
|
446
|
+
internal_hash[key] ||= base_value
|
447
|
+
end
|
448
|
+
|
449
|
+
# @return [Array<Dependency>] The dependencies specified by the user for
|
450
|
+
# this target definition.
|
451
|
+
#
|
452
|
+
def pod_dependencies
|
453
|
+
pods = get_hash_value('dependencies') || []
|
454
|
+
pods.map do |name_or_hash|
|
455
|
+
if name_or_hash.is_a?(Hash)
|
456
|
+
name = name_or_hash.keys.first
|
457
|
+
requirements = name_or_hash.values.first
|
458
|
+
Dependency.new(name, *requirements)
|
459
|
+
else
|
460
|
+
Dependency.new(name_or_hash)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
# @return [Array<Dependency>] The dependencies inherited by the podspecs.
|
466
|
+
#
|
467
|
+
def podspec_dependencies
|
468
|
+
podspecs = get_hash_value('podspecs') || []
|
469
|
+
podspecs.map do |options|
|
470
|
+
file = podspec_path_from_options(options)
|
471
|
+
spec = Specification.from_file(file)
|
472
|
+
all_specs = [spec, *spec.recursive_subspecs]
|
473
|
+
all_specs.map{ |s| s.dependencies(platform) }
|
474
|
+
|
475
|
+
end.flatten.uniq
|
476
|
+
end
|
477
|
+
|
478
|
+
# The path of the podspec with the given options.
|
479
|
+
#
|
480
|
+
# @param [Hash] options
|
481
|
+
# The options to use for finding the podspec. The supported keys
|
482
|
+
# are: `:name`, `:path`, `:autodetect`.
|
483
|
+
#
|
484
|
+
# @return [Pathname] The path.
|
485
|
+
#
|
486
|
+
def podspec_path_from_options(options)
|
487
|
+
if path = options[:path]
|
488
|
+
path_with_ext = File.extname(path) == '.podspec' ? path : "#{path}.podspec"
|
489
|
+
path_without_tilde = path_with_ext.gsub('~', ENV['HOME'])
|
490
|
+
file = podfile.defined_in_file.dirname + path_without_tilde
|
491
|
+
elsif name = options[:name]
|
492
|
+
name = File.extname(name) == '.podspec' ? name : "#{name}.podspec"
|
493
|
+
file = podfile.defined_in_file.dirname + name
|
494
|
+
elsif options[:autodetect]
|
495
|
+
file = Pathname.glob(podfile.defined_in_file.dirname + '*.podspec').first
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
#-----------------------------------------------------------------------#
|
500
|
+
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|