1#!/usr/bin/python3 2 3import itertools 4import os 5import re 6import subprocess 7 8HTML = r''' 9<!DOCTYPE html> 10<html> 11 <head> 12 <link rel="stylesheet" href="http://libuv.org/styles/vendor.css"> 13 <link rel="stylesheet" href="http://libuv.org/styles/main.css"> 14 <style> 15 table {{ 16 border-spacing: 0; 17 }} 18 body table {{ 19 margin: 0 0 0 12pt; 20 }} 21 th, td {{ 22 padding: 2pt; 23 text-align: left; 24 vertical-align: top; 25 }} 26 table table {{ 27 border-collapse: initial; 28 padding: 0 0 16pt 0; 29 }} 30 table table tr:nth-child(even) {{ 31 background-color: #777; 32 }} 33 </style> 34 </head> 35 <body> 36 <table>{groups}</table> 37 </body> 38</html> 39''' 40 41GROUPS = r''' 42<tr> 43 <td>{groups[0]}</td> 44 <td>{groups[1]}</td> 45 <td>{groups[2]}</td> 46 <td>{groups[3]}</td> 47</tr> 48''' 49 50GROUP = r''' 51<table> 52 <tr> 53 <th>version</th> 54 <th>tarball</th> 55 <th>gpg</th> 56 <th>windows</th> 57 </tr> 58 {rows} 59</table> 60''' 61 62ROW = r''' 63<tr> 64 <td> 65 <a href="http://dist.libuv.org/dist/{tag}/">{tag}</a> 66 </td> 67 <td> 68 <a href="http://dist.libuv.org/dist/{tag}/libuv-{tag}.tar.gz">tarball</a> 69 </td> 70 <td>{maybe_gpg}</td> 71 <td>{maybe_exe}</td> 72</tr> 73''' 74 75GPG = r''' 76<a href="http://dist.libuv.org/dist/{tag}/libuv-{tag}.tar.gz.sign">gpg</a> 77''' 78 79# The binaries don't have a predictable name, link to the directory instead. 80EXE = r''' 81<a href="http://dist.libuv.org/dist/{tag}/">exe</a> 82''' 83 84def version(tag): 85 return list(map(int, re.match('^v(\d+)\.(\d+)\.(\d+)', tag).groups())) 86 87def major_minor(tag): 88 return version(tag)[:2] 89 90def row_for(tag): 91 maybe_gpg = '' 92 maybe_exe = '' 93 # We didn't start signing releases and producing Windows installers 94 # until v1.7.0. 95 if version(tag) >= version('v1.7.0'): 96 maybe_gpg = GPG.format(**locals()) 97 maybe_exe = EXE.format(**locals()) 98 return ROW.format(**locals()) 99 100def group_for(tags): 101 rows = ''.join(row_for(tag) for tag in tags) 102 return GROUP.format(rows=rows) 103 104# Partition in groups of |n|. 105def groups_for(groups, n=4): 106 html = '' 107 groups = groups[:] + [''] * (n - 1) 108 while len(groups) >= n: 109 html += GROUPS.format(groups=groups) 110 groups = groups[n:] 111 return html 112 113if __name__ == '__main__': 114 os.chdir(os.path.dirname(__file__)) 115 tags = subprocess.check_output(['git', 'tag'], text=True) 116 tags = [tag for tag in tags.split('\n') if tag.startswith('v')] 117 tags.sort(key=version, reverse=True) 118 groups = [group_for(list(g)) for _, g in itertools.groupby(tags, major_minor)] 119 groups = groups_for(groups) 120 html = HTML.format(groups=groups).strip() 121 html = re.sub('>\\s+<', '><', html) 122 print(html) 123