aboutsummaryrefslogtreecommitdiffstats
path: root/doc/helpers.py
diff options
context:
space:
mode:
author1138-4EB <1138-4EB@users.noreply.github.com>2019-02-23 23:03:41 +0100
committertgingold <tgingold@users.noreply.github.com>2019-02-25 07:28:45 +0100
commitfb6fa7ceced6e74ae02ed24b92a488c6e65d3404 (patch)
treee868b6cb14074b81618d148d9f58077fb308924d /doc/helpers.py
parent5040ad31d9e7ac3f7d459e388b734a917ce412f2 (diff)
downloadghdl-fb6fa7ceced6e74ae02ed24b92a488c6e65d3404.tar.gz
ghdl-fb6fa7ceced6e74ae02ed24b92a488c6e65d3404.tar.bz2
ghdl-fb6fa7ceced6e74ae02ed24b92a488c6e65d3404.zip
doc: add custom directive 'exec', generate releases shields and tables
with json data retrieved from github api"
Diffstat (limited to 'doc/helpers.py')
-rw-r--r--doc/helpers.py216
1 files changed, 216 insertions, 0 deletions
diff --git a/doc/helpers.py b/doc/helpers.py
new file mode 100644
index 000000000..dd028037e
--- /dev/null
+++ b/doc/helpers.py
@@ -0,0 +1,216 @@
+# Try to load JSON data from a file. If not found, use the argument as a tag name and retrieve the data from GitHub.
+def getJSON(tag='all'):
+ f = tag
+ tag = '/'+tag
+ if f == 'all':
+ f = 'releases'
+ tag = ''
+
+ import json
+ try:
+ d = json.loads(open(f+'.json', 'r').read())
+ except:
+ from urllib.request import urlopen
+ d = json.loads(urlopen('https://api.github.com/repos/ghdl/ghdl/releases'+tag).read())
+ json.dump(d, open(f+'.json', 'w'), indent=4)
+ return d
+
+#
+# Functions to print table with format `[ [], [], [], ... ]` to reStructuredText
+#
+
+# Print a row of data elements.
+def printTabRow(l, r):
+ printTabItem(l, r, '| ')
+
+# Print a rule. Two characters in 'b' define the type of rule. Expected values are '+-', '+=' or '| '.
+def printTabRule(l, b):
+ printTabItem(l, [b[1] for x in range(len(l))], b)
+
+# Print a full row, be it a rule or data.
+# Extend the width of each field to the size specified in 'l'.
+def printTabItem(l, a, b):
+ for y, z in enumerate(a):
+ print((b + z).ljust(l[y]+3, b[1]), end='')
+ print(b[0])
+
+# Get number of cols from number of elements in row 0.
+# Compute minimum number of characters required for each col.
+def getTabColLens(t):
+ cl = [0 for _ in t[0]]
+ for row in t:
+ for y, z in enumerate(row):
+ cl[y] = max(cl[y], len(z))
+ return cl
+
+# Print a table using the functions above.
+# The first row contains the headers.
+def printTab(t):
+ clens = getTabColLens(t)
+
+ printTabRule(clens, '+-')
+ printTabRow(clens, t[0])
+ printTabRule(clens, '+=')
+ for x in t[1:]:
+ printTabRow(clens, x)
+ printTabRule(clens, '+-')
+ print()
+
+#
+# Print two versions of each shield. Onee for 'html' (`image::`) and one for 'latex' (`replace::`)
+#
+
+# Strip all non-alphanumeric characters when creating the labels
+def stripLabel(label):
+ import re
+ pattern = re.compile('[\W_]+')
+ return pattern.sub('', label)
+
+def printShieldSrc(label, alt, img, target, latex=False):
+ if latex:
+ i = stripLabel(label)
+ if label[-6:] == '/total':
+ label = label[:-6]
+ print('.. |l' + i + '| replace:: `' + label + '`_')
+ print('.. _' + label + ': ' + target + '\n')
+ else:
+ print('.. |' + label + '| image:: '+ img + '\n',
+ ' :target: ' + target + '\n',
+ ' :height: 22\n',
+ ' :alt: ' + alt + '\n')
+
+#
+# Display better OS and Backend names than those represented in the tarball name
+#
+
+def prettyOS(i):
+ if i == 'fedora28':
+ return 'Fedora 28'
+ elif i == 'macosx':
+ return 'Max OS X'
+ elif i == 'mingw32':
+ return 'Windows x86 (MinGW32)'
+ elif i == 'mingw64':
+ return 'Windows x86 (MinGW64)'
+ elif i == 'stretch':
+ return 'Debian 9 (Stretch)'
+ elif i == 'gpl':
+ return 'Debian 9 (Stretch) GPL'
+ elif i == 'ubuntu14':
+ return '14.04 LTS (Trusty Tahr)'
+ return i
+
+def prettyBackend(i):
+ if i == 'llvm':
+ return 'LLVM'
+ if i == 'llvm-3.8':
+ return 'LLVM (3.8)'
+ return i
+
+#
+# Get, extract and process JSON data to create the shields and table with the assets of a release
+#
+
+def createTagShields(data='latest'):
+ if isinstance(data, str):
+ data = getJSON(data)
+
+ assets=[['OS', 'Backend', 'Size', 'Downloads']]
+ tag = data['tag_name']
+ for x in data['assets']:
+ name = x['name']
+ s = []
+
+ p = 'ghdl-gpl-'+tag[1:]
+ if name[0:len(p)] == p:
+ s = ['gpl', 'mcode']
+
+ p = 'ghdl-'+tag[1:]
+ if name[0:len(p)] == p:
+ s = name[len(p)+1:-4].split('-',1)
+
+ if len(s) > 1:
+ assets.append([
+ prettyOS(s[0]),
+ prettyBackend(s[1]),
+ (str(round(x['size']/1024**2, 2))+' MB').rjust(8),
+ '|' + tag + '/' + name + '|']
+ )
+
+ assets.append(['Sum:', '', '', '|'+tag+'/total|'])
+
+ for x in assets[1:-1]:
+ i = x[3][1:-1]
+ for latex in [False, True]:
+ printShieldSrc(i, i,
+ 'https://img.shields.io/github/downloads/ghdl/ghdl/' + i + '.svg?longCache=true&style=flat-square&logo=github&label=%7F',
+ 'https://github.com/ghdl/ghdl/releases/download/' + i, latex=latex)
+
+ return assets
+
+# TODO: Is github.com/ghdl/ghdl/releases/download/<tag>/<file> subject to rate limit? Is there an alternative (not documented) domain?
+
+
+#
+# Get, extract and process JSON data to create the shields and list/table with all the releases except the latest
+#
+
+def createReleasesShields(tag='latest'):
+ d = getJSON()
+ from dateutil.parser import parse as parseTime
+ releases = [['Date', 'Downloads']]
+ if tag == 'latest':
+ t = d[0]
+ for x in d:
+ name = x['tag_name']
+ if tag == name:
+ t = x
+ date = parseTime( x['published_at'] ).strftime("%Y-%m-%d")
+ releases.append([date, '|'+name+'/total|'])
+ i = name
+ for l in [False, True]:
+ printShieldSrc(i+'/total', i+' Total',
+ 'https://img.shields.io/github/downloads/ghdl/ghdl/' + i + '/total.svg?longCache=true&style=flat-square&logo=github&label=%7F',
+ 'https://github.com/ghdl/ghdl/releases/' + i, l)
+
+ out = {'releases': releases, 'assets': createTagShields(t)}
+ import json
+ json.dump(out, open('data.json', 'w'), indent=4)
+ return out
+
+
+#
+# Print the table with all the assets of a release/tag
+#
+
+def printReleaseTab(assets, latex=False):
+ if isinstance(assets, str):
+ assets = getJSON(assets)["assets"]
+
+ if latex:
+ for y, z in enumerate(assets[1:]):
+ assets[y+1] = z[0:3] + ['|l' + stripLabel(z[3][1:-1]) + '|']
+
+ printTab(assets)
+
+#
+# Print list of releases, except the latest (second row)
+#
+
+def printReleasesList(releases, latex=False):
+ if isinstance(releases, str):
+ releases = getJSON(releases)["releases"]
+
+ rs = [releases[0]]
+ rs.extend(releases[2:])
+
+ if latex:
+ rs[0] = ['Release/Tag'] + [rs[0][0]]
+ for x, r in enumerate(rs[1:]):
+ rs[x+1] = ['|l' + stripLabel(r[1][1:-1]) + '|'] + [r[0]]
+ else:
+ rs[0] = ['Release/Tag'] + rs[0]
+ for x, r in enumerate(rs[1:]):
+ rs[x+1] = [r[1][1:-7]] + r
+
+ printTab(rs)