[scan-build-py] reuse command line output parameter for report directory

Differential Revision: https://reviews.llvm.org/D30861

llvm-svn: 298355
This commit is contained in:
Laszlo Nagy 2017-03-21 10:15:18 +00:00
parent 1ec03e46a7
commit 57db7c6860
2 changed files with 33 additions and 28 deletions

View File

@ -40,7 +40,8 @@ def scan_build():
""" Entry point for scan-build command. """
args = parse_args_for_scan_build()
with report_directory(args.output, args.keep_empty) as target_dir:
# will re-assign the report directory as new output
with report_directory(args.output, args.keep_empty) as args.output:
# Run against a build command. there are cases, when analyzer run
# is not required. But we need to set up everything for the
# wrappers, because 'configure' needs to capture the CC/CXX values
@ -50,13 +51,13 @@ def scan_build():
exit_code = capture(args)
# Run the analyzer against the captured commands.
if need_analyzer(args.build):
run_analyzer(args, target_dir)
run_analyzer(args)
else:
# Run build command and analyzer with compiler wrappers.
environment = setup_environment(args, target_dir)
environment = setup_environment(args)
exit_code = run_build(args.build, env=environment)
# Cover report generation and bug counting.
number_of_bugs = document(args, target_dir, False)
number_of_bugs = document(args)
# Set exit status as it was requested.
return number_of_bugs if args.status_bugs else exit_code
@ -66,11 +67,12 @@ def analyze_build():
""" Entry point for analyze-build command. """
args = parse_args_for_analyze_build()
with report_directory(args.output, args.keep_empty) as target_dir:
# will re-assign the report directory as new output
with report_directory(args.output, args.keep_empty) as args.output:
# Run the analyzer against a compilation db.
run_analyzer(args, target_dir)
run_analyzer(args)
# Cover report generation and bug counting.
number_of_bugs = document(args, target_dir, True)
number_of_bugs = document(args)
# Set exit status as it was requested.
return number_of_bugs if args.status_bugs else 0
@ -88,7 +90,7 @@ def need_analyzer(args):
return len(args) and not re.search('configure|autogen', args[0])
def run_analyzer(args, output_dir):
def run_analyzer(args):
""" Runs the analyzer against the given compilation database. """
def exclude(filename):
@ -98,7 +100,7 @@ def run_analyzer(args, output_dir):
consts = {
'clang': args.clang,
'output_dir': output_dir,
'output_dir': args.output,
'output_format': args.output_format,
'output_failures': args.output_failures,
'direct_args': analyzer_params(args),
@ -120,7 +122,7 @@ def run_analyzer(args, output_dir):
pool.join()
def setup_environment(args, destination):
def setup_environment(args):
""" Set up environment for build command to interpose compiler wrapper. """
environment = dict(os.environ)
@ -129,7 +131,7 @@ def setup_environment(args, destination):
'CC': COMPILER_WRAPPER_CC,
'CXX': COMPILER_WRAPPER_CXX,
'ANALYZE_BUILD_CLANG': args.clang if need_analyzer(args.build) else '',
'ANALYZE_BUILD_REPORT_DIR': destination,
'ANALYZE_BUILD_REPORT_DIR': args.output,
'ANALYZE_BUILD_REPORT_FORMAT': args.output_format,
'ANALYZE_BUILD_REPORT_FAILURES': 'yes' if args.output_failures else '',
'ANALYZE_BUILD_PARAMETERS': ' '.join(analyzer_params(args)),

View File

@ -18,58 +18,60 @@ import plistlib
import glob
import json
import logging
import datetime
from libscanbuild import duplicate_check
from libscanbuild.clang import get_version
__all__ = ['document']
def document(args, output_dir, use_cdb):
def document(args):
""" Generates cover report and returns the number of bugs/crashes. """
html_reports_available = args.output_format in {'html', 'plist-html'}
logging.debug('count crashes and bugs')
crash_count = sum(1 for _ in read_crashes(output_dir))
crash_count = sum(1 for _ in read_crashes(args.output))
bug_counter = create_counters()
for bug in read_bugs(output_dir, html_reports_available):
for bug in read_bugs(args.output, html_reports_available):
bug_counter(bug)
result = crash_count + bug_counter.total
if html_reports_available and result:
use_cdb = os.path.exists(args.cdb)
logging.debug('generate index.html file')
# common prefix for source files to have sort filenames
# common prefix for source files to have sorter path
prefix = commonprefix_from(args.cdb) if use_cdb else os.getcwd()
# assemble the cover from multiple fragments
fragments = []
try:
fragments = []
if bug_counter.total:
fragments.append(bug_summary(output_dir, bug_counter))
fragments.append(bug_report(output_dir, prefix))
fragments.append(bug_summary(args.output, bug_counter))
fragments.append(bug_report(args.output, prefix))
if crash_count:
fragments.append(crash_report(output_dir, prefix))
assemble_cover(output_dir, prefix, args, fragments)
# copy additinal files to the report
copy_resource_files(output_dir)
fragments.append(crash_report(args.output, prefix))
assemble_cover(args, prefix, fragments)
# copy additional files to the report
copy_resource_files(args.output)
if use_cdb:
shutil.copy(args.cdb, output_dir)
shutil.copy(args.cdb, args.output)
finally:
for fragment in fragments:
os.remove(fragment)
return result
def assemble_cover(output_dir, prefix, args, fragments):
def assemble_cover(args, prefix, fragments):
""" Put together the fragments into a final report. """
import getpass
import socket
import datetime
if args.html_title is None:
args.html_title = os.path.basename(prefix) + ' - analyzer results'
with open(os.path.join(output_dir, 'index.html'), 'w') as handle:
with open(os.path.join(args.output, 'index.html'), 'w') as handle:
indent = 0
handle.write(reindent("""
|<!DOCTYPE html>
@ -481,9 +483,10 @@ def commonprefix_from(filename):
def commonprefix(files):
""" Fixed version of os.path.commonprefix. Return the longest path prefix
that is a prefix of all paths in filenames. """
""" Fixed version of os.path.commonprefix.
:param files: list of file names.
:return: the longest path prefix that is a prefix of all files. """
result = None
for current in files:
if result is not None: