forked from JMcCloskey3/pySlip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbump_release
executable file
·176 lines (137 loc) · 4.85 KB
/
bump_release
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env python3
"""
A program to increment the major.minor.build numbers for a GitHub project.
Usage: bump_release [-M|--major] [-m|--minor] [-b|--build]
where -M | --major bumps the major number, & zeros minor+build
-m | --minor bumps the minor number, & zeros build
-b | --build bumps the build number (the default)
Release numbers are found in:
* the latest git tag
* setup.py
Check that the numbers from all sources are consistent, bump the release
number as required, rewrite setup.py to use the new number and prints
the new release number to stdout.
"""
import sys
import os.path
import getopt
import subprocess
# name of the config file
TagConfigFile = 'setup.py'
# variables indicating which number to bump
(BumpMajor, BumpMinor, BumpBuild) = range(3)
def abort(msg):
"""Print a message and abort."""
delim = '*' * 60
print(delim)
print(msg)
print(delim)
sys.exit(1)
def setup_tag():
"""Get the configured tag number from the setup file."""
# assume data doesn't exist in file
version_line = None
download_line = None
# read the expected tag number lines
with open(TagConfigFile) as fd:
for line in fd:
line = line.strip()
if line.startswith('version='):
version_line = line
if line.startswith('download_url='):
download_line = line
# make sure we got both
if version_line is None or download_line is None:
msg = (f"Can't find tag numbers in {TagConfigFile}:\n"
f"version_line={version_line}\n"
f"download_line={download_line}")
abort(msg)
# extract the release numbers from string, check they are the same
# version_line=version='4.0.5',
# download_url='https://github.com/rzzzwilson/pySlip/releases/tag/4.0.5',
version_tag = version_line.split("'")[1]
download_tag = os.path.basename(download_line.split("'")[1])
if version_tag != download_tag:
msg = f"Different release numbers in {TagConfigFile}: '{version_tag}' and '{download_tag}'"
abort(msg)
return version_tag
def write_tag(new_tag):
"""Update the config file with the new release number."""
# read all lines from the config file
with open(TagConfigFile) as fd:
config_data = fd.readlines()
# open the file for output, emit modified lines
# version='4.0.5',
# download_url='https://github.com/rzzzwilson/pySlip/releases/tag/4.0.5',
with open(TagConfigFile, 'w') as fd:
for line in config_data:
line = line.rstrip(',')
line_strip = line.strip()
if line_strip.startswith('version='):
(prefix, _) = line.split('=')
line = f"{prefix}='{new_tag}',\n"
if line_strip.startswith('download_url='):
(prefix, path) = line.split('=')
dirname = os.path.dirname(path)
line = f"{prefix}={dirname}/{new_tag}',\n"
fd.write(line)
def latest_tag():
"""Get the latest tag release number."""
p = subprocess.check_output(['git', 'describe'], text=True)
try:
(tag, _) = p.split('-', maxsplit=1)
except ValueError:
return None
return tag
def main(bump_what):
"""Bump the release number according to 'bump_what'."""
# get the latest git tag number
git_tag = latest_tag()
if git_tag is None:
abort('No release tag number set!?')
# get tag numbers from setup.py
config_tag = setup_tag()
# check tag numbers are the same
if git_tag != config_tag:
abort(f'Tags are inconsistent: git_tag={git_tag}, config_tag={config_tag}')
# bump the appropriate part of the old release number
(major, minor, build) = git_tag.split('.')
if bump_what == BumpMajor:
new_tag = f'{int(major)+1}.0.0'
elif bump_what == BumpMinor:
new_tag = f'{major}.{int(minor)+1}.0'
else:
new_tag = f'{major}.{minor}.{int(build)+1}'
# rewrite the config file to use new release number
write_tag(new_tag)
# return the new release number
return new_tag
def usage(msg=None):
"""Print program help with optional message."""
if msg:
delim = '=' * 60
print(delim)
print(msg)
print(delim)
print(__doc__)
# parse the CLI params
argv = sys.argv[1:]
try:
(opts, args) = getopt.getopt(argv, 'bmMh',
['build', 'minor', 'major', 'help'])
except getopt.error:
usage()
sys.exit(1)
bump_part = BumpBuild
for (opt, param) in opts:
if opt in ['-b', '--build']:
bump_part = BumpBuild
elif opt in ['-m', '--minor']:
bump_part = BumpMinor
elif opt in ['-M', '--major']:
bump_part = BumpMajor
elif opt in ['-h', '--help']:
usage()
sys.exit(0)
# print the new release number to stdout
print(main(bump_part))