Class: SemverDialects::SemanticVersion
- Inherits:
-
Object
- Object
- SemverDialects::SemanticVersion
- Includes:
- Comparable
- Defined in:
- lib/semver_dialects/semantic_version.rb
Overview
SemanticVersion is a generic version class. It parses and compares versions of any syntax. It can’t always be accurate because a single comparison logic can’t possibly handle all the supported syntaxes. Since it’s generic, it doesn’t validate versions.
Constant Summary collapse
- ANY_NUMBER =
'x'- VERSION_PATTERN =
String to build a regexp that matches a version.
A version might start with a leading “v”, then it must have a digit, then it might have any sequence made of alphanumerical characters, underscores, dots, dashes, and wildcards.
'v?[0-9][a-zA-Z0-9_.*+-]*'- VERSION_ONLY_REGEXP =
Regexp for a string that only contains a single version string.
Regexp.new("\\A#{VERSION_PATTERN}\\z").freeze
Instance Attribute Summary collapse
-
#prefix_segments ⇒ Object
readonly
Returns the value of attribute prefix_segments.
-
#segments ⇒ Object
readonly
Returns the value of attribute segments.
-
#suffix_segments ⇒ Object
readonly
Returns the value of attribute suffix_segments.
-
#version_string ⇒ Object
readonly
Returns the value of attribute version_string.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #_get_equalized_arrays_for(array_a, array_b) ⇒ Object
- #get_equalized_arrays_for(semver_a, semver_b) ⇒ Object
-
#initialize(version_string) ⇒ SemanticVersion
constructor
A new instance of SemanticVersion.
-
#is_zero? ⇒ Boolean
rubocop:todo Naming/PredicateName.
- #major ⇒ Object
- #minor ⇒ Object
- #patch ⇒ Object
- #post_release? ⇒ Boolean
- #pre_release? ⇒ Boolean
- #split_version_string!(version_string) ⇒ Object
- #to_normalized_s ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(version_string) ⇒ SemanticVersion
Returns a new instance of SemanticVersion.
28 29 30 31 32 33 34 35 36 |
# File 'lib/semver_dialects/semantic_version.rb', line 28 def initialize(version_string) raise InvalidVersionError, version_string unless VERSION_ONLY_REGEXP.match version_string @version_string = version_string @prefix_segments = [] @suffix_segments = [] version, = version_string.delete_prefix('v').split('+') @segments = split_version_string!(version) end |
Instance Attribute Details
#prefix_segments ⇒ Object (readonly)
Returns the value of attribute prefix_segments.
16 17 18 |
# File 'lib/semver_dialects/semantic_version.rb', line 16 def prefix_segments @prefix_segments end |
#segments ⇒ Object (readonly)
Returns the value of attribute segments.
16 17 18 |
# File 'lib/semver_dialects/semantic_version.rb', line 16 def segments @segments end |
#suffix_segments ⇒ Object (readonly)
Returns the value of attribute suffix_segments.
16 17 18 |
# File 'lib/semver_dialects/semantic_version.rb', line 16 def suffix_segments @suffix_segments end |
#version_string ⇒ Object (readonly)
Returns the value of attribute version_string.
16 17 18 |
# File 'lib/semver_dialects/semantic_version.rb', line 16 def version_string @version_string end |
Instance Method Details
#<=>(other) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/semver_dialects/semantic_version.rb', line 111 def <=>(other) return nil unless other.is_a?(SemanticVersion) self_array, other_array = get_equalized_arrays_for(self, other) zipped_arrays = self_array.zip(other_array) zipped_arrays.each do |(a, b)| return 0 if a.wildcard? || b.wildcard? cmp = a <=> b return cmp if cmp != 0 end 0 end |
#_get_equalized_arrays_for(array_a, array_b) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/semver_dialects/semantic_version.rb', line 74 def _get_equalized_arrays_for(array_a, array_b) first_array = array_a.clone second_array = array_b.clone if first_array.size < second_array.size (second_array.size - first_array.size).times do first_array << SemanticVersionSegment.new('0') end elsif first_array.size > second_array.size (first_array.size - second_array.size).times do second_array << SemanticVersionSegment.new('0') end end [first_array, second_array] end |
#get_equalized_arrays_for(semver_a, semver_b) ⇒ Object
89 90 91 92 93 94 95 96 97 |
# File 'lib/semver_dialects/semantic_version.rb', line 89 def get_equalized_arrays_for(semver_a, semver_b) first_array_prefix = semver_a.prefix_segments.clone second_array_prefix = semver_b.prefix_segments.clone first_array_suffix = semver_a.suffix_segments.clone second_array_suffix = semver_b.suffix_segments.clone first_array_prefix, second_array_prefix = _get_equalized_arrays_for(first_array_prefix, second_array_prefix) first_array_suffix, second_array_suffix = _get_equalized_arrays_for(first_array_suffix, second_array_suffix) [first_array_prefix.concat(first_array_suffix), second_array_prefix.concat(second_array_suffix)] end |
#is_zero? ⇒ Boolean
rubocop:todo Naming/PredicateName
99 100 101 |
# File 'lib/semver_dialects/semantic_version.rb', line 99 def is_zero? # rubocop:todo Naming/PredicateName @prefix_segments.empty? || @prefix_segments.all?(&:is_zero?) end |
#major ⇒ Object
137 138 139 |
# File 'lib/semver_dialects/semantic_version.rb', line 137 def major @prefix_segments.size >= 2 ? @prefix_segments[0].to_s : '0' end |
#minor ⇒ Object
133 134 135 |
# File 'lib/semver_dialects/semantic_version.rb', line 133 def minor @prefix_segments.size >= 1 ? @prefix_segments[1].to_s : '0' end |
#patch ⇒ Object
141 142 143 |
# File 'lib/semver_dialects/semantic_version.rb', line 141 def patch @prefix_segments.size >= 3 ? @prefix_segments[2].to_s : '0' end |
#post_release? ⇒ Boolean
107 108 109 |
# File 'lib/semver_dialects/semantic_version.rb', line 107 def post_release? @suffix_segments.any?(&:is_post_release) end |
#pre_release? ⇒ Boolean
103 104 105 |
# File 'lib/semver_dialects/semantic_version.rb', line 103 def pre_release? @suffix_segments.any?(&:is_pre_release) end |
#split_version_string!(version_string) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/semver_dialects/semantic_version.rb', line 38 def split_version_string!(version_string) delim_pattern = /[.-]/ split_array = version_string.split(delim_pattern).map do |grp| grp.split(/(\d+)/).reject { |cell| cell.nil? || cell.empty? } end.flatten # go as far to the right as possible considering numbers and placeholders prefix_delimiter = 0 (0..split_array.size - 1).each do |i| break unless split_array[i].number? || split_array[i] == 'X' || split_array[i] == 'x' prefix_delimiter = i end # remove redundant trailing zeros prefix_delimiter.downto(0).each do |i| break unless split_array[i] == '0' split_array.delete_at(i) prefix_delimiter -= 1 end unless prefix_delimiter.negative? @prefix_segments = split_array[0..prefix_delimiter].map do |group_string| SemanticVersionSegment.new(group_string) end end if split_array.size - 1 >= prefix_delimiter + 1 @suffix_segments = split_array[prefix_delimiter + 1, split_array.size].map do |group_string| SemanticVersionSegment.new(group_string) end end @prefix_segments.clone.concat(@suffix_segments) end |
#to_normalized_s ⇒ Object
125 126 127 |
# File 'lib/semver_dialects/semantic_version.rb', line 125 def to_normalized_s @segments.map(&:to_normalized_s).join(':') end |
#to_s ⇒ Object
129 130 131 |
# File 'lib/semver_dialects/semantic_version.rb', line 129 def to_s @version_string end |