You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
4.5 KiB

# Copyright (C) 2005-2024 Splunk Inc. All Rights Reserved.
'''
Module for VersionCheck class and related classes
'''
import re
from itsi_py3 import _
class VersionCheck(object):
'''
Class to check version
Note we do support only dotted version for example
1
1.0
1.0.1.2
1.0.1.234
#NOTE: This does not support the following formats
like v1.0
10.0.2-r1
10.0.4-build 2323
10.0.5-RC2 etc
'''
VERSION_REGEX = r'\d+(\.\d+)*$'
@staticmethod
def validate_version(version, is_accept_empty=True):
'''
validate version
@type version: string
@param version: version number
@type: boolean
@param is_accept_empty: should empty version be considered valid, useful during migration
@return: true|false
'''
# Handle empty string
if version == "" and is_accept_empty:
return True
match = re.match(VersionCheck.VERSION_REGEX, version)
return match is not None
@staticmethod
def compare(dest_version, src_version):
'''
@param dest_version: version
@type dest_version: string
@param src_version: version against, it does comparison
@type src_version: string
@return:
1 if dest_version > src_version
0 if dest_version = src_version
-1 if dest_version < src_version
'''
# We're disabling these checks because the return statements and branches
# Could be refactored at the cost of readability. And I think readability
# Is more important here
# pylint: disable=too-many-return-statements, too-many-branches
if not VersionCheck.validate_version(dest_version):
raise ValueError(_("Invalid format for `dest_version`:%s."), dest_version)
if not VersionCheck.validate_version(src_version):
raise ValueError(_("Invalid format for `src_version`:%s."), src_version)
dest_split_versions = dest_version.split(".") if dest_version != "" else []
src_split_versions = src_version.split(".") if src_version != "" else []
if len(dest_split_versions) == 0 and len(src_split_versions) == 0:
return 0
elif len(dest_split_versions) == 0 and len(src_split_versions) > 0:
return -1
index = 0
for index in range(0, len(dest_split_versions)):
if len(src_split_versions) > index:
if int(dest_split_versions[index]) > int(src_split_versions[index]):
return 1
elif int(dest_split_versions[index]) < int(src_split_versions[index]):
return -1
else:
continue
else:
break
if (len(dest_split_versions) == len(src_split_versions) and
index == len(dest_split_versions) - 1):
return 0
elif len(dest_split_versions) < len(src_split_versions):
# Check if any of values are more than 0
# in this case we need to increase index value because we compared old one
index = index + 1
while index < len(src_split_versions):
if int(src_split_versions[index]) > 0:
return -1
index = index + 1
else:
while index < len(dest_split_versions):
if int(dest_split_versions[index]) > 0:
return 1
index = index + 1
# Seems like all other values are zeros
return 0
@staticmethod
def in_range(version, start_inclusive_version, end_exclusive_version):
"""
Determine if the given version falls within the version range given by start_inclusive_version and
end_exclusive_version. If the version is >= start_inclusive_version and < end_exclusive_version, then the
version is considered to fall in the version range.
:param version: version to check if in range
:param start_inclusive_version: minimum version, inclusive
:param end_exclusive_version: maximum version, exclusive
:return: True if the given version is within the range
"""
start_satisfied = not start_inclusive_version or VersionCheck.compare(version, start_inclusive_version) >= 0
end_satisfied = not end_exclusive_version or VersionCheck.compare(version, end_exclusive_version) < 0
return start_satisfied and end_satisfied