88from git import Repo , NULL_TREE , InvalidGitRepositoryError
99from sys import getsizeof
1010from cli import printer
11+ from cli .printers import ResultsPrinter
1112from typing import List , Dict
12- from cli .models import Document , DetectionDetails
13+ from cli .models import Document , DocumentDetections
1314from cli .ci_integrations import get_commit_range
1415from cli .consts import SECRET_SCAN_TYPE , INFRA_CONFIGURATION_SCAN_TYPE , INFRA_CONFIGURATION_SCAN_SUPPORTED_FILES , \
1516 SECRET_SCAN_FILE_EXTENSIONS_TO_IGNORE , EXCLUSIONS_BY_VALUE_SECTION_NAME , EXCLUSIONS_BY_SHA_SECTION_NAME , \
2122from cli .zip_file import InMemoryZip
2223from cli .exceptions .custom_exceptions import CycodeError , HttpUnauthorizedError , ZipTooLargeError
2324from cyclient import logger
25+ from cyclient .models import ZippedFileScanResult
2426
2527start_scan_time = time .time ()
2628
@@ -43,7 +45,7 @@ def scan_repository(context: click.Context, path, branch):
4345 in get_git_repository_tree_file_entries (path , branch )]
4446 documents_to_scan = exclude_irrelevant_documents_to_scan (context , documents_to_scan )
4547 logger .debug ('Found all relevant files for scanning %s' , {'path' : path , 'branch' : branch })
46- return scan_documents (context . obj [ "scan_type" ] , documents_to_scan , is_git_diff = False )
48+ return scan_documents (context , documents_to_scan , is_git_diff = False )
4749 except Exception as e :
4850 _handle_exception (context , e )
4951
@@ -64,12 +66,11 @@ def scan_repository_commit_history(context: click.Context, path: str, commit_ran
6466 """ Scan all the commits history in this git repository """
6567 try :
6668 logger .debug ('Starting commit history scan process, %s' , {'path' : path , 'commit_range' : commit_range })
67- return scan_commit_range (path = path , commit_range = commit_range )
69+ return scan_commit_range (context , path = path , commit_range = commit_range )
6870 except Exception as e :
6971 _handle_exception (context , e )
7072
7173
72- @click .pass_context
7374def scan_commit_range (context : click .Context , path : str , commit_range : str ):
7475 scan_type = context .obj ["scan_type" ]
7576
@@ -88,14 +89,15 @@ def scan_commit_range(context: click.Context, path: str, commit_range: str):
8889
8990 documents_to_scan = exclude_irrelevant_documents_to_scan (context , documents_to_scan )
9091 logger .debug ('Found all relevant files for scanning %s' , {'path' : path , 'commit_range' : commit_range })
91- return scan_documents (context . obj [ "scan_type" ] , documents_to_scan , is_git_diff = True , is_commit_range = True )
92+ return scan_documents (context , documents_to_scan , is_git_diff = True , is_commit_range = True )
9293
9394
9495@click .command ()
95- def scan_ci ():
96+ @click .pass_context
97+ def scan_ci (context : click .Context ):
9698 """ Execute scan in a CI environment which relies on the
9799 CYCODE_TOKEN and CYCODE_REPO_LOCATION environment variables """
98- return scan_commit_range (path = os .getcwd (), commit_range = get_commit_range ())
100+ return scan_commit_range (context , path = os .getcwd (), commit_range = get_commit_range ())
99101
100102
101103@click .command ()
@@ -107,7 +109,7 @@ def scan_path(context: click.Context, path):
107109 files_to_scan = get_relevant_files_in_path (path = path , exclude_patterns = ["**/.git/**" , "**/.cycode/**" ])
108110 files_to_scan = exclude_irrelevant_files (context , files_to_scan )
109111 logger .debug ('Found all relevant files for scanning %s' , {'path' : path , 'file_to_scan_count' : len (files_to_scan )})
110- return scan_disk_files (context . obj [ "scan_type" ] , files_to_scan )
112+ return scan_disk_files (context , files_to_scan )
111113
112114
113115@click .command ()
@@ -117,27 +119,26 @@ def pre_commit_scan(context: click.Context, ignored_args: List[str]):
117119 """ Use this command to scan the content that was not committed yet """
118120 diff_files = Repo (os .getcwd ()).index .diff ("HEAD" , create_patch = True , R = True )
119121 documents_to_scan = [Document (get_path_by_os (get_diff_file_path (file )), get_diff_file_content (file ))
120- for file in diff_files ]
122+ for file in diff_files ]
121123 documents_to_scan = exclude_irrelevant_documents_to_scan (context , documents_to_scan )
122- return scan_documents (context . obj [ "scan_type" ] , documents_to_scan , is_git_diff = True )
124+ return scan_documents (context , documents_to_scan , is_git_diff = True )
123125
124126
125- @click .pass_context
126- def scan_disk_files (context : click .Context , scan_type : str , paths : List [str ]):
127+ def scan_disk_files (context : click .Context , paths : List [str ]):
127128 is_git_diff = False
128129 documents = []
129130 for path in paths :
130131 with open (path , "r" , encoding = "utf-8" ) as f :
131132 content = f .read ()
132133 documents .append (Document (path , content , is_git_diff ))
133134
134- return scan_documents (scan_type , documents , is_git_diff = is_git_diff )
135+ return scan_documents (context , documents , is_git_diff = is_git_diff )
135136
136137
137- @click .pass_context
138- def scan_documents (context : click .Context , scan_type : str , documents_to_scan : List [Document ],
138+ def scan_documents (context : click .Context , documents_to_scan : List [Document ],
139139 is_git_diff : bool = False , is_commit_range : bool = False ):
140140 cycode_client = context .obj ["client" ]
141+ scan_type = context .obj ["scan_type" ]
141142 scan_command_type = context .info_name
142143 error_message = None
143144 all_detections_count = 0
@@ -148,9 +149,16 @@ def scan_documents(context: click.Context, scan_type: str, documents_to_scan: Li
148149 try :
149150 zipped_documents = zip_documents_to_scan (zipped_documents , documents_to_scan )
150151 scan_result = perform_scan (cycode_client , zipped_documents , scan_type , scan_id , is_git_diff , is_commit_range )
151- issue_detected , all_detections_count , output_detections_count = print_result (scan_result , documents_to_scan ,
152- scan_type , scan_command_type )
153- context .obj ['issue_detected' ] = issue_detected
152+ document_detections_list = enrich_scan_result (scan_result , documents_to_scan )
153+ relevant_document_detections_list = exclude_irrelevant_scan_results (document_detections_list , scan_type ,
154+ scan_command_type )
155+ print_results (context , relevant_document_detections_list )
156+
157+ context .obj ['issue_detected' ] = len (relevant_document_detections_list ) > 0
158+ all_detections_count = sum (
159+ [len (document_detections .detections ) for document_detections in document_detections_list ])
160+ output_detections_count = sum (
161+ [len (document_detections .detections ) for document_detections in relevant_document_detections_list ])
154162 scan_completed = True
155163 except Exception as e :
156164 _handle_exception (context , e )
@@ -190,37 +198,42 @@ def perform_scan(cycode_client, zipped_documents: InMemoryZip, scan_type: str, s
190198 return scan_result
191199
192200
193- def print_result (scan_result , documents_to_scan : List [Document ], scan_type : str , scan_command_type : str ):
194- all_detections_count = 0
195- output_detections_count = 0
201+ def print_results (context : click .Context , document_detections_list : List [DocumentDetections ]):
202+ output_type = context .obj ['output' ]
203+ printer = ResultsPrinter ()
204+ printer .print_results (context , document_detections_list , output_type )
205+
206+
207+ def enrich_scan_result (scan_result : ZippedFileScanResult , documents_to_scan : List [Document ]) -> List [
208+ DocumentDetections ]:
209+ logger .debug ('enriching scan result' )
210+ document_detections_list = []
211+ for detections_per_file in scan_result .detections_per_file :
212+ file_name = get_path_by_os (detections_per_file .file_name )
213+ logger .debug ("going to find document of violated file, %s" , {'file_name' : file_name })
214+ document = _get_document_by_file_name (documents_to_scan , file_name )
215+ document_detections_list .append (
216+ DocumentDetections (document = document , detections = detections_per_file .detections ))
196217
197- issue_detected = False
198- if scan_result .did_detect :
199- for detections_per_file in scan_result .detections_per_file :
200- all_detections_count += len (detections_per_file .detections )
201- detections = exclude_irrelevant_detections (scan_type , scan_command_type , detections_per_file .detections )
202- if not detections :
203- continue
218+ return document_detections_list
204219
205- issue_detected = True
206- output_detections_count += len (detections )
207- file_name = get_path_by_os (detections_per_file .file_name )
208- logger .debug ("going to find document of violated file, %s" , {'file_name' : file_name })
209- document = _get_document_by_file_name (documents_to_scan , file_name )
210- logger .debug ('printing file\' s violations, %s' ,
211- {'filename' : file_name , 'socument_path' : document .path ,
212- 'unique_id' : document .unique_id })
213- print_file_result (document , detections )
214220
215- if not issue_detected :
216- click .secho ("Good job! No issues were found!!! 👏👏👏" , fg = 'green' )
221+ def exclude_irrelevant_scan_results (document_detections_list : List [DocumentDetections ], scan_type : str ,
222+ scan_command_type : str ) -> List [DocumentDetections ]:
223+ relevant_document_detections_list = []
224+ for document_detections in document_detections_list :
225+ relevant_detections = exclude_irrelevant_detections (scan_type , scan_command_type ,
226+ document_detections .detections )
227+ if relevant_detections :
228+ relevant_document_detections_list .append (DocumentDetections (document = document_detections .document ,
229+ detections = relevant_detections ))
217230
218- return issue_detected , all_detections_count , output_detections_count
231+ return relevant_document_detections_list
219232
220233
221234def print_file_result (document : Document , detections ):
222235 printer .print_detections (
223- detection_details = DetectionDetails (detections = detections , document = document ))
236+ detection_details = DocumentDetections (detections = detections , document = document ))
224237
225238
226239def get_diff_file_path (file ):
0 commit comments