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 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,5 @@
1
+ module Semantic
2
+ GEM_VERSION = '1.0.0'
3
+ autoload :Version, 'semantic/version'
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+ class String
2
+ def to_version
3
+ Semantic::Version.new self
4
+ end
5
+ end
@@ -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
@@ -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: