aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/scripts/coverage.py
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2018-03-14 21:54:33 +0100
committerJoel Klinghed <the_jk@spawned.biz>2018-03-19 21:52:34 +0100
commit79bb1df04faf96f03f2b5a6b2dcb95fcff1a3b0d (patch)
treeff0ac5e1743b62b133f70ce1b3dacf2dc2567d48 /mesonbuild/scripts/coverage.py
parent50c66f1f5c099cb1286dab8a646bed55f39d1e3e (diff)
downloadmeson-79bb1df04faf96f03f2b5a6b2dcb95fcff1a3b0d.zip
meson-79bb1df04faf96f03f2b5a6b2dcb95fcff1a3b0d.tar.gz
meson-79bb1df04faf96f03f2b5a6b2dcb95fcff1a3b0d.tar.bz2
Use standalone coverage script for legacy targets
ninja coverage -> generate all possible reports (text, xml, html) depending on gcovr and/or lcov/genhtml availability. ninja coverage-html -> generate only html report ninja coverage-xml -> generate only xml report ninja coverage-text -> generate only text report Make all targets phony, the old legacy rules where just annoying as you would have to remove the old report before being able to generate a new one. ninja coverage succeeds if it can generate at least one report. ninja coverage-* only succeeds if it can generate the requested report
Diffstat (limited to 'mesonbuild/scripts/coverage.py')
-rw-r--r--mesonbuild/scripts/coverage.py182
1 files changed, 109 insertions, 73 deletions
diff --git a/mesonbuild/scripts/coverage.py b/mesonbuild/scripts/coverage.py
index 2d1f8c3..dcc9465 100644
--- a/mesonbuild/scripts/coverage.py
+++ b/mesonbuild/scripts/coverage.py
@@ -14,87 +14,123 @@
from mesonbuild import environment
-import sys, os, subprocess, pathlib
+import argparse, sys, os, subprocess, pathlib
+
+def coverage(outputs, source_root, build_root, log_dir):
+ outfiles = []
+ exitcode = 0
-def coverage(source_root, build_root, log_dir):
(gcovr_exe, gcovr_new_rootdir, lcov_exe, genhtml_exe) = environment.find_coverage_tools()
- if gcovr_exe:
- # gcovr >= 3.1 interprets rootdir differently
- if gcovr_new_rootdir:
- rootdir = build_root
- else:
- rootdir = source_root
- subprocess.check_call([gcovr_exe,
- '-x',
- '-r', rootdir,
- '-o', os.path.join(log_dir, 'coverage.xml'),
- ])
- subprocess.check_call([gcovr_exe,
- '-r', rootdir,
- '-o', os.path.join(log_dir, 'coverage.txt'),
- ])
- if lcov_exe and genhtml_exe:
- htmloutdir = os.path.join(log_dir, 'coveragereport')
- covinfo = os.path.join(log_dir, 'coverage.info')
- initial_tracefile = covinfo + '.initial'
- run_tracefile = covinfo + '.run'
- raw_tracefile = covinfo + '.raw'
- subprocess.check_call([lcov_exe,
- '--directory', build_root,
- '--capture',
- '--initial',
- '--output-file',
- initial_tracefile])
- subprocess.check_call([lcov_exe,
- '--directory', build_root,
- '--capture',
- '--output-file', run_tracefile,
- '--no-checksum',
- '--rc', 'lcov_branch_coverage=1',
- ])
- # Join initial and test results.
- subprocess.check_call([lcov_exe,
- '-a', initial_tracefile,
- '-a', run_tracefile,
- '-o', raw_tracefile])
- # Remove all directories outside the source_root from the covinfo
- subprocess.check_call([lcov_exe,
- '--extract', raw_tracefile,
- os.path.join(source_root, '*'),
- '--output-file', covinfo])
- subprocess.check_call([genhtml_exe,
- '--prefix', build_root,
- '--output-directory', htmloutdir,
- '--title', 'Code coverage',
- '--legend',
- '--show-details',
- '--branch-coverage',
- covinfo])
- elif gcovr_exe and gcovr_new_rootdir:
- htmloutdir = os.path.join(log_dir, 'coveragereport')
- subprocess.check_call([gcovr_exe,
- '--html',
- '--html-details',
- '-r', build_root,
- '-o', os.path.join(htmloutdir, 'index.html'),
- ])
- if gcovr_exe:
+
+ # gcovr >= 3.1 interprets rootdir differently
+ if gcovr_new_rootdir:
+ gcovr_rootdir = build_root
+ else:
+ gcovr_rootdir = source_root
+
+ if not outputs or 'xml' in outputs:
+ if gcovr_exe:
+ subprocess.check_call([gcovr_exe,
+ '-x',
+ '-r', gcovr_rootdir,
+ '-o', os.path.join(log_dir, 'coverage.xml'),
+ ])
+ outfiles.append(('Xml', pathlib.Path(log_dir, 'coverage.xml')))
+ elif outputs:
+ print('gcovr needed to generate Xml coverage report')
+ exitcode = 1
+
+ if not outputs or 'text' in outputs:
+ if gcovr_exe:
+ subprocess.check_call([gcovr_exe,
+ '-r', gcovr_rootdir,
+ '-o', os.path.join(log_dir, 'coverage.txt'),
+ ])
+ outfiles.append(('Text', pathlib.Path(log_dir, 'coverage.txt')))
+ elif outputs:
+ print('gcovr needed to generate text coverage report')
+ exitcode = 1
+
+ if not outputs or 'html' in outputs:
+ if lcov_exe and genhtml_exe:
+ htmloutdir = os.path.join(log_dir, 'coveragereport')
+ covinfo = os.path.join(log_dir, 'coverage.info')
+ initial_tracefile = covinfo + '.initial'
+ run_tracefile = covinfo + '.run'
+ raw_tracefile = covinfo + '.raw'
+ subprocess.check_call([lcov_exe,
+ '--directory', build_root,
+ '--capture',
+ '--initial',
+ '--output-file',
+ initial_tracefile])
+ subprocess.check_call([lcov_exe,
+ '--directory', build_root,
+ '--capture',
+ '--output-file', run_tracefile,
+ '--no-checksum',
+ '--rc', 'lcov_branch_coverage=1',
+ ])
+ # Join initial and test results.
+ subprocess.check_call([lcov_exe,
+ '-a', initial_tracefile,
+ '-a', run_tracefile,
+ '-o', raw_tracefile])
+ # Remove all directories outside the source_root from the covinfo
+ subprocess.check_call([lcov_exe,
+ '--extract', raw_tracefile,
+ os.path.join(source_root, '*'),
+ '--output-file', covinfo])
+ subprocess.check_call([genhtml_exe,
+ '--prefix', build_root,
+ '--output-directory', htmloutdir,
+ '--title', 'Code coverage',
+ '--legend',
+ '--show-details',
+ '--branch-coverage',
+ covinfo])
+ outfiles.append(('Html', pathlib.Path(htmloutdir, 'index.html')))
+ elif gcovr_exe and gcovr_new_rootdir:
+ htmloutdir = os.path.join(log_dir, 'coveragereport')
+ subprocess.check_call([gcovr_exe,
+ '--html',
+ '--html-details',
+ '-r', build_root,
+ '-o', os.path.join(htmloutdir, 'index.html'),
+ ])
+ outfiles.append(('Html', pathlib.Path(htmloutdir, 'index.html')))
+ elif outputs:
+ print('lcov/genhtml or gcovr >= 3.1 needed to generate Html coverage report')
+ exitcode = 1
+
+ if not outputs and not outfiles:
+ print('Need gcovr or lcov/genhtml to generate any coverage reports')
+ exitcode = 1
+
+ if outfiles:
print('')
- print('XML coverage report can be found at',
- pathlib.Path(log_dir, 'coverage.xml').as_uri())
- print('Text coverage report can be found at',
- pathlib.Path(log_dir, 'coverage.txt').as_uri())
- if (lcov_exe and genhtml_exe) or (gcovr_exe and gcovr_new_rootdir):
- print('Html coverage report can be found at',
- pathlib.Path(htmloutdir, 'index.html').as_uri())
- return 0
+ for (filetype, path) in outfiles:
+ print(filetype + ' coverage report can be found at', path.as_uri())
+
+ return exitcode
def run(args):
if not os.path.isfile('build.ninja'):
print('Coverage currently only works with the Ninja backend.')
return 1
- source_root, build_root, log_dir = args[:]
- return coverage(source_root, build_root, log_dir)
+ parser = argparse.ArgumentParser(description='Generate coverage reports')
+ parser.add_argument('--text', dest='outputs', action='append_const',
+ const='text', help='generate Text report')
+ parser.add_argument('--xml', dest='outputs', action='append_const',
+ const='xml', help='generate Xml report')
+ parser.add_argument('--html', dest='outputs', action='append_const',
+ const='html', help='generate Html report')
+ parser.add_argument('source_root')
+ parser.add_argument('build_root')
+ parser.add_argument('log_dir')
+ options = parser.parse_args(args)
+ return coverage(options.outputs, options.source_root,
+ options.build_root, options.log_dir)
if __name__ == '__main__':
sys.exit(run(sys.argv[1:]))