Simon Clematide
feat: release v1.0.0 with restrained interface and versioning
1c44eff
Raw History Blame Contribute Delete
1.88 kB
#!/usr/bin/env python3
"""Prepare an explicit release by updating application version metadata."""
import argparse
from datetime import datetime
from pathlib import Path
import re
from zoneinfo import ZoneInfo
VERSION_FILE = Path(__file__).resolve().parents[1] / "core" / "version.py"
def bump_version(part="patch", *, version_file=VERSION_FILE, release_date=None):
"""Increment a semantic version and update its date; return the new version."""
if part not in {"major", "minor", "patch"}:
raise ValueError("Choose major, minor, or patch.")
content = version_file.read_text(encoding="utf-8")
match = re.search(r'^__version__ = "(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)"$',
content, re.MULTILINE)
if not match or not re.search(r'^__release_date__ = "\d{4}-\d{2}-\d{2}"$', content, re.MULTILINE):
raise ValueError("Expected semantic version and release date in the version file.")
major, minor, patch = map(int, match.groups())
if part == "major":
major, minor, patch = major + 1, 0, 0
elif part == "minor":
minor, patch = minor + 1, 0
else:
patch += 1
version = f"{major}.{minor}.{patch}"
date = release_date or datetime.now(ZoneInfo("Europe/Zurich")).date()
content = content[:match.start()] + f'__version__ = "{version}"' + content[match.end():]
content = re.sub(r'^__release_date__ = ".*"$',
f'__release_date__ = "{date.isoformat()}"', content, flags=re.MULTILINE)
version_file.write_text(content, encoding="utf-8")
return version
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("part", choices=("major", "minor", "patch"), nargs="?", default="patch")
args = parser.parse_args()
print(f"Prepared version {bump_version(args.part)}")
if __name__ == "__main__":
main()