cocoapods-core 0.30.0 → 1.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +7 -10
- data/lib/cocoapods-core/build_type.rb +121 -0
- data/lib/cocoapods-core/cdn_source.rb +501 -0
- data/lib/cocoapods-core/core_ui.rb +4 -3
- data/lib/cocoapods-core/dependency.rb +100 -73
- data/lib/cocoapods-core/gem_version.rb +1 -2
- data/lib/cocoapods-core/github.rb +32 -5
- data/lib/cocoapods-core/http.rb +86 -0
- data/lib/cocoapods-core/lockfile.rb +161 -56
- data/lib/cocoapods-core/metrics.rb +47 -0
- data/lib/cocoapods-core/platform.rb +99 -11
- data/lib/cocoapods-core/podfile/dsl.rb +623 -124
- data/lib/cocoapods-core/podfile/target_definition.rb +662 -109
- data/lib/cocoapods-core/podfile.rb +138 -65
- data/lib/cocoapods-core/requirement.rb +37 -8
- data/lib/cocoapods-core/source/acceptor.rb +16 -13
- data/lib/cocoapods-core/source/aggregate.rb +79 -103
- data/lib/cocoapods-core/source/health_reporter.rb +9 -18
- data/lib/cocoapods-core/source/manager.rb +488 -0
- data/lib/cocoapods-core/source/metadata.rb +79 -0
- data/lib/cocoapods-core/source.rb +241 -70
- data/lib/cocoapods-core/specification/consumer.rb +187 -47
- data/lib/cocoapods-core/specification/dsl/attribute.rb +49 -85
- data/lib/cocoapods-core/specification/dsl/attribute_support.rb +6 -8
- data/lib/cocoapods-core/specification/dsl/deprecations.rb +9 -126
- data/lib/cocoapods-core/specification/dsl/platform_proxy.rb +30 -20
- data/lib/cocoapods-core/specification/dsl.rb +943 -296
- data/lib/cocoapods-core/specification/json.rb +64 -23
- data/lib/cocoapods-core/specification/linter/analyzer.rb +218 -0
- data/lib/cocoapods-core/specification/linter/result.rb +128 -0
- data/lib/cocoapods-core/specification/linter.rb +310 -309
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +90 -39
- data/lib/cocoapods-core/specification/set/presenter.rb +35 -71
- data/lib/cocoapods-core/specification/set.rb +42 -96
- data/lib/cocoapods-core/specification.rb +368 -130
- data/lib/cocoapods-core/standard_error.rb +45 -24
- data/lib/cocoapods-core/trunk_source.rb +14 -0
- data/lib/cocoapods-core/vendor/requirement.rb +133 -53
- data/lib/cocoapods-core/vendor/version.rb +197 -156
- data/lib/cocoapods-core/vendor.rb +1 -5
- data/lib/cocoapods-core/version.rb +137 -42
- data/lib/cocoapods-core/yaml_helper.rb +334 -0
- data/lib/cocoapods-core.rb +10 -4
- metadata +100 -27
- data/lib/cocoapods-core/source/abstract_data_provider.rb +0 -71
- data/lib/cocoapods-core/source/file_system_data_provider.rb +0 -150
- data/lib/cocoapods-core/source/github_data_provider.rb +0 -143
- data/lib/cocoapods-core/specification/set/statistics.rb +0 -266
- data/lib/cocoapods-core/yaml_converter.rb +0 -192
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/string/strip.rb'
|
2
|
+
|
1
3
|
require 'cocoapods-core/specification/consumer'
|
2
4
|
require 'cocoapods-core/specification/dsl'
|
3
5
|
require 'cocoapods-core/specification/linter'
|
@@ -6,7 +8,6 @@ require 'cocoapods-core/specification/set'
|
|
6
8
|
require 'cocoapods-core/specification/json'
|
7
9
|
|
8
10
|
module Pod
|
9
|
-
|
10
11
|
# The Specification provides a DSL to describe a Pod. A pod is defined as a
|
11
12
|
# library originating from a source. A specification can support detailed
|
12
13
|
# attributes for modules of code through subspecs.
|
@@ -14,7 +15,6 @@ module Pod
|
|
14
15
|
# Usually it is stored in files with `podspec` extension.
|
15
16
|
#
|
16
17
|
class Specification
|
17
|
-
|
18
18
|
include Pod::Specification::DSL
|
19
19
|
include Pod::Specification::DSL::Deprecations
|
20
20
|
include Pod::Specification::RootAttributesAccessors
|
@@ -25,21 +25,46 @@ module Pod
|
|
25
25
|
#
|
26
26
|
attr_reader :parent
|
27
27
|
|
28
|
+
# @return [Integer] the cached hash value for this spec.
|
29
|
+
#
|
30
|
+
attr_reader :hash_value
|
31
|
+
|
28
32
|
# @param [Specification] parent @see parent
|
29
33
|
#
|
30
34
|
# @param [String] name
|
31
35
|
# the name of the specification.
|
32
36
|
#
|
33
|
-
|
37
|
+
# @param [Boolean] test_specification
|
38
|
+
# Whether the specification is a test specification
|
39
|
+
#
|
40
|
+
# @param [Boolean] app_specification
|
41
|
+
# Whether the specification is an app specification
|
42
|
+
#
|
43
|
+
def initialize(parent = nil, name = nil, test_specification = false, app_specification: false)
|
44
|
+
raise StandardError, "#{self} can not be both an app and test specification." if test_specification && app_specification
|
34
45
|
@attributes_hash = {}
|
35
46
|
@subspecs = []
|
36
47
|
@consumers = {}
|
37
48
|
@parent = parent
|
49
|
+
@hash_value = nil
|
50
|
+
@test_specification = test_specification
|
51
|
+
@app_specification = app_specification
|
38
52
|
attributes_hash['name'] = name
|
53
|
+
attributes_hash['test_type'] = :unit if test_specification
|
39
54
|
|
40
55
|
yield self if block_given?
|
41
56
|
end
|
42
57
|
|
58
|
+
def initialize_copy(other)
|
59
|
+
super
|
60
|
+
|
61
|
+
@subspecs = @subspecs.map do |subspec|
|
62
|
+
subspec = subspec.dup
|
63
|
+
subspec.instance_variable_set :@parent, self
|
64
|
+
subspec
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
43
68
|
# @return [Hash] the hash that stores the information of the attributes of
|
44
69
|
# the specification.
|
45
70
|
#
|
@@ -49,6 +74,16 @@ module Pod
|
|
49
74
|
#
|
50
75
|
attr_accessor :subspecs
|
51
76
|
|
77
|
+
# @return [Boolean] If this specification is a test specification.
|
78
|
+
#
|
79
|
+
attr_accessor :test_specification
|
80
|
+
alias_method :test_specification?, :test_specification
|
81
|
+
|
82
|
+
# @return [Boolean] If this specification is an app specification.
|
83
|
+
#
|
84
|
+
attr_accessor :app_specification
|
85
|
+
alias_method :app_specification?, :app_specification
|
86
|
+
|
52
87
|
# Checks if a specification is equal to the given one according its name
|
53
88
|
# and to its version.
|
54
89
|
#
|
@@ -59,23 +94,15 @@ module Pod
|
|
59
94
|
# go. This is used by the installer to group specifications by root
|
60
95
|
# spec.
|
61
96
|
#
|
62
|
-
# @return [
|
97
|
+
# @return [Boolean] Whether the specifications are equal.
|
63
98
|
#
|
64
99
|
def ==(other)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# subspecs == other.subspecs &&
|
69
|
-
# pre_install_callback == other.pre_install_callback &&
|
70
|
-
# post_install_callback == other.post_install_callback
|
71
|
-
to_s == other.to_s
|
100
|
+
other.is_a?(self.class) &&
|
101
|
+
name == other.name &&
|
102
|
+
version == other.version
|
72
103
|
end
|
73
104
|
|
74
|
-
|
75
|
-
#
|
76
|
-
def eql?(other)
|
77
|
-
self == other
|
78
|
-
end
|
105
|
+
alias_method :eql?, :==
|
79
106
|
|
80
107
|
# Return the hash value for this specification according to its attributes
|
81
108
|
# hash.
|
@@ -88,19 +115,23 @@ module Pod
|
|
88
115
|
# @return [Fixnum] The hash value.
|
89
116
|
#
|
90
117
|
def hash
|
91
|
-
|
118
|
+
if @hash_value.nil?
|
119
|
+
@hash_value = (name.hash * 53) ^ version.hash
|
120
|
+
end
|
121
|
+
@hash_value
|
92
122
|
end
|
93
123
|
|
94
124
|
# @return [String] A string suitable for representing the specification in
|
95
125
|
# clients.
|
96
126
|
#
|
97
127
|
def to_s
|
98
|
-
|
99
|
-
|
128
|
+
specified_version = raw_version || ''
|
129
|
+
if name && !specified_version.empty?
|
130
|
+
"#{name} (#{specified_version})"
|
100
131
|
elsif name
|
101
132
|
name
|
102
133
|
else
|
103
|
-
|
134
|
+
'No-name'
|
104
135
|
end
|
105
136
|
end
|
106
137
|
|
@@ -117,19 +148,18 @@ module Pod
|
|
117
148
|
# @example Input examples
|
118
149
|
#
|
119
150
|
# "libPusher (1.0)"
|
120
|
-
# "libPusher (HEAD based on 1.0)"
|
121
151
|
# "RestKit/JSON (1.0)"
|
122
152
|
#
|
123
153
|
# @return [Array<String, Version>] the name and the version of a
|
124
154
|
# pod.
|
125
155
|
#
|
126
156
|
def self.name_and_version_from_string(string_representation)
|
127
|
-
match_data = string_representation.match(
|
157
|
+
match_data = string_representation.match(/\A((?:\s?[^\s(])+)(?: \((.+)\))?\Z/)
|
128
158
|
unless match_data
|
129
|
-
raise Informative,
|
130
|
-
"
|
131
|
-
|
132
|
-
|
159
|
+
raise Informative, 'Invalid string representation for a ' \
|
160
|
+
"specification: `#{string_representation}`. " \
|
161
|
+
'The string representation should include the name and ' \
|
162
|
+
'optionally the version of the Pod.'
|
133
163
|
end
|
134
164
|
name = match_data[1]
|
135
165
|
vers = Version.new(match_data[2])
|
@@ -143,7 +173,46 @@ module Pod
|
|
143
173
|
# @return [String] the root name
|
144
174
|
#
|
145
175
|
def self.root_name(full_name)
|
146
|
-
full_name.
|
176
|
+
if index = full_name.index('/')
|
177
|
+
full_name.slice(0, index)
|
178
|
+
else
|
179
|
+
full_name
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Returns the module name of a specification
|
184
|
+
#
|
185
|
+
# @return [String] the module name
|
186
|
+
#
|
187
|
+
def module_name
|
188
|
+
attributes_hash['module_name'] ||
|
189
|
+
c99ext_identifier(attributes_hash['header_dir']) ||
|
190
|
+
c99ext_identifier(attributes_hash['name'])
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
# Transforms the given string into a valid +identifier+ after C99ext
|
196
|
+
# standard, so that it can be used in source code where escaping of
|
197
|
+
# ambiguous characters is not applicable.
|
198
|
+
#
|
199
|
+
# @param [String] name
|
200
|
+
# any name, which may contain leading numbers, spaces or invalid
|
201
|
+
# characters.
|
202
|
+
#
|
203
|
+
# @return [String]
|
204
|
+
#
|
205
|
+
def c99ext_identifier(name)
|
206
|
+
return nil if name.nil?
|
207
|
+
I18n.transliterate(name).gsub(/^([0-9])/, '_\1').
|
208
|
+
gsub(/[^a-zA-Z0-9_]/, '_').gsub(/_+/, '_')
|
209
|
+
end
|
210
|
+
|
211
|
+
# @return [Object, Nil]
|
212
|
+
# the raw value specified for the version attribute, or nil
|
213
|
+
#
|
214
|
+
def raw_version
|
215
|
+
root.attributes_hash['version']
|
147
216
|
end
|
148
217
|
|
149
218
|
#-------------------------------------------------------------------------#
|
@@ -158,13 +227,13 @@ module Pod
|
|
158
227
|
parent ? parent.root : self
|
159
228
|
end
|
160
229
|
|
161
|
-
# @return [
|
230
|
+
# @return [Boolean] whether the specification is root.
|
162
231
|
#
|
163
232
|
def root?
|
164
233
|
parent.nil?
|
165
234
|
end
|
166
235
|
|
167
|
-
# @return [
|
236
|
+
# @return [Boolean] whether the specification is a subspec.
|
168
237
|
#
|
169
238
|
def subspec?
|
170
239
|
!parent.nil?
|
@@ -174,9 +243,63 @@ module Pod
|
|
174
243
|
|
175
244
|
public
|
176
245
|
|
246
|
+
# @return [Symbol] Spec type of the current spec.
|
247
|
+
#
|
248
|
+
# @note see Attribute#SUPPORTED_SPEC_TYPES for the list of available spec_types.
|
249
|
+
#
|
250
|
+
def spec_type
|
251
|
+
return :app if app_specification?
|
252
|
+
return :test if test_specification?
|
253
|
+
|
254
|
+
:library
|
255
|
+
end
|
256
|
+
|
177
257
|
# @!group Dependencies & Subspecs
|
178
258
|
|
179
|
-
# @return [
|
259
|
+
# @return [Boolean] If this specification is a library specification.
|
260
|
+
#
|
261
|
+
# @note a library specification is a specification that is not of type app or test.
|
262
|
+
#
|
263
|
+
def library_specification?
|
264
|
+
!app_specification? && !test_specification?
|
265
|
+
end
|
266
|
+
|
267
|
+
# @return [Boolean] If this specification is not a library specification.
|
268
|
+
#
|
269
|
+
# @note see #library_specification?
|
270
|
+
#
|
271
|
+
def non_library_specification?
|
272
|
+
!library_specification?
|
273
|
+
end
|
274
|
+
|
275
|
+
# @return [Symbol] the test type supported if this is a test specification.
|
276
|
+
#
|
277
|
+
def test_type
|
278
|
+
attributes_hash['test_type'].to_sym
|
279
|
+
end
|
280
|
+
|
281
|
+
# @return [Array<Specification>] the list of all the test subspecs of
|
282
|
+
# a specification.
|
283
|
+
#
|
284
|
+
def test_specs
|
285
|
+
subspecs.select(&:test_specification?)
|
286
|
+
end
|
287
|
+
|
288
|
+
# @return [Array<Specification>] the list of all the app subspecs of
|
289
|
+
# a specification.
|
290
|
+
#
|
291
|
+
def app_specs
|
292
|
+
subspecs.select(&:app_specification?)
|
293
|
+
end
|
294
|
+
|
295
|
+
# @return [Array<Specification>] the list of all the non libary (app or test) subspecs of
|
296
|
+
# a specification.
|
297
|
+
#
|
298
|
+
def non_library_specs
|
299
|
+
subspecs.select(&:non_library_specification?)
|
300
|
+
end
|
301
|
+
|
302
|
+
# @return [Array<Specification>] the recursive list of all the subspecs of
|
180
303
|
# a specification.
|
181
304
|
#
|
182
305
|
def recursive_subspecs
|
@@ -195,58 +318,89 @@ module Pod
|
|
195
318
|
# the relative name of the subspecs starting from the receiver
|
196
319
|
# including the name of the receiver.
|
197
320
|
#
|
321
|
+
# @param [Boolean] raise_if_missing
|
322
|
+
# whether an exception should be raised if no specification named
|
323
|
+
# `relative_name` is found.
|
324
|
+
#
|
198
325
|
# @example Retrieving a subspec
|
199
326
|
#
|
200
327
|
# s.subspec_by_name('Pod/subspec').name #=> 'subspec'
|
201
328
|
#
|
202
329
|
# @return [Specification] the subspec with the given name or self.
|
203
330
|
#
|
204
|
-
def subspec_by_name(relative_name)
|
331
|
+
def subspec_by_name(relative_name, raise_if_missing = true, include_non_library_specifications = false)
|
205
332
|
if relative_name.nil? || relative_name == base_name
|
206
333
|
self
|
334
|
+
elsif base_name.nil?
|
335
|
+
if raise_if_missing
|
336
|
+
raise Informative, "Trying to access a `#{relative_name}` " \
|
337
|
+
"specification from `#{defined_in_file}`, which has no contents."
|
338
|
+
else
|
339
|
+
return nil
|
340
|
+
end
|
341
|
+
elsif relative_name.downcase == base_name.downcase
|
342
|
+
raise Informative, "Trying to access a `#{relative_name}` " \
|
343
|
+
"specification from `#{base_name}`, which has a different case."
|
207
344
|
else
|
208
345
|
remainder = relative_name[base_name.size + 1..-1]
|
209
346
|
subspec_name = remainder.split('/').shift
|
210
|
-
subspec = subspecs.find { |s| s.
|
347
|
+
subspec = subspecs.find { |s| s.base_name == subspec_name && (include_non_library_specifications || !s.non_library_specification?) }
|
211
348
|
unless subspec
|
212
|
-
|
213
|
-
|
349
|
+
if raise_if_missing
|
350
|
+
raise Informative, 'Unable to find a specification named ' \
|
351
|
+
"`#{relative_name}` in `#{name} (#{version})`."
|
352
|
+
else
|
353
|
+
return nil
|
354
|
+
end
|
214
355
|
end
|
215
|
-
subspec.subspec_by_name(remainder)
|
356
|
+
subspec.subspec_by_name(remainder, raise_if_missing, include_non_library_specifications)
|
216
357
|
end
|
217
358
|
end
|
218
359
|
|
219
|
-
# @return [String] the name of the default
|
360
|
+
# @return [Array<String>, Symbol] the name(s) of the default subspecs if provided or :none for no default subspecs.
|
220
361
|
#
|
221
|
-
def
|
222
|
-
|
362
|
+
def default_subspecs
|
363
|
+
# TODO: remove singular form and update the JSON specs.
|
364
|
+
value = Array(attributes_hash['default_subspecs'] || attributes_hash['default_subspec'])
|
365
|
+
first = value.first
|
366
|
+
if first == :none || first == 'none'
|
367
|
+
first.to_sym
|
368
|
+
else
|
369
|
+
value
|
370
|
+
end
|
223
371
|
end
|
224
372
|
|
225
373
|
# Returns the dependencies on subspecs.
|
226
374
|
#
|
227
375
|
# @note A specification has a dependency on either the
|
228
|
-
# {#
|
376
|
+
# {#default_subspecs} or each of its children subspecs that are
|
229
377
|
# compatible with its platform.
|
230
378
|
#
|
379
|
+
# @param [Platform] platform
|
380
|
+
# return only dependencies supported on the given platform.
|
381
|
+
#
|
231
382
|
# @return [Array<Dependency>] the dependencies on subspecs.
|
232
383
|
#
|
233
384
|
def subspec_dependencies(platform = nil)
|
234
|
-
if
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
385
|
+
specs = if default_subspecs.empty?
|
386
|
+
subspecs.compact.reject(&:non_library_specification?)
|
387
|
+
elsif default_subspecs == :none
|
388
|
+
[]
|
389
|
+
else
|
390
|
+
default_subspecs.map do |subspec_name|
|
391
|
+
root.subspec_by_name("#{name}/#{subspec_name}")
|
392
|
+
end
|
393
|
+
end
|
239
394
|
if platform
|
240
395
|
specs = specs.select { |s| s.supported_on_platform?(platform) }
|
241
396
|
end
|
242
|
-
specs.map { |s| Dependency.new(s.name) }
|
397
|
+
specs.map { |s| Dependency.new(s.name, version) }
|
243
398
|
end
|
244
399
|
|
245
400
|
# Returns the dependencies on other Pods or subspecs of other Pods.
|
246
401
|
#
|
247
|
-
# @param [
|
248
|
-
#
|
249
|
-
# instead of the active one.
|
402
|
+
# @param [Platform] platform
|
403
|
+
# return only dependencies supported on the given platform.
|
250
404
|
#
|
251
405
|
# @note External dependencies are inherited by subspecs
|
252
406
|
#
|
@@ -268,10 +422,29 @@ module Pod
|
|
268
422
|
dependencies(platform) + subspec_dependencies(platform)
|
269
423
|
end
|
270
424
|
|
425
|
+
# Returns whether a dependency is whitelisted for the given configuration.
|
426
|
+
#
|
427
|
+
# @param [Pod::Dependency] dependency
|
428
|
+
# the dependency verify.
|
429
|
+
#
|
430
|
+
# @param [Symbol, String] configuration
|
431
|
+
# the configuration to check against.
|
432
|
+
#
|
433
|
+
# @return [Boolean] whether the dependency is whitelisted or not.
|
434
|
+
#
|
435
|
+
def dependency_whitelisted_for_configuration?(dependency, configuration)
|
436
|
+
inherited = -> { root? ? true : parent.dependency_whitelisted_for_configuration?(dependency, configuration) }
|
437
|
+
|
438
|
+
return inherited[] unless configuration_whitelist = attributes_hash['configuration_pod_whitelist']
|
439
|
+
return inherited[] unless whitelist_for_pod = configuration_whitelist[dependency.name]
|
440
|
+
|
441
|
+
whitelist_for_pod.include?(configuration.to_s.downcase)
|
442
|
+
end
|
443
|
+
|
271
444
|
# Returns a consumer to access the multi-platform attributes.
|
272
445
|
#
|
273
446
|
# @param [String, Symbol, Platform] platform
|
274
|
-
#
|
447
|
+
# the platform of the consumer
|
275
448
|
#
|
276
449
|
# @return [Specification::Consumer] the consumer for the given platform
|
277
450
|
#
|
@@ -280,20 +453,61 @@ module Pod
|
|
280
453
|
@consumers[platform] ||= Consumer.new(self, platform)
|
281
454
|
end
|
282
455
|
|
456
|
+
# @return [Bool, String] The prefix_header_file value.
|
457
|
+
#
|
458
|
+
def prefix_header_file
|
459
|
+
attributes_hash['prefix_header_file']
|
460
|
+
end
|
461
|
+
|
462
|
+
# @return [Array<Hash{Symbol=>String}>] The script_phases value.
|
463
|
+
#
|
464
|
+
def script_phases
|
465
|
+
script_phases = attributes_hash['script_phases'] || []
|
466
|
+
script_phases.map do |script_phase|
|
467
|
+
phase = Specification.convert_keys_to_symbol(script_phase)
|
468
|
+
phase[:execution_position] = if phase.key?(:execution_position)
|
469
|
+
phase[:execution_position].to_sym
|
470
|
+
else
|
471
|
+
:any
|
472
|
+
end
|
473
|
+
phase
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
# @return [Hash] The on demand resources value.
|
478
|
+
#
|
479
|
+
def on_demand_resources
|
480
|
+
attributes_hash['on_demand_resources'] || {}
|
481
|
+
end
|
482
|
+
|
483
|
+
# @return [Hash] The scheme value.
|
484
|
+
#
|
485
|
+
def scheme
|
486
|
+
value = attributes_hash['scheme'] || {}
|
487
|
+
Specification.convert_keys_to_symbol(value, :recursive => false)
|
488
|
+
end
|
489
|
+
|
490
|
+
# @return [Hash] The Info.plist value.
|
491
|
+
#
|
492
|
+
def info_plist
|
493
|
+
attributes_hash['info_plist'] || {}
|
494
|
+
end
|
495
|
+
|
283
496
|
#-------------------------------------------------------------------------#
|
284
497
|
|
285
498
|
public
|
286
499
|
|
287
500
|
# @!group DSL helpers
|
288
501
|
|
289
|
-
# @return [
|
502
|
+
# @return [Boolean] whether the specification should use a directory as its
|
290
503
|
# source.
|
291
504
|
#
|
292
505
|
def local?
|
293
|
-
|
506
|
+
return true if source[:path]
|
507
|
+
false
|
294
508
|
end
|
295
509
|
|
296
|
-
# @return [
|
510
|
+
# @return [Boolean] whether the specification is supported in the given
|
297
511
|
# platform.
|
298
512
|
#
|
299
513
|
# @overload supported_on_platform?(platform)
|
@@ -303,11 +517,6 @@ module Pod
|
|
303
517
|
#
|
304
518
|
# @overload supported_on_platform?(symbolic_name, deployment_target)
|
305
519
|
#
|
306
|
-
# @param [Symbol] symbolic_name
|
307
|
-
# the name of the platform which is checked for support.
|
308
|
-
#
|
309
|
-
# @param [String] deployment_target
|
310
|
-
# the deployment target which is checked for support.
|
311
520
|
#
|
312
521
|
def supported_on_platform?(*platform)
|
313
522
|
platform = Platform.new(*platform)
|
@@ -359,7 +568,7 @@ module Pod
|
|
359
568
|
# information.
|
360
569
|
#
|
361
570
|
def platform_hash
|
362
|
-
case value = attributes_hash[
|
571
|
+
case value = attributes_hash['platforms']
|
363
572
|
when String
|
364
573
|
{ value => nil }
|
365
574
|
when Array
|
@@ -377,55 +586,8 @@ module Pod
|
|
377
586
|
|
378
587
|
public
|
379
588
|
|
380
|
-
# @!group Deprecated Hooks support
|
381
589
|
#-------------------------------------------------------------------------#
|
382
590
|
|
383
|
-
# @return [Proc] the pre install callback if defined.
|
384
|
-
#
|
385
|
-
attr_reader :pre_install_callback
|
386
|
-
|
387
|
-
# @return [Proc] the post install callback if defined.
|
388
|
-
#
|
389
|
-
attr_reader :post_install_callback
|
390
|
-
|
391
|
-
# Calls the pre install callback if defined.
|
392
|
-
#
|
393
|
-
# @param [Pod::LocalPod] pod
|
394
|
-
# the local pod instance that manages the files described by this
|
395
|
-
# specification.
|
396
|
-
#
|
397
|
-
# @param [Podfile::TargetDefinition] target_definition
|
398
|
-
# the target definition that required this specification as a
|
399
|
-
# dependency.
|
400
|
-
#
|
401
|
-
# @return [Bool] whether a pre install callback was specified and it was
|
402
|
-
# called.
|
403
|
-
#
|
404
|
-
def pre_install!(pod, target_definition)
|
405
|
-
return false unless @pre_install_callback
|
406
|
-
@pre_install_callback.call(pod, target_definition)
|
407
|
-
true
|
408
|
-
end
|
409
|
-
|
410
|
-
# Calls the post install callback if defined.
|
411
|
-
#
|
412
|
-
# @param [Pod::TargetInstaller] target_installer
|
413
|
-
# the target installer that is performing the installation of the
|
414
|
-
# pod.
|
415
|
-
#
|
416
|
-
# @return [Bool] whether a post install callback was specified and it was
|
417
|
-
# called.
|
418
|
-
#
|
419
|
-
def post_install!(target_installer)
|
420
|
-
return false unless @post_install_callback
|
421
|
-
@post_install_callback.call(target_installer)
|
422
|
-
true
|
423
|
-
end
|
424
|
-
|
425
|
-
#-------------------------------------------------------------------------#
|
426
|
-
|
427
|
-
public
|
428
|
-
|
429
591
|
# @!group DSL attribute writers
|
430
592
|
|
431
593
|
# Sets the value for the attribute with the given name.
|
@@ -436,7 +598,7 @@ module Pod
|
|
436
598
|
# @param [Object] value
|
437
599
|
# the value to store.
|
438
600
|
#
|
439
|
-
# @param [Symbol]
|
601
|
+
# @param [Symbol] platform_name
|
440
602
|
# If provided the attribute is stored only for the given platform.
|
441
603
|
#
|
442
604
|
# @note If the provides value is Hash the keys are converted to a string.
|
@@ -445,7 +607,8 @@ module Pod
|
|
445
607
|
#
|
446
608
|
def store_attribute(name, value, platform_name = nil)
|
447
609
|
name = name.to_s
|
448
|
-
value = convert_keys_to_string(value) if value.is_a?(Hash)
|
610
|
+
value = Specification.convert_keys_to_string(value) if value.is_a?(Hash)
|
611
|
+
value = value.strip_heredoc.strip if value.respond_to?(:strip_heredoc)
|
449
612
|
if platform_name
|
450
613
|
platform_name = platform_name.to_s
|
451
614
|
attributes_hash[platform_name] ||= {}
|
@@ -468,25 +631,46 @@ module Pod
|
|
468
631
|
end
|
469
632
|
end
|
470
633
|
|
471
|
-
private
|
472
|
-
|
473
634
|
# Converts the keys of the given hash to a string.
|
474
635
|
#
|
475
636
|
# @param [Object] value
|
476
637
|
# the value that needs to be stripped from the Symbols.
|
477
638
|
#
|
478
|
-
# @
|
639
|
+
# @param [Boolean] recursive
|
640
|
+
# whether to convert keys of nested hashes.
|
479
641
|
#
|
480
|
-
|
642
|
+
# @return [Hash] the hash with the keys as strings instead of symbols.
|
643
|
+
#
|
644
|
+
def self.convert_keys_to_string(value, recursive: true)
|
481
645
|
return unless value
|
482
646
|
result = {}
|
483
647
|
value.each do |key, subvalue|
|
484
|
-
subvalue = convert_keys_to_string(subvalue) if subvalue.is_a?(Hash)
|
648
|
+
subvalue = Specification.convert_keys_to_string(subvalue) if recursive && subvalue.is_a?(Hash)
|
485
649
|
result[key.to_s] = subvalue
|
486
650
|
end
|
487
651
|
result
|
488
652
|
end
|
489
653
|
|
654
|
+
# Converts the keys of the given hash to a symbol.
|
655
|
+
#
|
656
|
+
# @param [Object] value
|
657
|
+
# the value that needs to be stripped from the Strings.
|
658
|
+
#
|
659
|
+
# @param [Boolean] recursive
|
660
|
+
# whether to convert keys of nested hashes.
|
661
|
+
#
|
662
|
+
# @return [Hash] the hash with the keys as symbols instead of strings.
|
663
|
+
#
|
664
|
+
def self.convert_keys_to_symbol(value, recursive: true)
|
665
|
+
return unless value
|
666
|
+
result = {}
|
667
|
+
value.each do |key, subvalue|
|
668
|
+
subvalue = Specification.convert_keys_to_symbol(subvalue) if recursive && subvalue.is_a?(Hash)
|
669
|
+
result[key.to_sym] = subvalue
|
670
|
+
end
|
671
|
+
result
|
672
|
+
end
|
673
|
+
|
490
674
|
#-------------------------------------------------------------------------#
|
491
675
|
|
492
676
|
public
|
@@ -499,11 +683,17 @@ module Pod
|
|
499
683
|
# @return [Nil] If the specification is not defined in a file.
|
500
684
|
#
|
501
685
|
def checksum
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
686
|
+
@checksum ||= begin
|
687
|
+
if root?
|
688
|
+
unless defined_in_file.nil?
|
689
|
+
require 'digest'
|
690
|
+
checksum = Digest::SHA1.hexdigest(File.read(defined_in_file))
|
691
|
+
checksum = checksum.encode('UTF-8') if checksum.respond_to?(:encode)
|
692
|
+
checksum
|
693
|
+
end
|
694
|
+
else
|
695
|
+
root.checksum
|
696
|
+
end
|
507
697
|
end
|
508
698
|
end
|
509
699
|
|
@@ -534,9 +724,9 @@ module Pod
|
|
534
724
|
raise Informative, "No podspec exists at path `#{path}`."
|
535
725
|
end
|
536
726
|
|
537
|
-
string = File.open(path, 'r:utf-8'
|
727
|
+
string = File.open(path, 'r:utf-8', &:read)
|
538
728
|
# Work around for Rubinius incomplete encoding in 1.9 mode
|
539
|
-
if string.respond_to?(:encoding) && string.encoding.name !=
|
729
|
+
if string.respond_to?(:encoding) && string.encoding.name != 'UTF-8'
|
540
730
|
string.encode!('UTF-8')
|
541
731
|
end
|
542
732
|
|
@@ -544,6 +734,7 @@ module Pod
|
|
544
734
|
end
|
545
735
|
|
546
736
|
# Loads a specification with the given string.
|
737
|
+
# The specification is evaluated in the context of `path`.
|
547
738
|
#
|
548
739
|
# @param [String] spec_contents
|
549
740
|
# A string describing a specification.
|
@@ -554,21 +745,24 @@ module Pod
|
|
554
745
|
# @return [Specification] the specification
|
555
746
|
#
|
556
747
|
def self.from_string(spec_contents, path, subspec_name = nil)
|
557
|
-
path = Pathname.new(path)
|
748
|
+
path = Pathname.new(path).expand_path
|
749
|
+
spec = nil
|
558
750
|
case path.extname
|
559
751
|
when '.podspec'
|
560
|
-
|
561
|
-
|
562
|
-
|
752
|
+
Dir.chdir(path.parent.directory? ? path.parent : Dir.pwd) do
|
753
|
+
spec = ::Pod._eval_podspec(spec_contents, path)
|
754
|
+
unless spec.is_a?(Specification)
|
755
|
+
raise Informative, "Invalid podspec file at path `#{path}`."
|
756
|
+
end
|
563
757
|
end
|
564
758
|
when '.json'
|
565
|
-
spec = Specification.from_json(spec_contents)
|
759
|
+
spec = Specification.from_json(spec_contents, path)
|
566
760
|
else
|
567
|
-
raise Informative, "Unsupported specification format `#{path.extname}`."
|
761
|
+
raise Informative, "Unsupported specification format `#{path.extname}` for spec at `#{path}`."
|
568
762
|
end
|
569
763
|
|
570
764
|
spec.defined_in_file = path
|
571
|
-
spec.subspec_by_name(subspec_name)
|
765
|
+
spec.subspec_by_name(subspec_name, true)
|
572
766
|
end
|
573
767
|
|
574
768
|
# Sets the path of the `podspec` file used to load the specification.
|
@@ -582,10 +776,51 @@ module Pod
|
|
582
776
|
#
|
583
777
|
def defined_in_file=(file)
|
584
778
|
unless root?
|
585
|
-
raise StandardError,
|
779
|
+
raise StandardError, 'Defined in file can be set only for root specs.'
|
586
780
|
end
|
587
781
|
@defined_in_file = file
|
588
782
|
end
|
783
|
+
|
784
|
+
# Sets the name of the `podspec`.
|
785
|
+
#
|
786
|
+
# @param [String] name
|
787
|
+
# the `podspec` name.
|
788
|
+
#
|
789
|
+
# @return [void]
|
790
|
+
#
|
791
|
+
# @visibility private
|
792
|
+
#
|
793
|
+
def name=(name)
|
794
|
+
@hash_value = nil
|
795
|
+
attributes_hash['name'] = name
|
796
|
+
end
|
797
|
+
|
798
|
+
# Sets the version of the `podspec`.
|
799
|
+
#
|
800
|
+
# @param [String] version
|
801
|
+
# the `podspec` version.
|
802
|
+
#
|
803
|
+
# @return [void]
|
804
|
+
#
|
805
|
+
# @visibility private
|
806
|
+
#
|
807
|
+
def version=(version)
|
808
|
+
@hash_value = nil
|
809
|
+
store_attribute(:version, version)
|
810
|
+
@version = nil
|
811
|
+
end
|
812
|
+
|
813
|
+
# @!group Validation
|
814
|
+
|
815
|
+
# Validates the cocoapods_version in the specification against the current version of Core.
|
816
|
+
# It will raise an Informative error if the version is not satisfied.
|
817
|
+
#
|
818
|
+
def validate_cocoapods_version
|
819
|
+
unless cocoapods_version.satisfied_by?(Version.create(CORE_VERSION))
|
820
|
+
raise Informative, "`#{name}` requires CocoaPods version `#{cocoapods_version}`, " \
|
821
|
+
"which is not satisfied by your current version, `#{CORE_VERSION}`."
|
822
|
+
end
|
823
|
+
end
|
589
824
|
end
|
590
825
|
|
591
826
|
#---------------------------------------------------------------------------#
|
@@ -606,11 +841,14 @@ module Pod
|
|
606
841
|
#
|
607
842
|
#
|
608
843
|
def self._eval_podspec(string, path)
|
609
|
-
# rubocop:disable Eval
|
844
|
+
# rubocop:disable Security/Eval
|
610
845
|
eval(string, nil, path.to_s)
|
611
|
-
# rubocop:enable Eval
|
846
|
+
# rubocop:enable Security/Eval
|
847
|
+
|
848
|
+
# rubocop:disable Lint/RescueException
|
612
849
|
rescue Exception => e
|
850
|
+
# rubocop:enable Lint/RescueException
|
613
851
|
message = "Invalid `#{path.basename}` file: #{e.message}"
|
614
|
-
raise DSLError.new(message, path, e
|
852
|
+
raise DSLError.new(message, path, e, string)
|
615
853
|
end
|
616
854
|
end
|