Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import re

"""
This class should be used to compare module(service) versions.
Base method which should be used is parse(..), This method will validate and parse
version which you will pass as parameter, and return object of current class with
parsed version. Same thing you should do with another version, with which you are
planning to compare previous one. After that, use "==", "<", ">" to get final result.
"""
class ModuleVersion(object):
__module_version_pattern = "(?P<aMajor>[0-9]+).(?P<aMinor>[0-9]+).(?P<iMinor>[0-9]+).(?P<iMaint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)"
__module_version_regex = re.compile(__module_version_pattern)

def __init__(self, apache_major, apache_minor, internal_minor, internal_maint, hotfix, build):
"""
:type apache_major int
:type apache_minor int
:type internal_maint int
:type internal_minor int
:type hotfix int
:type build int
"""
self.__apache_major = int(apache_major)
self.__apache_minor = int(apache_minor)
self.__internal_maint = int(internal_maint)
self.__internal_minor = int(internal_minor)
self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group
self.__build = int(build)

def __repr__(self):
return "{0}.{1}.{2}.{3}-h{4}-b{5}".format(*self.to_list())

def to_list(self):
"""
Return version elements as list

:rtype list
"""
return [
self.__apache_major,
self.__apache_minor,
self.__internal_minor,
self.__internal_maint,
self.__hotfix,
self.__build
]

def __cmp__(self, other):
"""
:type other ModuleVersion

:raise TypeError
"""
if other and not isinstance(other, self.__class__):
raise TypeError("Operand type is different from {0}".format(self.__class__.__name__))

r = 0
x = self.to_list()
y = other.to_list()

for i in range(0, len(x)):
r = x[i] - y[i]
if r != 0:
break

return 1 if r > 0 else -1 if r < 0 else 0

@classmethod
def parse(cls, module_version):
"""
Parse string to module version

:type module_version str
:rtype ModuleVersion
"""
matcher = cls.validate(module_version)
return ModuleVersion(
matcher.group("aMajor"),
matcher.group("aMinor"),
matcher.group("iMinor"),
matcher.group("iMaint"),
matcher.group("hotfix"),
matcher.group("build")
)

@classmethod
def validate(cls, module_version):
"""
Check if provided version is valid. If version is valid will return match object
or will raise exception.

:param module_version version to check
:type module_version str

:rtype __Match[T] | None

:raise ValueError
"""

if not module_version:
raise ValueError("Module version can't be empty or null")

version = module_version.strip()

if not version:
raise ValueError("Module version can't be empty or null")

matcher = cls.__module_version_regex.match(version)

if not matcher:
raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))

return matcher

@property
def apache_major(self):
return self.__apache_major

@property
def apache_minor(self):
return self.__apache_minor

@property
def internal_minor(self):
return self.__internal_minor

@property
def internal_maint(self):
return self.__internal_maint

@property
def hotfix(self):
return self.__hotfix

@property
def build(self):
return self.__build



Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

import re

"""
This class should be used to compare mpack and stack versions.
Base method which should be used is parse/parse_stack_version, depends
on which versions you want to compare. This method will validate and parse
version which you will pass as parameter, and return object of current class with
parsed version. Same thing you should do with another version, with which you are
planning to compare previous one. After that, use "==", ">", "<" to get final result.
"""
class MpackVersion(object):
__mpack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+)(-h(?P<hotfix>[0-9]+))*-b(?P<build>[0-9]+)"
__mpack_legacy_stack_version_pattern = "(?P<major>[0-9]+).(?P<minor>[0-9]+).(?P<maint>[0-9]+).(?P<hotfix>[0-9]+)(-(?P<build>[0-9]+))"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vbrodetskyi ,
__mpack_version_pattern and __mpack_legacy_stack_version_pattern show the same pattern. I think
__mpack_legacy_stack_version_pattern = ^([0-9]+).([0-9]+).([0-9]+).([0-9]+)-([0-9]+) (same as the java counterpart)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not the same pattern.
__mpack_version_pattern = N.N.N-hN-bN
__mpack_legacy_stack_version_pattern = N.N.N.N-N
And it's the same as we have in java.

__mpack_version_regex = re.compile(__mpack_version_pattern)
__mpack_legacy_stack_version_regex = re.compile(__mpack_legacy_stack_version_pattern)

def __init__(self, major, minor, maint, hotfix, build):
"""
:type major int
:type minor int
:type maint int
:type hotfix int
:type build int
"""
self.__major = int(major)
self.__minor = int(minor)
self.__maint = int(maint)
self.__hotfix = int(hotfix) if hotfix else 0 # hotfix is optional group
self.__build = int(build)

def __repr__(self):
return "{0}.{1}.{2}-h{3}-b{4}".format(*self.to_list())

def to_list(self):
"""
Return version elements as list

:rtype list
"""
return [
self.__major,
self.__minor,
self.__maint,
self.__hotfix,
self.__build
]

def __cmp__(self, other):
"""
:type other MpackVersion

:raise TypeError
"""
if other and not isinstance(other, self.__class__):
raise TypeError("Operand type is different from {0}".format(self.__class__.__name__))

r = 0
x = self.to_list()
y = other.to_list()

for i in range(0, len(x)):
r = x[i] - y[i]
if r != 0:
break

return 1 if r > 0 else -1 if r < 0 else 0

@classmethod
def parse(cls, mpack_version):
"""
Parse string to mpack version

:type mpack_version str
:rtype MpackVersion
"""
matcher = cls.validate(mpack_version)
return MpackVersion(
matcher.group("major"),
matcher.group("minor"),
matcher.group("maint"),
matcher.group("hotfix"),
matcher.group("build")
)


@classmethod
def parse_stack_version(cls, stack_version):
"""
Parse string to mpack version

:type stack_version str
:rtype MpackVersion
"""
matcher = cls.validate_stack_version(stack_version)
return MpackVersion(
matcher.group("major"),
matcher.group("minor"),
matcher.group("maint"),
matcher.group("hotfix"),
matcher.group("build")
)


@classmethod
def validate_stack_version(cls, stack_version):
"""
Check if provided version is valid. If version is valid will return match object
or will raise exception.

:param stack_version version to check
:type stack_version str

:rtype __Match[T] | None

:raise ValueError
"""

if not stack_version:
raise ValueError("Module version can't be empty or null")

version = stack_version.strip()

if not version:
raise ValueError("Module version can't be empty or null")

matcher = cls.__mpack_version_regex.match(version)

if not matcher:
matcher = cls.__mpack_legacy_stack_version_regex.match(version)
if not matcher:
raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))
else:
if not matcher.group("hotfix"):
raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))

return matcher


@classmethod
def validate(cls, mpack_version):
"""
Check if provided version is valid. If version is valid will return match object
or will raise exception.

:param module_version version to check
:type module_version str

:rtype __Match[T] | None

:raise ValueError
"""

if not mpack_version:
raise ValueError("Module version can't be empty or null")

version = mpack_version.strip()

if not version:
raise ValueError("Module version can't be empty or null")

matcher = cls.__mpack_version_regex.match(version)

if not matcher:
raise ValueError("{0} is not a valid {1}".format(version, cls.__name__))

return matcher

@property
def major(self):
return self.__major

@property
def minor(self):
return self.__minor

@property
def maint(self):
return self.__maint

@property
def hotfix(self):
return self.__hotfix

@property
def build(self):
return self.__build



Loading