diff --git a/Makefile b/Makefile index 338e35010..3d10531b7 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ ifeq ($(IS_FACEBOOK_TREE),yes) include $(ROOT_DIR)/facebook//Makefile.env endif -BUILD_SYSTEMS_TESTS = ant +BUILD_SYSTEMS_TESTS = ant project_root_rel DIRECT_TESTS= ifeq ($(BUILD_C_ANALYZERS),yes) diff --git a/infer/lib/python/inferlib/analyze.py b/infer/lib/python/inferlib/analyze.py index f43ad42e1..0540a02fa 100644 --- a/infer/lib/python/inferlib/analyze.py +++ b/infer/lib/python/inferlib/analyze.py @@ -93,6 +93,10 @@ base_group.add_argument('--pmd-xml', infer_parser = argparse.ArgumentParser(parents=[base_parser]) infer_group = infer_parser.add_argument_group('backend arguments') +infer_group.add_argument('-pr', '--project-root', + dest='project_root', + help='Location of the project root ' + '(default is current directory)') infer_group.add_argument('-j', '--multicore', metavar='n', type=int, default=multiprocessing.cpu_count(), dest='multicore', help='Set the number of cores to ' @@ -352,7 +356,7 @@ class AnalyzerWrapper(object): if self.args.pmd_xml: xml_out = os.path.join(self.args.infer_out, config.PMD_XML_FILENAME) - issues.print_and_save_errors(json_report, + issues.print_and_save_errors(self.args.project_root, json_report, bugs_out, xml_out) def analyze_and_report(self): diff --git a/infer/lib/python/inferlib/bucklib.py b/infer/lib/python/inferlib/bucklib.py index 319b20cea..4a9fad845 100644 --- a/infer/lib/python/inferlib/bucklib.py +++ b/infer/lib/python/inferlib/bucklib.py @@ -391,7 +391,8 @@ def collect_results(args, start_time, targets): if args.pmd_xml: xml_out = os.path.join(args.infer_out, config.PMD_XML_FILENAME) - issues.print_and_save_errors(json_report, bugs_out, xml_out) + 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))) diff --git a/infer/lib/python/inferlib/capture/buck.py b/infer/lib/python/inferlib/capture/buck.py index 712f180dc..8913700fc 100644 --- a/infer/lib/python/inferlib/capture/buck.py +++ b/infer/lib/python/inferlib/capture/buck.py @@ -207,7 +207,8 @@ class BuckAnalyzer: if self.args.pmd_xml: xml_out = os.path.join( self.args.infer_out, config.PMD_XML_FILENAME) - issues.print_and_save_errors(merged_reports_path, bugs_out, xml_out) + issues.print_and_save_errors(self.args.project_root, + merged_reports_path, bugs_out, xml_out) return os.EX_OK def capture_with_compilation_database(self): diff --git a/infer/lib/python/inferlib/issues.py b/infer/lib/python/inferlib/issues.py index 43d104be3..cfae34483 100644 --- a/infer/lib/python/inferlib/issues.py +++ b/infer/lib/python/inferlib/issues.py @@ -93,7 +93,8 @@ def text_of_report(report): ) -def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER): +def _text_of_report_list(project_root, reports, + formatter=colorize.TERMINAL_FORMATTER): text_errors_list = [] error_types_count = {} for report in reports: @@ -103,7 +104,7 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER): source_context = '' if formatter == colorize.TERMINAL_FORMATTER: source_context = source.build_source_context( - filename, + os.path.join(project_root, filename), formatter, line, ) @@ -166,18 +167,18 @@ def _text_of_report_list(reports, formatter=colorize.TERMINAL_FORMATTER): return msg -def _is_user_visible(report): +def _is_user_visible(project_root, report): filename = report[JSON_INDEX_FILENAME] kind = report[JSON_INDEX_KIND] - return (os.path.isfile(filename) and + return (os.path.isfile(os.path.join(project_root, filename)) and kind in [ISSUE_KIND_ERROR, ISSUE_KIND_WARNING, ISSUE_KIND_ADVICE]) -def print_and_save_errors(json_report, bugs_out, xml_out): +def print_and_save_errors(project_root, json_report, bugs_out, xml_out): errors = utils.load_json_from_path(json_report) - errors = filter(_is_user_visible, errors) - utils.stdout('\n' + _text_of_report_list(errors)) - plain_out = _text_of_report_list(errors, + errors = [e for e in errors if _is_user_visible(project_root, e)] + utils.stdout('\n' + _text_of_report_list(project_root, errors)) + plain_out = _text_of_report_list(project_root, errors, formatter=colorize.PLAIN_FORMATTER) with codecs.open(bugs_out, 'w', encoding=config.CODESET, errors='replace') as file_out: diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index 96386ee5e..e82db8bcc 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -129,6 +129,7 @@ let capture build_cmd = function "-l" :: (string_of_float Config.load_average) :: (if not Config.pmd_xml then [] else ["--pmd-xml"]) @ + ["--project-root"; Config.project_root] @ (if not Config.reactive_mode then [] else ["--reactive"]) @ "--out" :: Config.results_dir :: diff --git a/infer/tests/build_systems/project_root_rel/Makefile b/infer/tests/build_systems/project_root_rel/Makefile new file mode 100644 index 000000000..8732e4692 --- /dev/null +++ b/infer/tests/build_systems/project_root_rel/Makefile @@ -0,0 +1,16 @@ +# 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. + +TESTS_DIR = ../.. +include $(TESTS_DIR)/clang.make + +ANALYZER = infer +CLANG_OPTIONS = -c +INFER_OPTIONS = --report-custom-error --developer-mode --project-root ../../../tests + +SOURCES = \ + ../codetoanalyze/hello.c \ diff --git a/infer/tests/build_systems/project_root_rel/issues.exp b/infer/tests/build_systems/project_root_rel/issues.exp new file mode 100644 index 000000000..496da380b --- /dev/null +++ b/infer/tests/build_systems/project_root_rel/issues.exp @@ -0,0 +1 @@ +build_systems/codetoanalyze/hello.c, test, 2, NULL_DEREFERENCE