123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import os
- import sys
- import zipfile
- import tarfile
- import subprocess as sp
- import optparse
- import shutil
- import xml.etree.ElementTree as et
- def parse_args():
- parser = optparse.OptionParser()
- parser.add_option(
- '--classes-jar-path',
- dest='classes_jar_paths',
- action='append',
- default=[],
- )
- parser.add_option('--sources-jar-path')
- parser.add_option('--sonar-scanner-jar-path')
- parser.add_option('--sonar-scanner-main-class')
- parser.add_option('--java-coverage-merged-tar')
- parser.add_option('--java-binary-path')
- parser.add_option('--log-path')
- parser.add_option('--gcov-report-path')
- parser.add_option('--source-root')
- parser.add_option('--java-args', action='append', default=[])
- return parser.parse_args()
- def extract_zip_file(zip_file_path, dest_dir):
- with zipfile.ZipFile(zip_file_path) as arch:
- arch.extractall(dest_dir)
- def get_source_real_path(source_root, path):
- parts = os.path.normpath(path).split(os.path.sep)
- for i in xrange(len(parts)):
- if os.path.exists(os.path.join(source_root, *parts[i:])):
- return os.path.join(*parts[i:])
- return None
- def collect_cpp_sources(report, source_root, destination):
- sources = set()
- with open(report) as f:
- root = et.fromstring(f.read())
- for f in root.findall('.//class[@filename]'):
- real_filename = get_source_real_path(source_root, f.attrib['filename'])
- if real_filename:
- f.attrib['filename'] = real_filename
- sources.add(real_filename)
- with open(report, 'w') as f:
- pref = '''<?xml version="1.0" ?>
- <!DOCTYPE coverage
- SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>\n'''
- f.write(pref + et.tostring(root, encoding='utf-8') + '\n\n')
- for src in sources:
- dst = os.path.join(destination, src)
- src = os.path.join(source_root, src)
- if os.path.isfile(src):
- if not os.path.exists(os.path.dirname(dst)):
- os.makedirs(os.path.dirname(dst))
- os.link(src, dst)
- def main(opts, props_args):
- sources_dir = os.path.abspath('src')
- base_props_args = ['-Dsonar.sources=' + sources_dir]
- os.mkdir(sources_dir)
- if opts.sources_jar_path:
- extract_zip_file(opts.sources_jar_path, sources_dir)
- if opts.gcov_report_path:
- collect_cpp_sources(opts.gcov_report_path, opts.source_root, sources_dir)
- base_props_args += [
- '-Dsonar.projectBaseDir=' + sources_dir,
- '-Dsonar.cxx.coverage.reportPath=' + opts.gcov_report_path,
- ]
- if opts.classes_jar_paths:
- classes_dir = os.path.abspath('cls')
- os.mkdir(classes_dir)
- for classes_jar_path in opts.classes_jar_paths:
- extract_zip_file(classes_jar_path, classes_dir)
- base_props_args.append('-Dsonar.java.binaries=' + classes_dir)
- if opts.java_coverage_merged_tar:
- jacoco_report_path = os.path.abspath('jacoco.exec')
- with open(jacoco_report_path, 'w') as dest:
- with tarfile.open(opts.java_coverage_merged_tar) as tar:
- for src in tar:
- extracted = tar.extractfile(src)
- if extracted is not None:
- shutil.copyfileobj(extracted, dest)
- base_props_args += ['-Dsonar.core.codeCoveragePlugin=jacoco', '-Dsonar.jacoco.reportPath=' + jacoco_report_path]
- java_args = ['-{}'.format(i) for i in opts.java_args] + [
- '-Djava.net.preferIPv6Addresses=true',
- '-Djava.net.preferIPv4Addresses=false',
- ]
- sonar_cmd = (
- [
- opts.java_binary_path,
- ]
- + java_args
- + [
- '-classpath',
- opts.sonar_scanner_jar_path,
- ]
- + base_props_args
- + props_args
- + [opts.sonar_scanner_main_class, '-X']
- )
- p = sp.Popen(sonar_cmd, stdout=sp.PIPE, stderr=sp.STDOUT)
- out, _ = p.communicate()
- sys.stderr.write(out)
- with open(opts.log_path, 'a') as f:
- f.write(out)
- sys.exit(p.returncode)
- if __name__ == '__main__':
- opts, args = parse_args()
- props_args = ['-D' + arg for arg in args]
- main(opts, props_args)
|