
    V^i-                         S r SSKrSSKrSSKrSSKJr  SSKJrJr  SSK	J
r
Jr  SSKJr  \R                  " \5      r " S S5      rg)	z?
Git operations manager for cloning and updating repositories.
    N)Path)OptionalTuple)RepoGitCommandError)InvalidGitRepositoryErrorc                       \ rS rSrSrSS\4S jjrS rS\S\	4S jr
SS
\S\S\S\S\\\   \	4   4
S jjrS\S\	4S jrS\S\\   4S jrS
\S\	4S jrSrg	)
GitManager   z:Manages Git operations for repository cloning and updates.	repos_dirc                 x    [        U5      U l        U R                  R                  SSS9  U R                  5         g)z[
Initialize Git manager.

Args:
    repos_dir: Directory where repositories will be cloned
T)parentsexist_okN)r   r   mkdir_configure_ssh_for_bitbucket)selfr   s     +C:\wamp64\www\sonar_scan\src\git_manager.py__init__GitManager.__init__   s2     iTD9))+    c                 J   SSK n[        R                  R                  S5      n[        R                  " USS9  [        R                  R                  S5      nUR                  5       S:X  a  SU S	3nOS
U 3nU[        R                  S'   [        R                  SU S35        g)z
Configure SSH to handle Bitbucket host key verification.
Sets GIT_SSH_COMMAND environment variable to accept Bitbucket's host key.
r   Nz~/.sshT)r   z~/.ssh/known_hostsWindowsz?ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=""z>ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=GIT_SSH_COMMANDz+Configured SSH for Bitbucket (known_hosts: ))	platformospath
expandusermakedirssystemenvironloggerinfo)r   r   ssh_dirknown_hosts_pathssh_commands        r   r   'GitManager._configure_ssh_for_bitbucket   s    
 	 ''$$X.
Gd+ 77--.BC
 ??	)[\l[mmnoK [[kZlmK )4

$%ABRASSTUVr   	repo_pathreturnc                    UR                  5       (       d  gUS-  nUR                  5       (       a   [        U5      nUR                  ng [        UR                  5       5      nU(       d  [        R                  SU S35        g[        R                  SU S	35        g! [        [        [
        4 a%  n[        R                  SU SU 35         SnAgSnAff = f! [
         a%  n[        R                  S
U SU 35         SnAgSnAff = f)z
Check if repository directory is empty or contains an invalid git repository.

Args:
    repo_path: Path to repository directory
    
Returns:
    True if directory is empty or contains invalid git repository
T.gitFzRepository at z" appears to be invalid/corrupted: NzRepository directory z	 is emptyz! exists but has no .git directoryz&Error checking directory contents for : )existsr   remotesr   r   	Exceptionr#   warninglistiterdirr$   )r   r)   git_dirrepo_eitemss          r   _is_repo_empty_or_invalid$GitManager._is_repo_empty_or_invalid:   s    !! f$>>ILL	**,-E3I;iHI 3I;>_`a .	J 	{:\]^\_`a   	NNCI;bQRPSTU	s5   B 9C C C4CC
D&DDN	repo_slug	clone_urlusernamepasswordc                    U R                   U-  nUnU(       aT  SU;   a3  SU;   a-  UR                  SS5      n[        U5      S:X  a	  US   S-   nOUnOUn[        R	                  SU 35        O[        R                  SU 35        g	S
n	 U R                  U5      (       a  UR                  5       (       aH  [        R	                  SU S35         [        R                  " U5        [        R	                  SU 35        Sn	[        R	                  SU 35        [        R                  " Xe5      n[        R	                  SU 35        GOUR                  5       (       a  US-  R                  5       (       a  [        R	                  SU 35        [        U5      n UR                  SS9nUR                  (       dD  [        R                  SU 35        UR                   R#                  SSS5        UR                  SS9nUR%                  5          UR&                  R(                  nUR                   R+                  5         [        R	                  SU SU S35        XY4$ ! [         a%  n
[        R                  SU SU
 35         Sn
A
g	Sn
A
ff = f! [         aO  n
[        R-                  SU SU
 S 35        UR%                  5         [        R	                  S!U S"35         Sn
A
NSn
A
ff = f! [.         aU    [        R	                  S#U 35        UR1                  SU5      nUR%                  5         [        R	                  S$U 35         Nf = f! [2         a  n
[5        U
5      n[        R                  S%U SU
 35        S&U;   d  S'U;   aY  [        R                  S(U S)35        [        R                  S*5        [        R                  S+5        [        R                  S,5        OOS-U;   d  S.U;   aC  [        R                  S/U S)35        [        R                  S05        [        R                  S,5         Sn
A
g	Sn
A
f[         a%  n
[        R                  S1U SU
 35         Sn
A
g	Sn
A
ff = f)2a  
Clone repository if it doesn't exist, or update if it does.
Uses SSH for cloning (SSH key must be set up).

Args:
    repo_slug: Repository slug/name
    clone_url: Repository clone URL (SSH format: git@bitbucket.org:workspace/repo.git)
    username: Optional - not used for SSH (kept for backward compatibility)
    password: Optional - not used for SSH (kept for backward compatibility)
    
Returns:
    Tuple of (Path to repository directory, is_first_clone), or (None, False) if failed
@:      r   z:*****zUsing SSH clone URL: zNo clone URL provided for )NFFzRepository directory for z0 is empty or invalid, removing and cloning freshz,Removed invalid/empty repository directory: z.Failed to remove invalid repository directory r-   NTzCloning repository: z Successfully cloned repository: r,   zUpdating repository: origin)namezConfiguring refspec for z--addzremote.origin.fetchz#+refs/heads/*:refs/remotes/origin/*z!Successfully updated repository: z
 (branch: r   zCould not pull z+. Repository may be in detached HEAD state.zFetched changes for z (could not pull)zAdding origin remote for z*Successfully added remote and fetched for zGit operation failed for zPermission deniedzHost key verification failedzSSH authentication failed for z. Please verify:z,  - SSH key is set up and added to Bitbucketz:  - SSH key is in SSH agent or configured in ~/.ssh/configz)  - Repository exists and you have accesszAuthentication failedzfatal: unable to accesszAuthentication failed for z"  - SSH key is properly configuredz%Unexpected error handling repository )r   splitlenr#   r$   errorr9   r.   shutilrmtreer0   r   
clone_fromremoterefsdebuggitconfigfetchactive_branchrE   pullr1   
ValueErrorcreate_remoter   str)r   r;   r<   r=   r>   r)   authenticated_urlparts
masked_urlis_first_cloner7   r5   rD   current_branch	error_msgs                  r   clone_or_updateGitManager.clone_or_updated   s    NNY.	 &  ''C3D,D)//Q7u:?!&qH!4J!2J.
KK/
|<=LL5i[ABH	--i88##%%KK";I;Fv wx+i0&RS\R]$^_ "&29+>?'8D>ykJK!!##V);(C(C(E(E3I;?@IZ![[h[7F ";;'?	{%KL1FHmn!%(!; LLNY)-););)@)@&G	{R\]k\llm$no ,,[ % +'UV_U``bcdbe%fg*+@ % Y2aSHs'tu&:9+EV$WXX	Y
 " ZKK";I; GH!//:KLFLLNKK"LYK XYZ  	AILL4YKr!EF #i/3QU^3^=i[HXYZKMY[HJ(I59RV_9_9)DTUVACHJ 	LL@2aSQR	s   	AM .I <BM A4K) AJ M 
J
%J M J

M 
K&AK!K)  M !K&&K) )AMM MM 
Q&CP44Q&Q!!Q&c                 n    US-  nUR                  5       nU(       d  [        R                  SU 35        U$ )z
Check if repository has sonar-project.properties file.

Args:
    repo_path: Path to repository directory
    
Returns:
    True if sonar-project.properties exists
sonar-project.propertiesz&sonar-project.properties not found in )r.   r#   r1   )r   r)   sonar_propsr.   s       r   has_sonar_propertiesGitManager.has_sonar_properties   s9      "<<##%NNCI;OPr   c                 <    US-  nUR                  5       (       a  U$ g)z
Get path to sonar-project.properties file.

Args:
    repo_path: Path to repository directory
    
Returns:
    Path to sonar-project.properties, or None if not found
r`   N)r.   )r   r)   ra   s      r   get_sonar_properties_path$GitManager.get_sonar_properties_path   s'      "<<r   c                    U R                   U-  n UR                  5       (       a/  [        R                  " U5        [        R                  SU 35        g g! [         a%  n[        R                  SU SU 35         SnAgSnAff = f)z
Remove a cloned repository (optional cleanup).

Args:
    repo_slug: Repository slug/name
    
Returns:
    True if successfully removed
zCleaned up repository: TzFailed to cleanup repository r-   NF)r   r.   rI   rJ   r#   r$   r0   rH   )r   r;   r)   r7   s       r   cleanup_repoGitManager.cleanup_repo   s     NNY.		K!!i(5i[AB "   	KLL82aSIJJ	Ks   AA 
B!BB)r   )z./repos)NN)__name__
__module____qualname____firstlineno____doc__rV   r   r   r   boolr9   r   r   r]   rb   re   rh   __static_attributes__ r   r   r
   r
      s    D	,# 	,W:(4 (D (Tn n n n^a nmrs{  }A  tB  DH  tH  nI n`d t $4 HTN c d r   r
   )rn   r   loggingrI   pathlibr   typingr   r   rO   r   r   git.excr   	getLoggerrj   r#   r
   rq   r   r   <module>rw      s=    
    " % -			8	$x xr   