[python] add script report.py to post-process report.json

Summary:
This will help porting more Python code over to OCaml. Since the reporting step
uses a lot of Python libraries that would be a pain to rewrite in OCaml (eg,
syntax highlighting), keep this functionality in Python and make it possible to
call it from OCaml as a script.

Reviewed By: jberdine

Differential Revision: D4182832

fbshipit-source-id: fc83220
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 17179d4275
commit 4a673f540d

@ -348,16 +348,12 @@ class AnalyzerWrapper(object):
elapsed = utils.elapsed_time(reporting_start_time) elapsed = utils.elapsed_time(reporting_start_time)
self.timing['reporting'] = elapsed self.timing['reporting'] = elapsed
if report_status == os.EX_OK and not self.args.buck: if report_status == os.EX_OK and not self.args.buck:
json_report = os.path.join(self.args.infer_out, infer_out = self.args.infer_out
config.JSON_REPORT_FILENAME) json_report = os.path.join(infer_out, config.JSON_REPORT_FILENAME)
bugs_out = os.path.join(self.args.infer_out, bugs_out = os.path.join(infer_out, config.BUGS_FILENAME)
config.BUGS_FILENAME) issues.print_and_save_errors(self.args.project_root,
xml_out = None json_report, bugs_out,
if self.args.pmd_xml: self.args.pmd_xml)
xml_out = os.path.join(self.args.infer_out,
config.PMD_XML_FILENAME)
issues.print_and_save_errors(self.args.project_root, json_report,
bugs_out, xml_out)
def analyze_and_report(self): def analyze_and_report(self):
if self.args.analyzer not in [config.ANALYZER_COMPILE, if self.args.analyzer not in [config.ANALYZER_COMPILE,

@ -359,7 +359,6 @@ def collect_results(args, start_time, targets):
csv_report = os.path.join(args.infer_out, config.CSV_REPORT_FILENAME) csv_report = os.path.join(args.infer_out, config.CSV_REPORT_FILENAME)
json_report = os.path.join(args.infer_out, config.JSON_REPORT_FILENAME) json_report = os.path.join(args.infer_out, config.JSON_REPORT_FILENAME)
bugs_out = os.path.join(args.infer_out, config.BUGS_FILENAME)
if len(headers) > 1: if len(headers) > 1:
if any(map(lambda x: x != headers[0], headers)): if any(map(lambda x: x != headers[0], headers)):
@ -387,12 +386,10 @@ def collect_results(args, start_time, targets):
report.flush() report.flush()
print('\n') print('\n')
xml_out = None json_report = os.path.join(args.infer_out, config.JSON_REPORT_FILENAME)
if args.pmd_xml: bugs_out = os.path.join(args.infer_out, config.BUGS_FILENAME)
xml_out = os.path.join(args.infer_out, issues.print_and_save_errors(args.project_root, json_report, bugs_out,
config.PMD_XML_FILENAME) args.pmd_xml)
issues.print_and_save_errors(args.project_root, json_report,
bugs_out, xml_out)
stats['int']['total_time'] = int(round(utils.elapsed_time(start_time))) stats['int']['total_time'] = int(round(utils.elapsed_time(start_time)))

@ -199,13 +199,11 @@ class BuckAnalyzer:
self.args.infer_out, config.INFER_BUCK_DEPS_FILENAME) self.args.infer_out, config.INFER_BUCK_DEPS_FILENAME)
self._merge_infer_report_files(result_paths, merged_reports_path) self._merge_infer_report_files(result_paths, merged_reports_path)
self._merge_infer_dep_files(result_paths, merged_deps_path) self._merge_infer_dep_files(result_paths, merged_deps_path)
bugs_out = os.path.join(self.args.infer_out, config.BUGS_FILENAME) infer_out = self.args.infer_out
xml_out = None json_report = os.path.join(infer_out, config.JSON_REPORT_FILENAME)
if self.args.pmd_xml: bugs_out = os.path.join(infer_out, config.BUGS_FILENAME)
xml_out = os.path.join( issues.print_and_save_errors(self.args.project_root, json_report,
self.args.infer_out, config.PMD_XML_FILENAME) bugs_out, self.args.pmd_xml)
issues.print_and_save_errors(self.args.project_root,
merged_reports_path, bugs_out, xml_out)
return os.EX_OK return os.EX_OK
def capture_without_flavors(self): def capture_without_flavors(self):

@ -93,7 +93,7 @@ def text_of_report(report):
) )
def _text_of_report_list(project_root, reports, bugs_txt_path, limit=-1, def _text_of_report_list(project_root, reports, bugs_txt_path, limit=None,
formatter=colorize.TERMINAL_FORMATTER): formatter=colorize.TERMINAL_FORMATTER):
text_errors_list = [] text_errors_list = []
error_types_count = {} error_types_count = {}
@ -181,18 +181,20 @@ def _is_user_visible(project_root, report):
kind in [ISSUE_KIND_ERROR, ISSUE_KIND_WARNING, ISSUE_KIND_ADVICE]) kind in [ISSUE_KIND_ERROR, ISSUE_KIND_WARNING, ISSUE_KIND_ADVICE])
def print_and_save_errors(project_root, json_report, bugs_out, xml_out): def print_and_save_errors(project_root, json_report, bugs_out, pmd_xml):
errors = utils.load_json_from_path(json_report) errors = utils.load_json_from_path(json_report)
errors = [e for e in errors if _is_user_visible(project_root, e)] errors = [e for e in errors if _is_user_visible(project_root, e)]
console_out = _text_of_report_list(project_root, errors, bugs_out, console_out = _text_of_report_list(project_root, errors, bugs_out,
limit=10) limit=10)
utils.stdout('\n' + console_out) utils.stdout('\n' + console_out)
plain_out = _text_of_report_list(project_root, errors, bugs_out, limit=-1, plain_out = _text_of_report_list(project_root, errors, bugs_out,
formatter=colorize.PLAIN_FORMATTER) formatter=colorize.PLAIN_FORMATTER)
with codecs.open(bugs_out, 'w', with codecs.open(bugs_out, 'w',
encoding=config.CODESET, errors='replace') as file_out: encoding=config.CODESET, errors='replace') as file_out:
file_out.write(plain_out) file_out.write(plain_out)
if xml_out is not None:
if pmd_xml:
xml_out = os.path.join(infer_out, config.PMD_XML_FILENAME)
with codecs.open(xml_out, 'w', with codecs.open(xml_out, 'w',
encoding=config.CODESET, encoding=config.CODESET,
errors='replace') as file_out: errors='replace') as file_out:

@ -0,0 +1,47 @@
#!/usr/bin/env python2.7
# Copyright (c) 2016 - present Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import os
import sys
import inferlib
from inferlib import config, issues, utils
arg_parser = argparse.ArgumentParser(add_help=False)
arg_parser.add_argument('--issues-csv', metavar='<file>',
help='Location of the csv report (ignored for now)')
arg_parser.add_argument('--issues-json', metavar='<file>', required=True,
help='Location of the json report')
arg_parser.add_argument('--issues-txt', metavar='<file>',
help='Location of the text report (ignored for now)')
arg_parser.add_argument('--issues-xml', metavar='<file>',
help='Location of the xml report (ignored for now)')
arg_parser.add_argument('--pmd-xml', action='store_true',
help='Output issues in (PMD) XML format.')
arg_parser.add_argument('--project-root', metavar='<directory>', required=True,
help='Location of the project root')
arg_parser.add_argument('--results-dir', metavar='<directory>', required=True,
help='Location of the results directory')
def main():
sys_argv = map(utils.decode, sys.argv)
args = arg_parser.parse_args(sys_argv[1:])
bugs_out = os.path.join(args.results_dir, config.BUGS_FILENAME)
issues.print_and_save_errors(args.project_root, args.issues_json, bugs_out,
args.pmd_xml)
if __name__ == '__main__':
main()
Loading…
Cancel
Save