
    i 8                        d Z ddlZddlZddlmZ ddlmZmZmZ 	 ddl	m
Z
 ddlmZ ddlmZ  ej                   ej"                  d	 ej$                  d
       ej&                  ej(                        g        ej*                  e      Zdedee   fdZdede
dee   fdZd Zedk(  r e        yy# e$ r ddl	m
Z
 ddlmZ ddlmZ Y w xY w)z
Script to verify all Bitbucket repositories are present and up-to-date.
Compares Bitbucket repos with local repos and updates/clones as needed.
    N)Path)DictListSet)ConfigManager)BitbucketClient)
GitManager   z4%(asctime)s - %(name)s - %(levelname)s - %(message)szrepo_verification.log)levelformathandlers	repos_dirreturnc                 ^   t               }| j                         st        j                  d|         |S | j	                         D ]e  }|j                         s|dz  j                         r|j                  |j                         Ct        j                  d|j                   d       g |S )z
    Get list of all local repository directories.
    
    Args:
        repos_dir: Path to repositories directory
        
    Returns:
        Set of repository names/slugs
    z'Repositories directory does not exist: .gitz
Directory z# exists but is not a git repository)	setexistsloggerwarningiterdiris_diraddnamedebug)r   local_repositems      src/verify_repos.pyget_local_reposr   !   s     %K@LM !!# Z;;=v%%'		*z$))4WXYZ     	bitbucketconfigc                    | j                         xs g }|j                  dg       }|r+t        j                  dt	        |       d       |D ]  }t        |t              rH|j                  d      rf|j                  dd      j                  dd      }|j                  d      }t	        |      dk(  sh|\  }}|j                  ||d	|id
d|dgid       |j                  d      rk|j                  dd      j                  dd      }|j                  d      }t	        |      dk(  s|\  }	}|j                  ||d	|	id
d|dd|dgid       d|v s|j                  d      }t	        |      dk(  s/|\  }}d| d| d}
|j                  ||d	|id
d|
dgid       ]t        |t              so|j                  d      xs |j                  d	      }|j                  d      }|j                  d      xs |j                  d      }
|s|
st        |t              rd	|i}|j                  |||xs i d
d|
dgid        |S )z
    Get all repositories from Bitbucket (including additional repos).
    
    Args:
        bitbucket: Bitbucket client instance
        config: Configuration manager
        
    Returns:
        List of repository info dictionaries
    z scanning.additional_repositoriesFound z" additional repositories in configzgit@bitbucket.org: r   /   slugclonessh)r   href)r   r'   	workspacelinkszhttps://github.com/httpsr   r+   ssh_url	clone_url)get_all_repositoriesgetr   infolen
isinstancestr
startswithreplacesplitappenddict)r    r!   reposadditional_repos_configrepo_configpathpartsr+   	repo_nameorgr.   s              r   get_bitbucket_reposrB   =   s    **,2E %jj)KRPfS!89::\]^2 B	K+s+))*>?&../CRHPPQWY[\D JJsOE5zQ/4,	9$-$-*0))< '-2K$H*"&		& 	 !++,AB&../DbIQQRXZ\]D JJsOE5zQ).Y$-$-*0# '-2K$H-4k$J*"&	
& 
 K''--c2E5zQ/4,	9$6yk9+T"R$-$-*0))< '-2G$D*"&		& 	 K.'OOF3N{v7N	'OOK8	%//)4T8T!)S1%+Y$7	LL ) )%._"#). @&"		" 	sB	H Lr   c                  L   t         j                  d       t         j                  d       t         j                  d       	 t               } | j                  d      s*t         j	                  d       t        j                  d       t        | j                  d            }t        | j                  d            }| j                  d      s*t         j	                  d	       t        j                  d       |s,|s*t         j	                  d
       t        j                  d       t        | j                  d      | j                  d      |s| j                  d      nd| j                  d            }t        | j                  d            }t        | j                  d            }t         j                  d       t        ||       }|st         j                  d       yt         j                  dt        |       d       t         j                  d       t        |      }t         j                  dt        |       d       i }|D ]  }	|	j                  d      xs |	j                  d      }
|
s*|
j                  d      s|
j                  d      r[|
j!                  d      j#                  d      }t        |      dk\  r|d   }
|
r|
j                  d      r|	j                  d      xs |
}
|	||
<    t%        |j'                               }||z
  }||z  }||z
  }t         j                  d       t         j                  d       t         j                  dt        |              t         j                  dt        |              t         j                  d t        |              t         j                  d!t        |              |r!t         j                  d"t        |              t         j                  d       |r=t         j                  d#       t)        |      D ]  }t         j                  d$|         |r=t         j                  d%       t)        |      D ]  }t         j                  d$|         d&}d&}|rt         j                  d'd        t         j                  d(t        |       d)       t         j                  d        t)        |      D ]  }
||
   }	t         j                  d*|
        	 |j+                  |	d+,      }|st         j                  d-|
 d.       |dz  }U|j-                  |
|/      }|r3t/        |t0              r#|d&   r|dz  }t         j                  d0|
        n|dz  }t         j	                  d1|
         d&}d&}|rt         j                  d'd        t         j                  d6t        |       d7       t         j                  d        t)        |      D ]  }
||
   }	t         j                  d8|
        	 |j+                  |	d+,      }|st         j                  d-|
 d.       |dz  }U|j-                  |
|/      }|r3t/        |t0              r#|d&   r|dz  }t         j                  d9|
        n|dz  }t         j	                  d:|
         t         j                  d<       t         j                  d=       t         j                  dt        |              t         j                  d>|        t         j                  d?|        t         j                  d@|        t         j                  dA|        t         j                  d       ||z   t        |      k(  rt         j                  dB       yt         j                  dC       y# t2        $ r-}|dz  }t         j	                  d2|
 d3| d45       Y d}~d}~ww xY w# t2        $ r-}|dz  }t         j	                  d;|
 d3| d45       Y d}~#d}~ww xY w# t4        $ r- t         j                  dD       t        j                  d       Y yt2        $ r9}t         j	                  dE| d45       t        j                  d       Y d}~yd}~ww xY w)Fz4Main function to verify and update all repositories.z<============================================================z+Starting Repository Verification and Updatezbitbucket.workspacez"Bitbucket workspace not configuredr
   zbitbucket.api_tokenzbitbucket.app_passwordzbitbucket.usernamez'Bitbucket username/email not configuredz'Bitbucket authentication not configuredN)r+   usernameapp_password	api_tokenzscanning.repos_dir)r   z'Fetching repositories from Bitbucket...z"No repositories found in Bitbucketr#   z repositories in BitbucketzScanning local repositories...z local repositoriesr   r'   zhttp://zhttps://r%   r&   httpzRepository Status Summary:z  Total Bitbucket repos: z  Total local repos: z  Missing repos (need clone): z   Existing repos (need update): z(  Extra local repos (not in Bitbucket): z'
Missing Repositories (will be cloned):z  - z-
Extra Local Repositories (not in Bitbucket):r   
zCloning z missing repositories...z

Cloning: r)   )protocolzNo SSH clone URL found for z
, skipping)	repo_slugr/   z[OK] Successfully cloned z[FAIL] Failed to clone u   ✗ Error cloning z: T)exc_infoz	Updating z existing repositories...z
Updating: z[OK] Successfully updated z[FAIL] Failed to update u   ✗ Error updating z=
============================================================zVerification Summary:z
  Cloned: z  Updated: z  Failed to clone: z  Failed to update: z6[SUCCESS] All repositories are present and up-to-date!zP[WARNING] Some repositories could not be cloned/updated. Check logs for details.z!
Verification interrupted by userzFatal error: )r   r2   r   r1   errorsysexitboolr   r	   r   rB   r   r3   r   r6   rstripr8   r   keyssortedget_clone_urlclone_or_updater4   tuple	ExceptionKeyboardInterrupt)r!   has_api_tokenhas_app_passwordr    git_managerr   bitbucket_reposr   bitbucket_repo_map	repo_inforK   r?   bitbucket_repo_namesmissing_reposexisting_reposextra_local_reposr@   cloned_countfailed_clone_countr/   clone_resulteupdated_countfailed_update_counts                           r   verify_and_update_reposri      s   
KK
KK=>
KKx zz/0LL=>HHQKVZZ(=>?

+C DEzz./LLBCHHQK%5LLBCHHQK $jj!67ZZ 45ER$<=X\jj!67	
	 !jj!56
 $89:	 	=>-i@NN?@fS122LMN 	45%i0fS-..ABC  ( 	:I!f-Fv1FI''	2i6J6J:6V%,,S177<E5zQ$)"I	$	(<(<V(D$-MM&$9$FY	09"9-	:  ##5#:#:#<=,{:-;'*>> 	H01/4H0I/JKL+C,<+=>?4S5G4HIJ6s>7J6KLMKKB3GXCYBZ[\H KKBC#M2 0	d9+./0 KKHI#$56 0	d9+./0 KK"VH&KK(3}#5"66NOPKK6($#M2 W	.y9	k)56W ) 7 7	E 7 RI$)DYKz'Z[*a/* #.#>#>"+"+ $? $L
 $L%)H\Z[_$)&?	{$KL*a/*'>yk%JK+W6 KK"VH&KK)C$7#88QRSKK6($#N3 X	.y9	l9+67X ) 7 7	E 7 RI$)DYKz'Z[+q0+ #.#>#>"+"+ $? $L
 $L%)H\Z[_%*&@$LM+q0+'?	{%KL+X6 	O$+,/4H0I/JKLj/0k-12)*<)=>?*+>*?@AH-'3/C+DDKKPQNNmni ! W&!+&LL#5i[1#!FQULVVWF ! X'1,'LL#6ykA3!GRVLWWX&  89 }QC(48s   F`-  B`- 2J`- 3^;8`- 9A%^;B`- #3_4`- A%_4<C(`- %`- ;	_1"_,&`- ,_11`- 4	`*="`%`- %`**`- -3b#"b#*/bb#__main__)__doc__rN   loggingpathlibr   typingr   r   r   config_managerr   bitbucket_clientr   r[   r	   ImportErrorbasicConfigINFOFileHandlerStreamHandlerstdout	getLogger__name__r   r5   r   rB   ri    r   r   <module>rz      s       " "(,0&   
,,A34cjj) 
		8	$t C 8V? VM VdSWj Vr~B z Q
  (-1'(s   B4 4CC