91 lines
2 KiB
Ruby
91 lines
2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
class VersionInfo
|
|
include Comparable
|
|
|
|
attr_reader :major, :minor, :patch
|
|
|
|
VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/.freeze
|
|
|
|
def self.parse(str, parse_suffix: false)
|
|
if str.is_a?(self.class)
|
|
str
|
|
elsif str && m = str.match(VERSION_REGEX)
|
|
VersionInfo.new(m[1].to_i, m[2].to_i, m[3].to_i, parse_suffix ? m.post_match : nil)
|
|
else
|
|
VersionInfo.new
|
|
end
|
|
end
|
|
|
|
def initialize(major = 0, minor = 0, patch = 0, suffix = nil)
|
|
@major = major
|
|
@minor = minor
|
|
@patch = patch
|
|
@suffix_s = suffix.to_s
|
|
end
|
|
|
|
# rubocop:disable Metrics/CyclomaticComplexity
|
|
# rubocop:disable Metrics/PerceivedComplexity
|
|
def <=>(other)
|
|
return unless other.is_a? VersionInfo
|
|
return unless valid? && other.valid?
|
|
|
|
if other.major < @major
|
|
1
|
|
elsif @major < other.major
|
|
-1
|
|
elsif other.minor < @minor
|
|
1
|
|
elsif @minor < other.minor
|
|
-1
|
|
elsif other.patch < @patch
|
|
1
|
|
elsif @patch < other.patch
|
|
-1
|
|
elsif @suffix_s.empty? && other.suffix.present?
|
|
1
|
|
elsif other.suffix.empty? && @suffix_s.present?
|
|
-1
|
|
else
|
|
suffix <=> other.suffix
|
|
end
|
|
end
|
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
|
|
def to_s
|
|
if valid?
|
|
"%d.%d.%d%s" % [@major, @minor, @patch, @suffix_s]
|
|
else
|
|
'Unknown'
|
|
end
|
|
end
|
|
|
|
def suffix
|
|
@suffix ||= @suffix_s.strip.gsub('-', '.pre.').scan(/\d+|[a-z]+/i).map do |s|
|
|
/^\d+$/ =~ s ? s.to_i : s
|
|
end.freeze
|
|
end
|
|
|
|
def valid?
|
|
@major >= 0 && @minor >= 0 && @patch >= 0 && @major + @minor + @patch > 0
|
|
end
|
|
|
|
def hash
|
|
[self.class, to_s].hash
|
|
end
|
|
|
|
def eql?(other)
|
|
(self <=> other) == 0
|
|
end
|
|
|
|
def same_minor_version?(other)
|
|
@major == other.major && @minor == other.minor
|
|
end
|
|
|
|
def without_patch
|
|
self.class.new(@major, @minor, 0)
|
|
end
|
|
end
|
|
end
|