diff --git a/setup.py b/setup.py index a669b82a3..3b361d605 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ python_requires=">=3.8", install_requires=[ "packaging", - "prettytable>=3.3.0", + "prettytable>=3.10.2", "pycryptodome>=3.4.6", "crytic-compile>=0.3.7,<0.4.0", # "crytic-compile@git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile", diff --git a/slither/printers/summary/loc.py b/slither/printers/summary/loc.py index 35bb20fc4..886803e8e 100644 --- a/slither/printers/summary/loc.py +++ b/slither/printers/summary/loc.py @@ -17,8 +17,8 @@ class LocPrinter(AbstractPrinter): ARGUMENT = "loc" - HELP = """Count the total number lines of code (LOC), source lines of code (SLOC), \ - and comment lines of code (CLOC) found in source files (SRC), dependencies (DEP), \ + HELP = """Count the total number lines of code (LOC), source lines of code (SLOC), + and comment lines of code (CLOC) found in source files (SRC), dependencies (DEP), and test files (TEST).""" WIKI = "https://github.com/trailofbits/slither/wiki/Printer-documentation#loc" diff --git a/slither/utils/command_line.py b/slither/utils/command_line.py index f5b9ab452..b8888cb85 100644 --- a/slither/utils/command_line.py +++ b/slither/utils/command_line.py @@ -360,8 +360,10 @@ def output_printers(printer_classes: List[Type[AbstractPrinter]]) -> None: printers_list = sorted(printers_list, key=lambda element: (element[0])) idx = 1 for (argument, help_info) in printers_list: - table.add_row([str(idx), argument, help_info]) + # Clean multi line HELP info + table.add_row([str(idx), argument, " ".join(x.strip() for x in help_info.splitlines())]) idx = idx + 1 + print(table) diff --git a/slither/utils/myprettytable.py b/slither/utils/myprettytable.py index b33fb9c5f..ac666a501 100644 --- a/slither/utils/myprettytable.py +++ b/slither/utils/myprettytable.py @@ -1,3 +1,4 @@ +from shutil import get_terminal_size from typing import List, Dict, Union from prettytable import PrettyTable @@ -7,7 +8,12 @@ class MyPrettyTable: - def __init__(self, field_names: List[str], pretty_align: bool = True): # TODO: True by default? + def __init__( + self, + field_names: List[str], + pretty_align: bool = True, + max_width: Union[int, None] = "max", # Default value is "max" + ): self._field_names = field_names self._rows: List = [] self._options: Dict = {} @@ -19,6 +25,17 @@ def __init__(self, field_names: List[str], pretty_align: bool = True): # TODO: else: self._options["set_alignment"] = [] + self.max_width = None + if max_width == "max": + # We use (0,0) as a fallback to detect if we are not attached to a terminal + # In this case, we fall back to the default behavior (i.e. printing as much as possible) + terminal_column = get_terminal_size((0, 0)).columns + if terminal_column != 0: + # We reduce slightly the max-width to take into account inconsistencies in terminals + self.max_width = terminal_column - 3 + else: + self.max_width = max_width + def add_row(self, row: List[Union[str, List[str]]]) -> None: self._rows.append(row) @@ -28,6 +45,9 @@ def to_pretty_table(self) -> PrettyTable: else: table = PrettyTable(self._field_names) + if self.max_width is not None: + table.max_table_width = self.max_width + for row in self._rows: table.add_row(row) if len(self._options["set_alignment"]): @@ -63,7 +83,5 @@ def make_pretty_table( table_row = [row] + [body[row][key] for key in headers[1:]] table.add_row(table_row) if totals: - table.add_row( - [total_header] + [sum([body[row][key] for row in body]) for key in headers[1:]] - ) + table.add_row([total_header] + [sum(body[row][key] for row in body) for key in headers[1:]]) return table