semver-string 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ab6e9b795fc2232aac580c9c5950f6e9091e663c5675bc30c264f599c7a0bac2
4
+ data.tar.gz: 83c393f0951e5b8ea6980ef15f8036ae634242c26c34e6a1cb262f01e659266b
5
+ SHA512:
6
+ metadata.gz: 0eef77d8973cf20c4932f1b4229d4272003bd9e4544aed31c38ed7d4fe699267f57c802ac5469eb71019ee1c3b313d0a517d4c3be7c2a60803e22882e276e72c
7
+ data.tar.gz: 1e5a5e8397e88f216f2fab1c995b77e5d6cd94d7e74aebaeddcba1830af55e03ecbf2b0db7bee5499bf41ead906de8f20f3742d8280b6a1e6d5b07b47879dfed
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'semver/string'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Semver
4
+ # @api private
5
+ class Comparator
6
+
7
+ # @param [Semver::String] left
8
+ # @param [Semver::String] right
9
+ def compare(left:, right:)
10
+ parts(left) <=> parts(right)
11
+ end
12
+
13
+ def parts(semver)
14
+ [semver.major, semver.minor, semver.patch] + pre_release(semver)
15
+ end
16
+
17
+ def pre_release(semver)
18
+ if semver.pre_release
19
+ [-1] + pre_release_identifiers(semver)
20
+ else
21
+ [1]
22
+ end
23
+ end
24
+
25
+ def pre_release_identifiers(semver)
26
+ semver.pre_release.split('.').map { |value| Identifier.new(value) }
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Semver
4
+ # @api private
5
+ class Identifier
6
+
7
+ # @param [String, Integer] value
8
+ def initialize(value)
9
+ @value = value
10
+ end
11
+
12
+ # @return [String, Integer]
13
+ attr_reader :value
14
+
15
+ # @return [Integer] Returns -1, 0, or 1.
16
+ def <=>(other)
17
+ if other.value.is_a?(value.class)
18
+ value <=> other.value
19
+ elsif value.is_a?(Integer)
20
+ -1
21
+ else
22
+ 1
23
+ end
24
+ end
25
+
26
+ # @param [String] value
27
+ def self.new(value)
28
+ identifier = allocate
29
+ identifier.send(:initialize, value =~ /^\d+$/ ? value.to_i : value)
30
+ identifier
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Semver
4
+ # Thrown when parsing a string that is not valid
5
+ # [semver 2.0](https://semver.org/spec/v2.0.0.html).
6
+ class InvalidFormatError < StandardError
7
+
8
+ def initialize(value)
9
+ msg = 'invalid format, expected semver string, e.g. ' \
10
+ + '1.2.3, 1.2.3-rc.1, 1.2.3.alpha+1234567890, got :' \
11
+ + value.inspect
12
+ super(msg)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Semver
4
+ # @api private
5
+ class Parser
6
+
7
+ PATTERN = %r{^
8
+ (0|[1-9]\d*)\. # major
9
+ (0|[1-9]\d*)\. # minor
10
+ (0|[1-9]\d*) # patch
11
+ (- # pre release
12
+ (0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
13
+ (\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*
14
+ )?
15
+ (\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)? # build metadata
16
+ $}x
17
+
18
+ def parse(string)
19
+ matches = PATTERN.match(string.to_s)
20
+ raise InvalidFormatError, string unless matches
21
+ {
22
+ major: matches[1].to_i,
23
+ minor: matches[2].to_i,
24
+ patch: matches[3].to_i,
25
+ pre_release: left_chop(matches[4]),
26
+ build_metadata: left_chop(matches[8]),
27
+ }
28
+ end
29
+
30
+ private
31
+
32
+ def left_chop(value)
33
+ value ? value[1..-1] : nil
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'comparator'
4
+ require_relative 'identifier'
5
+ require_relative 'invalid_format_error'
6
+ require_relative 'parser'
7
+
8
+ module Semver
9
+ # A helper class for working with semantic versioning strings.
10
+ #
11
+ # ~~~
12
+ # version = Semver::String.new('1.2.3-alpha+build-123')
13
+ #
14
+ # version.major #=> 1
15
+ # version.major #=> 2
16
+ # version.patch #=> 3
17
+ # version.pre_release #=> alpha
18
+ # version.build_metadata #=> build-123
19
+ # version.to_s #=> "1.2.3-alpha+build-123"
20
+ # ~~~
21
+ class String
22
+
23
+ # @param [String] string
24
+ # @return [Version]
25
+ def self.parse(string)
26
+ semver = allocate
27
+ semver.send(:initialize, Parser.new.parse(string))
28
+ semver
29
+ end
30
+
31
+ # @param [Integer] major
32
+ # @param [Integer] minor
33
+ # @param [Integer] patch
34
+ # @param [String,nil] pre_release
35
+ # @param [String,nil] build_metadata
36
+ def initialize(
37
+ major:,
38
+ minor:,
39
+ patch:,
40
+ pre_release: nil,
41
+ build_metadata: nil
42
+ )
43
+ @major = major
44
+ @minor = minor
45
+ @patch = patch
46
+ @pre_release = pre_release
47
+ @build_metadata = build_metadata
48
+ @string = format_string
49
+ end
50
+
51
+ # @return [Integer]
52
+ attr_reader :major
53
+
54
+ # @return [Integer]
55
+ attr_reader :minor
56
+
57
+ # @return [Integer]
58
+ attr_reader :patch
59
+
60
+ # @return [String, nil]
61
+ attr_reader :pre_release
62
+
63
+ # @return [String, nil]
64
+ attr_reader :build_metadata
65
+
66
+ # @return [String]
67
+ def to_str
68
+ @string
69
+ end
70
+ alias to_s to_str
71
+
72
+ # @return [Boolean]
73
+ # @api private
74
+ def eql?(other)
75
+ if other.is_a?(Semver::String)
76
+ to_str == other.to_str
77
+ else
78
+ false
79
+ end
80
+ end
81
+
82
+ # @return [Boolean] Returns `true` if the string value of the
83
+ # two objects are equal.
84
+ def ==(other)
85
+ to_s == other.to_s
86
+ end
87
+
88
+ # See section #11 of https://semver.org/spec/v2.0.0.html
89
+ # @return [Integer] Returns -1, 0, or 1.
90
+ def <=>(other)
91
+ Comparator.new.compare(left: self, right: other)
92
+ end
93
+
94
+ private
95
+
96
+ def format_string
97
+ string = [major, minor, patch].join('.')
98
+ string += "-#{pre_release}" if pre_release
99
+ string += "+#{build_metadata}" if build_metadata
100
+ string
101
+ end
102
+
103
+ end
104
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semver-string
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - The Incognito Coder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - theincognitocoder@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/semver-string.rb
21
+ - lib/semver/comparator.rb
22
+ - lib/semver/identifier.rb
23
+ - lib/semver/invalid_format_error.rb
24
+ - lib/semver/parser.rb
25
+ - lib/semver/string.rb
26
+ homepage: https://github.com/theincognitocoder/semver-string
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ bug_tracker_uri: https://github.com/theincognitocoder/semver-string/issues
31
+ changelog_uri: https://github.com/theincognitocoder/semver-string/blob/master/CHANGELOG.md
32
+ documentation_uri: https://www.rubydoc.info/github/theincognitocoder/semver-string/master
33
+ homepage_uri: https://github.com/theincognitocoder/semver-string
34
+ mailing_list_uri: https://gitter.im/theincognitocoder/semver-string
35
+ source_code_uri: https://github.com/theincognitocoder/semver-string
36
+ wiki_uri: https://github.com/theincognitocoder/semver-string/wiki
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 2.7.7
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Semver v2.0 version strings in Ruby.
57
+ test_files: []