Skip to content

Commit

Permalink
fix: move versioning from semver to PyPA spec due to normalization
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelSasser committed Dec 28, 2024
1 parent 170f88f commit dc999e9
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 50 deletions.
49 changes: 48 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ All notable changes to MatrixCtl will be documented in this file.
You can find the issue tracker on
[GitHub](https://github.com/MichaelSasser/matrixctl/issues).

## Unreleased
## 0.12.1-beta.1 - 2024-12-28

### 🏗️ Breaking changes

### ⚙️ Miscellaneous Tasks

Expand Down Expand Up @@ -56,29 +58,74 @@ You can find the issue tracker on
- Update dependency pylint to v3.3.1
- Update dependency tox to v4.20.0
- Update dependency types-setuptools to v75
- Update pypa/gh-action-pypi-publish action to v1.10.3
- Update dependency ruff to v0.6.9
- Update dependency tox to v4.21.2
- Update dependency vulture to v2.13
- Update actions/cache action to v4.1.0
- Update dependency pre-commit to v4
- Update actions/checkout action to v4.2.1
- Update pandoc/core docker tag to v3.5.0
- Update dependency pre-commit to v4.0.1
- Update actions/checkout action to v4.2.1 ([#856](https://github.com/MichaelSasser/matrixctl/issues/856))
- Update actions/checkout action to v4.2.2 ([#857](https://github.com/MichaelSasser/matrixctl/issues/857))
- Update astral-sh/setup-uv action to v5 ([#860](https://github.com/MichaelSasser/matrixctl/issues/860))
- Lock file maintenance ([#861](https://github.com/MichaelSasser/matrixctl/issues/861))

### 🚀 Features

#### Addon

- Add download command

#### Ci

- Add codeql workflow

### 🐛 Bug Fixes

#### Ci

- Replace master/develop branch with main branch
- Rye run sync regardless of cache hit; remove old codeql workflow
- Add `tomli` since it seems to be required for ci to build the docs
- Use a version matrix and let rye pin the python version
- Create `.python-version` before installing rye to avoid multiple toolchains
- Remove `--no-lock` from `rye sync`
- Wrap make for docs in 'uv run'

#### Deps

- Update dependency psycopg to v3.2.1
- Update dependency psycopg to v3.2.2
- Update dependency paramiko to v3.5.0
- Update dependency psycopg to v3.2.3
- Update dependency rich to v13.9.2

#### Docs

- Add docs for the download feature
- Replace master branch with main branch
- Wrap make in 'uv run'

#### Pre-commit

- Ignore all `lock` files

#### Renovate

- Add missing `:`

### 📚 Documentation

#### Changelog

- Make the old changelog available under changelog

#### Readme

- Typo

## 0.12.0 - 2024-06-05

### ⚙️ Miscellaneous Tasks
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,11 @@ If you have any thoughts or questions, you can ask them in the
[discusions](https://github.com/MichaelSasser/matrixctl/discussions) or in the
projects matrix room `#matrixctl:matrix.org`.

## Semantic Versioning and Branching Model
## PyPA Versioning and Branching Model

This Python package uses [SemVer](https://semver.org/) for its release cycle
and follows the
This Python package uses
[PyPA](https://packaging.python.org/en/latest/specifications/) for its release
cycle and follows the
[GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow).

## Contributing
Expand Down
6 changes: 3 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ To use this program you need to have this config file in
.. include:: getting_started/config_file_snippet.rst


Semantic Versioning
^^^^^^^^^^^^^^^^^^^
PyPA Versioning
^^^^^^^^^^^^^^^

.. include:: semantic_versioning.rst
.. include:: pypa_versioning.rst

Indices and tables
==================
Expand Down
3 changes: 3 additions & 0 deletions docs/source/pypa_versioning.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This repository uses
`PyPA <https://packaging.python.org/en/latest/specifications/>`_ for its
release cycle.
8 changes: 0 additions & 8 deletions docs/source/semantic_versioning.rst

This file was deleted.

10 changes: 9 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "matrixctl"
version = "0.12.1-beta.1"
version = "0.12.1b2"
description = "Control, manage, provision and deploy matrix homeservers."
authors = [{ name = "Michael Sasser", email = "[email protected]" }]
maintainers = [{ name = "Michael Sasser", email = "[email protected]" }]
Expand Down Expand Up @@ -40,6 +40,7 @@ dependencies = [
"httpx[http2]>=0.27.2",
"sshtunnel>=0.4.0,<0.5.0",
"rich>=13.8.0,<14.0.0",
"packaging>=24.2",
]

requires-python = ">=3.10,<4.0"
Expand Down Expand Up @@ -277,6 +278,13 @@ sort_by_size = true
[tool.coverage.report]
exclude_also = ["@t.overload", "pragma: no cover"]

# Note: Useful for debugging while testing. When enabled, doctests will fail.
#
# [tool.pytest.ini_options]
# log_cli = true
# log_cli_level = "DEBUG"
# log_cli_format = "%(asctime)s %(name)s:%(lineno)d [%(funcName)s] %(levelname)s %(message)s"
# log_cli_date_format = "%Y-%m-%dT%H:%M:%S"

[tool.git-cliff.changelog]
# DOCS: https://git-cliff.org/docs/configuration
Expand Down
5 changes: 1 addition & 4 deletions src/matrixctl/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@

from sys import version_info

from .package_version import get_version


__version__: str | None = get_version(__name__, __file__)
from matrixctl import __version__


class Error(Exception):
Expand Down
49 changes: 29 additions & 20 deletions src/matrixctl/package_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,26 @@

from __future__ import annotations

import logging
import re
import typing as t

from contextlib import suppress
from pathlib import Path

from packaging import version as pversion


__author__: str = "Michael Sasser"
__email__: str = "[email protected]"

logger = logging.getLogger(__name__)


# semver
VERSION_PATTERN: str = (
r"^\s*version\s*=\s*[\"']\s*"
r"(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)"
r"(?:-(?P<prerelease>"
r"(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)"
r"(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
r"(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?\s*[\"']\s*$"
VERSION_PATTERN: t.Pattern[str] = re.compile(
r"^\s*version\s*=\s*[\"']\s*" + pversion.VERSION_PATTERN + r"\s*[\"']\s*$",
re.VERBOSE | re.IGNORECASE,
)
# Fast approx. for simpel versions


def __from_pyproject(file: Path) -> str | None:
Expand All @@ -67,20 +66,19 @@ def __from_pyproject(file: Path) -> str | None:
If the package is installed, the return value will be ``None``.
"""
logger.debug("Trying to get the version from the file %s.", file)
with suppress(FileNotFoundError), file.open() as fp:
vers: t.Pattern[str] = re.compile(VERSION_PATTERN)
for line in fp:
version: t.Match[str] | None = vers.search(line)
if version is not None:
# semver
version_: t.Match[str] | None = VERSION_PATTERN.search(line)
if version_ is not None:
logger.debug("Found version: %s", version_)
return (
f"{version.group(1)}."
f"{version.group(2) or '0'}."
f"{version.group(3) or '0'}"
f"{f'-{version.group(4)}' if version.group(4) else ''}"
f"{f'+{version.group(5)}' if version.group(5) else ''}"
f"{version_.group(1)}."
f"{version_.group(2) or '0'}."
f"{version_.group(3) or '0'}"
f"{f'-{version_.group(4)}' if version_.group(4) else ''}"
f"{f'+{version_.group(5)}' if version_.group(5) else ''}"
)
# Fast approx.
return None


Expand All @@ -101,8 +99,13 @@ def __from_metadata(name: str) -> str | None:
"""
import importlib.metadata as importlib_metadata # Python >= 3.8

logger.debug(
"Trying to get the version from the metadata of the package %s.", name
)
with suppress(importlib_metadata.PackageNotFoundError):
return importlib_metadata.version(name).strip()
version_: str = importlib_metadata.version(name).strip()
logger.debug("Found version: %s", version_)
return version_
return None


Expand Down Expand Up @@ -156,4 +159,10 @@ def get_version(name: str, file: str | Path) -> str | None:
"""
file_: Path = Path(file).parent.parent / "pyproject.toml"
logger.debug(
"Trying to get the version from either the file %s or the metadata "
"of %s.",
file_,
name,
)
return __from_pyproject(file_) or __from_metadata(name)
2 changes: 2 additions & 0 deletions src/matrixctl/sanitizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,12 @@ def sanitize(
"""
if identifier is None:
logger.debug("The identifier is None.")
return None
with suppress(TypeError, AttributeError):
identifier = str(identifier).strip()
if pattern.match(identifier):
logger.debug("The identifier is valid.")
return t.cast(str, identifier)
logger.error(error_message)
return False
Expand Down
24 changes: 15 additions & 9 deletions tests/test_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,22 @@

from __future__ import annotations

import logging
import re

from matrixctl import __version__
from packaging import version as pversion


logger = logging.getLogger(__name__)


def test_version() -> None:
"""Test, if the version matches SemVer.
"""Test, if the version matches the PyPA specification.
Notes
-----
The regular expression is from `SemVer.org
<https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-
expression-regex-to-check-a-semver-string>`_.
See `PyPA <https://packaging.python.org/en/latest/specifications/>`_ for
more information.
Parameters
----------
Expand All @@ -46,15 +49,18 @@ def test_version() -> None:
None
"""

# Setup
logger.info("Using version pattern %s", pversion.VERSION_PATTERN)

desired = re.compile(
r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\."
r"(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-]"
r"[0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
r"(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$",
r"^\s*" + pversion.VERSION_PATTERN + r"\s*$",
re.VERBOSE | re.IGNORECASE,
)

# Exercise
from matrixctl import __version__

actual = __version__

# Verify
Expand Down
4 changes: 3 additions & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit dc999e9

Please sign in to comment.