Source code for statick_tool.plugins.reporting.json

"""Prints the Statick reports out to the terminal or file in JSON format."""

import json
import logging
import os
from collections import OrderedDict
from typing import Optional, Tuple, Union

from statick_tool.issue import Issue
from statick_tool.package import Package
from statick_tool.reporting_plugin import ReportingPlugin


[docs] class JsonReportingPlugin(ReportingPlugin): """Prints the Statick reports out to the terminal or file in JSON format."""
[docs] def get_name(self) -> str: """Return the plugin name.""" return "json"
[docs] def report( self, package: Package, issues: dict[str, list[Issue]], level: str ) -> Tuple[Optional[None], bool]: """Go through the issues list and print them in JSON format. Args: package: The Package object that was analyzed. issues: The issues found by the Statick analysis, keyed by the tool that found them. level: Name of the level used in the scan. Returns: None, True if the report was successfully printed, otherwise None, False. """ if not self.plugin_context or not self.plugin_context.config: return None, False file_output = False terminal_output = False file_output_str = self.plugin_context.config.get_reporting_config( self.get_name(), level, "files" ) if file_output_str and file_output_str.lower() == "true": file_output = True terminal_output_str = self.plugin_context.config.get_reporting_config( self.get_name(), level, "terminal" ) if terminal_output_str and terminal_output_str.lower() == "true": terminal_output = True all_issues = [] for _, value in issues.items(): for issue in value: issue_dict: OrderedDict[str, Union[str, int]] = OrderedDict() issue_dict["fileName"] = issue.filename issue_dict["lineNumber"] = issue.line_number issue_dict["tool"] = issue.tool issue_dict["type"] = issue.issue_type issue_dict["severity"] = issue.severity issue_dict["message"] = issue.message issue_dict["certReference"] = "" if issue.cert_reference: issue_dict["certReference"] = issue.cert_reference all_issues.append(issue_dict) report_json = {"issues": all_issues} line = json.dumps(report_json) if file_output: if not self.write_output(package, level, line): return None, False if terminal_output: print(line) return None, True
[docs] def write_output(self, package: Package, level: str, line: str) -> bool: """Write JSON output to a file. Args: package: The Package object that was analyzed. level: Name of the level used in the scan. line: The JSON string to write to the file. Returns: True if the output was successfully written, otherwise False. """ # By default write report to the current directory. output_dir = os.getcwd() if ( self.plugin_context and "output_directory" in self.plugin_context.args and self.plugin_context.args.output_directory is not None ): # If an output directory is specified use it for the report. output_dir = os.path.join( self.plugin_context.args.output_directory, package.name + "-" + level ) if not os.path.exists(output_dir): os.mkdir(output_dir) if not os.path.isdir(output_dir): logging.error("Unable to create output directory at %s!", output_dir) return False output_file = os.path.join( output_dir, package.name + "-" + level + ".statick.json" ) logging.info("Writing output to %s", output_file) with open(output_file, "w", encoding="utf8") as out: out.write(line) return True