summaryrefslogtreecommitdiffstats
path: root/utils/bump_version.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xutils/bump_version.py57
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()