Skip to content

Commit 8149d13

Browse files
committed
align the format of printing report urls and errors across all printers; separate printing of summary using blank lines
1 parent c1ddb7b commit 8149d13

File tree

9 files changed

+42
-51
lines changed

9 files changed

+42
-51
lines changed

cycode/cli/apps/scan/code_scanner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ def print_results(
571571
ctx: typer.Context, local_scan_results: list[LocalScanResult], errors: Optional[dict[str, 'CliError']] = None
572572
) -> None:
573573
printer = ctx.obj.get('console_printer')
574+
printer.update_ctx(ctx)
574575
printer.print_scan_results(local_scan_results, errors)
575576

576577

cycode/cli/printers/console_printer.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ def printer(self) -> 'PrinterBase':
7070

7171
return printer_class(self.ctx, self.console, self.console_err)
7272

73+
def update_ctx(self, ctx: 'typer.Context') -> None:
74+
self.ctx = ctx
75+
7376
def enable_recording(self, export_type: str, export_file: 'Path') -> None:
7477
if self.console_record is None:
7578
self.export_file = export_file
@@ -117,6 +120,7 @@ def export(self) -> None:
117120
# resolve file extension based on the export type if not provided in the file name
118121
export_file = export_file.with_suffix(f'.{self.export_type.lower()}')
119122

123+
export_file = str(export_file)
120124
if self.export_type is ExportTypeOption.HTML:
121125
self.console_record.console.save_html(export_file)
122126
elif self.export_type is ExportTypeOption.SVG:

cycode/cli/printers/printer_base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
class PrinterBase(ABC):
2222
NO_DETECTIONS_MESSAGE = (
23-
'[green]Good job! No issues were found!!! :clapping_hands::clapping_hands::clapping_hands:[/]'
23+
'[b green]Good job! No issues were found!!! :clapping_hands::clapping_hands::clapping_hands:[/]'
2424
)
2525
FAILED_SCAN_MESSAGE = (
26-
'[red]Unfortunately, Cycode was unable to complete the full scan. '
26+
'[b red]Unfortunately, Cycode was unable to complete the full scan. '
2727
'Please note that not all results may be available:[/]'
2828
)
2929

@@ -99,6 +99,7 @@ def print_scan_results_summary(self, local_scan_results: list['LocalScanResult']
9999
detections_count += 1
100100
severity_counts[SeverityOption(detection.severity)] += 1
101101

102+
self.console.line()
102103
self.console.print(f'[bold]Cycode found {detections_count} violations[/]', end=': ')
103104

104105
# Example of string: CRITICAL - 6 | HIGH - 0 | MEDIUM - 14 | LOW - 0 | INFO - 0
@@ -110,3 +111,5 @@ def print_scan_results_summary(self, local_scan_results: list['LocalScanResult']
110111
self.console.print(
111112
SeverityOption.get_member_emoji(severity), severity, '-', severity_counts[severity], end=end
112113
)
114+
115+
self.console.line()

cycode/cli/printers/tables/sca_table_printer.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from cycode.cli.printers.tables.table import Table
88
from cycode.cli.printers.tables.table_models import ColumnInfoBuilder
99
from cycode.cli.printers.tables.table_printer_base import TablePrinterBase
10+
from cycode.cli.printers.utils import is_git_diff_based_scan
1011
from cycode.cli.printers.utils.detection_ordering.sca_ordering import sort_and_group_detections
1112
from cycode.cli.utils.string_utils import shortcut_dependency_paths
1213

@@ -31,23 +32,19 @@
3132

3233
class ScaTablePrinter(TablePrinterBase):
3334
def _print_results(self, local_scan_results: list['LocalScanResult']) -> None:
34-
aggregation_report_url = self.ctx.obj.get('aggregation_report_url')
3535
detections_per_policy_id = self._extract_detections_per_policy_id(local_scan_results)
3636
for policy_id, detections in detections_per_policy_id.items():
3737
table = self._get_table(policy_id)
3838

3939
resulting_detections, group_separator_indexes = sort_and_group_detections(detections)
4040
for detection in resulting_detections:
41-
self._enrich_table_with_values(policy_id, table, detection)
41+
self._enrich_table_with_values(table, detection)
4242

4343
table.set_group_separator_indexes(group_separator_indexes)
4444

4545
self._print_summary_issues(len(detections), self._get_title(policy_id))
4646
self._print_table(table)
4747

48-
self.print_scan_results_summary(local_scan_results)
49-
self._print_report_urls(local_scan_results, aggregation_report_url)
50-
5148
@staticmethod
5249
def _get_title(policy_id: str) -> str:
5350
if policy_id == PACKAGE_VULNERABILITY_POLICY_ID:
@@ -66,7 +63,7 @@ def _get_table(self, policy_id: str) -> Table:
6663
elif policy_id == LICENSE_COMPLIANCE_POLICY_ID:
6764
table.add_column(LICENSE_COLUMN)
6865

69-
if self._is_git_repository():
66+
if is_git_diff_based_scan(self.scan_type, self.command_scan_type):
7067
table.add_column(REPOSITORY_COLUMN)
7168

7269
table.add_column(SEVERITY_COLUMN)
@@ -80,7 +77,7 @@ def _get_table(self, policy_id: str) -> Table:
8077
return table
8178

8279
@staticmethod
83-
def _enrich_table_with_values(policy_id: str, table: Table, detection: Detection) -> None:
80+
def _enrich_table_with_values(table: Table, detection: Detection) -> None:
8481
detection_details = detection.detection_details
8582

8683
if detection.severity:

cycode/cli/printers/tables/table_printer.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from cycode.cli.printers.tables.table import Table
77
from cycode.cli.printers.tables.table_models import ColumnInfoBuilder
88
from cycode.cli.printers.tables.table_printer_base import TablePrinterBase
9+
from cycode.cli.printers.utils import is_git_diff_based_scan
910
from cycode.cli.printers.utils.detection_ordering.common_ordering import sort_and_group_detections_from_scan_result
1011
from cycode.cli.utils.string_utils import get_position_in_line, obfuscate_text
1112

@@ -37,8 +38,6 @@ def _print_results(self, local_scan_results: list['LocalScanResult']) -> None:
3738
table.set_group_separator_indexes(group_separator_indexes)
3839

3940
self._print_table(table)
40-
self.print_scan_results_summary(local_scan_results)
41-
self._print_report_urls(local_scan_results, self.ctx.obj.get('aggregation_report_url'))
4241

4342
def _get_table(self) -> Table:
4443
table = Table()
@@ -49,7 +48,7 @@ def _get_table(self) -> Table:
4948
table.add_column(LINE_NUMBER_COLUMN)
5049
table.add_column(COLUMN_NUMBER_COLUMN)
5150

52-
if self._is_git_repository():
51+
if is_git_diff_based_scan(self.scan_type, self.command_scan_type):
5352
table.add_column(COMMIT_SHA_COLUMN)
5453

5554
if self.scan_type == SECRET_SCAN_TYPE:

cycode/cli/printers/tables/table_printer_base.py

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111

1212

1313
class TablePrinterBase(PrinterBase, abc.ABC):
14+
def __init__(self, *args, **kwargs) -> None:
15+
super().__init__(*args, **kwargs)
16+
self.text_printer = TextPrinter(self.ctx, self.console, self.console_err)
17+
1418
def print_result(self, result: CliResult) -> None:
15-
TextPrinter(self.ctx, self.console, self.console_err).print_result(result)
19+
self.text_printer.print_result(result)
1620

1721
def print_error(self, error: CliError) -> None:
18-
TextPrinter(self.ctx, self.console, self.console_err).print_error(error)
22+
self.text_printer.print_error(error)
1923

2024
def print_scan_results(
2125
self, local_scan_results: list['LocalScanResult'], errors: Optional[dict[str, 'CliError']] = None
@@ -26,16 +30,8 @@ def print_scan_results(
2630

2731
self._print_results(local_scan_results)
2832

29-
if not errors:
30-
return
31-
32-
self.console.print(self.FAILED_SCAN_MESSAGE)
33-
for scan_id, error in errors.items():
34-
self.console.print(f'- {scan_id}: ', end='')
35-
self.print_error(error)
36-
37-
def _is_git_repository(self) -> bool:
38-
return self.ctx.info_name in {'commit_history', 'pre_commit', 'pre_receive'} and 'remote_url' in self.ctx.obj
33+
self.print_scan_results_summary(local_scan_results)
34+
self.text_printer.print_report_urls_and_errors(local_scan_results, errors)
3935

4036
@abc.abstractmethod
4137
def _print_results(self, local_scan_results: list['LocalScanResult']) -> None:
@@ -44,19 +40,3 @@ def _print_results(self, local_scan_results: list['LocalScanResult']) -> None:
4440
def _print_table(self, table: 'Table') -> None:
4541
if table.get_rows():
4642
self.console.print(table.get_table())
47-
48-
def _print_report_urls(
49-
self,
50-
local_scan_results: list['LocalScanResult'],
51-
aggregation_report_url: Optional[str] = None,
52-
) -> None:
53-
report_urls = [scan_result.report_url for scan_result in local_scan_results if scan_result.report_url]
54-
if not report_urls and not aggregation_report_url:
55-
return
56-
if aggregation_report_url:
57-
self.console.print(f'Report URL: {aggregation_report_url}')
58-
return
59-
60-
self.console.print('Report URLs:')
61-
for report_url in report_urls:
62-
self.console.print(f'- {report_url}')

cycode/cli/printers/text_printer.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,15 @@ def print_report_urls_and_errors(
9898
def print_report_urls(self, report_urls: list[str], aggregation_report_url: Optional[str] = None) -> None:
9999
if not report_urls and not aggregation_report_url:
100100
return
101-
if aggregation_report_url:
102-
self.console.print(f'Report URL: {aggregation_report_url}')
101+
102+
# Prioritize aggregation report URL; if report urls is only one, use it instead
103+
single_url = report_urls[0] if len(report_urls) == 1 else None
104+
single_url = aggregation_report_url or single_url
105+
if single_url:
106+
self.console.print(f'[b]Report URL:[/] {single_url}')
103107
return
104108

105-
self.console.print('Report URLs:')
109+
# If there are multiple report URLs, print them all
110+
self.console.print('[b]Report URLs:[/]')
106111
for report_url in report_urls:
107112
self.console.print(f'- {report_url}')
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from cycode.cli import consts
2+
3+
4+
def is_git_diff_based_scan(scan_type: str, command_scan_type: str) -> bool:
5+
return (
6+
command_scan_type in consts.COMMIT_RANGE_BASED_COMMAND_SCAN_TYPES
7+
and scan_type in consts.COMMIT_RANGE_SCAN_SUPPORTED_SCAN_TYPES
8+
)

cycode/cli/printers/utils/code_snippet_syntax.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from cycode.cli import consts
77
from cycode.cli.console import _SYNTAX_HIGHLIGHT_THEME
8+
from cycode.cli.printers.utils import is_git_diff_based_scan
89
from cycode.cli.utils.string_utils import get_position_in_line, obfuscate_text
910

1011
if TYPE_CHECKING:
@@ -91,13 +92,6 @@ def _get_code_snippet_syntax_from_git_diff(
9192
)
9293

9394

94-
def _is_git_diff_based_scan(scan_type: str, command_scan_type: str) -> bool:
95-
return (
96-
command_scan_type in consts.COMMIT_RANGE_BASED_COMMAND_SCAN_TYPES
97-
and scan_type in consts.COMMIT_RANGE_SCAN_SUPPORTED_SCAN_TYPES
98-
)
99-
100-
10195
def get_code_snippet_syntax(
10296
scan_type: str,
10397
command_scan_type: str,
@@ -106,7 +100,7 @@ def get_code_snippet_syntax(
106100
lines_to_display: int = 3,
107101
obfuscate: bool = True,
108102
) -> Syntax:
109-
if _is_git_diff_based_scan(scan_type, command_scan_type):
103+
if is_git_diff_based_scan(scan_type, command_scan_type):
110104
# it will return syntax with just one line
111105
return _get_code_snippet_syntax_from_git_diff(scan_type, detection, document, obfuscate)
112106

0 commit comments

Comments
 (0)