Skip to content

Commit 503f758

Browse files
hpkfftwjakob
authored andcommitted
Add python script src/version.py (#1014)
1 parent 4d62d9c commit 503f758

File tree

4 files changed

+114
-15
lines changed

4 files changed

+114
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ if(NB_CREATE_INSTALL_RULES AND NOT CMAKE_SKIP_INSTALL_RULES)
9393
DIRECTORY src/
9494
DESTINATION "${NB_INSTALL_MODULE_DIR}"
9595
FILES_MATCHING PATTERN "*\.py"
96+
PATTERN "version.py" EXCLUDE
9697
)
9798

9899
if(NB_USE_SUBMODULE_DEPS)

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Version TBD (unreleased)
6868
<https://github.com/wjakob/nanobind/pull/1012>`__
6969

7070
- Miscellaneous fixes and improvements (PRs
71+
`#1014 <https://github.com/wjakob/nanobind/pull/1014>`__,
7172
`#1005 <https://github.com/wjakob/nanobind/pull/1005>`__,
7273
`#1004 <https://github.com/wjakob/nanobind/pull/1004>`__,
7374
`#990 <https://github.com/wjakob/nanobind/pull/990>`__,

docs/release.rst

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ How to make a new release?
44
1. Ensure that the full version of nanobind is checked out (including the
55
``robin_map`` submodule)
66

7-
2. Update version in ``src/__init__.py``, ``include/nanobind/nanobind.h``,
8-
and ``pyproject.toml``:
9-
10-
Also:
11-
12-
- Remove ``dev1`` suffix from ``X.Y.Zdev1`` in ``src/__init__.py`` and
13-
``pyproject.toml``.
14-
15-
- Set ``NB_VERSION_DEV`` to ``0`` in ``include/nanobind/nanobind.h``.
7+
2. Run ``python src/version.py -w X.Y.Z``
168

179
3. Add release date to ``docs/changelog.rst``.
1810

@@ -30,9 +22,4 @@ How to make a new release?
3022

3123
9. Upload: ``twine upload --repository nanobind <filename>``
3224

33-
10. Update version in ``src/__init__.py`` and ``include/nanobind/nanobind.h``:
34-
35-
- Append ``dev1`` suffix from ``X.Y.Zdev1`` in ``src/__init__.py`` and
36-
``pyproject.toml``.
37-
38-
- Set ``NB_VERSION_DEV`` to ``1`` in ``include/nanobind/nanobind.h``
25+
10. Run ``python src/version.py -w X.Y.Zdev1``

src/version.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env python3
2+
3+
# With no command line flag, this prints the nanobind version.
4+
# With flags -w semver, this writes the new version to where it's needed.
5+
6+
import os
7+
import re
8+
import sys
9+
10+
# Parse the header file <nanobind/nanobind.h> and print the version.
11+
def get_version(root):
12+
major = ''
13+
minor = ''
14+
patch = ''
15+
dev = ''
16+
with open(os.path.join(root, "include/nanobind/nanobind.h"), 'r') as f:
17+
for line in f:
18+
if m := re.match(r'#define NB_VERSION_(.+)', line):
19+
if m_major := re.match(r'MAJOR\s+([0-9]+)', m.group(1)):
20+
major = m_major.group(1)
21+
if m_minor := re.match(r'MINOR\s+([0-9]+)', m.group(1)):
22+
minor = m_minor.group(1)
23+
if m_patch := re.match(r'PATCH\s+([0-9]+)', m.group(1)):
24+
patch = m_patch.group(1)
25+
if m_dev := re.match(r'DEV\s+([0-9]+)', m.group(1)):
26+
dev = m_dev.group(1)
27+
28+
version_core = '.'.join([major, minor, patch])
29+
if int(dev) > 0:
30+
print(version_core, '-dev', dev, sep='')
31+
else:
32+
print(version_core)
33+
34+
# Write the semantic version to nanobind.h, pyproject.toml, and __init__.py.
35+
# The semver string must be either 'X.Y.Z' or 'X.Y.Z-devN', where X, Y, Z are
36+
# non-negative integers and N is a positive integer.
37+
def write_version(root, semver):
38+
major = 0
39+
minor = 0
40+
patch = 0
41+
dev = 0
42+
try:
43+
beginning, middle, end = semver.split('.', maxsplit=2)
44+
major = int(beginning)
45+
minor = int(middle)
46+
if m := re.match(r'([0-9]+)-dev([1-9][0-9]*)', end):
47+
patch = int(m.group(1))
48+
dev = int(m.group(2))
49+
else:
50+
patch = int(end)
51+
except:
52+
print("Invalid version: '", semver, "'", sep='', file=sys.stderr)
53+
print("Valid examples: '1.2.3' or '1.2.3-dev4'", file=sys.stderr)
54+
return
55+
56+
# Write to nanobind.h
57+
with open(os.path.join(root, "include/nanobind/nanobind.h"), "r+") as f:
58+
contents = f.read()
59+
contents = re.sub(r'#define NB_VERSION_MAJOR\s+[0-9]+',
60+
r'#define NB_VERSION_MAJOR ' + str(major),
61+
contents, count=1)
62+
contents = re.sub(r'#define NB_VERSION_MINOR\s+[0-9]+',
63+
r'#define NB_VERSION_MINOR ' + str(minor),
64+
contents, count=1)
65+
contents = re.sub(r'#define NB_VERSION_PATCH\s+[0-9]+',
66+
r'#define NB_VERSION_PATCH ' + str(patch),
67+
contents, count=1)
68+
contents = re.sub(r'#define NB_VERSION_DEV\s+[0-9]+',
69+
r'#define NB_VERSION_DEV ' + str(dev),
70+
contents, count=1)
71+
f.seek(0)
72+
f.truncate()
73+
f.write(contents)
74+
75+
# Write to pyproject.toml
76+
with open(os.path.join(root, "pyproject.toml"), "r+") as f:
77+
contents = f.read()
78+
contents = re.sub(r'version\s+=\s+"[^"]+"',
79+
r'version = "' + semver + '"',
80+
contents, count=1)
81+
f.seek(0)
82+
f.truncate()
83+
f.write(contents)
84+
85+
# Write to __init__.py
86+
with open(os.path.join(root, "src/__init__.py"), "r+") as f:
87+
contents = f.read()
88+
contents = re.sub(r'__version__\s+=\s+"[^"]+"',
89+
r'__version__ = "' + semver + '"',
90+
contents, count=1)
91+
f.seek(0)
92+
f.truncate()
93+
f.write(contents)
94+
95+
96+
def main():
97+
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
98+
if len(sys.argv) == 1:
99+
get_version(root)
100+
elif len(sys.argv) == 3 and sys.argv[1] == '-w':
101+
write_version(root, sys.argv[2])
102+
else:
103+
print("Usage: ", sys.argv[0], file=sys.stderr)
104+
print(" or: ", sys.argv[0], "-w X.Y.Z", file=sys.stderr)
105+
print(" or: ", sys.argv[0], "-w X.Y.Z-devN", file=sys.stderr)
106+
107+
108+
if __name__ == '__main__':
109+
main()
110+

0 commit comments

Comments
 (0)