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