Source code for mythx_cli.formatter.simple_stdout

"""This module contains a simple text formatter class printing a subset of the response data."""

from typing import List, Union

import click
from mythx_models.response import (
    AnalysisInputResponse,
    AnalysisListResponse,
    AnalysisStatusResponse,
    DetectedIssuesResponse,
    VersionResponse,
)

from mythx_cli.formatter.base import BaseFormatter
from mythx_cli.util import get_source_location_by_offset


[docs]class SimpleFormatter(BaseFormatter):
[docs] @staticmethod def format_analysis_list(resp: AnalysisListResponse) -> str: """Format an analysis list response to a simple text representation.""" res = [] for analysis in resp: res.append("UUID: {}".format(analysis.uuid)) res.append("Submitted at: {}".format(analysis.submitted_at)) res.append("Status: {}".format(analysis.status)) res.append("") return "\n".join(res)
[docs] @staticmethod def format_analysis_status(resp: AnalysisStatusResponse) -> str: """Format an analysis status response to a simple text representation.""" res = [ "UUID: {}".format(resp.uuid), "Submitted at: {}".format(resp.submitted_at), "Status: {}".format(resp.status), "", ] return "\n".join(res)
[docs] @staticmethod def format_detected_issues( resp: DetectedIssuesResponse, inp: AnalysisInputResponse ) -> str: """Format an issue report to a simple text representation.""" res = [] ctx = click.get_current_context() # TODO: Sort by file for report in resp.issue_reports: for issue in report.issues: res.append("UUID: {}".format(ctx.obj["uuid"])) res.append( "Title: {} ({})".format(issue.swc_title or "-", issue.severity) ) res.append("Description: {}".format(issue.description_long)) res.append("") for loc in issue.locations: comp = loc.source_map.components[0] source_list = loc.source_list or report.source_list if source_list and 0 >= comp.file_id < len(source_list): filename = source_list[comp.file_id] if filename not in inp.sources: # Skip files we don't have source for (e.g. with unresolved bytecode hashes) res.append("") continue line = get_source_location_by_offset( inp.sources[filename]["source"], comp.offset ) snippet = inp.sources[filename]["source"].split("\n")[line - 1] res.append("{}:{}".format(filename, line)) res.append(snippet) res.append("") return "\n".join(res)
[docs] @staticmethod def format_version(resp: VersionResponse) -> str: """Format a version response to a simple text representation.""" return "\n".join( [ "API: {}".format(resp.api_version), "Harvey: {}".format(resp.harvey_version), "Maru: {}".format(resp.maru_version), "Mythril: {}".format(resp.mythril_version), "Hashed: {}".format(resp.hashed_version), ] )