aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2018-08-12 12:35:30 +0200
committerMichał Górny <mgorny@gentoo.org>2018-08-12 12:35:30 +0200
commitdbb818c206f82819fd0ce85bc6375748dd170201 (patch)
tree37abe4898f552875de45bba5fd04c783ffc1d857
parentcheck_eclasses_eapis: Include supported EAPIs in STATS.txt (diff)
downloadqa-scripts-dbb818c206f82819fd0ce85bc6375748dd170201.tar.gz
qa-scripts-dbb818c206f82819fd0ce85bc6375748dd170201.tar.bz2
qa-scripts-dbb818c206f82819fd0ce85bc6375748dd170201.zip
Add script to print eclass-EAPI matrix
-rwxr-xr-xeclass-eapi-matrix.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/eclass-eapi-matrix.py b/eclass-eapi-matrix.py
new file mode 100755
index 0000000..8117d63
--- /dev/null
+++ b/eclass-eapi-matrix.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# Eclass-EAPI matrix
+# (c) 2018 Michał Górny
+# Licensed under the terms of the 2-clause BSD license
+
+import math
+import os
+import os.path
+import re
+import sys
+
+
+STATS_LINE_RE = re.compile(r'EAPI=(?P<eapi>\w+) count: (?P<count>\d+)')
+SUPP_LINE_RE = re.compile(r'EAPIs declared supported by eclass: (.*)')
+
+
+def collect_data(work_dir):
+ """
+ Collect data about supported and used EAPIs from work_dir.
+
+ work_dir: directory with eapi-per-eclass stats
+
+ Returns dict of {eclass: (supported_eapis, {eapi: count, ...}), ...}
+ """
+ data = {}
+ for eclass in os.listdir(work_dir):
+ if not eclass.endswith('.eclass'):
+ continue
+
+ with open(os.path.join(work_dir, eclass, 'STATS.txt')) as f:
+ eapis = {}
+ supp_eapis = None
+ for l in f:
+ m = STATS_LINE_RE.match(l)
+ if m is not None:
+ eapis[m.group('eapi')] = int(m.group('count'))
+ continue
+
+ m = SUPP_LINE_RE.match(l)
+ if m is not None:
+ supp_eapis = m.group(1).split()
+
+ data[eclass[:-7]] = (supp_eapis, eapis)
+ return data
+
+
+def format_table(data):
+ """
+ Pretty-format table of eclass-EAPI data.
+ """
+
+ ret = ''
+
+ max_eclass_length = max(len(k) for k in data)
+ max_count = max(v for supp, eapis in data.values()
+ for v in eapis.values())
+ max_count_length = math.ceil(math.log10(max_count))
+
+ all_eapis = sorted(frozenset(v for supp, eapis in data.values()
+ for v in eapis))
+
+ # format strings
+ format_str = '{{eclass:>{}}}'.format(max_eclass_length)
+ for eapi in all_eapis:
+ format_str += ' {{eapi_{}:>{}}}'.format(eapi, max_count_length)
+ format_str += '\n'
+
+ # header
+ hdr = {'eclass': 'eclass / EAPI'}
+ for eapi in all_eapis:
+ hdr['eapi_'+eapi] = eapi
+ ret += format_str.format(**hdr)
+
+ # ruler
+ rule = {'eclass': max_eclass_length * '-'}
+ for eapi in all_eapis:
+ rule['eapi_'+eapi] = max_count_length * '-'
+ ret += format_str.format(**rule)
+
+ # data
+ for eclass, ecl_data in sorted(data.items()):
+ line = {'eclass': eclass}
+ supp_eapis, eapis = ecl_data
+ for eapi in all_eapis:
+ if supp_eapis is not None and eapi not in supp_eapis:
+ assert eapis.get(eapi, 0) == 0
+ line['eapi_'+eapi] = 'xx'
+ else:
+ line['eapi_'+eapi] = eapis.get(eapi, 0)
+ ret += format_str.format(**line)
+
+ return ret
+
+
+def main(work_dir):
+ data = collect_data(work_dir)
+ out = format_table(data)
+
+ with open(os.path.join(work_dir, 'matrix.txt'), 'w') as f:
+ f.write(out)
+
+
+if __name__ == '__main__':
+ main(*sys.argv[1:])