The API has one set of consumers and no outside users, so declaring 1.0.0 with a stability guarantee was premature. Until 1.0.0 any minor bump may reshape the API; the written guarantee starts there. Plugins pin 0.1.0.
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
"""Version of the core library and the compatibility check plugins call."""
|
|
|
|
coreVersion = "0.1.0"
|
|
|
|
|
|
class CoreVersionError(RuntimeError):
|
|
"""Raised when the installed core cannot satisfy a plugin's requirement."""
|
|
|
|
|
|
def parseVersion(text):
|
|
"""Turn "1.2.3" into (1, 2, 3). Missing components count as zero."""
|
|
parts = []
|
|
for chunk in str(text).split("."):
|
|
digits = "".join(character for character in chunk if character.isdigit())
|
|
parts.append(int(digits) if digits else 0)
|
|
while len(parts) < 3:
|
|
parts.append(0)
|
|
return tuple(parts[:3])
|
|
|
|
|
|
def breakingSeries(parts):
|
|
"""The leading components that have to match exactly for compatibility.
|
|
|
|
From 1.0.0 on that is the major component alone. While the major is 0 the
|
|
API is still allowed to change with every minor bump, so 0.1 and 0.2 are
|
|
treated as different series and neither can serve the other.
|
|
"""
|
|
return parts[:2] if parts[0] == 0 else parts[:1]
|
|
|
|
|
|
def satisfies(installed, minimum):
|
|
"""True when `installed` can serve a plugin that asked for `minimum`.
|
|
|
|
Semantic versioning: the breaking component must match exactly and the
|
|
version as a whole must be greater than or equal to the requirement.
|
|
"""
|
|
installedParts = parseVersion(installed)
|
|
minimumParts = parseVersion(minimum)
|
|
if breakingSeries(installedParts) != breakingSeries(minimumParts):
|
|
return False
|
|
return installedParts >= minimumParts
|
|
|
|
|
|
def requireCore(minimumVersion):
|
|
"""Assert that this core is new enough for the calling plugin.
|
|
|
|
Call it once, at import time, before touching any other core symbol.
|
|
Nemo logs the resulting exception and skips the extension, which is the
|
|
behaviour we want: a plugin built against a newer core must not load
|
|
half-working.
|
|
"""
|
|
if not satisfies(coreVersion, minimumVersion):
|
|
raise CoreVersionError(
|
|
"nemo-repo-core %s cannot satisfy the required version %s; "
|
|
"install a core compatible with %s" % (coreVersion, minimumVersion, minimumVersion)
|
|
)
|
|
return coreVersion
|