feat: make tables fit within terminal by default (#2426)

This PR adds a `max_width` parameter to MyPrettyTable to restrict the maximum width of its underlying table.

The value can be an integer, "max" (detect automatically the correct width) or None (no width limit)

* Add a new parameter `max_width` to MyPrettyTable to enhance its display for CLI usage

* Fix the description of the Loc printer, and adjust the maximal width.

* bump prettytable

* default all prettytable's to fit within max terminal width

---------

Co-authored-by: alpharush <0xalpharush@protonmail.com>
pull/2289/merge
dm 4 months ago committed by GitHub
parent 7c7b71ff60
commit 48815192f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      setup.py
  2. 4
      slither/printers/summary/loc.py
  3. 4
      slither/utils/command_line.py
  4. 26
      slither/utils/myprettytable.py

@ -13,7 +13,7 @@ setup(
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",

@ -17,8 +17,8 @@ from slither.utils.output import Output
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"

@ -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)

@ -1,3 +1,4 @@
from shutil import get_terminal_size
from typing import List, Dict, Union
from prettytable import PrettyTable
@ -7,7 +8,12 @@ from slither.utils.colors import Colors
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 @@ class MyPrettyTable:
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 @@ class MyPrettyTable:
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

Loading…
Cancel
Save