-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathkoji-build-table
executable file
·157 lines (128 loc) · 5.22 KB
/
koji-build-table
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
#!/usr/bin/env python3
"""Build a table in JIRA syntax for the latest builds of the given packages
in a tag. Useful if you need a new copy of the table that osg-promote
generates.
"""
import re
import subprocess
from subprocess import Popen, PIPE
import sys
from optparse import OptionParser
KOJI_WEB = "https://koji.opensciencegrid.org"
def get_args(argv):
usage = """\
Usage; %prog [-f tag|build] <tag> <packages>...
OR %prog [-f tag|build] -t <tag1> [-t <tag2>]... <packages>..."""
parser = OptionParser(usage, prog=argv[0])
parser.add_option("-t", "--tag", dest="tags", action="append",
help="Tag to get build(s) for. May include commas or be specified multiple times.")
parser.add_option("-f", "--format", dest="tblformat", default="build", type="choice", choices=["tag", "build"],
help="Table format: either 'tag' (tag in first column and sorted by tag)"
" or 'build' (build in first column and sorted by build)")
options, args = parser.parse_args(argv[1:])
try:
if not options.tags:
tags = [args.pop(0)]
else:
tags = options.tags
realtags = []
for t in tags:
realtags.extend(t.split(","))
return options.tblformat, realtags, args
except IndexError:
parser.error("Incorrect number of arguments")
def get_latest_build(tag, package):
"""Get the latest build NVR for a package in the given tag, or None on failure"""
proc = Popen(["osg-koji", "-q", "list-tagged", "--latest", tag, package],
stdout=PIPE)
out = proc.communicate()[0] or b''
ret = proc.returncode
latest_build_line = out.decode("latin-1").strip()
if ret != 0 or not latest_build_line:
return
return latest_build_line.split()[0]
def get_build_line(latest_build):
"""Get the line containing the build ID from `koji buildinfo` output"""
proc = Popen(["osg-koji", "buildinfo", latest_build],
stdout=PIPE)
build_line = proc.stdout.readline().decode("latin-1").strip()
ret = proc.wait()
if ret != 0 or not build_line:
return
return build_line
def get_build_id(build_line):
"""Get the build ID from the line containing it from `koji buildinfo`"""
match = re.search(r'\[(\d+)\]', build_line)
if match:
return match.group(1)
def build_table(tag_package_table, header, divider, formatstr):
lines = [header]
errors = []
if divider:
lines.append(divider)
for tag, package in tag_package_table:
latest_build = get_latest_build(tag, package)
if not latest_build:
errors.append("Error getting latest build for tag %s, package %s" % (tag, package))
continue
build_line = get_build_line(latest_build)
if not build_line:
errors.append("Error getting build info for %s" % latest_build)
continue
build_id = get_build_id(build_line)
if not build_id:
errors.append("Error getting build ID for %s; text returned was:\n%s" % (latest_build, build_line))
continue
build_url = KOJI_WEB + "/koji/buildinfo?buildID=" + build_id
lines.append(formatstr % locals())
return lines, errors
def main(argv):
tblformat, tags, packages = get_args(argv)
old_lines = []
org_lines = []
new_lines = []
errors = []
tag_package_table = [[tag, package] for tag in tags for package in packages]
old_divider = ""
org_divider = "|---+---|"
new_divider = "--- | ---"
if tblformat == 'tag':
tag_package_table.sort(key=lambda pair:pair[0])
old_header = "|| Tag || Build ||"
old_formatstr = "| %(tag)s | [%(latest_build)s|%(build_url)s] |"
org_header = "| *Tag* | *Build* |"
org_formatstr = "| %(tag)s | [[%(build_url)s][%(latest_build)s]] |"
new_header = "**Tag** | **Build**"
new_formatstr = " %(tag)s | [%(latest_build)s](%(build_url)s)"
elif tblformat == 'build':
tag_package_table.sort(key=lambda pair:pair[1])
old_header = "|| Build || Tag ||"
old_formatstr = "| [%(latest_build)s|%(build_url)s] | %(tag)s |"
org_header = "| *Build* | *Tag* |"
org_formatstr = "| [[%(build_url)s][%(latest_build)s]] | %(tag)s |"
new_header = "**Build** | **Tag**"
new_formatstr = " [%(latest_build)s](%(build_url)s) | %(tag)s"
else:
assert False, "shouldn't get here"
old_lines, errors = build_table(tag_package_table, old_header, old_divider, old_formatstr)
org_lines, _ = build_table(tag_package_table, org_header, org_divider, org_formatstr)
new_lines, _ = build_table(tag_package_table, new_header, new_divider, new_formatstr)
ret = 0
if errors:
ret = 1
print("\n".join(errors), file=sys.stderr)
if old_lines:
print(" ************* Old JIRA syntax *************")
print("\n".join(old_lines))
print("\n")
if org_lines:
print(" ************* org-mode syntax *************")
print("\n".join(org_lines))
print("\n")
if new_lines:
print(" ************* New JIRA syntax *************")
print("\n".join(new_lines))
print("\n")
return ret
if __name__ == "__main__":
sys.exit(main(sys.argv))