Skip to content

Commit 5d98be6

Browse files
Cleaner argument handling and type-checking in calc_release_version
Enable debug output in calc-version selftest
1 parent 070b35a commit 5d98be6

File tree

2 files changed

+56
-47
lines changed

2 files changed

+56
-47
lines changed

build/calc_release_version.py

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
current Git commit.
2323
"""
2424

25+
2526
# XXX NOTE XXX NOTE XXX NOTE XXX
2627
# After modifying this script it is advisable to execute the self-test.
2728
#
@@ -34,10 +35,13 @@
3435
# of each command is desired, then add the -x option to the bash invocation.
3536
# XXX NOTE XXX NOTE XXX NOTE XXX
3637

38+
from __future__ import annotations
39+
3740
import datetime
3841
import re
3942
import subprocess
4043
import sys
44+
import argparse
4145

4246
try:
4347
# Prefer newer `packaging` over deprecated packages.
@@ -46,21 +50,35 @@
4650
except ImportError:
4751
# Fallback to deprecated pkg_resources.
4852
try:
49-
from pkg_resources.extern.packaging.version import Version
53+
from pkg_resources.extern.packaging.version import Version # type: ignore
5054
from pkg_resources import parse_version
5155
except ImportError:
5256
# Fallback to deprecated distutils.
5357
from distutils.version import LooseVersion as Version
5458
from distutils.version import LooseVersion as parse_version
5559

56-
DEBUG = len(sys.argv) > 1 and '-d' in sys.argv
57-
if DEBUG:
58-
print('Debugging output enabled.')
60+
parser = argparse.ArgumentParser()
61+
parser.add_argument("--debug", "-d", action="store_true", help="Enable debug output")
62+
parser.add_argument("--previous", "-p", action="store_true", help="Calculate the previous version, not the current")
63+
parser.add_argument("--next-minor", action="store_true", help="Calculate the next minor release instead of the current")
64+
args = parser.parse_args()
65+
66+
_DEBUG: bool = args.debug
67+
68+
69+
def debug(msg: str) -> None:
70+
if _DEBUG:
71+
print(msg, file=sys.stderr, flush=True)
72+
73+
74+
debug("Debugging output enabled.")
75+
76+
# fmt: off
5977

6078
# This option indicates we are to determine the previous release version
61-
PREVIOUS = len(sys.argv) > 1 and '-p' in sys.argv
79+
PREVIOUS: bool = args.previous
6280
# This options indicates to output the next minor release version
63-
NEXT_MINOR = len(sys.argv) > 1 and '--next-minor' in sys.argv
81+
NEXT_MINOR: bool = args.next_minor
6482

6583
PREVIOUS_TAG_RE = re.compile('(?P<ver>(?P<vermaj>[0-9]+)\\.(?P<vermin>[0-9]+)'
6684
'\\.(?P<verpatch>[0-9]+)(?:-(?P<verpre>.*))?)')
@@ -69,29 +87,29 @@
6987
RELEASE_BRANCH_RE = re.compile('(?:(?:refs/remotes/)?origin/)?(?P<brname>r'
7088
'(?P<vermaj>[0-9]+)\\.(?P<vermin>[0-9]+))')
7189

72-
def check_output(args):
90+
def check_output(args: list[str]) -> str:
7391
"""
7492
Delegates to subprocess.check_output() if it is available, otherwise
7593
provides a reasonable facsimile.
7694
"""
95+
debug(f'Run command: {args}')
7796
if 'check_output' in dir(subprocess):
7897
out = subprocess.check_output(args)
7998
else:
8099
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
81100
out, err = proc.communicate()
82101
ret = proc.poll()
83102
if ret:
84-
raise subprocess.CalledProcessError(ret, args[0], output=out)
103+
raise subprocess.CalledProcessError(ret, args[0], output=out, stderr=err)
85104

86-
if type(out) is bytes:
87-
# git isn't guaranteed to always return UTF-8, but for our purposes
88-
# this should be fine as tags and hashes should be ASCII only.
89-
out = out.decode('utf-8')
105+
# git isn't guaranteed to always return UTF-8, but for our purposes
106+
# this should be fine as tags and hashes should be ASCII only.
107+
out = out.decode('utf-8')
90108

91109
return out
92110

93111

94-
def check_head_tag():
112+
def check_head_tag() -> str | None:
95113
"""
96114
Checks the current HEAD to see if it has been tagged with a tag that matches
97115
the pattern for a release tag. Returns release version calculated from the
@@ -115,21 +133,19 @@ def check_head_tag():
115133
if release_tag_match:
116134
new_version_str = release_tag_match.group('ver')
117135
new_version_parsed = parse_version(new_version_str)
118-
if new_version_parsed > version_parsed:
119-
if DEBUG:
120-
print('HEAD release tag: ' + new_version_str)
136+
if new_version_parsed > version_parsed: # type: ignore
137+
debug('HEAD release tag: ' + new_version_str)
121138
version_str = new_version_str
122139
version_parsed = new_version_parsed
123140
found_tag = True
124141

125142
if found_tag:
126-
if DEBUG:
127-
print('Calculated version: ' + version_str)
143+
debug('Calculated version: ' + version_str)
128144
return version_str
129145

130146
return None
131147

132-
def get_next_minor(prerelease_marker):
148+
def get_next_minor(prerelease_marker: str):
133149
"""
134150
get_next_minor does the following:
135151
- Inspect the branches that fit the convention for a release branch.
@@ -157,16 +173,15 @@ def get_next_minor(prerelease_marker):
157173
str(version_new['patch']) + '-' + \
158174
version_new['prerelease']
159175
new_version_parsed = parse_version(new_version_str)
160-
if new_version_parsed > version_parsed:
176+
if new_version_parsed > version_parsed: # type: ignore
161177
version_str = new_version_str
162178
version_parsed = new_version_parsed
163-
if DEBUG:
164-
print('Found new best version "' + version_str \
179+
debug('Found new best version "' + version_str \
165180
+ '" based on branch "' \
166181
+ release_branch_match.group('brname') + '"')
167182
return version_str
168183

169-
def get_branch_tags(active_branch_name):
184+
def get_branch_tags(active_branch_name: str):
170185
"""
171186
Returns the tag or tags (as a single string with newlines between tags)
172187
corresponding to the current branch, which must not be master. If the
@@ -199,7 +214,7 @@ def get_branch_tags(active_branch_name):
199214

200215
return tags
201216

202-
def process_and_sort_tags(tags):
217+
def process_and_sort_tags(tags: str):
203218
"""
204219
Given a string (as returned from get_branch_tags), return a sorted list of
205220
zero or more tags (sorted based on the Version comparison) which meet
@@ -209,7 +224,7 @@ def process_and_sort_tags(tags):
209224
1.x.y-preX iff 1.x.y does not already exist)
210225
"""
211226

212-
processed_and_sorted_tags = []
227+
processed_and_sorted_tags: list[str] = []
213228
if not tags or len(tags) == 0:
214229
return processed_and_sorted_tags
215230

@@ -225,7 +240,7 @@ def process_and_sort_tags(tags):
225240
tag_parts = tag.split('-')
226241
if len(tag_parts) >= 2 and tag_parts[0] not in processed_and_sorted_tags:
227242
processed_and_sorted_tags.append(tag)
228-
processed_and_sorted_tags.sort(key=Version)
243+
processed_and_sorted_tags.sort(key=Version) # type: ignore
229244

230245
return processed_and_sorted_tags
231246

@@ -254,8 +269,7 @@ def main():
254269
+ '+git' + head_commit_short
255270

256271
if NEXT_MINOR:
257-
if DEBUG:
258-
print('Calculating next minor release')
272+
debug('Calculating next minor release')
259273
return get_next_minor(prerelease_marker)
260274

261275
head_tag_ver = check_head_tag()
@@ -264,8 +278,7 @@ def main():
264278

265279
active_branch_name = check_output(['git', 'rev-parse',
266280
'--abbrev-ref', 'HEAD']).strip()
267-
if DEBUG:
268-
print('Calculating release version for branch: ' + active_branch_name)
281+
debug('Calculating release version for branch: ' + active_branch_name)
269282
if active_branch_name == 'master':
270283
return get_next_minor(prerelease_marker)
271284

@@ -287,22 +300,20 @@ def main():
287300
str(version_new['patch']) + '-' + \
288301
version_new['prerelease']
289302
new_version_parsed = parse_version(new_version_str)
290-
if new_version_parsed > version_parsed:
303+
if new_version_parsed > version_parsed: # type: ignore
291304
version_str = new_version_str
292305
version_parsed = new_version_parsed
293-
if DEBUG:
294-
print('Found new best version "' + version_str \
306+
debug('Found new best version "' + version_str \
295307
+ '" from tag "' + release_tag_match.group('ver') + '"')
296308

297309
return version_str
298310

299-
def previous(rel_ver):
311+
def previous(rel_ver: str):
300312
"""
301313
Given a release version, find the previous version based on the latest Git
302314
tag that is strictly a lower version than the given release version.
303315
"""
304-
if DEBUG:
305-
print('Calculating previous release version (option -p was specified).')
316+
debug('Calculating previous release version (option -p was specified).')
306317
version_str = '0.0.0'
307318
version_parsed = parse_version(version_str)
308319
rel_ver_str = rel_ver
@@ -323,17 +334,15 @@ def previous(rel_ver):
323334
if version_new['prerelease'] is not None:
324335
new_version_str += '-' + version_new['prerelease']
325336
new_version_parsed = parse_version(new_version_str)
326-
if new_version_parsed < rel_ver_parsed and new_version_parsed > version_parsed:
337+
if new_version_parsed < rel_ver_parsed and new_version_parsed > version_parsed: # type: ignore
327338
version_str = new_version_str
328339
version_parsed = new_version_parsed
329-
if DEBUG:
330-
print('Found new best version "' + version_str \
340+
debug('Found new best version "' + version_str \
331341
+ '" from tag "' + tag + '"')
332342

333343
return version_str
334344

335345
RELEASE_VER = previous(main()) if PREVIOUS else main()
336346

337-
if DEBUG:
338-
print('Final calculated release version:')
347+
debug('Final calculated release version:')
339348
print(RELEASE_VER)

build/calc_release_version_selftest.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ cp calc_release_version.py calc_release_version_test.py
4040
echo "Test a tagged commit ... begin"
4141
{
4242
git checkout 1.23.4 --quiet
43-
got=$("${PYTHON_INTERP}" calc_release_version_test.py)
43+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug)
4444
assert_eq "$got" "1.23.4"
45-
got=$("${PYTHON_INTERP}" calc_release_version_test.py -p)
45+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug -p)
4646
assert_eq "$got" "1.23.3"
4747
git checkout - --quiet
4848
}
@@ -53,9 +53,9 @@ echo "Test an untagged commit ... begin"
5353
{
5454
# 42a818429d6d586a6abf22367ac6fea1e9ce3f2c is commit before 1.23.4
5555
git checkout 42a818429d6d586a6abf22367ac6fea1e9ce3f2c --quiet
56-
got=$("${PYTHON_INTERP}" calc_release_version_test.py)
56+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug)
5757
assert_eq "$got" "1.23.4-$DATE+git42a818429d"
58-
got=$("${PYTHON_INTERP}" calc_release_version_test.py -p)
58+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug -p)
5959
assert_eq "$got" "1.23.4"
6060
git checkout - --quiet
6161
}
@@ -64,14 +64,14 @@ echo "Test an untagged commit ... end"
6464
echo "Test next minor version ... begin"
6565
{
6666
CURRENT_SHORTREF=$(git rev-parse --revs-only --short=10 HEAD)
67-
got=$("${PYTHON_INTERP}" calc_release_version_test.py --next-minor)
67+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug --next-minor)
6868
# XXX NOTE XXX NOTE XXX
6969
# If you find yourself looking at this line because the assertion below
7070
# failed, then it is probably because a new major/minor release was made.
7171
# Update the expected output to represent the correct next version.
7272
# XXX NOTE XXX NOTE XXX
7373
assert_eq "$got" "1.25.0-$DATE+git$CURRENT_SHORTREF"
74-
got=$("${PYTHON_INTERP}" calc_release_version_test.py --next-minor -p)
74+
got=$("${PYTHON_INTERP}" calc_release_version_test.py --debug --next-minor -p)
7575
# XXX NOTE XXX NOTE XXX
7676
# If you find yourself looking at this line because the assertion below
7777
# failed, then it is probably because a new major/minor release was made.

0 commit comments

Comments
 (0)