diff options
Diffstat (limited to 'utils/bump_version.py')
-rwxr-xr-x | utils/bump_version.py | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/utils/bump_version.py b/utils/bump_version.py index 6e50755..7275cca 100755 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -1,19 +1,29 @@ #!/usr/bin/env python3 +from __future__ import annotations + import argparse -import os import re import sys import time from contextlib import contextmanager +from pathlib import Path +from typing import TYPE_CHECKING + +from typing_extensions import TypeAlias -script_dir = os.path.dirname(__file__) -package_dir = os.path.abspath(os.path.join(script_dir, '..')) +if TYPE_CHECKING: + from collections.abc import Iterator, Sequence + +script_dir = Path(__file__).parent +package_dir = script_dir.parent RELEASE_TYPE = {'a': 'alpha', 'b': 'beta'} +VersionInfo: TypeAlias = tuple[int, int, int, str, int] + -def stringify_version(version_info, in_develop=True): +def stringify_version(version_info: VersionInfo, in_develop: bool = True) -> str: version = '.'.join(str(v) for v in version_info[:3]) if not in_develop and version_info[3] != 'final': version += version_info[3][0] + str(version_info[4]) @@ -21,7 +31,7 @@ def stringify_version(version_info, in_develop=True): return version -def bump_version(path, version_info, in_develop=True): +def bump_version(path: Path, version_info: VersionInfo, in_develop: bool = True) -> None: version = stringify_version(version_info, in_develop) with open(path, encoding='utf-8') as f: @@ -42,7 +52,7 @@ def bump_version(path, version_info, in_develop=True): f.write('\n'.join(lines) + '\n') -def parse_version(version): +def parse_version(version: str) -> VersionInfo: matched = re.search(r'^(\d+)\.(\d+)$', version) if matched: major, minor = matched.groups() @@ -73,7 +83,7 @@ class Skip(Exception): @contextmanager -def processing(message): +def processing(message: str) -> Iterator[None]: try: print(message + ' ... ', end='') yield @@ -87,11 +97,11 @@ def processing(message): class Changes: - def __init__(self, path): + def __init__(self, path: Path) -> None: self.path = path self.fetch_version() - def fetch_version(self): + def fetch_version(self) -> None: with open(self.path, encoding='utf-8') as f: version = f.readline().strip() matched = re.search(r'^Release (.*) \((.*)\)$', version) @@ -105,7 +115,7 @@ class Changes: else: self.in_development = False - def finalize_release_date(self): + def finalize_release_date(self) -> None: release_date = time.strftime('%b %d, %Y') heading = f'Release {self.version} (released {release_date})' @@ -120,16 +130,18 @@ class Changes: f.write('=' * len(heading) + '\n') f.write(self.filter_empty_sections(body)) - def add_release(self, version_info): + def add_release(self, version_info: VersionInfo) -> None: if version_info[-2:] in (('beta', 0), ('final', 0)): version = stringify_version(version_info) else: reltype = version_info[3] - version = (f'{stringify_version(version_info)} ' - f'{RELEASE_TYPE.get(reltype, reltype)}{version_info[4] or ""}') + version = ( + f'{stringify_version(version_info)} ' + f'{RELEASE_TYPE.get(reltype, reltype)}{version_info[4] or ""}' + ) heading = 'Release %s (in development)' % version - with open(os.path.join(script_dir, 'CHANGES_template'), encoding='utf-8') as f: + with open(script_dir / 'CHANGES_template.rst', encoding='utf-8') as f: f.readline() # skip first two lines f.readline() tmpl = f.read() @@ -145,11 +157,11 @@ class Changes: f.write('\n') f.write(body) - def filter_empty_sections(self, body): - return re.sub('^\n.+\n-{3,}\n+(?=\n.+\n[-=]{3,}\n)', '', body, flags=re.M) + def filter_empty_sections(self, body: str) -> str: + return re.sub('^\n.+\n-{3,}\n+(?=\n.+\n[-=]{3,}\n)', '', body, flags=re.MULTILINE) -def parse_options(argv): +def parse_options(argv: Sequence[str]) -> argparse.Namespace: parser = argparse.ArgumentParser() parser.add_argument('version', help='A version number (cf. 1.6b0)') parser.add_argument('--in-develop', action='store_true') @@ -158,15 +170,16 @@ def parse_options(argv): return options -def main(): +def main() -> None: options = parse_options(sys.argv[1:]) - with processing("Rewriting sphinx/__init__.py"): - bump_version(os.path.join(package_dir, 'sphinx/__init__.py'), - options.version, options.in_develop) + with processing('Rewriting sphinx/__init__.py'): + bump_version( + package_dir / 'sphinx' / '__init__.py', options.version, options.in_develop + ) with processing('Rewriting CHANGES'): - changes = Changes(os.path.join(package_dir, 'CHANGES')) + changes = Changes(package_dir / 'CHANGES.rst') if changes.version_info == options.version: if changes.in_development: changes.finalize_release_date() |