aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-04-02 20:08:30 +0300
committerGitHub <noreply@github.com>2018-04-02 20:08:30 +0300
commit98267e104effb919fe2a84f72d7d790b57577e34 (patch)
tree5ef16e60d49018f83394c5fe94b364437333b799
parent519cd40a064d43e1ce57b60d898a7adabd9e6034 (diff)
parentb2ffb6b56560d212e58192b85b0a8e9232a66dd4 (diff)
downloadmeson-98267e104effb919fe2a84f72d7d790b57577e34.zip
meson-98267e104effb919fe2a84f72d7d790b57577e34.tar.gz
meson-98267e104effb919fe2a84f72d7d790b57577e34.tar.bz2
Merge pull request #3242 from thejk/coverage_targets
Use standalone coverage script for legacy targets
-rw-r--r--mesonbuild/backend/ninjabackend.py110
-rw-r--r--mesonbuild/scripts/coverage.py194
2 files changed, 152 insertions, 152 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 2eff796..cee1434 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -613,13 +613,19 @@ int dummy;
self.create_target_alias(target_name, outfile)
self.processed_targets[target.get_id()] = True
+ def generate_coverage_command(self, elem, outputs):
+ elem.add_item('COMMAND', self.environment.get_build_command() +
+ ['--internal', 'coverage'] +
+ outputs +
+ [self.environment.get_source_dir(),
+ os.path.join(self.environment.get_source_dir(),
+ self.build.get_subproject_dir()),
+ self.environment.get_build_dir(),
+ self.environment.get_log_dir()])
+
def generate_coverage_rules(self, outfile):
e = NinjaBuildElement(self.all_outputs, 'meson-coverage', 'CUSTOM_COMMAND', 'PHONY')
- e.add_item('COMMAND', self.environment.get_build_command() +
- ['--internal', 'coverage',
- self.environment.get_source_dir(),
- self.environment.get_build_dir(),
- self.environment.get_log_dir()])
+ self.generate_coverage_command(e, [])
e.add_item('description', 'Generates coverage reports.')
e.write(outfile)
# Alias that runs the target defined above
@@ -627,80 +633,26 @@ int dummy;
self.generate_coverage_legacy_rules(outfile)
def generate_coverage_legacy_rules(self, outfile):
- (gcovr_exe, gcovr_new_rootdir, lcov_exe, genhtml_exe) = environment.find_coverage_tools()
- added_rule = False
- if gcovr_exe:
- # gcovr >= 3.1 interprets rootdir differently
- if gcovr_new_rootdir:
- rootdir = self.environment.get_build_dir()
- else:
- rootdir = self.environment.get_source_dir(),
- added_rule = True
- elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-xml', 'CUSTOM_COMMAND', '')
- elem.add_item('COMMAND', [gcovr_exe, '-x', '-r', rootdir,
- '-o', os.path.join(self.environment.get_log_dir(), 'coverage.xml')])
- elem.add_item('DESC', 'Generating XML coverage report.')
- elem.write(outfile)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-xml', outfile)
- elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-text', 'CUSTOM_COMMAND', '')
- elem.add_item('COMMAND', [gcovr_exe, '-r', rootdir,
- '-o', os.path.join(self.environment.get_log_dir(), 'coverage.txt')])
- elem.add_item('DESC', 'Generating text coverage report.')
- elem.write(outfile)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-text', outfile)
- if lcov_exe and genhtml_exe:
- added_rule = True
- htmloutdir = os.path.join(self.environment.get_log_dir(), 'coveragereport')
- covinfo = os.path.join(self.environment.get_log_dir(), 'coverage.info')
- phony_elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-html', 'phony', os.path.join(htmloutdir, 'index.html'))
- phony_elem.write(outfile)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-html', outfile)
- elem = NinjaBuildElement(self.all_outputs, os.path.join(htmloutdir, 'index.html'), 'CUSTOM_COMMAND', '')
-
- subproject_dir = self.build.get_subproject_dir()
- command = [lcov_exe,
- '--directory', self.environment.get_build_dir(),
- '--capture',
- '--output-file', covinfo,
- '--no-checksum',
- '&&', lcov_exe,
- '--extract',
- covinfo,
- os.path.join(self.environment.get_source_dir(), '*'),
- '--output-file', covinfo,
- '&&', lcov_exe,
- '--remove',
- covinfo,
- os.path.join(self.environment.get_source_dir(), subproject_dir, '*'),
- '--output-file', covinfo,
- '&&', genhtml_exe,
- '--prefix', self.environment.get_build_dir(),
- '--output-directory', htmloutdir,
- '--title', 'Code coverage',
- '--legend',
- '--show-details',
- covinfo]
- elem.add_item('COMMAND', command)
- elem.add_item('DESC', 'Generating HTML coverage report.')
- elem.write(outfile)
- elif gcovr_exe and gcovr_new_rootdir:
- added_rule = True
- htmloutdir = os.path.join(self.environment.get_log_dir(), 'coveragereport')
- phony_elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-html', 'phony', os.path.join(htmloutdir, 'index.html'))
- phony_elem.write(outfile)
- # Alias that runs the target defined above
- self.create_target_alias('meson-coverage-html', outfile)
- elem = NinjaBuildElement(self.all_outputs, os.path.join(htmloutdir, 'index.html'), 'CUSTOM_COMMAND', '')
- command = [gcovr_exe, '--html', '--html-details', '-r', self.environment.get_build_dir(),
- '-o', os.path.join(htmloutdir, 'index.html')]
- elem.add_item('COMMAND', command)
- elem.add_item('DESC', 'Generating HTML coverage report.')
- elem.write(outfile)
- if not added_rule:
- mlog.warning('coverage requested but neither gcovr nor lcov/genhtml found.')
+ e = NinjaBuildElement(self.all_outputs, 'meson-coverage-xml', 'CUSTOM_COMMAND', 'PHONY')
+ self.generate_coverage_command(e, ['--xml'])
+ e.add_item('description', 'Generates XML coverage report.')
+ e.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-xml', outfile)
+
+ e = NinjaBuildElement(self.all_outputs, 'meson-coverage-text', 'CUSTOM_COMMAND', 'PHONY')
+ self.generate_coverage_command(e, ['--text'])
+ e.add_item('description', 'Generates text coverage report.')
+ e.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-text', outfile)
+
+ e = NinjaBuildElement(self.all_outputs, 'meson-coverage-html', 'CUSTOM_COMMAND', 'PHONY')
+ self.generate_coverage_command(e, ['--html'])
+ e.add_item('description', 'Generates HTML coverage report.')
+ e.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-html', outfile)
def generate_install(self, outfile):
install_data_file = os.path.join(self.environment.get_scratch_dir(), 'install.dat')
diff --git a/mesonbuild/scripts/coverage.py b/mesonbuild/scripts/coverage.py
index 2d1f8c3..916c84f 100644
--- a/mesonbuild/scripts/coverage.py
+++ b/mesonbuild/scripts/coverage.py
@@ -14,87 +14,135 @@
from mesonbuild import environment
-import sys, os, subprocess, pathlib
+import argparse, sys, os, subprocess, pathlib
+
+def coverage(outputs, source_root, subproject_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,
+ '-e', subproject_root,
+ '-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,
+ '-e', subproject_root,
+ '-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])
+ # Remove all directories inside subproject dir
+ subprocess.check_call([lcov_exe,
+ '--remove', covinfo,
+ os.path.join(subproject_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')
+ if not os.path.isdir(htmloutdir):
+ os.mkdir(htmloutdir)
+ subprocess.check_call([gcovr_exe,
+ '--html',
+ '--html-details',
+ '-r', build_root,
+ '-e', subproject_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('subproject_root')
+ parser.add_argument('build_root')
+ parser.add_argument('log_dir')
+ options = parser.parse_args(args)
+ return coverage(options.outputs, options.source_root,
+ options.subproject_root, options.build_root,
+ options.log_dir)
if __name__ == '__main__':
sys.exit(run(sys.argv[1:]))