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,333 @@
|
|
1
|
+
module Pod::Vendor
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Version class processes string versions into comparable
|
5
|
+
# values. A version string should normally be a series of numbers
|
6
|
+
# separated by periods. Each part (digits separated by periods) is
|
7
|
+
# considered its own number, and these are used for sorting. So for
|
8
|
+
# instance, 3.10 sorts higher than 3.2 because ten is greater than
|
9
|
+
# two.
|
10
|
+
#
|
11
|
+
# If any part contains letters (currently only a-z are supported) then
|
12
|
+
# that version is considered prerelease. Versions with a prerelease
|
13
|
+
# part in the Nth part sort less than versions with N-1
|
14
|
+
# parts. Prerelease parts are sorted alphabetically using the normal
|
15
|
+
# Ruby string sorting rules. If a prerelease part contains both
|
16
|
+
# letters and numbers, it will be broken into multiple parts to
|
17
|
+
# provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is
|
18
|
+
# greater than 1.0.a9).
|
19
|
+
#
|
20
|
+
# Prereleases sort between real releases (newest to oldest):
|
21
|
+
#
|
22
|
+
# 1. 1.0
|
23
|
+
# 2. 1.0.b1
|
24
|
+
# 3. 1.0.a.2
|
25
|
+
# 4. 0.9
|
26
|
+
#
|
27
|
+
# == How Software Changes
|
28
|
+
#
|
29
|
+
# Users expect to be able to specify a version constraint that gives them
|
30
|
+
# some reasonable expectation that new versions of a library will work with
|
31
|
+
# their software if the version constraint is true, and not work with their
|
32
|
+
# software if the version constraint is false. In other words, the perfect
|
33
|
+
# system will accept all compatible versions of the library and reject all
|
34
|
+
# incompatible versions.
|
35
|
+
#
|
36
|
+
# Libraries change in 3 ways (well, more than 3, but stay focused here!).
|
37
|
+
#
|
38
|
+
# 1. The change may be an implementation detail only and have no effect on
|
39
|
+
# the client software.
|
40
|
+
# 2. The change may add new features, but do so in a way that client software
|
41
|
+
# written to an earlier version is still compatible.
|
42
|
+
# 3. The change may change the public interface of the library in such a way
|
43
|
+
# that old software is no longer compatible.
|
44
|
+
#
|
45
|
+
# Some examples are appropriate at this point. Suppose I have a Stack class
|
46
|
+
# that supports a <tt>push</tt> and a <tt>pop</tt> method.
|
47
|
+
#
|
48
|
+
# === Examples of Category 1 changes:
|
49
|
+
#
|
50
|
+
# * Switch from an array based implementation to a linked-list based
|
51
|
+
# implementation.
|
52
|
+
# * Provide an automatic (and transparent) backing store for large stacks.
|
53
|
+
#
|
54
|
+
# === Examples of Category 2 changes might be:
|
55
|
+
#
|
56
|
+
# * Add a <tt>depth</tt> method to return the current depth of the stack.
|
57
|
+
# * Add a <tt>top</tt> method that returns the current top of stack (without
|
58
|
+
# changing the stack).
|
59
|
+
# * Change <tt>push</tt> so that it returns the item pushed (previously it
|
60
|
+
# had no usable return value).
|
61
|
+
#
|
62
|
+
# === Examples of Category 3 changes might be:
|
63
|
+
#
|
64
|
+
# * Changes <tt>pop</tt> so that it no longer returns a value (you must use
|
65
|
+
# <tt>top</tt> to get the top of the stack).
|
66
|
+
# * Rename the methods to <tt>push_item</tt> and <tt>pop_item</tt>.
|
67
|
+
#
|
68
|
+
# == RubyGems Rational Versioning
|
69
|
+
#
|
70
|
+
# * Versions shall be represented by three non-negative integers, separated
|
71
|
+
# by periods (e.g. 3.1.4). The first integers is the "major" version
|
72
|
+
# number, the second integer is the "minor" version number, and the third
|
73
|
+
# integer is the "build" number.
|
74
|
+
#
|
75
|
+
# * A category 1 change (implementation detail) will increment the build
|
76
|
+
# number.
|
77
|
+
#
|
78
|
+
# * A category 2 change (backwards compatible) will increment the minor
|
79
|
+
# version number and reset the build number.
|
80
|
+
#
|
81
|
+
# * A category 3 change (incompatible) will increment the major build number
|
82
|
+
# and reset the minor and build numbers.
|
83
|
+
#
|
84
|
+
# * Any "public" release of a gem should have a different version. Normally
|
85
|
+
# that means incrementing the build number. This means a developer can
|
86
|
+
# generate builds all day long for himself, but as soon as he/she makes a
|
87
|
+
# public release, the version must be updated.
|
88
|
+
#
|
89
|
+
# === Examples
|
90
|
+
#
|
91
|
+
# Let's work through a project lifecycle using our Stack example from above.
|
92
|
+
#
|
93
|
+
# Version 0.0.1:: The initial Stack class is release.
|
94
|
+
# Version 0.0.2:: Switched to a linked=list implementation because it is
|
95
|
+
# cooler.
|
96
|
+
# Version 0.1.0:: Added a <tt>depth</tt> method.
|
97
|
+
# Version 1.0.0:: Added <tt>top</tt> and made <tt>pop</tt> return nil
|
98
|
+
# (<tt>pop</tt> used to return the old top item).
|
99
|
+
# Version 1.1.0:: <tt>push</tt> now returns the value pushed (it used it
|
100
|
+
# return nil).
|
101
|
+
# Version 1.1.1:: Fixed a bug in the linked list implementation.
|
102
|
+
# Version 1.1.2:: Fixed a bug introduced in the last fix.
|
103
|
+
#
|
104
|
+
# Client A needs a stack with basic push/pop capability. He writes to the
|
105
|
+
# original interface (no <tt>top</tt>), so his version constraint looks
|
106
|
+
# like:
|
107
|
+
#
|
108
|
+
# gem 'stack', '~> 0.0'
|
109
|
+
#
|
110
|
+
# Essentially, any version is OK with Client A. An incompatible change to
|
111
|
+
# the library will cause him grief, but he is willing to take the chance (we
|
112
|
+
# call Client A optimistic).
|
113
|
+
#
|
114
|
+
# Client B is just like Client A except for two things: (1) He uses the
|
115
|
+
# <tt>depth</tt> method and (2) he is worried about future
|
116
|
+
# incompatibilities, so he writes his version constraint like this:
|
117
|
+
#
|
118
|
+
# gem 'stack', '~> 0.1'
|
119
|
+
#
|
120
|
+
# The <tt>depth</tt> method was introduced in version 0.1.0, so that version
|
121
|
+
# or anything later is fine, as long as the version stays below version 1.0
|
122
|
+
# where incompatibilities are introduced. We call Client B pessimistic
|
123
|
+
# because he is worried about incompatible future changes (it is OK to be
|
124
|
+
# pessimistic!).
|
125
|
+
#
|
126
|
+
# == Preventing Version Catastrophe:
|
127
|
+
#
|
128
|
+
# From: http://blog.zenspider.com/2008/10/rubygems-howto-preventing-cata.html
|
129
|
+
#
|
130
|
+
# Let's say you're depending on the fnord gem version 2.y.z. If you
|
131
|
+
# specify your dependency as ">= 2.0.0" then, you're good, right? What
|
132
|
+
# happens if fnord 3.0 comes out and it isn't backwards compatible
|
133
|
+
# with 2.y.z? Your stuff will break as a result of using ">=". The
|
134
|
+
# better route is to specify your dependency with a "spermy" version
|
135
|
+
# specifier. They're a tad confusing, so here is how the dependency
|
136
|
+
# specifiers work:
|
137
|
+
#
|
138
|
+
# Specification From ... To (exclusive)
|
139
|
+
# ">= 3.0" 3.0 ... ∞
|
140
|
+
# "~> 3.0" 3.0 ... 4.0
|
141
|
+
# "~> 3.0.0" 3.0.0 ... 3.1
|
142
|
+
# "~> 3.5" 3.5 ... 4.0
|
143
|
+
# "~> 3.5.0" 3.5.0 ... 3.6
|
144
|
+
|
145
|
+
class Gem::Version
|
146
|
+
autoload :Requirement, 'rubygems/requirement'
|
147
|
+
|
148
|
+
include Comparable
|
149
|
+
|
150
|
+
VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
|
151
|
+
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # :nodoc:
|
152
|
+
|
153
|
+
##
|
154
|
+
# A string representation of this Version.
|
155
|
+
|
156
|
+
attr_reader :version
|
157
|
+
alias to_s version
|
158
|
+
|
159
|
+
##
|
160
|
+
# True if the +version+ string matches RubyGems' requirements.
|
161
|
+
|
162
|
+
def self.correct? version
|
163
|
+
version.to_s =~ ANCHORED_VERSION_PATTERN
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Factory method to create a Version object. Input may be a Version
|
168
|
+
# or a String. Intended to simplify client code.
|
169
|
+
#
|
170
|
+
# ver1 = Version.create('1.3.17') # -> (Version object)
|
171
|
+
# ver2 = Version.create(ver1) # -> (ver1)
|
172
|
+
# ver3 = Version.create(nil) # -> nil
|
173
|
+
|
174
|
+
def self.create input
|
175
|
+
if input.respond_to? :version then
|
176
|
+
input
|
177
|
+
elsif input.nil? then
|
178
|
+
nil
|
179
|
+
else
|
180
|
+
new input
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Constructs a Version from the +version+ string. A version string is a
|
186
|
+
# series of digits or ASCII letters separated by dots.
|
187
|
+
|
188
|
+
def initialize version
|
189
|
+
raise ArgumentError, "Malformed version number string #{version}" unless
|
190
|
+
self.class.correct?(version)
|
191
|
+
|
192
|
+
@version = version.to_s
|
193
|
+
@version.strip!
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# Return a new version object where the next to the last revision
|
198
|
+
# number is one greater (e.g., 5.3.1 => 5.4).
|
199
|
+
#
|
200
|
+
# Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.
|
201
|
+
|
202
|
+
def bump
|
203
|
+
segments = self.segments.dup
|
204
|
+
segments.pop while segments.any? { |s| String === s }
|
205
|
+
segments.pop if segments.size > 1
|
206
|
+
|
207
|
+
segments[-1] = segments[-1].succ
|
208
|
+
self.class.new segments.join(".")
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
212
|
+
# A Version is only eql? to another version if it's specified to the
|
213
|
+
# same precision. Version "1.0" is not the same as version "1".
|
214
|
+
|
215
|
+
def eql? other
|
216
|
+
self.class === other and @version == other.version
|
217
|
+
end
|
218
|
+
|
219
|
+
def hash # :nodoc:
|
220
|
+
@hash ||= segments.hash
|
221
|
+
end
|
222
|
+
|
223
|
+
def init_with coder # :nodoc:
|
224
|
+
yaml_initialize coder.tag, coder.map
|
225
|
+
end
|
226
|
+
|
227
|
+
def inspect # :nodoc:
|
228
|
+
"#<#{self.class} #{version.inspect}>"
|
229
|
+
end
|
230
|
+
|
231
|
+
##
|
232
|
+
# Dump only the raw version string, not the complete object. It's a
|
233
|
+
# string for backwards (RubyGems 1.3.5 and earlier) compatibility.
|
234
|
+
|
235
|
+
def marshal_dump
|
236
|
+
[version]
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# Load custom marshal format. It's a string for backwards (RubyGems
|
241
|
+
# 1.3.5 and earlier) compatibility.
|
242
|
+
|
243
|
+
def marshal_load array
|
244
|
+
initialize array[0]
|
245
|
+
end
|
246
|
+
|
247
|
+
def yaml_initialize(tag, map)
|
248
|
+
@version = map['version']
|
249
|
+
@segments = nil
|
250
|
+
@hash = nil
|
251
|
+
end
|
252
|
+
|
253
|
+
##
|
254
|
+
# A version is considered a prerelease if it contains a letter.
|
255
|
+
|
256
|
+
def prerelease?
|
257
|
+
@prerelease ||= @version =~ /[a-zA-Z]/
|
258
|
+
end
|
259
|
+
|
260
|
+
def pretty_print q # :nodoc:
|
261
|
+
q.text "Gem::Version.new(#{version.inspect})"
|
262
|
+
end
|
263
|
+
|
264
|
+
##
|
265
|
+
# The release for this version (e.g. 1.2.0.a -> 1.2.0).
|
266
|
+
# Non-prerelease versions return themselves.
|
267
|
+
|
268
|
+
def release
|
269
|
+
return self unless prerelease?
|
270
|
+
|
271
|
+
segments = self.segments.dup
|
272
|
+
segments.pop while segments.any? { |s| String === s }
|
273
|
+
self.class.new segments.join('.')
|
274
|
+
end
|
275
|
+
|
276
|
+
def segments # :nodoc:
|
277
|
+
|
278
|
+
# segments is lazy so it can pick up version values that come from
|
279
|
+
# old marshaled versions, which don't go through marshal_load.
|
280
|
+
|
281
|
+
@segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
|
282
|
+
/^\d+$/ =~ s ? s.to_i : s
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
##
|
287
|
+
# A recommended version for use with a ~> Requirement.
|
288
|
+
|
289
|
+
def spermy_recommendation
|
290
|
+
segments = self.segments.dup
|
291
|
+
|
292
|
+
segments.pop while segments.any? { |s| String === s }
|
293
|
+
segments.pop while segments.size > 2
|
294
|
+
segments.push 0 while segments.size < 2
|
295
|
+
|
296
|
+
"~> #{segments.join(".")}"
|
297
|
+
end
|
298
|
+
|
299
|
+
##
|
300
|
+
# Compares this version with +other+ returning -1, 0, or 1 if the
|
301
|
+
# other version is larger, the same, or smaller than this
|
302
|
+
# one. Attempts to compare to something that's not a
|
303
|
+
# <tt>Gem::Version</tt> return +nil+.
|
304
|
+
|
305
|
+
def <=> other
|
306
|
+
return unless Gem::Version === other
|
307
|
+
return 0 if @version == other.version
|
308
|
+
|
309
|
+
lhsegments = segments
|
310
|
+
rhsegments = other.segments
|
311
|
+
|
312
|
+
lhsize = lhsegments.size
|
313
|
+
rhsize = rhsegments.size
|
314
|
+
limit = (lhsize > rhsize ? lhsize : rhsize) - 1
|
315
|
+
|
316
|
+
i = 0
|
317
|
+
|
318
|
+
while i <= limit
|
319
|
+
lhs, rhs = lhsegments[i] || 0, rhsegments[i] || 0
|
320
|
+
i += 1
|
321
|
+
|
322
|
+
next if lhs == rhs
|
323
|
+
return -1 if String === lhs && Numeric === rhs
|
324
|
+
return 1 if Numeric === lhs && String === rhs
|
325
|
+
|
326
|
+
return lhs <=> rhs
|
327
|
+
end
|
328
|
+
|
329
|
+
return 0
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# Namespaces the vendored modules.
|
4
|
+
#
|
5
|
+
module Vendor
|
6
|
+
|
7
|
+
# Namespaces the classes of RubyGems used by CocoaPods.
|
8
|
+
#
|
9
|
+
# CocoaPods needs to vendor RubyGems because OS X ships with `v1.3.6` which
|
10
|
+
# has a couple of bugs related to the comparison of pre-release versions.
|
11
|
+
#
|
12
|
+
# E.g. https://github.com/CocoaPods/CocoaPods/issues/398
|
13
|
+
#
|
14
|
+
# The following classes are copied from RubyGems `v1.8.24`. The changes
|
15
|
+
# performed to the source files are the following:
|
16
|
+
#
|
17
|
+
# - Namespaced in `Pod::Vendor`
|
18
|
+
# - commented all the `require` calls
|
19
|
+
# - replaced `::Gem` with `Pod::Vendor::Gem`
|
20
|
+
#
|
21
|
+
module Gem
|
22
|
+
|
23
|
+
require 'cocoapods-core/vendor/version'
|
24
|
+
require 'cocoapods-core/vendor/requirement'
|
25
|
+
require 'cocoapods-core/vendor/dependency'
|
26
|
+
|
27
|
+
#-----------------------------------------------------------------------#
|
28
|
+
# RubyGems License #
|
29
|
+
# https://github.com/rubygems/rubygems/blob/master/MIT.txt
|
30
|
+
#-----------------------------------------------------------------------#
|
31
|
+
|
32
|
+
# Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
33
|
+
#
|
34
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
35
|
+
# a copy of this software and associated documentation files (the
|
36
|
+
# 'Software'), to deal in the Software without restriction, including
|
37
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
38
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
39
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
40
|
+
# the following conditions:
|
41
|
+
#
|
42
|
+
# The above copyright notice and this permission notice shall be
|
43
|
+
# included in all copies or substantial portions of the Software.
|
44
|
+
#
|
45
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
46
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
47
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
48
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
49
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
50
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
51
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# The Version class stores information about the version of a
|
4
|
+
# {Specification}.
|
5
|
+
#
|
6
|
+
# It is based on the RubyGems class adapted to support head information.
|
7
|
+
#
|
8
|
+
# ### From RubyGems:
|
9
|
+
#
|
10
|
+
# The Version class processes string versions into comparable
|
11
|
+
# values. A version string should normally be a series of numbers
|
12
|
+
# separated by periods. Each part (digits separated by periods) is
|
13
|
+
# considered its own number, and these are used for sorting. So for
|
14
|
+
# instance, 3.10 sorts higher than 3.2 because ten is greater than
|
15
|
+
# two.
|
16
|
+
#
|
17
|
+
# If any part contains letters (currently only a-z are supported) then
|
18
|
+
# that version is considered prerelease. Versions with a prerelease
|
19
|
+
# part in the Nth part sort less than versions with N-1
|
20
|
+
# parts. Prerelease parts are sorted alphabetically using the normal
|
21
|
+
# Ruby string sorting rules. If a prerelease part contains both
|
22
|
+
# letters and numbers, it will be broken into multiple parts to
|
23
|
+
# provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is
|
24
|
+
# greater than 1.0.a9).
|
25
|
+
#
|
26
|
+
# Prereleases sort between real releases (newest to oldest):
|
27
|
+
#
|
28
|
+
# 1. 1.0
|
29
|
+
# 2. 1.0.b1
|
30
|
+
# 3. 1.0.a.2
|
31
|
+
# 4. 0.9
|
32
|
+
#
|
33
|
+
class Version < Pod::Vendor::Gem::Version
|
34
|
+
|
35
|
+
# Override the constants defined by the superclass to add Semantic
|
36
|
+
# Versioning prerelease support (with a dash). E.g.: 1.0.0-alpha1
|
37
|
+
#
|
38
|
+
# For more info, see: http://semver.org
|
39
|
+
#
|
40
|
+
VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z\-]+)*'
|
41
|
+
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/
|
42
|
+
|
43
|
+
# @return [Bool] whether the version represents the `head` of repository.
|
44
|
+
#
|
45
|
+
attr_accessor :head
|
46
|
+
alias_method :head?, :head
|
47
|
+
|
48
|
+
# @param [String,Version] version
|
49
|
+
# A string representing a version, or another version.
|
50
|
+
#
|
51
|
+
# @todo The `from` part of the regular expression should be remove in
|
52
|
+
# CocoaPods 1.0.0.
|
53
|
+
#
|
54
|
+
def initialize(version)
|
55
|
+
if version.is_a?(Version) && version.head?
|
56
|
+
version = version.version
|
57
|
+
@head = true
|
58
|
+
elsif version.is_a?(String) && version =~ /HEAD (based on|from) (.*)/
|
59
|
+
version = $2
|
60
|
+
@head = true
|
61
|
+
end
|
62
|
+
super(version)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [String] a string representation that indicates if the version is
|
66
|
+
# head.
|
67
|
+
#
|
68
|
+
# @note The raw version string is still accessible with the {#version}
|
69
|
+
# method.
|
70
|
+
#
|
71
|
+
def to_s
|
72
|
+
head? ? "HEAD based on #{super}" : super
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [String] a string representation suitable for debugging.
|
76
|
+
#
|
77
|
+
def inspect
|
78
|
+
"<#{self.class} version=#{self.version}>"
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Boolean] indicates whether or not the version is a prerelease.
|
82
|
+
#
|
83
|
+
# @note Prerelease Pods can contain a hyphen and/or a letter (conforms to
|
84
|
+
# Semantic Versioning instead of RubyGems).
|
85
|
+
#
|
86
|
+
# For more info, see: http://semver.org
|
87
|
+
#
|
88
|
+
def prerelease?
|
89
|
+
@prerelease ||= @version =~ /[a-zA-Z\-]/
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [Bool] Whether a string representation is correct.
|
93
|
+
#
|
94
|
+
def self.correct? version
|
95
|
+
version.to_s =~ ANCHORED_VERSION_PATTERN
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
@@ -0,0 +1,202 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# Converts objects to their YAML representation.
|
4
|
+
#
|
5
|
+
# This class was created for the need having control on how the YAML is
|
6
|
+
# representation is generated. In details it provides:
|
7
|
+
#
|
8
|
+
# - sorting for hashes in ruby 1.8.x
|
9
|
+
# - ability to hint the sorting of the keys of a dictionary when converting
|
10
|
+
# it. In this case the keys are also separated by an additional new line
|
11
|
+
# feed for readability.
|
12
|
+
#
|
13
|
+
# @note This class misses important features necessary for a correct YAML
|
14
|
+
# serialization and thus it is safe to use only for the Lockfile.
|
15
|
+
# The missing features include:
|
16
|
+
# - Strings are never quoted even when ambiguous.
|
17
|
+
#
|
18
|
+
class YAMLConverter
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
# Returns the YAML representation of the given object. If the given object
|
23
|
+
# is an Hash it accepts an optional hint for sorting the keys.
|
24
|
+
#
|
25
|
+
# @param [String, Symbol, Array, Hash] object
|
26
|
+
# the object to convert
|
27
|
+
#
|
28
|
+
# @param [Array] hash_keys_hint
|
29
|
+
# an array to use as a hint for sorting the keys of the object to
|
30
|
+
# convert if it is an hash.
|
31
|
+
#
|
32
|
+
# @return [String] the YAML representation of the given object.
|
33
|
+
#
|
34
|
+
def convert(value)
|
35
|
+
result = process_according_to_class(value)
|
36
|
+
result << "\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_hash(value, hash_keys_hint, line_separator = "\n")
|
40
|
+
result = process_hash(value, hash_keys_hint, line_separator)
|
41
|
+
result << "\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
#-----------------------------------------------------------------------#
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Implementation notes:
|
49
|
+
#
|
50
|
+
# - each of the methods returns a YAML partial without an ending new
|
51
|
+
# line.
|
52
|
+
# - if a partial needs to be indented is responsibility of the method
|
53
|
+
# using it.
|
54
|
+
#
|
55
|
+
# ---
|
56
|
+
|
57
|
+
# @!group Private Helpers
|
58
|
+
|
59
|
+
# @return [String] the YAML representation of the given object.
|
60
|
+
#
|
61
|
+
def process_according_to_class(value, hash_keys_hint = nil)
|
62
|
+
case value
|
63
|
+
when String then value
|
64
|
+
when Symbol then ":#{value}"
|
65
|
+
when TrueClass then 'true'
|
66
|
+
when FalseClass then 'false'
|
67
|
+
when Array then process_array(value)
|
68
|
+
when Hash then process_hash(value, hash_keys_hint)
|
69
|
+
else
|
70
|
+
raise "Unsupported class for YAML conversion #{value.class}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Converts a string to YAML.
|
75
|
+
#
|
76
|
+
# @param [String] string
|
77
|
+
# the string to convert.
|
78
|
+
#
|
79
|
+
# @return [String] the YAML representation of the given object.
|
80
|
+
#
|
81
|
+
def process_string(string)
|
82
|
+
string
|
83
|
+
end
|
84
|
+
|
85
|
+
# Converts an array to YAML after sorting it.
|
86
|
+
#
|
87
|
+
# @param [Array] array
|
88
|
+
# the array to convert.
|
89
|
+
#
|
90
|
+
# @return [String] the YAML representation of the given object.
|
91
|
+
#
|
92
|
+
def process_array(array)
|
93
|
+
result = []
|
94
|
+
sorted_array(array).each do |array_value|
|
95
|
+
result << process_according_to_class(array_value)
|
96
|
+
end
|
97
|
+
"- #{result*"\n- "}"
|
98
|
+
end
|
99
|
+
|
100
|
+
# Converts a hash to YAML after sorting its keys. Optionally accepts a
|
101
|
+
# hint for sorting the keys.
|
102
|
+
#
|
103
|
+
# @note If a hint for sorting the keys is provided the array is assumed
|
104
|
+
# to be the root object and the keys are separated by an
|
105
|
+
# additional new line feed for readability.
|
106
|
+
#
|
107
|
+
# @note If the value of a given key is a String it displayed inline,
|
108
|
+
# otherwise it is displayed below and indented.
|
109
|
+
#
|
110
|
+
# @param [Hash] hash
|
111
|
+
# the hash to convert.
|
112
|
+
#
|
113
|
+
# @return [String] the YAML representation of the given object.
|
114
|
+
#
|
115
|
+
def process_hash(hash, hash_keys_hint = nil, line_separator = "\n")
|
116
|
+
keys = sorted_array_with_hint(hash.keys, hash_keys_hint)
|
117
|
+
key_lines = []
|
118
|
+
keys.each do |key|
|
119
|
+
key_value = hash[key]
|
120
|
+
processed = process_according_to_class(key_value)
|
121
|
+
processed_key = process_according_to_class(key)
|
122
|
+
case key_value
|
123
|
+
when Array, Hash
|
124
|
+
key_partial_yaml = processed.lines.map { |line| " #{line}" } * ""
|
125
|
+
key_lines << "#{processed_key}:\n#{key_partial_yaml}"
|
126
|
+
else
|
127
|
+
key_lines << "#{processed_key}: #{processed}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
key_lines * line_separator
|
131
|
+
end
|
132
|
+
|
133
|
+
#-----------------------------------------------------------------------#
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
# @!group Array Sorting
|
138
|
+
|
139
|
+
# Sorts an array using another one as a sort hint. All the values of the
|
140
|
+
# hint which appear in the array will be returned respecting the order in
|
141
|
+
# the hint. If any other key is present in the original array they are
|
142
|
+
# sorted using the {#sorted_array} method.
|
143
|
+
#
|
144
|
+
# @param [Array] array
|
145
|
+
# The array which needs to be sorted.
|
146
|
+
#
|
147
|
+
# @param [Array] sort_hint
|
148
|
+
# The array which should be used to sort the keys.
|
149
|
+
#
|
150
|
+
# @return [Array] The sorted Array.
|
151
|
+
#
|
152
|
+
def sorted_array_with_hint(array, sort_hint)
|
153
|
+
if sort_hint
|
154
|
+
hinted = sort_hint & array
|
155
|
+
remaining = array - sort_hint
|
156
|
+
hinted + sorted_array(remaining)
|
157
|
+
else
|
158
|
+
sorted_array(array)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Sorts an array according to the string representation of it values.
|
163
|
+
# This method allows to sort arrays which contains strings or hashes.
|
164
|
+
#
|
165
|
+
# @note If the value contained in the array is another Array or a Hash
|
166
|
+
# the first value of the collection is used for sorting, as this
|
167
|
+
# method is more useful, for arrays which contains a collection
|
168
|
+
# composed by one object.
|
169
|
+
#
|
170
|
+
# @todo This stuff is here only because the Lockfile intermixes strings
|
171
|
+
# and hashes for the `PODS` key. The Lockfile should be more
|
172
|
+
# consistent.
|
173
|
+
#
|
174
|
+
# @return [Array] The sorted array.
|
175
|
+
#
|
176
|
+
def sorted_array(array)
|
177
|
+
array.sort do |x, y|
|
178
|
+
x_string = sorting_string(x)
|
179
|
+
y_string = sorting_string(y)
|
180
|
+
x_string <=> y_string
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns the string representation of a value useful for sorting.
|
185
|
+
#
|
186
|
+
# @param [String, Symbol, Array, Hash] value
|
187
|
+
# The value which needs to be sorted
|
188
|
+
#
|
189
|
+
# @return [String] A string useful to compare the value with other ones.
|
190
|
+
#
|
191
|
+
def sorting_string(value)
|
192
|
+
return "" unless value
|
193
|
+
case value
|
194
|
+
when String then value.downcase
|
195
|
+
when Symbol then sorting_string(value.to_s)
|
196
|
+
when Array then sorting_string(value.first)
|
197
|
+
when Hash then sorting_string(value.keys.sort.first)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|