semantic_version 0.1
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 +41 -0
- data/lib/semantic_version.rb +177 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7f66dedf8397b08654d2916450edd305292885da
|
4
|
+
data.tar.gz: 533285d4dc57aac800fcbd44192c449e3ba300bb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc6fb8ebca00aaf4e9668d9d2f31278a946e41ebe86d82261a1578977514931b2f6994e9084b94a36a36f19de0d05c14eef7fe09126b017f450dd31c5b885736
|
7
|
+
data.tar.gz: 9b6c19356538f190ff03ede3466aa311c039af9d52a03c07d0ee641cd98db03cd4f46ffe19a2deff091f06a9ab16627a6b8718db6ebe4c381779bd4710051223
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 Jared Wyatt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
semantic_version
|
2
|
+
================
|
3
|
+
|
4
|
+
A utility for comparing semantic version numbers (see: http://semver.org).
|
5
|
+
|
6
|
+
### Usage
|
7
|
+
|
8
|
+
Initialize a new SemanticVersion object with `SemanticVersion.new()` or `SemanticVersion[]`.
|
9
|
+
|
10
|
+
SemanticVersion objects have an `is` method for comparing against strings or other SemanticVersion objects.
|
11
|
+
|
12
|
+
__Available operators for use with the `is` method:__
|
13
|
+
|
14
|
+
* `eq` or `equal_to` returns true if versions are equivalent; false otherwise
|
15
|
+
* `lt` or `less_than` returns true if SemanticVersion is less than comparison version; false otherwise
|
16
|
+
* `lte` or `less_than_or_equal_to` returns true if SemanticVersion is less than or equal to comparison version; false otherwise
|
17
|
+
* `gt` or `greater_than` returns true if SemanticVersion is greater than comparison version; false otherwise
|
18
|
+
* `gte` or `greater_than_or_equal_to` returns true if SemanticVersion is greater than or equal to comparison version; false otherwise
|
19
|
+
* `between` returns true if SemanticVersion falls between two comparison versions; false otherwise
|
20
|
+
* `within` returns true if SemanticVersion falls within the range of two comparison versions (inclusive); false otherwise
|
21
|
+
* `any_of` returns true if SemanticVersion is equivalent to any of the versions in a list; false otherwise
|
22
|
+
|
23
|
+
__Examples:__
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
version_a = SemanticVersion.new("1.0")
|
27
|
+
version_b = SemanticVersion.new("2.0")
|
28
|
+
version_a.is less_than: version_b #=> true
|
29
|
+
|
30
|
+
SemanticVersion["2.5.0"].is eq: "2.5" #=> true
|
31
|
+
|
32
|
+
SemanticVersion["2.5.0"].is gt: "2.5.0-beta" #=> true
|
33
|
+
|
34
|
+
SemanticVersion["3.2.0-beta"].is gt: "3.2.0-alpha", lt: "3.2.0-rc" #=> true
|
35
|
+
|
36
|
+
SemanticVersion["5.6.2"].is between: ["5.6.0", "5.6.4"] #=> true
|
37
|
+
|
38
|
+
SemanticVersion["2.2.48"].is any_of: ["2.2.2", "2.2.48", "3.8.0"] #=> true
|
39
|
+
|
40
|
+
SemanticVersion["1.0.0-rc+1234"].is eq: "1.0.0-rc+6789" #=> true
|
41
|
+
```
|
@@ -0,0 +1,177 @@
|
|
1
|
+
class SemanticVersion
|
2
|
+
|
3
|
+
SINGLE_OPERATORS = {
|
4
|
+
eq: [0],
|
5
|
+
lt: [-1],
|
6
|
+
lte: [-1, 0],
|
7
|
+
gt: [1],
|
8
|
+
gte: [1, 0],
|
9
|
+
equal_to: [0],
|
10
|
+
less_than: [-1],
|
11
|
+
less_than_or_equal_to: [-1, 0],
|
12
|
+
greater_than: [1],
|
13
|
+
greater_than_or_equal_to: [1, 0]
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
RANGE_OPERATORS = {
|
17
|
+
between: [],
|
18
|
+
within: [],
|
19
|
+
any_of: []
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
OPERATORS = SINGLE_OPERATORS.merge(RANGE_OPERATORS).freeze
|
23
|
+
|
24
|
+
|
25
|
+
attr_reader :number_components, :prerelease_components, :build_metadata
|
26
|
+
|
27
|
+
|
28
|
+
# Instantiates a new SemanticVersion.
|
29
|
+
#
|
30
|
+
# @param [String] version: A semantic version (see http://semver.org).
|
31
|
+
#
|
32
|
+
def self.[](version)
|
33
|
+
self.new(version)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Parses the given value into version components.
|
38
|
+
#
|
39
|
+
# @param [String or SemanticVersion] version: A semantic version (see http://semver.org).
|
40
|
+
#
|
41
|
+
# @return An array [version_number, prerelease, build_metadata], where `version_number` is an array of the
|
42
|
+
# number components [MAJOR, MINOR, PATCH], `prerelease` is an array of the prerelease components,
|
43
|
+
# and `build_metadata` is, like, you know, the build metadata.
|
44
|
+
#
|
45
|
+
def self.parse_components(version)
|
46
|
+
return version.components if version.is_a? SemanticVersion
|
47
|
+
|
48
|
+
version_number, extensions = version.to_s.split('-', 2)
|
49
|
+
prerelease, build_metadata = extensions.to_s.split('+', 2)
|
50
|
+
|
51
|
+
version_number = version_number.to_s.split('.').map(&:to_i)
|
52
|
+
prerelease = prerelease.to_s.split('.').map {|c| c == c.to_i.to_s ? c.to_i : c }
|
53
|
+
|
54
|
+
return [version_number, prerelease, build_metadata]
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Instantiates a new SemanticVersion.
|
59
|
+
#
|
60
|
+
# @param [String] version: A semantic version (see http://semver.org).
|
61
|
+
#
|
62
|
+
def initialize(version)
|
63
|
+
@number_components, @prerelease_components, @build_metadata = self.class.parse_components(version)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Compares this SemanticVersion with one or more other version numbers.
|
68
|
+
#
|
69
|
+
# @param [Hash] assertions: A hash where keys are OPERATORS and values are operands in the form of semantic versions.
|
70
|
+
#
|
71
|
+
# @return True if all assertions are true, false otherwise.
|
72
|
+
#
|
73
|
+
def is(comparison)
|
74
|
+
comparison.each_pair do |operator, version|
|
75
|
+
unless OPERATORS.keys.include? operator
|
76
|
+
raise ArgumentError.new("unrecognized operator `#{operator}'")
|
77
|
+
end
|
78
|
+
|
79
|
+
if RANGE_OPERATORS.keys.include? operator
|
80
|
+
unless version.is_a?(Array) && version.length >= 2
|
81
|
+
raise ArgumentError.new("range operand must be an array containing at least two elements")
|
82
|
+
end
|
83
|
+
|
84
|
+
result = if operator == :between
|
85
|
+
is gt: version[0], lt: version[1]
|
86
|
+
elsif operator == :within
|
87
|
+
is gte: version[0], lte: version[1]
|
88
|
+
elsif operator == :any_of
|
89
|
+
version.map {|v| is eq: v }.any?
|
90
|
+
else
|
91
|
+
false
|
92
|
+
end
|
93
|
+
|
94
|
+
return false unless result == true
|
95
|
+
|
96
|
+
else
|
97
|
+
number_components, prerelease_components, _ = self.class.parse_components(version)
|
98
|
+
|
99
|
+
result = 0
|
100
|
+
|
101
|
+
# Compare version number components.
|
102
|
+
|
103
|
+
(0..[@number_components.count, number_components.count].max-1).each do |i|
|
104
|
+
a = @number_components[i]
|
105
|
+
b = number_components[i]
|
106
|
+
|
107
|
+
result = if !a.nil? && b.nil?
|
108
|
+
a == 0 ? 0 : 1
|
109
|
+
elsif a.nil? && !b.nil?
|
110
|
+
b == 0 ? 0 : -1
|
111
|
+
else
|
112
|
+
a <=> b
|
113
|
+
end
|
114
|
+
|
115
|
+
break unless result == 0
|
116
|
+
end
|
117
|
+
|
118
|
+
if result == 0
|
119
|
+
if @prerelease_components.empty? && !prerelease_components.empty?
|
120
|
+
result = 1
|
121
|
+
elsif !@prerelease_components.empty? && prerelease_components.empty?
|
122
|
+
result = -1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Compare pre-release components.
|
127
|
+
|
128
|
+
if result == 0
|
129
|
+
(0..[@prerelease_components.count, prerelease_components.count].max-1).each do |i|
|
130
|
+
break unless result == 0
|
131
|
+
|
132
|
+
a = @prerelease_components[i]
|
133
|
+
b = prerelease_components[i]
|
134
|
+
|
135
|
+
result = if !a.nil? && b.nil?
|
136
|
+
1
|
137
|
+
elsif a.nil? && !b.nil?
|
138
|
+
-1
|
139
|
+
elsif a.class == b.class
|
140
|
+
a <=> b
|
141
|
+
else
|
142
|
+
a.to_s <=> b.to_s
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
return false unless OPERATORS[operator].include? result
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
return true
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# Returns the string representation of the "MAJOR.MINOR.PATCH" version part.
|
156
|
+
#
|
157
|
+
def number
|
158
|
+
@number_components.join('.')
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
# Returns the string representation of the pre-release version part.
|
163
|
+
#
|
164
|
+
def prerelease
|
165
|
+
@prerelease_components.join('.')
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# Returns the string representation of the version.
|
170
|
+
#
|
171
|
+
def to_s
|
172
|
+
number +
|
173
|
+
(@prerelease_components.empty? ? "" : "-#{prerelease}") +
|
174
|
+
(@build_metadata.nil? ? "" : "+#{@build_metadata}")
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: semantic_version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jared Wyatt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: j@wyatt.co
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- LICENSE
|
20
|
+
- README.md
|
21
|
+
- lib/semantic_version.rb
|
22
|
+
homepage: http://github.com/wyattisimo/semantic_version
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.4.6
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: 'A utility for comparing semantic version numbers (see: http://semver.org).'
|
46
|
+
test_files: []
|