rorm 0.8.0

A asynchronous declarative ORM written in pure rust.
import contextlib
import dataclasses
import logging
import re
import subprocess
from argparse import ArgumentParser

LOGGER = logging.getLogger("")


@dataclasses.dataclass
class Crate:
    name: str
    path: str
    dependencies: list[str]


CRATES = {crate.name: crate for crate in [
    Crate(name="rorm", path=".", dependencies=["rorm-db", "rorm-macro", "rorm-declaration"]),
    Crate(name="rorm-db", path="rorm-db", dependencies=["rorm-sql", "rorm-declaration"]),
    Crate(name="rorm-macro", path="rorm-macro", dependencies=["rorm-macro-impl"]),
    Crate(name="rorm-macro-impl", path="rorm-macro-impl", dependencies=[]),
    Crate(name="rorm-sql", path="rorm-sql", dependencies=["rorm-declaration"]),
    Crate(name="rorm-declaration", path="rorm-declaration", dependencies=[]),
]}


def main():
    parser = ArgumentParser()
    parser.add_argument("crate")
    parser.add_argument("version")
    parser.add_argument("-v", "--verbose", action="store_true")
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO if not args.verbose else logging.DEBUG)

    if args.crate not in CRATES:
        LOGGER.error("Unknown crate")
        exit(1)
    crate = CRATES[args.crate]

    current_version = get_version(crate)
    if not check_clean_git(crate) or current_version is None:
        exit(1)

    print(current_version)


def get_version(crate: Crate) -> str | None:
    """
    Determine a crates current version (according to `Cargo.toml`)

    It also checks the existence of a corresponding git tag.

    :param crate: the crate whose version to get
    :return: the version (according to `Cargo.toml`), the corresponding git tag is prefixed with `'v'`
    """
    logger = logging.getLogger(crate.name)

    toml_version_regex = re.compile(rf'\[package]\nname = "{crate.name}"\nversion = "([^"]+)"')

    with contextlib.chdir(crate.path):
        with open("Cargo.toml") as cargo_toml:
            match = toml_version_regex.search(cargo_toml.read())
            if match is None:
                logger.error("Failed to find current version in Cargo.toml")
                return None
            else:
                return match.group(1)


def check_clean_git(crate: Crate) -> bool:
    """Check git to be in a clean state"""
    logger = logging.getLogger(crate.name)

    with contextlib.chdir(crate.path):
        # tag = f"v{version}"
        # if tag not in subprocess.run(["git", "tag"], stdout=subprocess.PIPE).stdout.decode(
        #         "utf-8").splitlines():
        #     logger.error("The current version has not git tag")
        #     return False

        if len(subprocess.run(["git", "status", "--porcelain"], stdout=subprocess.PIPE).stdout) > 0:
            logger.error("The repository contains uncommited changes or files")
            return False

    return True


if __name__ == "__main__":
    main()