Skip to content

Commit 41fa912

Browse files
authored
Add a tool to update release version numbers (#15)
1 parent e101d09 commit 41fa912

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

tools/version.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python
2+
"""A simple script to update the version embedded in the source."""
3+
4+
import argparse
5+
import pathlib
6+
import re
7+
8+
from packaging.version import Version
9+
10+
11+
def main() -> None:
12+
parser = argparse.ArgumentParser(description=__doc__)
13+
parser.add_argument('version', type=Version, help='version number to embed in source files')
14+
args = parser.parse_args()
15+
version: Version = args.version
16+
17+
major_minor_version = f'{version.major}.{version.minor}'
18+
version_info = ', '.join(map(repr, get_version_info(version)))
19+
20+
updates: list[tuple[str, re.Pattern, str | Version]] = [
21+
('doc/source/conf.py', re.compile(r"^(version = ')[^']*(')$", flags=re.MULTILINE), major_minor_version),
22+
('doc/source/conf.py', re.compile(r"^(release = ')[^']*(')$", flags=re.MULTILINE), version),
23+
('setup.py', re.compile(r"^( +version=')[^']*(',)$", flags=re.MULTILINE), version),
24+
('src/c/_cffi_backend.c', re.compile(r'^(#define CFFI_VERSION +")[^"]*(")$', flags=re.MULTILINE), version),
25+
('src/c/test_c.py', re.compile(r'^(assert __version__ == ")[^"]*(", .*)$', flags=re.MULTILINE), version),
26+
('src/cffi/__init__.py', re.compile(r'^(__version__ = ")[^"]*(")$', flags=re.MULTILINE), version),
27+
('src/cffi/__init__.py', re.compile(r'^(__version_info__ = \()[^)]*(\))$', flags=re.MULTILINE), version_info),
28+
('src/cffi/_embedding.h', re.compile(r'^( +"\\ncompiled with cffi version: )[^"]*(")$', flags=re.MULTILINE), version),
29+
]
30+
31+
repo_root = pathlib.Path(__file__).parent.parent
32+
33+
for relative_path, pattern, replacement in updates:
34+
path = repo_root / relative_path
35+
original_content = path.read_text()
36+
37+
if not pattern.search(original_content):
38+
raise RuntimeError(f'{relative_path}: no match found for pattern: {pattern.pattern}')
39+
40+
updated_content = pattern.sub(rf'\g<1>{replacement}\g<2>', original_content)
41+
42+
if updated_content == original_content:
43+
print(f'{relative_path}: unchanged')
44+
else:
45+
path.write_text(updated_content)
46+
print(f'{relative_path}: updated')
47+
48+
49+
def get_version_info(version: Version) -> tuple:
50+
"""Return a tuple representing the given version."""
51+
version_info = list(version.release)
52+
53+
if version.pre is not None:
54+
version_info.append(''.join(map(str, version.pre)))
55+
56+
if version.post is not None:
57+
version_info.append(f'post{version.post}')
58+
59+
if version.dev is not None:
60+
version_info.append(f'dev{version.dev}')
61+
62+
if version.local is not None:
63+
version_info.append(f'+{version.local}')
64+
65+
return tuple(version_info)
66+
67+
68+
if __name__ == '__main__':
69+
main()

0 commit comments

Comments
 (0)