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
|
#!/usr/bin/env python3
# src:
# https://git.sr.ht/~sircmpwn/dotfiles/blob/f9e7e88a72c2b87e5ab823205cb3a3aa8f3babd0/bin/semver
# usage: semver [patch|minor|major|<new_version>]
# desc: will tag a new version either based on last tag or <new_version>
#
# patch(robertgzr)
# allow tagging a new non-annotated release
import os
import subprocess
import sys
import tempfile
import getopt
simple_tag = False
force = False
def usage():
print(f"usage: {sys.argv[0]} OPTIONS COMMANDS")
print("""
OPTIONS:
\t-h\tshow this help
\t-t\tonly create a simple tag, otherwise annotate as well
\t-f\toverwrite existing tag
COMMANDS:
\tpatch
\tminor
\tmajor\tbump the previous tag and create a new one
""")
sys.exit(2)
try:
opts, argv = getopt.getopt(sys.argv[1:], 'tfh')
except getopt.GetoptError as err:
print(err)
usage()
for o, val in opts:
if o == "-t":
simple_tag = True
elif o == "-f":
force = True
elif o == "-h":
usage()
else:
assert False, "unhandled option"
if subprocess.run(["git", "branch", "--show-current"],
stdout=subprocess.PIPE).stdout.decode().strip() != "master":
print("WARNING! Not on the master branch.")
subprocess.run(["git", "pull", "--rebase"])
p = subprocess.run(["git", "describe", "--abbrev=0"], stdout=subprocess.PIPE)
describe = p.stdout.decode().strip()
# TODO also ask to re-append the trailing portion.... e.g. -rev1
old_version = describe.split("-")[0].split(".")
if len(old_version) == 2:
[major, minor] = old_version
[major, minor] = map(int, [major, minor])
patch = 0
elif len(old_version) == 3:
[major, minor, patch] = old_version
[major, minor, patch] = map(int, [major, minor, patch])
else:
print(f"WARNING: git describe returned invalid semver version: \"{describe}\"")
# sys.exit(1)
# old_version = [0, 0, 0]
p = subprocess.run(["git", "shortlog", "--no-merges", f"{describe}..HEAD"],
stdout=subprocess.PIPE)
shortlog = p.stdout.decode()
new_version = None
if argv[0] == "patch":
patch += 1
elif argv[0] == "minor":
minor += 1
patch = 0
elif argv[0] == "major":
major += 1
minor = patch = 0
else:
new_version = argv[0]
if new_version is None:
if len(old_version) == 2 and patch == 0:
new_version = f"{major}.{minor}"
else:
new_version = f"{major}.{minor}.{patch}"
p = None
if os.path.exists("contrib/_incr_version"):
p = subprocess.run(["contrib/_incr_version", describe, new_version])
elif os.path.exists(".git/_incr_version"):
print("Warning: _incr_version found at legacy path")
p = subprocess.run([".git/_incr_version", describe, new_version])
else:
print("Warning: no _incr_version script. " +
"Does this project have any specific release requirements?")
if p and p.returncode != 0:
print("Error: _incr_version returned nonzero exit code")
sys.exit(1)
args = ["git", "tag"]
if force:
args.extend(["-f"])
if not simple_tag:
with tempfile.NamedTemporaryFile() as f:
basename = os.path.basename(os.getcwd())
f.write(f"{basename} {new_version}\n\n".encode())
f.write(shortlog.encode())
f.flush()
args.extend(["-e", "-F", f.name, "-a", new_version])
subprocess.run(args)
else:
args.extend([new_version])
subprocess.run(args)
print(args)
print(new_version)
|