semantic 1.0.0
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.
- data/LICENSE +20 -0
- data/README.md +43 -0
- data/lib/semantic.rb +5 -0
- data/lib/semantic/core_ext.rb +5 -0
- data/lib/semantic/version.rb +85 -0
- data/spec/core_ext_spec.rb +43 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/version_spec.rb +127 -0
- metadata +91 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Josh Lindsey
|
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,43 @@
|
|
1
|
+
Semantic
|
2
|
+
========
|
3
|
+
|
4
|
+
A small Ruby utility class to aid in the storage, parsing, and comparison of SemVer-style Version strings.
|
5
|
+
|
6
|
+
See [the SemVer site](http://semver.org) for more details.
|
7
|
+
|
8
|
+
Usage
|
9
|
+
-----
|
10
|
+
|
11
|
+
This library exposes a single class – `Semantic::Version`. Simply pass in a valid SemVer string to
|
12
|
+
the initializer.
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'semantic'
|
16
|
+
|
17
|
+
version = Semantic::Version.new '1.6.5'
|
18
|
+
version.major # => 1
|
19
|
+
version.minor # => 6
|
20
|
+
version.patch # => 5
|
21
|
+
|
22
|
+
newer_version = Semantic::Version.new '1.7.0'
|
23
|
+
version > newer_version # => false
|
24
|
+
newer_version <=> version # => 1
|
25
|
+
|
26
|
+
complex_version = Semantic::Version.new '3.7.9-pre.1+revision.15723'
|
27
|
+
complex_version.pre # => "pre.1"
|
28
|
+
complex_version.build # => "revision.15623"
|
29
|
+
```
|
30
|
+
|
31
|
+
There is also a set of core extensions as an optional require:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'semantic'
|
35
|
+
require 'semantic/core_ext'
|
36
|
+
|
37
|
+
"1.8.7-pre.123".to_version
|
38
|
+
```
|
39
|
+
|
40
|
+
License
|
41
|
+
-------
|
42
|
+
Copyright (c) 2012 Josh Lindsey. See LICENSE for details.
|
43
|
+
|
data/lib/semantic.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# See: http://semver.org
|
2
|
+
class Semantic::Version
|
3
|
+
SemVerRegexp = /^(\d+\.\d+\.\d+)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$/
|
4
|
+
attr_accessor :major, :minor, :patch, :pre, :build
|
5
|
+
|
6
|
+
def initialize version_str
|
7
|
+
raise ArgumentError.new("Not a valid SemVer Version (http://semver.org)") unless version_str =~ SemVerRegexp
|
8
|
+
|
9
|
+
version, parts = version_str.split '-'
|
10
|
+
if not parts.nil? and parts.include? '+'
|
11
|
+
@pre, @build = parts.split '+'
|
12
|
+
elsif version.include? '+'
|
13
|
+
version, @build = version.split '+'
|
14
|
+
else
|
15
|
+
@pre = parts
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
@major, @minor, @patch = version.split('.').map &:to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_a
|
23
|
+
[@major, @minor, @patch, @pre, @build]
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
str = [@major, @minor, @patch].join '.'
|
28
|
+
str << '-' << @pre unless @pre.nil?
|
29
|
+
str << '+' << @build unless @build.nil?
|
30
|
+
|
31
|
+
str
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_h
|
35
|
+
keys = [:major, :minor, :patch, :pre, :build]
|
36
|
+
Hash[keys.zip(self.to_a)]
|
37
|
+
end
|
38
|
+
|
39
|
+
alias to_hash to_h
|
40
|
+
alias to_array to_a
|
41
|
+
alias to_string to_s
|
42
|
+
|
43
|
+
def <=> other_version
|
44
|
+
other_version = Version.new(other_version) if other_version.is_a? String
|
45
|
+
compare_recursively self.to_a.dup, other_version.to_a.dup
|
46
|
+
end
|
47
|
+
|
48
|
+
def > other_version
|
49
|
+
if (self <=> other_version) == 1 then true else false end
|
50
|
+
end
|
51
|
+
|
52
|
+
def < other_version
|
53
|
+
if (self <=> other_version) == -1 then true else false end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def compare_recursively ary1, ary2
|
59
|
+
# Short-circuit the recursion entirely if they're just equal
|
60
|
+
return 0 if ary1 == ary2
|
61
|
+
|
62
|
+
a = ary1.shift; b = ary2.shift
|
63
|
+
|
64
|
+
# Reached the end of the arrays, equal all the way down
|
65
|
+
return 0 if a.nil? and b.nil?
|
66
|
+
|
67
|
+
# Mismatched types (ie. one has a build and the other doesn't)
|
68
|
+
if a.nil? and not b.nil?
|
69
|
+
return -1
|
70
|
+
elsif not a.nil? and b.nil?
|
71
|
+
return 1
|
72
|
+
end
|
73
|
+
|
74
|
+
# Less or greater than
|
75
|
+
if a > b
|
76
|
+
return 1
|
77
|
+
elsif a < b
|
78
|
+
return -1
|
79
|
+
end
|
80
|
+
|
81
|
+
# Recurse down to the next part if equal
|
82
|
+
compare_recursively ary1, ary2
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'semantic/core_ext'
|
3
|
+
|
4
|
+
describe 'Core Extensions' do
|
5
|
+
context "String#to_version" do
|
6
|
+
before(:each) do
|
7
|
+
@test_versions = [
|
8
|
+
'1.0.0',
|
9
|
+
'12.45.182',
|
10
|
+
'0.0.1-pre.1',
|
11
|
+
'1.0.1-pre.5+build.123.5',
|
12
|
+
'1.1.1+123',
|
13
|
+
'0.0.0+hello',
|
14
|
+
'1.2.3-1'
|
15
|
+
]
|
16
|
+
|
17
|
+
@bad_versions = [
|
18
|
+
'a.b.c',
|
19
|
+
'1.a.3',
|
20
|
+
'a.3.4',
|
21
|
+
'5.2.a',
|
22
|
+
'pre3-1.5.3'
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "extends String with a #to_version method" do
|
27
|
+
String.new.should respond_to(:to_version)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "converts the String into a Version object" do
|
31
|
+
@test_versions.each do |v|
|
32
|
+
expect { v.to_version }.to_not raise_error(ArgumentError)
|
33
|
+
v.to_version.should be_a(Semantic::Version)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises an error on invalid strings" do
|
38
|
+
@bad_versions.each do |v|
|
39
|
+
expect { v.to_version }.to raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
require 'semantic'
|
9
|
+
|
10
|
+
config.mock_framework = :rspec
|
11
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
config.filter_run :focus
|
14
|
+
|
15
|
+
# Run specs in random order to surface order dependencies. If you find an
|
16
|
+
# order dependency and want to debug it, you can fix the order by providing
|
17
|
+
# the seed, which is printed after each run.
|
18
|
+
# --seed 1234
|
19
|
+
config.order = 'random'
|
20
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Semantic::Version do
|
4
|
+
before(:each) do
|
5
|
+
@test_versions = [
|
6
|
+
'1.0.0',
|
7
|
+
'12.45.182',
|
8
|
+
'0.0.1-pre.1',
|
9
|
+
'1.0.1-pre.5+build.123.5',
|
10
|
+
'1.1.1+123',
|
11
|
+
'0.0.0+hello',
|
12
|
+
'1.2.3-1'
|
13
|
+
]
|
14
|
+
|
15
|
+
@bad_versions = [
|
16
|
+
'a.b.c',
|
17
|
+
'1.a.3',
|
18
|
+
'a.3.4',
|
19
|
+
'5.2.a',
|
20
|
+
'pre3-1.5.3'
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
context "parsing" do
|
25
|
+
it "parses valid SemVer versions" do
|
26
|
+
@test_versions.each do |v|
|
27
|
+
expect { Semantic::Version.new v }.to_not raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "raises an error on invalid versions" do
|
32
|
+
@bad_versions.each do |v|
|
33
|
+
expect { Semantic::Version.new v }.to raise_error(ArgumentError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "stores parsed versions in member variables" do
|
38
|
+
v1 = Semantic::Version.new '1.5.9'
|
39
|
+
v1.major.should == 1
|
40
|
+
v1.minor.should == 5
|
41
|
+
v1.patch.should == 9
|
42
|
+
v1.pre.should be_nil
|
43
|
+
v1.build.should be_nil
|
44
|
+
|
45
|
+
v2 = Semantic::Version.new '0.0.1-pre.1'
|
46
|
+
v2.major.should == 0
|
47
|
+
v2.minor.should == 0
|
48
|
+
v2.patch.should == 1
|
49
|
+
v2.pre.should == 'pre.1'
|
50
|
+
v2.build.should be_nil
|
51
|
+
|
52
|
+
v3 = Semantic::Version.new '1.0.1-pre.5+build.123.5'
|
53
|
+
v3.major.should == 1
|
54
|
+
v3.minor.should == 0
|
55
|
+
v3.patch.should == 1
|
56
|
+
v3.pre.should == 'pre.5'
|
57
|
+
v3.build.should == 'build.123.5'
|
58
|
+
|
59
|
+
v4 = Semantic::Version.new '0.0.0+hello'
|
60
|
+
v4.major.should == 0
|
61
|
+
v4.minor.should == 0
|
62
|
+
v4.patch.should == 0
|
63
|
+
v4.pre.should be_nil
|
64
|
+
v4.build.should == 'hello'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "comparisons" do
|
69
|
+
before(:each) do
|
70
|
+
@v1 = Semantic::Version.new '1.5.9'
|
71
|
+
@v2 = Semantic::Version.new '1.6.0'
|
72
|
+
@v3 = Semantic::Version.new '1.5.9-pre.1'
|
73
|
+
@v4 = Semantic::Version.new '1.5.9-pre.1+build.5127'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "determines sort order" do
|
77
|
+
(@v1 <=> @v2).should == -1
|
78
|
+
(@v3 <=> @v1).should == 1
|
79
|
+
(@v3 <=> @v4).should == -1
|
80
|
+
(@v4 <=> @v4).should == 0
|
81
|
+
(@v4 <=> @v1).should == 1
|
82
|
+
|
83
|
+
[@v3, @v1, @v2, @v4].sort.should == [@v1, @v3, @v4, @v2]
|
84
|
+
end
|
85
|
+
|
86
|
+
it "determines whether it is greater than another instance" do
|
87
|
+
@v1.should_not > @v2
|
88
|
+
@v4.should > @v3
|
89
|
+
@v2.should > @v4
|
90
|
+
@v3.should_not > @v4
|
91
|
+
end
|
92
|
+
|
93
|
+
it "determines whether it is less than another insance" do
|
94
|
+
@v1.should < @v2
|
95
|
+
@v2.should_not < @v4
|
96
|
+
@v4.should < @v2
|
97
|
+
@v3.should < @v4
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "type coercions" do
|
102
|
+
it "converts to a string" do
|
103
|
+
@test_versions.each do |v|
|
104
|
+
Semantic::Version.new(v).to_s.should == v
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "converts to an array" do
|
109
|
+
Semantic::Version.new('1.0.0').to_a.should == [1, 0, 0, nil, nil]
|
110
|
+
Semantic::Version.new('6.1.4-pre.5').to_a.should == [6, 1, 4, 'pre.5', nil]
|
111
|
+
Semantic::Version.new('91.6.0+build.17').to_a.should == [91, 6, 0, nil, 'build.17']
|
112
|
+
Semantic::Version.new('0.1.5-pre.7+build191').to_a.should == [0, 1, 5, 'pre.7', 'build191']
|
113
|
+
end
|
114
|
+
|
115
|
+
it "converts to a hash" do
|
116
|
+
Semantic::Version.new('1.0.0').to_h.should == { major: 1, minor: 0, patch: 0, pre: nil, build: nil }
|
117
|
+
Semantic::Version.new('6.1.4-pre.5').to_h.should == { major: 6, minor: 1, patch: 4, pre: 'pre.5', build: nil }
|
118
|
+
Semantic::Version.new('91.6.0+build.17').to_h.should == { major: 91, minor: 6, patch: 0, pre: nil, build: 'build.17' }
|
119
|
+
Semantic::Version.new('0.1.5-pre.7+build191').to_h.should == { major: 0, minor: 1, patch: 5, pre: 'pre.7', build: 'build191' }
|
120
|
+
end
|
121
|
+
|
122
|
+
it "aliases conversion methods" do
|
123
|
+
v = Semantic::Version.new('0.0.0')
|
124
|
+
[:to_hash, :to_array, :to_string].each { |sym| v.should respond_to(sym) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: semantic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Josh Lindsey
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.2.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.11.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.11.0
|
46
|
+
description: ! 'Semantic Version utility class for parsing, storing, and comparing
|
47
|
+
versions. See: http://semver.org'
|
48
|
+
email:
|
49
|
+
- josh@core-apps.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/semantic/core_ext.rb
|
55
|
+
- lib/semantic/version.rb
|
56
|
+
- lib/semantic.rb
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
- spec/core_ext_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
- spec/version_spec.rb
|
62
|
+
homepage: https://github.com/jlindsey/semantic
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.8.23
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Semantic Version utility class
|
87
|
+
test_files:
|
88
|
+
- spec/core_ext_spec.rb
|
89
|
+
- spec/spec_helper.rb
|
90
|
+
- spec/version_spec.rb
|
91
|
+
has_rdoc:
|