1 #!/usr/bin/python3 2 3 import itertools 4 import os 5 import re 6 import subprocess 7 8 HTML = 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 41 GROUPS = 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 50 GROUP = 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 62 ROW = 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 75 GPG = 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. 80 EXE = r''' 81 <a href="http://dist.libuv.org/dist/{tag}/">exe</a> 82 ''' 83 84 def version(tag): 85 return list(map(int, re.match('^v(\d+)\.(\d+)\.(\d+)', tag).groups())) 86 87 def major_minor(tag): 88 return version(tag)[:2] 89 90 def 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 100 def 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|. 105 def 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 113 if __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