diff --git a/cycode/cli/consts.py b/cycode/cli/consts.py index 3b0aaafe..f37bbdef 100644 --- a/cycode/cli/consts.py +++ b/cycode/cli/consts.py @@ -126,3 +126,8 @@ LICENSE_COMPLIANCE_POLICY_ID = '8f681450-49e1-4f7e-85b7-0c8fe84b3a35' PACKAGE_VULNERABILITY_POLICY_ID = '9369d10a-9ac0-48d3-9921-5de7fe9a37a7' + +# Shortcut dependency paths by remove all middle depndencies between direct dependency and influence/vulnerable dependency. +# Example: A -> B -> C +# Result: A -> ... -> C +SCA_SHORTCUT_DEPENDENCY_PATHS = 2 diff --git a/cycode/cli/printers/sca_table_printer.py b/cycode/cli/printers/sca_table_printer.py index ca441ca6..7feac6b1 100644 --- a/cycode/cli/printers/sca_table_printer.py +++ b/cycode/cli/printers/sca_table_printer.py @@ -7,6 +7,7 @@ from cycode.cli.consts import LICENSE_COMPLIANCE_POLICY_ID, PACKAGE_VULNERABILITY_POLICY_ID from cycode.cli.models import DocumentDetections, Detection from cycode.cli.printers.base_table_printer import BaseTablePrinter +from cycode.cli.utils.string_utils import shortcut_dependency_paths SEVERITY_COLUMN = 'Severity' LICENSE_COLUMN = 'License' @@ -108,20 +109,11 @@ def set_table_width(headers: List[str], text_table: Texttable) -> None: def _print_summary_issues(detections: List, title: str) -> None: click.echo(f'⛔ Found {len(detections)} issues of type: {click.style(title, bold=True)}') - @staticmethod - def _shortcut_dependency_paths(dependency_paths: str) -> str: - dependencies = dependency_paths.split(' -> ') - - if len(dependencies) < 2: - return dependencies[0] - - return f'{dependencies[0]} -> ... -> {dependencies[-1]}' - def _get_common_detection_fields(self, detection: Detection) -> List[str]: dependency_paths = 'N/A' dependency_paths_raw = detection.detection_details.get('dependency_paths') if dependency_paths_raw: - dependency_paths = self._shortcut_dependency_paths(dependency_paths_raw) + dependency_paths = shortcut_dependency_paths(dependency_paths_raw) row = [ detection.detection_details.get('file_name'), @@ -129,7 +121,7 @@ def _get_common_detection_fields(self, detection: Detection) -> List[str]: detection.detection_details.get('package_name'), detection.detection_details.get('is_direct_dependency_str'), detection.detection_details.get('is_dev_dependency_str'), - dependency_paths, + dependency_paths ] if self._is_git_repository(): diff --git a/cycode/cli/utils/string_utils.py b/cycode/cli/utils/string_utils.py index 0e7d0c23..f301f9ac 100644 --- a/cycode/cli/utils/string_utils.py +++ b/cycode/cli/utils/string_utils.py @@ -6,6 +6,8 @@ from sys import getsizeof from binaryornot.check import is_binary_string +from cycode.cli.consts import SCA_SHORTCUT_DEPENDENCY_PATHS + def obfuscate_text(text: str) -> str: match_len = len(text) @@ -47,3 +49,18 @@ def generate_random_string(string_len: int): def get_position_in_line(text: str, position: int) -> int: return position - text.rfind('\n', 0, position) - 1 + + +def shortcut_dependency_paths(dependency_paths_list: str) -> str: + separate_dependency_paths_list = dependency_paths_list.split(',') + result = '' + for dependency_paths in separate_dependency_paths_list: + dependency_paths = dependency_paths.strip().rstrip() + dependencies = dependency_paths.split(' -> ') + if len(dependencies) <= SCA_SHORTCUT_DEPENDENCY_PATHS: + result += dependency_paths + else: + result += f'{dependencies[0]} -> ... -> {dependencies[-1]}' + result += '\n\n' + + return result.rstrip().rstrip(',') diff --git a/tests/utils/test_string_utils.py b/tests/utils/test_string_utils.py new file mode 100644 index 00000000..7b20fd4c --- /dev/null +++ b/tests/utils/test_string_utils.py @@ -0,0 +1,7 @@ +from cycode.cli.utils.string_utils import shortcut_dependency_paths + + +def test_shortcut_dependency_paths_list_single_dependencies(): + dependency_paths = "A, A -> B, A -> B -> C" + expected_result = "A\n\nA -> B\n\nA -> ... -> C" + assert shortcut_dependency_paths(dependency_paths) == expected_result