3434from cycode .cli .utils .progress_bar import ScanProgressBarSection
3535from cycode .cli .utils .scan_batch import run_parallel_batched_scan
3636from cycode .cli .utils .scan_utils import set_issue_detected
37+ from cycode .cli .utils .shell_executor import shell
3738from cycode .cyclient .models import Detection , DetectionSchema , DetectionsPerFile , ZippedFileScanResult
3839from cycode .logger import get_logger , set_logging_level
3940
@@ -661,6 +662,9 @@ def get_scan_parameters(ctx: typer.Context, paths: Optional[Tuple[str]] = None)
661662 return scan_parameters
662663
663664 remote_url = try_get_git_remote_url (paths [0 ])
665+ if not remote_url :
666+ remote_url = try_to_get_plastic_remote_url (paths [0 ])
667+
664668 if remote_url :
665669 # TODO(MarshalX): remove hardcode in context
666670 ctx .obj ['remote_url' ] = remote_url
@@ -679,6 +683,93 @@ def try_get_git_remote_url(path: str) -> Optional[str]:
679683 return None
680684
681685
686+ def _get_plastic_repository_name (path : str ) -> Optional [str ]:
687+ """Gets the name of the Plastic repository from the current working directory.
688+
689+ The command to execute is:
690+ cm status --header --machinereadable --fieldseparator=":::"
691+
692+ Example of status header in machine-readable format:
693+ STATUS:::0:::Project/RepoName:::OrgName@ServerInfo
694+ """
695+
696+ try :
697+ command = [
698+ 'cm' ,
699+ 'status' ,
700+ '--header' ,
701+ '--machinereadable' ,
702+ f'--fieldseparator={ consts .PLASTIC_VCS_DATA_SEPARATOR } ' ,
703+ ]
704+
705+ status = shell (command = command , timeout = consts .PLASTIC_VSC_CLI_TIMEOUT , working_directory = path )
706+ if not status :
707+ logger .debug ('Failed to get Plastic repository name (command failed)' )
708+ return None
709+
710+ status_parts = status .split (consts .PLASTIC_VCS_DATA_SEPARATOR )
711+ if len (status_parts ) < 2 :
712+ logger .debug ('Failed to parse Plastic repository name (command returned unexpected format)' )
713+ return None
714+
715+ return status_parts [2 ].strip ()
716+ except Exception as e :
717+ logger .debug ('Failed to get Plastic repository name' , exc_info = e )
718+ return None
719+
720+
721+ def _get_plastic_repository_list (working_dir : Optional [str ] = None ) -> Dict [str , str ]:
722+ """Gets the list of Plastic repositories and their GUIDs.
723+
724+ The command to execute is:
725+ cm repo list --format="{repname}:::{repguid}"
726+
727+ Example line with data:
728+ Project/RepoName:::tapo1zqt-wn99-4752-h61m-7d9k79d40r4v
729+
730+ Each line represents an individual repository.
731+ """
732+
733+ repo_name_to_guid = {}
734+
735+ try :
736+ command = ['cm' , 'repo' , 'ls' , f'--format={{repname}}{ consts .PLASTIC_VCS_DATA_SEPARATOR } {{repguid}}' ]
737+
738+ status = shell (command = command , timeout = consts .PLASTIC_VSC_CLI_TIMEOUT , working_directory = working_dir )
739+ if not status :
740+ logger .debug ('Failed to get Plastic repository list (command failed)' )
741+ return repo_name_to_guid
742+
743+ status_lines = status .splitlines ()
744+ for line in status_lines :
745+ data_parts = line .split (consts .PLASTIC_VCS_DATA_SEPARATOR )
746+ if len (data_parts ) < 2 :
747+ logger .debug ('Failed to parse Plastic repository list line (unexpected format), %s' , {'line' : line })
748+ continue
749+
750+ repo_name , repo_guid = data_parts
751+ repo_name_to_guid [repo_name .strip ()] = repo_guid .strip ()
752+
753+ return repo_name_to_guid
754+ except Exception as e :
755+ logger .debug ('Failed to get Plastic repository list' , exc_info = e )
756+ return repo_name_to_guid
757+
758+
759+ def try_to_get_plastic_remote_url (path : str ) -> Optional [str ]:
760+ repository_name = _get_plastic_repository_name (path )
761+ if not repository_name :
762+ return None
763+
764+ repository_map = _get_plastic_repository_list (path )
765+ if repository_name not in repository_map :
766+ logger .debug ('Failed to get Plastic repository GUID (repository not found in the list)' )
767+ return None
768+
769+ repository_guid = repository_map [repository_name ]
770+ return f'{ consts .PLASTIC_VCS_REMOTE_URI_PREFIX } { repository_guid } '
771+
772+
682773def exclude_irrelevant_detections (
683774 detections : List [Detection ], scan_type : str , command_scan_type : str , severity_threshold : str
684775) -> List [Detection ]:
@@ -690,9 +781,7 @@ def exclude_irrelevant_detections(
690781def _exclude_detections_by_severity (detections : List [Detection ], severity_threshold : str ) -> List [Detection ]:
691782 relevant_detections = []
692783 for detection in detections :
693- severity = detection .detection_details .get ('advisory_severity' )
694- if not severity :
695- severity = detection .severity
784+ severity = detection .severity
696785
697786 if _does_severity_match_severity_threshold (severity , severity_threshold ):
698787 relevant_detections .append (detection )
0 commit comments