@@ -525,7 +525,7 @@ def perform_scan_sync(
525525 logger .debug ('Sync scan request has been triggered successfully, %s' , {'scan_id' : scan_results .id })
526526 return ZippedFileScanResult (
527527 did_detect = True ,
528- detections_per_file = _map_detections_per_file (scan_results .detection_messages ),
528+ detections_per_file = _map_detections_per_file_and_commit_id (scan_results .detection_messages ),
529529 scan_id = scan_results .id ,
530530 )
531531
@@ -870,11 +870,11 @@ def _get_scan_result(
870870 if not scan_details .detections_count :
871871 return init_default_scan_result (cycode_client , scan_id , scan_type , should_get_report )
872872
873- scan_detections = cycode_client .get_scan_detections (scan_type , scan_id )
873+ scan_raw_detections = cycode_client .get_scan_raw_detections (scan_type , scan_id )
874874
875875 return ZippedFileScanResult (
876876 did_detect = True ,
877- detections_per_file = _map_detections_per_file ( scan_detections ),
877+ detections_per_file = _map_detections_per_file_and_commit_id ( scan_raw_detections ),
878878 scan_id = scan_id ,
879879 report_url = _try_get_report_url_if_needed (cycode_client , should_get_report , scan_id , scan_type ),
880880 )
@@ -904,42 +904,58 @@ def _try_get_report_url_if_needed(
904904 logger .debug ('Failed to get report URL' , exc_info = e )
905905
906906
907- def _map_detections_per_file (detections : List [dict ]) -> List [DetectionsPerFile ]:
907+ def _map_detections_per_file_and_commit_id (raw_detections : List [dict ]) -> List [DetectionsPerFile ]:
908+ """Converts list of detections (async flow) to list of DetectionsPerFile objects (sync flow).
909+
910+ Args:
911+ raw_detections: List of detections as is returned from the server.
912+
913+ Note:
914+ This method fakes server response structure
915+ to be able to use the same logic for both async and sync scans.
916+
917+ Note:
918+ Aggregation is performed by file name and commit ID (if available)
919+ """
908920 detections_per_files = {}
909- for detection in detections :
921+ for raw_detection in raw_detections :
910922 try :
911- detection ['message' ] = detection ['correlation_message' ]
912- file_name = _get_file_name_from_detection (detection )
913- if file_name is None :
914- logger .debug ('File name is missing from detection with ID %s' , detection .get ('id' ))
915- continue
916- if detections_per_files .get (file_name ) is None :
917- detections_per_files [file_name ] = [DetectionSchema ().load (detection )]
923+ # FIXME(MarshalX): investigate this field mapping
924+ raw_detection ['message' ] = raw_detection ['correlation_message' ]
925+
926+ file_name = _get_file_name_from_detection (raw_detection )
927+ detection : Detection = DetectionSchema ().load (raw_detection )
928+ commit_id : Optional [str ] = detection .detection_details .get ('commit_id' ) # could be None
929+ group_by_key = (file_name , commit_id )
930+
931+ if group_by_key in detections_per_files :
932+ detections_per_files [group_by_key ].append (detection )
918933 else :
919- detections_per_files [file_name ]. append ( DetectionSchema (). load ( detection ))
934+ detections_per_files [group_by_key ] = [ detection ]
920935 except Exception as e :
921936 logger .debug ('Failed to parse detection' , exc_info = e )
922937 continue
923938
924939 return [
925- DetectionsPerFile (file_name = file_name , detections = file_detections )
926- for file_name , file_detections in detections_per_files .items ()
940+ DetectionsPerFile (file_name = file_name , detections = file_detections , commit_id = commit_id )
941+ for ( file_name , commit_id ) , file_detections in detections_per_files .items ()
927942 ]
928943
929944
930- def _get_file_name_from_detection (detection : dict ) -> str :
931- if detection .get ('category' ) == 'SAST' :
932- return detection ['detection_details' ]['file_path' ]
945+ def _get_file_name_from_detection (raw_detection : dict ) -> str :
946+ category = raw_detection .get ('category' )
933947
934- if detection .get ('category' ) == 'SecretDetection' :
935- return _get_secret_file_name_from_detection (detection )
948+ if category == 'SAST' :
949+ return raw_detection ['detection_details' ]['file_path' ]
950+ if category == 'SecretDetection' :
951+ return _get_secret_file_name_from_detection (raw_detection )
936952
937- return detection ['detection_details' ]['file_name' ]
953+ return raw_detection ['detection_details' ]['file_name' ]
938954
939955
940- def _get_secret_file_name_from_detection (detection : dict ) -> str :
941- file_path : str = detection ['detection_details' ]['file_path' ]
942- file_name : str = detection ['detection_details' ]['file_name' ]
956+ def _get_secret_file_name_from_detection (raw_detection : dict ) -> str :
957+ file_path : str = raw_detection ['detection_details' ]['file_path' ]
958+ file_name : str = raw_detection ['detection_details' ]['file_name' ]
943959 return os .path .join (file_path , file_name )
944960
945961
0 commit comments