2025-02-05 13:43:43 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
# coding: utf-8 -*-
|
2025-02-10 06:39:48 +01:00
|
|
|
"""The module implements version management following semantic versioning principles with custom adaptations for
|
|
|
|
Arista EOS and CloudVision Portal (CVP) software versioning schemes.
|
|
|
|
|
|
|
|
Classes
|
|
|
|
-------
|
|
|
|
SemVer:
|
|
|
|
Base class implementing semantic versioning with comparison and matching capabilities.
|
|
|
|
EosVersion:
|
|
|
|
Specialized version handling for Arista EOS software releases.
|
|
|
|
CvpVersion:
|
|
|
|
Specialized version handling for CloudVision Portal releases.
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
major : int
|
|
|
|
Major version number.
|
|
|
|
minor : int
|
|
|
|
Minor version number.
|
|
|
|
patch : int
|
|
|
|
Patch version number.
|
|
|
|
rtype : Optional[str]
|
|
|
|
Release type (e.g., 'M' for maintenance, 'F' for feature).
|
|
|
|
other : Any
|
|
|
|
Additional version information.
|
|
|
|
regex_version : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract version information.
|
|
|
|
regex_branch : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract branch information.
|
|
|
|
description : str
|
|
|
|
A basic description of this class.
|
|
|
|
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
# Basic SemVer usage:
|
|
|
|
>>> version = SemVer(major=4, minor=23, patch=3)
|
|
|
|
'4.23.3'
|
|
|
|
|
|
|
|
# EOS version handling:
|
|
|
|
>>> eos = EosVersion.from_str('4.23.3M')
|
|
|
|
>>> eos.branch
|
|
|
|
'4.23'
|
|
|
|
|
|
|
|
# CVP version handling:
|
|
|
|
>>> cvp = CvpVersion.from_str('2024.1.0')
|
|
|
|
>>> str(cvp)
|
|
|
|
|
|
|
|
The module enforces version format validation through regular expressions and provides
|
|
|
|
comprehensive comparison operations (==, !=, <, <=, >, >=) between versions.
|
|
|
|
|
|
|
|
Note:
|
|
|
|
--------
|
|
|
|
- EOS versions follow the format: <major>.<minor>.<patch>[M|F]
|
|
|
|
- CVP versions follow the format: <year>.<minor>.<patch>
|
|
|
|
"""
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
import re
|
|
|
|
import typing
|
2025-02-10 06:39:48 +01:00
|
|
|
import logging
|
|
|
|
from typing import Any, Optional, Pattern, ClassVar
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
from loguru import logger
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
from eos_downloader.tools import exc_to_str
|
|
|
|
|
|
|
|
# logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
class SemVer(BaseModel):
|
|
|
|
"""A class to represent a Semantic Version (SemVer) based on pydanntic.
|
|
|
|
|
|
|
|
This class provides methods to parse, compare, and manipulate semantic versions.
|
|
|
|
It supports standard semantic versioning with optional release type and additional version information.
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
>>> version = SemVer(major=4, minor=23, patch=3, rtype="M")
|
|
|
|
>>> str(version)
|
|
|
|
'4.23.3M'
|
|
|
|
|
|
|
|
>>> version2 = SemVer.from_str('4.24.1F')
|
|
|
|
>>> version2.branch
|
|
|
|
'4.24'
|
|
|
|
|
|
|
|
>>> version < version2
|
|
|
|
True
|
|
|
|
|
|
|
|
>>> version.match("<=4.24.0")
|
|
|
|
True
|
|
|
|
|
|
|
|
>>> version.is_in_branch("4.23")
|
|
|
|
True
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
major : int
|
|
|
|
Major version number.
|
|
|
|
minor : int
|
|
|
|
Minor version number.
|
|
|
|
patch : int
|
|
|
|
Patch version number.
|
|
|
|
rtype : Optional[str]
|
|
|
|
Release type (e.g., 'M' for maintenance, 'F' for feature).
|
|
|
|
other : Any
|
|
|
|
Additional version information.
|
|
|
|
regex_version : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract version information.
|
|
|
|
regex_branch : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract branch information.
|
|
|
|
description : str
|
|
|
|
A basic description of this class.
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
major: int = 0
|
2025-02-05 13:43:43 +01:00
|
|
|
minor: int = 0
|
|
|
|
patch: int = 0
|
2025-02-10 06:39:48 +01:00
|
|
|
rtype: Optional[str] = None
|
2025-02-05 13:47:22 +01:00
|
|
|
other: Any = None
|
2025-02-10 06:39:48 +01:00
|
|
|
# Regular Expression to extract version information.
|
|
|
|
regex_version: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d{1,2})(?P<other>\.\d*)*(?P<rtype>[M,F])*$"
|
|
|
|
)
|
|
|
|
regex_branch: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>\d+)\.(?P<minor>\d+)(\.?P<patch>\d)*(\.\d)*(?P<rtype>[M,F])*$"
|
|
|
|
)
|
|
|
|
# A Basic description of this class
|
|
|
|
description: str = "A Generic SemVer implementation"
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
@classmethod
|
2025-02-10 06:39:48 +01:00
|
|
|
def from_str(cls, semver: str) -> SemVer:
|
|
|
|
"""Parse a string into a SemVer object.
|
|
|
|
|
|
|
|
This method parses a semantic version string or branch name into a SemVer object.
|
|
|
|
It supports both standard semver format (x.y.z) and branch format.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
semver : str
|
|
|
|
The version string to parse. Can be either a semantic version
|
|
|
|
string (e.g., "1.2.3") or a branch format.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
SemVer
|
|
|
|
A SemVer object representing the parsed version.
|
|
|
|
Returns an empty SemVer object if parsing fails.
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
>>> SemVer.from_str("1.2.3")
|
|
|
|
SemVer(major=1, minor=2, patch=3)
|
|
|
|
>>> SemVer.from_str("branch-1.2.3")
|
|
|
|
SemVer(major=1, minor=2, patch=3)
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.debug(f"Creating SemVer object from string: {semver}")
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
if cls.regex_version.match(semver):
|
|
|
|
matches = cls.regex_version.match(semver)
|
2025-02-05 13:43:43 +01:00
|
|
|
# assert matches is not None
|
|
|
|
assert matches is not None
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.debug(f"Matches version: {matches}")
|
2025-02-05 13:43:43 +01:00
|
|
|
return cls(**matches.groupdict())
|
2025-02-10 06:39:48 +01:00
|
|
|
if cls.regex_branch.match(semver):
|
|
|
|
matches = cls.regex_branch.match(semver)
|
2025-02-05 13:43:43 +01:00
|
|
|
# assert matches is not None
|
|
|
|
assert matches is not None
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.debug(f"Matches branch: {matches}")
|
2025-02-05 13:43:43 +01:00
|
|
|
return cls(**matches.groupdict())
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.error(f"Error occured with {semver}")
|
|
|
|
return SemVer()
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def branch(self) -> str:
|
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
Extract branch of version.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
str
|
|
|
|
Branch from version.
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
2025-02-05 13:48:40 +01:00
|
|
|
return f"{self.major}.{self.minor}"
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
Standard str representation.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Return string for EOS version like 4.23.3M.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
str
|
|
|
|
A standard EOS version string representing <MAJOR>.<MINOR>.<PATCH><RTYPE>.
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
return f"{self.major}.{self.minor}.{self.patch}{self.other if self.other is not None else ''}{self.rtype if self.rtype is not None else ''}"
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
def _compare(self, other: SemVer) -> float:
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
An internal comparison function to compare 2 EosVersion objects.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Do a deep comparison from Major to Release Type.
|
|
|
|
The return value is:
|
2025-02-05 13:43:43 +01:00
|
|
|
- negative if ver1 < ver2,
|
2025-02-10 06:39:48 +01:00
|
|
|
- zero if ver1 == ver2,
|
|
|
|
- strictly positive if ver1 > ver2.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
other : SemVer
|
|
|
|
An EosVersion to compare with this object.
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
ValueError
|
|
|
|
Raise ValueError if input is incorrect type.
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
float
|
|
|
|
-1 if ver1 < ver2, 0 if ver1 == ver2, 1 if ver1 > ver2.
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
if not isinstance(other, SemVer):
|
2025-02-05 13:48:40 +01:00
|
|
|
raise ValueError(
|
|
|
|
f"could not compare {other} as it is not an EosVersion object"
|
|
|
|
)
|
2025-02-05 13:43:43 +01:00
|
|
|
comparison_flag: float = 0
|
|
|
|
for key, _ in self.dict().items():
|
2025-02-05 13:48:40 +01:00
|
|
|
if (
|
|
|
|
comparison_flag == 0
|
2025-02-10 06:39:48 +01:00
|
|
|
and self.model_dump()[key] is None
|
|
|
|
or other.model_dump()[key] is None
|
2025-02-05 13:48:40 +01:00
|
|
|
):
|
2025-02-05 13:43:43 +01:00
|
|
|
return comparison_flag
|
2025-02-10 06:39:48 +01:00
|
|
|
if (
|
|
|
|
comparison_flag == 0
|
|
|
|
and self.model_dump()[key] < other.model_dump()[key]
|
|
|
|
):
|
2025-02-05 13:43:43 +01:00
|
|
|
comparison_flag = -1
|
2025-02-10 06:39:48 +01:00
|
|
|
if (
|
|
|
|
comparison_flag == 0
|
|
|
|
and self.model_dump()[key] > other.model_dump()[key]
|
|
|
|
):
|
2025-02-05 13:43:43 +01:00
|
|
|
comparison_flag = 1
|
|
|
|
if comparison_flag != 0:
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.debug(
|
|
|
|
f"Comparison flag {self.model_dump()[key]} with {other.model_dump()[key]}: {comparison_flag}"
|
|
|
|
)
|
2025-02-05 13:43:43 +01:00
|
|
|
return comparison_flag
|
|
|
|
return comparison_flag
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __eq__(self, other):
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __eq__ function (==)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) == 0
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __ne__(self, other):
|
|
|
|
# type: ignore
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __nw__ function (!=)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) != 0
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __lt__(self, other):
|
|
|
|
# type: ignore
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __lt__ function (<)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) < 0
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __le__(self, other):
|
|
|
|
# type: ignore
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __le__ function (<=)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) <= 0
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __gt__(self, other):
|
|
|
|
# type: ignore
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __gt__ function (>)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) > 0
|
|
|
|
|
|
|
|
@typing.no_type_check
|
|
|
|
def __ge__(self, other):
|
|
|
|
# type: ignore
|
2025-02-05 13:48:40 +01:00
|
|
|
"""Implement __ge__ function (>=)"""
|
2025-02-05 13:43:43 +01:00
|
|
|
return self._compare(other) >= 0
|
|
|
|
|
|
|
|
def match(self, match_expr: str) -> bool:
|
|
|
|
"""
|
|
|
|
Compare self to match a match expression.
|
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
match_expr : str
|
|
|
|
Optional operator and version; valid operators are:
|
2025-02-05 13:43:43 +01:00
|
|
|
``<`` smaller than
|
|
|
|
``>`` greater than
|
2025-02-10 06:39:48 +01:00
|
|
|
``>=`` greater or equal than
|
2025-02-05 13:43:43 +01:00
|
|
|
``<=`` smaller or equal than
|
|
|
|
``==`` equal
|
2025-02-10 06:39:48 +01:00
|
|
|
``!=`` not equal.
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
ValueError
|
|
|
|
If input has no match_expr nor match_ver.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
bool
|
|
|
|
True if the expression matches the version, otherwise False.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
>>> eos_version.match("<=4.23.3M")
|
|
|
|
True
|
|
|
|
>>> eos_version.match("==4.23.3M")
|
|
|
|
False
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
|
|
|
prefix = match_expr[:2]
|
|
|
|
if prefix in (">=", "<=", "==", "!="):
|
|
|
|
match_version = match_expr[2:]
|
|
|
|
elif prefix and prefix[0] in (">", "<"):
|
|
|
|
prefix = prefix[0]
|
|
|
|
match_version = match_expr[1:]
|
|
|
|
elif match_expr and match_expr[0] in "0123456789":
|
|
|
|
prefix = "=="
|
|
|
|
match_version = match_expr
|
|
|
|
else:
|
|
|
|
raise ValueError(
|
|
|
|
"match_expr parameter should be in format <op><ver>, "
|
|
|
|
"where <op> is one of "
|
|
|
|
"['<', '>', '==', '<=', '>=', '!=']. "
|
|
|
|
f"You provided: {match_expr}"
|
|
|
|
)
|
|
|
|
possibilities_dict = {
|
|
|
|
">": (1,),
|
|
|
|
"<": (-1,),
|
|
|
|
"==": (0,),
|
|
|
|
"!=": (-1, 1),
|
|
|
|
">=": (0, 1),
|
|
|
|
"<=": (-1, 0),
|
|
|
|
}
|
|
|
|
possibilities = possibilities_dict[prefix]
|
2025-02-10 06:39:48 +01:00
|
|
|
cmp_res = self._compare(SemVer.from_str(match_version))
|
2025-02-05 13:43:43 +01:00
|
|
|
|
|
|
|
return cmp_res in possibilities
|
|
|
|
|
|
|
|
def is_in_branch(self, branch_str: str) -> bool:
|
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
Check if current version is part of a branch version.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Comparison is done across MAJOR and MINOR.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
branch_str : str
|
|
|
|
A string for EOS branch. It supports following formats 4.23 or 4.23.0.
|
2025-02-05 13:43:43 +01:00
|
|
|
|
2025-02-10 06:39:48 +01:00
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
bool
|
|
|
|
True if current version is in provided branch, otherwise False.
|
2025-02-05 13:43:43 +01:00
|
|
|
"""
|
2025-02-10 06:39:48 +01:00
|
|
|
logging.info(f"Checking if {self} is in branch {branch_str}")
|
2025-02-05 13:43:43 +01:00
|
|
|
try:
|
2025-02-10 06:39:48 +01:00
|
|
|
branch = SemVer.from_str(branch_str)
|
2025-02-05 13:43:43 +01:00
|
|
|
except Exception as error: # pylint: disable = broad-exception-caught
|
|
|
|
logger.error(exc_to_str(error))
|
|
|
|
else:
|
|
|
|
return self.major == branch.major and self.minor == branch.minor
|
|
|
|
return False
|
2025-02-10 06:39:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
class EosVersion(SemVer):
|
|
|
|
"""EosVersion object to play with version management in code.
|
|
|
|
|
|
|
|
Since EOS is not using strictly semver approach, this class mimics some functions from the semver library for Arista EOS versions.
|
|
|
|
It is based on Pydantic and provides helpers for comparison.
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
>>> version = EosVersion(major=4, minor=21, patch=1, rtype="M")
|
|
|
|
>>> print(version)
|
|
|
|
EosVersion(major=4, minor=21, patch=1, rtype='M', other=None)
|
|
|
|
>>> version = EosVersion.from_str('4.32.1F')
|
|
|
|
>>> print(version)
|
|
|
|
EosVersion(major=4, minor=32, patch=1, rtype='F', other=None)
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
major : int
|
|
|
|
Major version number, default is 4.
|
|
|
|
minor : int
|
|
|
|
Minor version number, default is 0.
|
|
|
|
patch : int
|
|
|
|
Patch version number, default is 0.
|
|
|
|
rtype : Optional[str]
|
|
|
|
Release type, default is "F".
|
|
|
|
other : Any
|
|
|
|
Any other version information.
|
|
|
|
regex_version : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract version information.
|
|
|
|
regex_branch : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to extract branch information.
|
|
|
|
description : str
|
|
|
|
A basic description of this class, default is "A Generic SemVer implementation".
|
|
|
|
"""
|
|
|
|
|
|
|
|
major: int = 4
|
|
|
|
minor: int = 0
|
|
|
|
patch: int = 0
|
|
|
|
rtype: Optional[str] = "F"
|
|
|
|
other: Any = None
|
|
|
|
# Regular Expression to extract version information.
|
|
|
|
regex_version: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>4)\.(?P<minor>\d{1,2})\.(?P<patch>\d{1,2})(?P<other>\.\d*)*(?P<rtype>[M,F])*$"
|
|
|
|
)
|
|
|
|
regex_branch: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>4)\.(?P<minor>\d{1,2})(\.?P<patch>\d)*(\.\d)*(?P<rtype>[M,F])*$"
|
|
|
|
)
|
|
|
|
# A Basic description of this class
|
|
|
|
description: str = "A SemVer implementation for EOS"
|
|
|
|
|
|
|
|
|
|
|
|
class CvpVersion(SemVer):
|
|
|
|
"""A CloudVision Portal Version class that inherits from SemVer.
|
|
|
|
|
|
|
|
This class implements version management for CloudVision Portal (CVP) versions
|
|
|
|
following a modified semantic versioning pattern where:
|
|
|
|
- major version represents the year (e.g. 2024)
|
|
|
|
- minor version represents feature releases
|
|
|
|
- patch version represents bug fixes
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
>>> version = CvpVersion(2024, 1, 0)
|
|
|
|
>>> str(version)
|
|
|
|
'2024.1.0'
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
----------
|
|
|
|
major : int
|
|
|
|
The year component of the version (e.g. 2024).
|
|
|
|
minor : int
|
|
|
|
The minor version number.
|
|
|
|
patch : int
|
|
|
|
The patch version number.
|
|
|
|
rtype : Optional[str]
|
|
|
|
Release type if any.
|
|
|
|
other : Any
|
|
|
|
Additional version information if any.
|
|
|
|
regex_version : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to parse version strings.
|
|
|
|
regex_branch : ClassVar[Pattern[str]]
|
|
|
|
Regular expression to parse branch version strings.
|
|
|
|
description : str
|
|
|
|
Brief description of the class purpose.
|
|
|
|
"""
|
|
|
|
|
|
|
|
major: int = 2024
|
|
|
|
minor: int = 0
|
|
|
|
patch: int = 0
|
|
|
|
rtype: Optional[str] = None
|
|
|
|
other: Any = None
|
|
|
|
# Regular Expression to extract version information.
|
|
|
|
regex_version: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>\d{4})\.(?P<minor>\d{1,2})\.(?P<patch>\d{1,2})(?P<other>\.\d*)*$"
|
|
|
|
)
|
|
|
|
regex_branch: ClassVar[Pattern[str]] = re.compile(
|
|
|
|
r"^.*(?P<major>\d{4})\.(?P<minor>\d{1,2})\.(?P<patch>\d{1,2})(?P<other>\.\d*)*$"
|
|
|
|
)
|
|
|
|
# A Basic description of this class
|
|
|
|
description: str = "A SemVer implementation for CloudVision"
|