Factor out the versions information. Finding next release is now accurate

This commit is contained in:
Pedro Algarvio 2021-06-30 16:03:40 +01:00 committed by Gareth J. Greenaway
parent 996e3ea625
commit 11d5c08af4
2 changed files with 250 additions and 164 deletions

View file

@ -2,9 +2,12 @@
Set up the version of Salt
"""
import operator
import platform
import re
import sys
from collections import namedtuple
from functools import total_ordering
import salt.utils.entrypoints
@ -33,6 +36,200 @@ VERSION_LIMIT = MAX_SIZE - 200
# <---- ATTENTION ----------------------------------------------------------------------------------------------------
@total_ordering
class SaltVersion(namedtuple("SaltVersion", "name, info, released")):
__slots__ = ()
def __new__(cls, name, info, released=False):
if isinstance(info, int):
info = (info,)
return super().__new__(cls, name, info, released)
def __eq__(self, other):
return self.info == other.info
def __gt__(self, other):
return self.info > other.info
class SaltVersionsInfo(type):
_sorted_versions = ()
_current_release = None
_previous_release = None
_next_release = None
# pylint: disable=bad-whitespace,multiple-spaces-before-operator
# ----- Please refrain from fixing whitespace ---------------------------------->
# The idea is to keep this readable.
# -------------------------------------------------------------------------------
# fmt: off
HYDROGEN = SaltVersion("Hydrogen" , info=(2014, 1), released=True)
HELIUM = SaltVersion("Helium" , info=(2014, 7), released=True)
LITHIUM = SaltVersion("Lithium" , info=(2015, 5), released=True)
BERYLLIUM = SaltVersion("Beryllium" , info=(2015, 8), released=True)
BORON = SaltVersion("Boron" , info=(2016, 3), released=True)
CARBON = SaltVersion("Carbon" , info=(2016, 11), released=True)
NITROGEN = SaltVersion("Nitrogen" , info=(2017, 7), released=True)
OXYGEN = SaltVersion("Oxygen" , info=(2018, 3), released=True)
FLUORINE = SaltVersion("Fluorine" , info=(2019, 2), released=True)
NEON = SaltVersion("Neon" , info=3000, released=True)
SODIUM = SaltVersion("Sodium" , info=3001, released=True)
MAGNESIUM = SaltVersion("Magnesium" , info=3002, released=True)
ALUMINIUM = SaltVersion("Aluminium" , info=3003, released=True)
SILICON = SaltVersion("Silicon" , info=3004)
PHOSPHORUS = SaltVersion("Phosphorus" , info=3005)
SULFUR = SaltVersion("Sulfur" , info=3006)
CHLORINE = SaltVersion("Chlorine" , info=3007)
ARGON = SaltVersion("Argon" , info=3008)
POTASSIUM = SaltVersion("Potassium" , info=3009)
CALCIUM = SaltVersion("Calcium" , info=3010)
SCANDIUM = SaltVersion("Scandium" , info=3011)
TITANIUM = SaltVersion("Titanium" , info=3012)
VANADIUM = SaltVersion("Vanadium" , info=3013)
CHROMIUM = SaltVersion("Chromium" , info=3014)
MANGANESE = SaltVersion("Manganese" , info=3015)
IRON = SaltVersion("Iron" , info=3016)
COBALT = SaltVersion("Cobalt" , info=3017)
NICKEL = SaltVersion("Nickel" , info=3018)
COPPER = SaltVersion("Copper" , info=3019)
ZINC = SaltVersion("Zinc" , info=3020)
GALLIUM = SaltVersion("Gallium" , info=3021)
GERMANIUM = SaltVersion("Germanium" , info=3022)
ARSENIC = SaltVersion("Arsenic" , info=3023)
SELENIUM = SaltVersion("Selenium" , info=3024)
BROMINE = SaltVersion("Bromine" , info=3025)
KRYPTON = SaltVersion("Krypton" , info=3026)
RUBIDIUM = SaltVersion("Rubidium" , info=3027)
STRONTIUM = SaltVersion("Strontium" , info=3028)
YTTRIUM = SaltVersion("Yttrium" , info=3029)
ZIRCONIUM = SaltVersion("Zirconium" , info=3030)
NIOBIUM = SaltVersion("Niobium" , info=3031)
MOLYBDENUM = SaltVersion("Molybdenum" , info=3032)
TECHNETIUM = SaltVersion("Technetium" , info=3033)
RUTHENIUM = SaltVersion("Ruthenium" , info=3034)
RHODIUM = SaltVersion("Rhodium" , info=3035)
PALLADIUM = SaltVersion("Palladium" , info=3036)
SILVER = SaltVersion("Silver" , info=3037)
CADMIUM = SaltVersion("Cadmium" , info=3038)
INDIUM = SaltVersion("Indium" , info=3039)
TIN = SaltVersion("Tin" , info=3040)
ANTIMONY = SaltVersion("Antimony" , info=3041)
TELLURIUM = SaltVersion("Tellurium" , info=3042)
IODINE = SaltVersion("Iodine" , info=3043)
XENON = SaltVersion("Xenon" , info=3044)
CESIUM = SaltVersion("Cesium" , info=3045)
BARIUM = SaltVersion("Barium" , info=3046)
LANTHANUM = SaltVersion("Lanthanum" , info=3047)
CERIUM = SaltVersion("Cerium" , info=3048)
PRASEODYMIUM = SaltVersion("Praseodymium" , info=3049)
NEODYMIUM = SaltVersion("Neodymium" , info=3050)
PROMETHIUM = SaltVersion("Promethium" , info=3051)
SAMARIUM = SaltVersion("Samarium" , info=3052)
EUROPIUM = SaltVersion("Europium" , info=3053)
GADOLINIUM = SaltVersion("Gadolinium" , info=3054)
TERBIUM = SaltVersion("Terbium" , info=3055)
DYSPROSIUM = SaltVersion("Dysprosium" , info=3056)
HOLMIUM = SaltVersion("Holmium" , info=3057)
ERBIUM = SaltVersion("Erbium" , info=3058)
THULIUM = SaltVersion("Thulium" , info=3059)
YTTERBIUM = SaltVersion("Ytterbium" , info=3060)
LUTETIUM = SaltVersion("Lutetium" , info=3061)
HAFNIUM = SaltVersion("Hafnium" , info=3062)
TANTALUM = SaltVersion("Tantalum" , info=3063)
TUNGSTEN = SaltVersion("Tungsten" , info=3064)
RHENIUM = SaltVersion("Rhenium" , info=3065)
OSMIUM = SaltVersion("Osmium" , info=3066)
IRIDIUM = SaltVersion("Iridium" , info=3067)
PLATINUM = SaltVersion("Platinum" , info=3068)
GOLD = SaltVersion("Gold" , info=3069)
MERCURY = SaltVersion("Mercury" , info=3070)
THALLIUM = SaltVersion("Thallium" , info=3071)
LEAD = SaltVersion("Lead" , info=3072)
BISMUTH = SaltVersion("Bismuth" , info=3073)
POLONIUM = SaltVersion("Polonium" , info=3074)
ASTATINE = SaltVersion("Astatine" , info=3075)
RADON = SaltVersion("Radon" , info=3076)
FRANCIUM = SaltVersion("Francium" , info=3077)
RADIUM = SaltVersion("Radium" , info=3078)
ACTINIUM = SaltVersion("Actinium" , info=3079)
THORIUM = SaltVersion("Thorium" , info=3080)
PROTACTINIUM = SaltVersion("Protactinium" , info=3081)
URANIUM = SaltVersion("Uranium" , info=3082)
NEPTUNIUM = SaltVersion("Neptunium" , info=3083)
PLUTONIUM = SaltVersion("Plutonium" , info=3084)
AMERICIUM = SaltVersion("Americium" , info=3085)
CURIUM = SaltVersion("Curium" , info=3086)
BERKELIUM = SaltVersion("Berkelium" , info=3087)
CALIFORNIUM = SaltVersion("Californium" , info=3088)
EINSTEINIUM = SaltVersion("Einsteinium" , info=3089)
FERMIUM = SaltVersion("Fermium" , info=3090)
MENDELEVIUM = SaltVersion("Mendelevium" , info=3091)
NOBELIUM = SaltVersion("Nobelium" , info=3092)
LAWRENCIUM = SaltVersion("Lawrencium" , info=3093)
RUTHERFORDIUM = SaltVersion("Rutherfordium", info=3094)
DUBNIUM = SaltVersion("Dubnium" , info=3095)
SEABORGIUM = SaltVersion("Seaborgium" , info=3096)
BOHRIUM = SaltVersion("Bohrium" , info=3097)
HASSIUM = SaltVersion("Hassium" , info=3098)
MEITNERIUM = SaltVersion("Meitnerium" , info=3099)
DARMSTADTIUM = SaltVersion("Darmstadtium" , info=3100)
ROENTGENIUM = SaltVersion("Roentgenium" , info=3101)
COPERNICIUM = SaltVersion("Copernicium" , info=3102)
NIHONIUM = SaltVersion("Nihonium" , info=3103)
FLEROVIUM = SaltVersion("Flerovium" , info=3104)
MOSCOVIUM = SaltVersion("Moscovium" , info=3105)
LIVERMORIUM = SaltVersion("Livermorium" , info=3106)
TENNESSINE = SaltVersion("Tennessine" , info=3107)
OGANESSON = SaltVersion("Oganesson" , info=3108)
# <---- Please refrain from fixing whitespace -----------------------------------
# The idea is to keep this readable.
# -------------------------------------------------------------------------------
# pylint: enable=bad-whitespace,multiple-spaces-before-operator
# fmt: on
@classmethod
def versions(cls):
if not cls._sorted_versions:
cls._sorted_versions = sorted(
[getattr(cls, name) for name in dir(cls) if name.isupper()],
key=operator.attrgetter("info"),
)
return cls._sorted_versions
@classmethod
def current_release(cls):
if cls._current_release is None:
for version in cls.versions():
if version.released is False:
cls._current_release = version
break
return cls._current_release
@classmethod
def next_release(cls):
if cls._next_release is None:
next_release_ahead = False
for version in cls.versions():
if next_release_ahead:
cls._next_release = version
break
if version == cls.current_release():
next_release_ahead = True
return cls._next_release
@classmethod
def previous_release(cls):
if cls._previous_release is None:
previous = None
for version in cls.versions():
if version == cls.current_release():
break
previous = version
cls._previous_release = previous
return cls._previous_release
class SaltStackVersion:
"""
Handle SaltStack versions class.
@ -67,145 +264,7 @@ class SaltStackVersion:
git_sha_regex = re.compile(git_sha_regex)
# Salt versions after 0.17.0 will be numbered like:
# <4-digit-year>.<month>.<bugfix>
#
# Since the actual version numbers will only be know on release dates, the
# periodic table element names will be what's going to be used to name
# versions and to be able to mention them.
NAMES = {
# Let's keep at least 3 version names uncommented counting from the
# latest release so we can map deprecation warnings to versions.
# pylint: disable=E8203
# ----- Please refrain from fixing PEP-8 E203 and E265 ----->
# The idea is to keep this readable.
# -----------------------------------------------------------
# fmt: off
"Hydrogen" : (2014, 1),
"Helium" : (2014, 7),
"Lithium" : (2015, 5),
"Beryllium" : (2015, 8),
"Boron" : (2016, 3),
"Carbon" : (2016, 11),
"Nitrogen" : (2017, 7),
"Oxygen" : (2018, 3),
"Fluorine" : (2019, 2),
"Neon" : (3000,),
"Sodium" : (3001,),
"Magnesium" : (3002,),
"Aluminium" : (3003,),
"Silicon" : (3004,),
"Phosphorus" : (3005,),
'Sulfur' : (3006,),
'Chlorine' : (3007,),
'Argon' : (3008,),
'Potassium' : (3009,),
'Calcium' : (3010,),
'Scandium' : (3011,),
'Titanium' : (3012,),
'Vanadium' : (3013,),
'Chromium' : (3014,),
'Manganese' : (3015,),
"Iron" : (3016,),
"Cobalt" : (3017,),
"Nickel" : (3018,),
"Copper" : (3019,),
"Zinc" : (3020,),
"Gallium" : (3021,),
"Germanium" : (3022,),
"Arsenic" : (3023,),
"Selenium" : (3024,),
"Bromine" : (3025,),
"Krypton" : (3026,),
"Rubidium" : (3027,),
"Strontium" : (3028,),
"Yttrium" : (3029,),
"Zirconium" : (3030,),
"Niobium" : (3031,),
"Molybdenum" : (3032,),
"Technetium" : (3033,),
"Ruthenium" : (3034,),
"Rhodium" : (3035,),
"Palladium" : (3036,),
"Silver" : (3037,),
"Cadmium" : (3038,),
"Indium" : (3039,),
"Tin" : (3040,),
"Antimony" : (3041,),
"Tellurium" : (3042,),
"Iodine" : (3043,),
"Xenon" : (3044,),
"Cesium" : (3045,),
"Barium" : (3046,),
"Lanthanum" : (3047,),
"Cerium" : (3048,),
"Praseodymium" : (3049,),
"Neodymium" : (3050,),
"Promethium" : (3051,),
"Samarium" : (3052,),
"Europium" : (3053,),
"Gadolinium" : (3054,),
"Terbium" : (3055,),
"Dysprosium" : (3056,),
"Holmium" : (3057,),
"Erbium" : (3058,),
"Thulium" : (3059,),
"Ytterbium" : (3060,),
"Lutetium" : (3061,),
"Hafnium" : (3062,),
"Tantalum" : (3063,),
"Tungsten" : (3064,),
"Rhenium" : (3065,),
"Osmium" : (3066,),
"Iridium" : (3067,),
"Platinum" : (3068,),
"Gold" : (3069,),
"Mercury" : (3070,),
"Thallium" : (3071,),
"Lead" : (3072,),
"Bismuth" : (3073,),
"Polonium" : (3074,),
"Astatine" : (3075,),
"Radon" : (3076,),
"Francium" : (3077,),
"Radium" : (3078,),
"Actinium" : (3079,),
"Thorium" : (3080,),
"Protactinium" : (3081,),
"Uranium" : (3082,),
"Neptunium" : (3083,),
"Plutonium" : (3084,),
"Americium" : (3085,),
"Curium" : (3086,),
"Berkelium" : (3087,),
"Californium" : (3088,),
"Einsteinium" : (3089,),
"Fermium" : (3090,),
"Mendelevium" : (3091,),
"Nobelium" : (3092,),
"Lawrencium" : (3093,),
"Rutherfordium": (3094,),
"Dubnium" : (3095,),
"Seaborgium" : (3096,),
"Bohrium" : (3097,),
"Hassium" : (3098,),
"Meitnerium" : (3099,),
"Darmstadtium" : (3100,),
"Roentgenium" : (3101,),
"Copernicium" : (3102,),
"Nihonium" : (3103,),
"Flerovium" : (3104,),
"Moscovium" : (3105,),
"Livermorium" : (3106,),
"Tennessine" : (3107,),
"Oganesson" : (3108,),
# pylint: disable=E8265
# <---- Please refrain from fixing PEP-8 E203 and E265 ------
# pylint: enable=E8203,E8265
# fmt: on
}
NAMES = {v.name: v.info for v in SaltVersionsInfo.versions()}
LNAMES = {k.lower(): v for (k, v) in iter(NAMES.items())}
VNAMES = {v: k for (k, v) in iter(NAMES.items())}
RMATCH = {v[:2]: k for (k, v) in iter(NAMES.items())}
@ -265,9 +324,11 @@ class SaltStackVersion:
self.mbugfix = mbugfix
self.pre_type = pre_type
self.pre_num = pre_num
self.name = self.VNAMES.get((major, minor), None)
if self.new_version(major):
self.name = self.VNAMES.get((major,), None)
vnames_key = (major,)
else:
vnames_key = (major, minor)
self.name = self.VNAMES.get(vnames_key)
self.noc = noc
self.sha = sha
@ -301,31 +362,23 @@ class SaltStackVersion:
@classmethod
def from_last_named_version(cls):
return cls.from_name(
cls.VNAMES[
max(
[
version_info
for version_info in cls.VNAMES
if version_info[0] < (VERSION_LIMIT)
]
)
]
import salt.utils.versions
salt.utils.versions.warn_until(
SaltVersionsInfo.SULFUR.name,
"The use of SaltStackVersion.from_last_named_version() is "
"deprecated and set to be removed in {version}. Please use "
"SaltStackVersion.current_release() instead.",
)
return cls.current_release()
@classmethod
def current_release(cls):
return cls(*SaltVersionsInfo.current_release().info)
@classmethod
def next_release(cls):
return cls.from_name(
cls.VNAMES[
min(
[
version_info
for version_info in cls.VNAMES
if version_info > __saltstack_version__.info
]
)
]
)
return cls(*SaltVersionsInfo.next_release().info)
@property
def sse(self):
@ -512,7 +565,7 @@ class SaltStackVersion:
#
# There's no need to do anything here. The last released codename will be picked up
# --------------------------------------------------------------------------------------------------------------------
__saltstack_version__ = SaltStackVersion.from_last_named_version()
__saltstack_version__ = SaltStackVersion.current_release()
# <---- Hardcoded Salt Version Information ---------------------------------------------------------------------------
@ -613,6 +666,12 @@ def __get_version(saltstack_version):
# Get additional version information if available
__saltstack_version__ = __get_version(__saltstack_version__)
if __saltstack_version__.name:
# Set SaltVersionsInfo._current_release to avoid lookups when finding previous and next releases
SaltVersionsInfo._current_release = getattr(
SaltVersionsInfo, __saltstack_version__.name.upper()
)
# This function has executed once, we're done with it. Delete it!
del __get_version
# <---- Dynamic/Runtime Salt Version Information ---------------------------------------------------------------------

View file

@ -8,7 +8,12 @@ import re
import pytest
import salt.version
from salt.version import SaltStackVersion, system_information, versions_report
from salt.version import (
SaltStackVersion,
SaltVersionsInfo,
system_information,
versions_report,
)
from tests.support.mock import MagicMock, patch
STRIP_INITIAL_NON_NUMBERS_REGEX = re.compile(r"(?:[^\d]+)?(?P<vs>.*)")
@ -378,6 +383,28 @@ def test_version_repr(version_tuple, expected):
assert repr(SaltStackVersion(*version_tuple)) == expected
def test_previous_and_next_releases():
with patch.multiple(
SaltVersionsInfo,
_previous_release=None,
_next_release=None,
_current_release=SaltVersionsInfo.CALIFORNIUM,
):
assert SaltVersionsInfo.current_release() == SaltVersionsInfo.CALIFORNIUM
assert SaltVersionsInfo.next_release() == SaltVersionsInfo.EINSTEINIUM
assert SaltVersionsInfo.previous_release() == SaltVersionsInfo.BERKELIUM
with patch.multiple(
SaltVersionsInfo,
_previous_release=None,
_next_release=None,
_current_release=SaltVersionsInfo.NEPTUNIUM,
):
assert SaltVersionsInfo.current_release() == SaltVersionsInfo.NEPTUNIUM
assert SaltVersionsInfo.next_release() == SaltVersionsInfo.PLUTONIUM
assert SaltVersionsInfo.previous_release() == SaltVersionsInfo.URANIUM
@pytest.mark.skip_unless_on_linux
def test_system_version_linux():
"""