
    `iw0                        d Z ddlZddlZddlZddlmZ  ee      j                  j                  Zej                  j                  d ee             ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ ddlZddlZ ej4                  ej6                  d
        ej8                  e      Z G d d      Zd Z edk(  r e         yy)z9
Script to scan specific repositories against SonarQube.
    N)Path)ConfigManager)BitbucketClient)
GitManager)SonarQubeScanner)ReportGenerator)_get_additional_repositoriesz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)levelformatc            	       Z    e Zd ZdZdefdZdefdZddZdde	d	e
d
eddfdZdeddfdZy)SpecificRepoScannerz"Scanner for specific repositories.configc                 *   || _         |j                  d      }|j                  d      }t        |j                  d      |j                  d      |s|nd|      | _        t	        |j                  d            | _        t        |j                  d	      |j                  d
      |j                  d            | _        t        |j                  d            | _	        t        |j                  d            | _        | j                         | _        y)z&Initialize scanner with configuration.zbitbucket.api_tokenzbitbucket.app_passwordbitbucket.workspacezbitbucket.usernameN)	workspaceusernameapp_password	api_tokenzscanning.repos_dir)	repos_dirzsonarqube.urlzsonarqube.tokenzscanning.sonar_scanner_path)	sonar_urlsonar_tokenscanner_pathzscanning.reports_dir)reports_dirzscanning.history_file)r   getr   	bitbucketr   git_managerr   sonar_scannerr   report_generatorr   history_file_load_historyscan_history)selfr   r   r   s       src/scan_specific_repos.py__init__zSpecificRepoScanner.__init__!   s     JJ45	zz":;(jj!67ZZ 45-6D	
 &jj!56
 .jj1

#45$AB
 !0

#9:!

 !,C!DE ..0    returnc                    | j                   j                         r6	 t        | j                   d      5 }t        j                  |      cddd       S i S # 1 sw Y   i S xY w# t
        $ r#}t        j                  d|        Y d}~i S d}~ww xY w)z!Load scan history from JSON file.rNzFailed to load scan history: )r   existsopenjsonload	Exceptionloggerwarningr"   fes      r#   r    z!SpecificRepoScanner._load_historyB   s    ##%D$++S1 (Q99Q<( ( 		( 	  D!>qcBCC	Ds4   A  A	A  AA  A   	B)BBNc                     	 t        | j                  d      5 }t        j                  | j                  |d       ddd       y# 1 sw Y   yxY w# t
        $ r"}t        j                  d|        Y d}~yd}~ww xY w)zSave scan history to JSON file.w   )indentNzFailed to save scan history: )r*   r   r+   dumpr!   r-   r.   errorr0   s      r#   _save_historyz!SpecificRepoScanner._save_historyL   sj    	>d''- :		$++Qq9: : : 	>LL8<==	>s3   A #AA A	A A 	A;A66A;	repo_slugsuccessreport_pathc                     ddl m } |j                         j                         ||rt        |      ndd| j                  |<   | j                          y)z%Update scan history for a repository.r   )datetimeN)	last_scanr;   r<   )r>   now	isoformatstrr!   r9   )r"   r:   r;   r<   r>   s        r#   _update_scan_historyz(SpecificRepoScanner._update_scan_historyT   sH    % "113/:3{+(
)$
 	r%   
repo_namesc           
         t         j                  dt        |       d       d}d}d}|D ]T  }t         j                  dd        t         j                  d|        t         j                  d        	 | j                  j	                  |      }|s^t        | j                        D ]F  }|j                  d      xs |j                  d      |k(  s+|}t         j                  d	| d
        n |st         j                  d| d       |dz  }| j                  j                  |d      }|s t         j                  d| d       |dz  }&t         j                  d|        | j                  j                  ||      }	|	rt        |	t              r6|	d   s1t         j                  d|        |dz  }| j                  |d       t        |	t              r|	\  }
}n|	}
d}| j                  j!                  |
      }|s| j                  j                  d      }| d| j#                         j%                  dd      j%                  dd      }ddl}|j)                  dd|      }|j                  d      xs |}t         j                  d| d| d       	 | j*                  j-                  |
||       }| j*                  j1                  |      }|st         j                  d#|        |dz  }| j*                  j3                  |      st         j                  d$| d%       |j                  d      xs |}|j                  d&d'      xs d'}	 t5        |d(d)*      5 }|D ]F  }|j7                         j9                  d+      s#|j;                  d,d      d   j7                         } n ddd       | j*                  j=                  |||-      rt         j                  d.| d/| d       n3t         j                  d0| d1       nt         j?                  d$| d2       t         j                  d3| d4       | j*                  jA                  |
|      }d}|rV|j                  d5      rEt         j                  d6       tC        jD                  d7       | j*                  jG                  |      }	 | jH                  jK                  ||||j                  d8      9      }t         j                  d:|        | j                  ||j                  d5d      |       |j                  d5      r|dz  }t         j                  d<|        n0|dz  }t         j                  d=| d"|j                  d>d?              W t         j                  dd        t         j                  dB       t         j                  d        t         j                  dC|        t         j                  dD|        t         j                  dE|        t         j                  dFt        |              y# t.        $ r+}t         j                  d!| d"|        |dz  }Y d}~4d}~ww xY w# 1 sw Y   xY w# t.        $ r Y w xY w# t.        $ r(}t         j                  d;| d"|        d}Y d}~d}~ww xY w# t.        $ r?}t         j                  d@| d"| dA       |dz  }| j                  |d       Y d}~d}~ww xY w)Gz
        Scan specific repositories.
        
        Args:
            repo_names: List of repository names/slugs to scan
        zStarting scan for z repositoriesr   
z<============================================================zProcessing repository: nameslugz
Resolved 'z'' from scanning.additional_repositorieszRepository 'z7' not in Bitbucket or additional_repositories, skipping   ssh)protocolzNo SSH clone URL found for z
, skippingzCloning/updating repository: )r:   	clone_urlzFailed to clone/update FTr   _- Nz
[^a-z0-9_]z(Generating sonar-project.properties for z (project key: ))	repo_pathproject_keyproject_namez0Failed to generate sonar-project.properties for z: z@Could not extract project key from sonar-project.properties for z	Project 'z-' does not exist in SonarQube, creating it...description r(   zutf-8)encodingzsonar.projectName=)rR   rS   rT   z(Successfully created SonarQube project: z (z$Failed to create SonarQube project 'z', but continuing with scanz' already exists in SonarQubezRunning SonarQube scan for z...r;   zWaiting for scan to process...   output)	repo_namescan_resultssonar_resultsscan_outputzReport generated: zFailed to generate report for z[SUCCESS] Completed scan for z[FAILED] Scan failed for r8   zUnknown errorzUnexpected error processing exc_infozScan SummaryzSuccessfully scanned: z	Skipped: zFailed: zTotal: )&r.   infolenr   get_repository_infor	   r   r   r/   get_clone_urlr   clone_or_update
isinstancetupler8   rC   get_sonar_properties_pathlowerreplaceresubr   generate_sonar_propertiesr-   get_project_keycheck_project_existsr*   strip
startswithsplitcreate_projectdebugrun_scantimesleepget_scan_resultsr   generate_report)r"   rD   scanned_countskipped_countfailed_countr:   	repo_infoarrL   clone_resultrQ   is_first_clonesonar_props_pathr   rR   rj   rS   r2   rT   r1   liner[   r\   r<   s                           r#   scan_repositoriesz%SpecificRepoScanner.scan_repositories_   s    	(Z(9GH# R	<IKK"VH&KK1)=>KK6($M< NN>>yI	 :4;;G "FF6N<bffVnJ(*I"KK*YK?f(gh!	"
 !NN\)<s#tu!Q&M !NN88U8S	 NN%@:#VW!Q&M ;I;GH#//??''  @  
 $
<(GP\]^P_LL#:9+!FG A%L--i? lE20<-I~ ,I%)N $(#3#3#M#Mi#X ' $0E FI%.Kq"<"B"B"D"L"LSRU"V"^"^_bdg"hK"$&&["IK#,==#8#EILKK"J9+Udepdqqr st	!+/+=+=+W+W&/(3)5 ,X ,( #00@@AQR"NN%efoep#qr!Q&M ))>>{KKK)K=8e fg#,==#8#EIL"+--r"B"HbK!"2C'J *a() *#'::<#:#:;N#O37::c13Ea3H3N3N3PL$)** ))88$/%1$/ 9 
 &N{m[]^j]kkl$mn)Mk]Zu'vwLL9[M9V!WX 9)CHI#11::9FVW !%<#3#3I#>KK @AJJqM$($6$6$G$G$TM
'"&"7"7"G"G"+%1&3$0$4$4X$>	 #H #K KK"4[M BC )) $$Y6  ##I.!Q&MKK"?	{ KL A%LLL#<YKr,JZJZ[bdsJtIu!vw[R	<j 	bM"N#vh ,]O<=i/0h|n-.gc*o./0s % !'WXaWbbdefdg%hi%* !(* *
 % D ! 'LL#A)Bqc!RS"&K'$  <;I;bLW[\!)))U;;<s   6AZ8>Z8=Z8A;Z8CZ8X0<:Z88AZ8Y4&%Y'&Y'2Y4:C=Z88AZ>BZ80	Y$9 YZ8Y$$Z8'Y1	,Y44	Z=Z8 ZZ8	Z5Z0*Z80Z55Z88	\ 4[;;\ )r&   N)N)__name__
__module____qualname____doc__r   r$   dictr    r9   rB   boolr   rC   listr    r%   r#   r   r      s[    ,1} 1Bt >	c 	D 	t 	_c 	h1D h1T h1r%   r   c                     t        j                  dt         j                        } | j                  ddd       | j	                         }	 t
        j                  d       t               }t        |      }|j                  |j                         y# t        $ r- t
        j                  d       t        j                  d	       Y yt        $ r9}t
        j                  d
| d       t        j                  d	       Y d}~yd}~ww xY w)zMain entry point.z,Scan specific repositories against SonarQube)rT   formatter_classrepos+zRepository names/slugs to scan)nargshelpzLoading configuration...zInterrupted by userrI   zUnexpected error: Tr^   N)argparseArgumentParserRawDescriptionHelpFormatteradd_argument
parse_argsr.   r`   r   r   r   r   KeyboardInterruptsysexitr-   r8   )parserargsr   scannerr2   s        r#   mainr   
  s    $$B <<F
 -   D./ &f- 	!!$**- )* )!-=s   AB 3DD/DD__main__)!r   r   loggingr   pathlibr   __file__parent
parent_dirpathinsertrB   src.config_managerr   src.bitbucket_clientr   src.git_managerr   src.sonarqube_scannerr   src.report_generatorr   src.scan_recentr	   r+   ru   basicConfigINFO	getLoggerr   r.   r   r   r   r%   r#   <module>r      s        (^""))
 3z? # , 0 & 2 0 8     
,,A 
		8	$i1 i1XD zF r%   