import argparse import tarfile import zipfile import os import sys import time import subprocess def mkdir_p(path): try: os.makedirs(path) except OSError: pass class Timer(object): def __init__(self): self.start = time.time() def step(self, msg): sys.stderr.write("{} ({}s)\n".format(msg, int(time.time() - self.start))) self.start = time.time() def main( source, output, java, prefix_filter, exclude_filter, jars_list, output_format, tar_output, agent_disposition, runners_paths, ): timer = Timer() reports_dir = 'jacoco_reports_dir' mkdir_p(reports_dir) with tarfile.open(source) as tf: tf.extractall(reports_dir) timer.step("Coverage data extracted") reports = [os.path.join(reports_dir, fname) for fname in os.listdir(reports_dir)] with open(jars_list) as f: jars = f.read().strip().split() if jars and runners_paths: for r in runners_paths: try: jars.remove(r) except ValueError: pass src_dir = 'sources_dir' cls_dir = 'classes_dir' mkdir_p(src_dir) mkdir_p(cls_dir) for jar in jars: if jar.endswith('devtools-jacoco-agent.jar'): agent_disposition = jar # Skip java contrib - it's irrelevant coverage if jar.startswith('contrib/java'): continue with zipfile.ZipFile(jar) as jf: for entry in jf.infolist(): if entry.filename.endswith('.java'): dest = src_dir elif entry.filename.endswith('.class'): dest = cls_dir else: continue entry.filename = entry.filename.encode('utf-8') jf.extract(entry, dest) timer.step("Jar files extracted") if not agent_disposition: print >> sys.stderr, 'Can\'t find jacoco agent. Will not generate html report for java coverage.' if tar_output: report_dir = 'java.report.temp' else: report_dir = output mkdir_p(report_dir) if agent_disposition: agent_cmd = [ java, '-jar', agent_disposition, src_dir, cls_dir, prefix_filter or '.', exclude_filter or '__no_exclude__', report_dir, output_format, ] agent_cmd += reports subprocess.check_call(agent_cmd) timer.step("Jacoco finished") if tar_output: with tarfile.open(output, 'w') as outf: outf.add(report_dir, arcname='.') if __name__ == '__main__': if 'LC_ALL' in os.environ: if os.environ['LC_ALL'] == 'C': os.environ['LC_ALL'] = 'en_GB.UTF-8' parser = argparse.ArgumentParser() parser.add_argument('--source', action='store') parser.add_argument('--output', action='store') parser.add_argument('--java', action='store') parser.add_argument('--prefix-filter', action='store') parser.add_argument('--exclude-filter', action='store') parser.add_argument('--jars-list', action='store') parser.add_argument('--output-format', action='store', default="html") parser.add_argument('--raw-output', dest='tar_output', action='store_false', default=True) parser.add_argument('--agent-disposition', action='store') parser.add_argument('--runner-path', dest='runners_paths', action='append', default=[]) args = parser.parse_args() main(**vars(args))