semver-string 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.
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: []