Skip to content

Commit

Permalink
[report-converter] Support sarif format
Browse files Browse the repository at this point in the history
Fixes #1797. Based on a commit authored by @csordasmarton. Credit goes
to him!

We've long wanted to support sarif
(https://sarifweb.azurewebsites.net/), and finally, this is the first
real step towards it!

This patch can both parse and and export to sarif.
  • Loading branch information
csordasmarton authored and Szelethus committed Sep 18, 2023
1 parent c3dbb1b commit e7aee25
Show file tree
Hide file tree
Showing 8 changed files with 450 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

import logging
from typing import Dict, List

from codechecker_report_converter.report import Report
from codechecker_report_converter.report.parser import sarif

from ..analyzer_result import AnalyzerResultBase


LOG = logging.getLogger('report-converter')


class AnalyzerResult(AnalyzerResultBase):
""" Transform analyzer result of the FB Infer. """

TOOL_NAME = 'gcc'
NAME = 'GNU Compiler Collection Static Analyzer'
URL = 'https://gcc.gnu.org/wiki/StaticAnalyzer'

def __init__(self):
super(AnalyzerResult, self).__init__()
self.__infer_out_parent_dir = None
self._file_cache: Dict[str, File] = {}

def get_reports(self, result_file_path: str) -> List[Report]:
""" Get reports from the given analyzer result file. """

return sarif.Parser().get_reports(result_file_path)
9 changes: 6 additions & 3 deletions tools/report-converter/codechecker_report_converter/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class RawDescriptionDefaultHelpFormatter(
analyzer_result = getattr(module, "AnalyzerResult")
supported_converters[analyzer_result.TOOL_NAME] = analyzer_result
except ModuleNotFoundError:
pass
raise


supported_metadata_keys = ["analyzer_command", "analyzer_version"]
Expand Down Expand Up @@ -188,6 +188,9 @@ def __add_arguments_to_parser(parser):
"Currently supported output types are: " +
', '.join(sorted(supported_converters)) + ".")

extensions_with_dot = \
sorted([f".{ext}" for ext in SUPPORTED_ANALYZER_EXTENSIONS])

parser.add_argument('-e', '--export',
type=str,
dest='export',
Expand All @@ -196,8 +199,8 @@ def __add_arguments_to_parser(parser):
default=plist.EXTENSION,
help="Specify the export format of the converted "
"reports. Currently supported export types "
"are: " + ', '.join(sorted(
SUPPORTED_ANALYZER_EXTENSIONS)) + ".")
"are: " +
', '.join(extensions_with_dot) + ".")

parser.add_argument('--meta',
nargs='*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
"""

import logging
import os

from abc import ABCMeta, abstractmethod
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple

from codechecker_report_converter import __title__, __version__
from codechecker_report_converter.report import File, Report
from codechecker_report_converter.report.checker_labels import CheckerLabels
from codechecker_report_converter.report.hash import HashType
Expand Down Expand Up @@ -44,6 +46,26 @@ def get_severity(self, checker_name: str) -> Optional[str]:
return self._checker_labels.severity(checker_name)
return None

def get_tool_info(self) -> Tuple[str, str]:
""" Get tool info.
If this was called through CodeChecker, this function will return
CodeChecker information, otherwise this tool (report-converter)
information.
"""
data_files_dir_path = os.environ.get('CC_DATA_FILES_DIR')
if data_files_dir_path:
analyzer_version_file_path = os.path.join(
data_files_dir_path, 'config', 'analyzer_version.json')
if os.path.exists(analyzer_version_file_path):
data = self.__load_json(analyzer_version_file_path)
version = data.get('version')
if version:
return 'CodeChecker', f"{version['major']}." \
f"{version['minor']}.{version['revision']}"

return __title__, __version__

@abstractmethod
def get_reports(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
else:
from mypy_extensions import TypedDict

from codechecker_report_converter import __title__, __version__
from codechecker_report_converter.report import BugPathEvent, \
BugPathPosition, File, get_or_create_file, MacroExpansion, Range, Report
from codechecker_report_converter.report.hash import get_report_hash, HashType
Expand Down Expand Up @@ -447,33 +446,13 @@ def __load_json(self, path: str):

return ret

def __get_tool_info(self) -> Tuple[str, str]:
""" Get tool info.
If this was called through CodeChecker, this function will return
CodeChecker information, otherwise this tool (report-converter)
information.
"""
data_files_dir_path = os.environ.get('CC_DATA_FILES_DIR')
if data_files_dir_path:
analyzer_version_file_path = os.path.join(
data_files_dir_path, 'config', 'analyzer_version.json')
if os.path.exists(analyzer_version_file_path):
data = self.__load_json(analyzer_version_file_path)
version = data.get('version')
if version:
return 'CodeChecker', f"{version['major']}." \
f"{version['minor']}.{version['revision']}"

return __title__, __version__

def convert(
self,
reports: List[Report],
analyzer_info: Optional[AnalyzerInfo] = None
):
""" Converts the given reports. """
tool_name, tool_version = self.__get_tool_info()
tool_name, tool_version = self.get_tool_info()

data: Dict[str, Any] = {
'files': [],
Expand Down
Loading

0 comments on commit e7aee25

Please sign in to comment.