Module materialize.mz_version

Version types

Expand source code Browse git
# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.

"""Version types"""

from __future__ import annotations

import json
import subprocess
from typing import TypeVar

try:
    from semver.version import Version
except ImportError:
    from semver import VersionInfo as Version  # type: ignore

T = TypeVar("T", bound="TypedVersionBase")


class TypedVersionBase(Version):
    """Typed version, can be parsed from version string"""

    @classmethod
    def get_prefix(cls) -> str:
        raise NotImplementedError(f"Not implemented in {cls}")

    @classmethod
    def create(
        cls: type[T], major: int, minor: int, patch: int, prerelease: str | None = None
    ) -> T:
        prerelease_suffix = f"-{prerelease}" if prerelease is not None else ""
        return cls.parse(
            f"{cls.get_prefix()}{major}.{minor}.{patch}{prerelease_suffix}"
        )

    @classmethod
    def parse_without_prefix(
        cls: type[T], version_without_prefix: str, drop_dev_suffix: bool = False
    ) -> T:
        version = f"{cls.get_prefix()}{version_without_prefix}"
        return cls.parse(version, drop_dev_suffix=drop_dev_suffix)

    @classmethod
    def parse(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
        """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
        expected_prefix = cls.get_prefix()
        if not version.startswith(expected_prefix):
            raise ValueError(
                f"Invalid version string '{version}', expected prefix '{expected_prefix}'"
            )
        version = version.removeprefix(expected_prefix)
        if " " in version:
            version, git_hash = version.split(" ")
            if not git_hash[0] == "(" or not git_hash[-1] == ")":
                raise ValueError(f"Invalid mz version string: {version}")
            # Hash ignored

        if drop_dev_suffix:
            version = version.replace("-dev", "")

        return super().parse(version)

    @classmethod
    def try_parse(
        cls: type[T], version: str, drop_dev_suffix: bool = False
    ) -> T | None:
        """Parses a version string but returns empty if that fails"""
        try:
            return cls.parse(version, drop_dev_suffix=drop_dev_suffix)
        except ValueError:
            return None

    @classmethod
    def is_valid_version_string(cls, version: str) -> bool:
        return cls.try_parse(version) is not None

    def str_without_prefix(self) -> str:
        return super().__str__()

    def __str__(self) -> str:
        return f"{self.get_prefix()}{self.str_without_prefix()}"


class MzVersion(TypedVersionBase):
    """Version of Materialize, can be parsed from version string, SQL, cargo"""

    @classmethod
    def get_prefix(cls) -> str:
        return "v"

    @classmethod
    def parse_mz(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
        """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
        return cls.parse(version=version, drop_dev_suffix=drop_dev_suffix)

    @classmethod
    def parse_cargo(cls) -> MzVersion:
        """Uses the cargo mz-environmentd package info to get the version of current source code state"""
        metadata = json.loads(
            subprocess.check_output(
                ["cargo", "metadata", "--no-deps", "--format-version=1"]
            )
        )
        for package in metadata["packages"]:
            if package["name"] == "mz-environmentd":
                return cls.parse_without_prefix(package["version"])
        else:
            raise ValueError("No mz-environmentd version found in cargo metadata")


class MzCliVersion(TypedVersionBase):
    """Version of Materialize APT"""

    @classmethod
    def get_prefix(cls) -> str:
        return "mz-v"


class MzLspServerVersion(TypedVersionBase):
    """Version of Materialize LSP Server"""

    @classmethod
    def get_prefix(cls) -> str:
        return "mz-lsp-server-v"

Classes

class MzCliVersion (major: , minor:  = 0, patch:  = 0, prerelease: Union[str, bytes, int, ForwardRef(None)] = None, build: Union[str, bytes, int, ForwardRef(None)] = None)

Version of Materialize APT

Expand source code Browse git
class MzCliVersion(TypedVersionBase):
    """Version of Materialize APT"""

    @classmethod
    def get_prefix(cls) -> str:
        return "mz-v"

Ancestors

Static methods

def get_prefix() ‑> str
Expand source code Browse git
@classmethod
def get_prefix(cls) -> str:
    return "mz-v"

Inherited members

class MzLspServerVersion (major: , minor:  = 0, patch:  = 0, prerelease: Union[str, bytes, int, ForwardRef(None)] = None, build: Union[str, bytes, int, ForwardRef(None)] = None)

Version of Materialize LSP Server

Expand source code Browse git
class MzLspServerVersion(TypedVersionBase):
    """Version of Materialize LSP Server"""

    @classmethod
    def get_prefix(cls) -> str:
        return "mz-lsp-server-v"

Ancestors

Static methods

def get_prefix() ‑> str
Expand source code Browse git
@classmethod
def get_prefix(cls) -> str:
    return "mz-lsp-server-v"

Inherited members

class MzVersion (major: , minor:  = 0, patch:  = 0, prerelease: Union[str, bytes, int, ForwardRef(None)] = None, build: Union[str, bytes, int, ForwardRef(None)] = None)

Version of Materialize, can be parsed from version string, SQL, cargo

Expand source code Browse git
class MzVersion(TypedVersionBase):
    """Version of Materialize, can be parsed from version string, SQL, cargo"""

    @classmethod
    def get_prefix(cls) -> str:
        return "v"

    @classmethod
    def parse_mz(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
        """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
        return cls.parse(version=version, drop_dev_suffix=drop_dev_suffix)

    @classmethod
    def parse_cargo(cls) -> MzVersion:
        """Uses the cargo mz-environmentd package info to get the version of current source code state"""
        metadata = json.loads(
            subprocess.check_output(
                ["cargo", "metadata", "--no-deps", "--format-version=1"]
            )
        )
        for package in metadata["packages"]:
            if package["name"] == "mz-environmentd":
                return cls.parse_without_prefix(package["version"])
        else:
            raise ValueError("No mz-environmentd version found in cargo metadata")

Ancestors

Static methods

def get_prefix() ‑> str
Expand source code Browse git
@classmethod
def get_prefix(cls) -> str:
    return "v"
def parse_cargo() ‑> MzVersion

Uses the cargo mz-environmentd package info to get the version of current source code state

Expand source code Browse git
@classmethod
def parse_cargo(cls) -> MzVersion:
    """Uses the cargo mz-environmentd package info to get the version of current source code state"""
    metadata = json.loads(
        subprocess.check_output(
            ["cargo", "metadata", "--no-deps", "--format-version=1"]
        )
    )
    for package in metadata["packages"]:
        if package["name"] == "mz-environmentd":
            return cls.parse_without_prefix(package["version"])
    else:
        raise ValueError("No mz-environmentd version found in cargo metadata")
def parse_mz(version: str, drop_dev_suffix: bool = False) ‑> ~T

Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)

Expand source code Browse git
@classmethod
def parse_mz(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
    """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
    return cls.parse(version=version, drop_dev_suffix=drop_dev_suffix)

Inherited members

class TypedVersionBase (major: , minor:  = 0, patch:  = 0, prerelease: Union[str, bytes, int, ForwardRef(None)] = None, build: Union[str, bytes, int, ForwardRef(None)] = None)

Typed version, can be parsed from version string

Expand source code Browse git
class TypedVersionBase(Version):
    """Typed version, can be parsed from version string"""

    @classmethod
    def get_prefix(cls) -> str:
        raise NotImplementedError(f"Not implemented in {cls}")

    @classmethod
    def create(
        cls: type[T], major: int, minor: int, patch: int, prerelease: str | None = None
    ) -> T:
        prerelease_suffix = f"-{prerelease}" if prerelease is not None else ""
        return cls.parse(
            f"{cls.get_prefix()}{major}.{minor}.{patch}{prerelease_suffix}"
        )

    @classmethod
    def parse_without_prefix(
        cls: type[T], version_without_prefix: str, drop_dev_suffix: bool = False
    ) -> T:
        version = f"{cls.get_prefix()}{version_without_prefix}"
        return cls.parse(version, drop_dev_suffix=drop_dev_suffix)

    @classmethod
    def parse(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
        """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
        expected_prefix = cls.get_prefix()
        if not version.startswith(expected_prefix):
            raise ValueError(
                f"Invalid version string '{version}', expected prefix '{expected_prefix}'"
            )
        version = version.removeprefix(expected_prefix)
        if " " in version:
            version, git_hash = version.split(" ")
            if not git_hash[0] == "(" or not git_hash[-1] == ")":
                raise ValueError(f"Invalid mz version string: {version}")
            # Hash ignored

        if drop_dev_suffix:
            version = version.replace("-dev", "")

        return super().parse(version)

    @classmethod
    def try_parse(
        cls: type[T], version: str, drop_dev_suffix: bool = False
    ) -> T | None:
        """Parses a version string but returns empty if that fails"""
        try:
            return cls.parse(version, drop_dev_suffix=drop_dev_suffix)
        except ValueError:
            return None

    @classmethod
    def is_valid_version_string(cls, version: str) -> bool:
        return cls.try_parse(version) is not None

    def str_without_prefix(self) -> str:
        return super().__str__()

    def __str__(self) -> str:
        return f"{self.get_prefix()}{self.str_without_prefix()}"

Ancestors

  • semver.version.Version

Subclasses

Static methods

def create(major: int, minor: int, patch: int, prerelease: str | None = None) ‑> ~T
Expand source code Browse git
@classmethod
def create(
    cls: type[T], major: int, minor: int, patch: int, prerelease: str | None = None
) -> T:
    prerelease_suffix = f"-{prerelease}" if prerelease is not None else ""
    return cls.parse(
        f"{cls.get_prefix()}{major}.{minor}.{patch}{prerelease_suffix}"
    )
def get_prefix() ‑> str
Expand source code Browse git
@classmethod
def get_prefix(cls) -> str:
    raise NotImplementedError(f"Not implemented in {cls}")
def is_valid_version_string(version: str) ‑> bool
Expand source code Browse git
@classmethod
def is_valid_version_string(cls, version: str) -> bool:
    return cls.try_parse(version) is not None
def parse(version: str, drop_dev_suffix: bool = False) ‑> ~T

Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)

Expand source code Browse git
@classmethod
def parse(cls: type[T], version: str, drop_dev_suffix: bool = False) -> T:
    """Parses a version string with prefix, for example: v0.45.0-dev (f01773cb1)"""
    expected_prefix = cls.get_prefix()
    if not version.startswith(expected_prefix):
        raise ValueError(
            f"Invalid version string '{version}', expected prefix '{expected_prefix}'"
        )
    version = version.removeprefix(expected_prefix)
    if " " in version:
        version, git_hash = version.split(" ")
        if not git_hash[0] == "(" or not git_hash[-1] == ")":
            raise ValueError(f"Invalid mz version string: {version}")
        # Hash ignored

    if drop_dev_suffix:
        version = version.replace("-dev", "")

    return super().parse(version)
def parse_without_prefix(version_without_prefix: str, drop_dev_suffix: bool = False) ‑> ~T
Expand source code Browse git
@classmethod
def parse_without_prefix(
    cls: type[T], version_without_prefix: str, drop_dev_suffix: bool = False
) -> T:
    version = f"{cls.get_prefix()}{version_without_prefix}"
    return cls.parse(version, drop_dev_suffix=drop_dev_suffix)
def try_parse(version: str, drop_dev_suffix: bool = False) ‑> Optional[~T]

Parses a version string but returns empty if that fails

Expand source code Browse git
@classmethod
def try_parse(
    cls: type[T], version: str, drop_dev_suffix: bool = False
) -> T | None:
    """Parses a version string but returns empty if that fails"""
    try:
        return cls.parse(version, drop_dev_suffix=drop_dev_suffix)
    except ValueError:
        return None

Methods

def str_without_prefix(self) ‑> str
Expand source code Browse git
def str_without_prefix(self) -> str:
    return super().__str__()