-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
update_version_next.py
executable file
·92 lines (81 loc) · 2.53 KB
/
update_version_next.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python3
"""
Replace `.. versionchanged:: next` lines in docs files by the given version.
Run this at release time to replace `next` with the just-released version
in the sources.
No backups are made; add/commit to Git before running the script.
Applies to all the VersionChange directives. For deprecated-removed, only
handle the first argument (deprecation version, not the removal version).
"""
import argparse
import re
import sys
from pathlib import Path
DIRECTIVE_RE = re.compile(
r"""
(?P<before>
\s*\.\.\s+
(version(added|changed|removed)|deprecated(-removed)?)
\s*::\s*
)
next
(?P<after>
.*
)
""",
re.VERBOSE | re.DOTALL,
)
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
"version",
help='String to replace "next" with. Usually `x.y`, but can be anything.',
)
parser.add_argument(
"directory",
type=Path,
help="Directory to process",
)
parser.add_argument(
"--verbose",
"-v",
action="count",
default=0,
help="Increase verbosity. Can be repeated (`-vv`).",
)
def main(argv: list[str]) -> None:
args = parser.parse_args(argv)
version = args.version
if args.verbose:
print(
f'Updating "next" versions in {args.directory} to {version!r}',
file=sys.stderr,
)
for path in Path(args.directory).glob("**/*.rst"):
num_changed_lines = 0
lines = []
with open(path, encoding="utf-8") as file:
for lineno, line in enumerate(file, start=1):
try:
if match := DIRECTIVE_RE.fullmatch(line):
line = match["before"] + version + match["after"]
num_changed_lines += 1
lines.append(line)
except Exception as exc:
exc.add_note(f"processing line {path}:{lineno}")
raise
if num_changed_lines:
if args.verbose:
s = "" if num_changed_lines == 1 else "s"
print(
f"Updating file {path} ({num_changed_lines} change{s})",
file=sys.stderr,
)
with open(path, "w", encoding="utf-8") as file:
file.writelines(lines)
else:
if args.verbose > 1:
print(f"Unchanged file {path}", file=sys.stderr)
if __name__ == "__main__":
main(sys.argv[1:])