aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/run_sonar.py
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /build/scripts/run_sonar.py
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'build/scripts/run_sonar.py')
-rw-r--r--build/scripts/run_sonar.py121
1 files changed, 121 insertions, 0 deletions
diff --git a/build/scripts/run_sonar.py b/build/scripts/run_sonar.py
new file mode 100644
index 00000000000..761cc34b788
--- /dev/null
+++ b/build/scripts/run_sonar.py
@@ -0,0 +1,121 @@
+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)