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,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
|