o
    b5                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZmZmZmZmZmZmZmZ d d
lm Z  d dl!Z!dZ"e dkZ#e#rsdndZ$e#rydndZ%e&e'Z(ejdkre )e *  G dd deZ+e"dddfdee, de-deee,e,f  dee
 dee. dee.e.f fddZ/de0de+de0fddZ1d eeee, e,f  dee, fd!d"Z2	#dFd$e,d%ee
 d&ee,ef de+d'e3ddfd(d)Z4	#dFd*d+d,e
d&ee,ef d-e3d.e0dee
 f
d/d0Z5d1ed2e
d3eeeef ddfd4d5Z6d6e
deee,ef e j7f fd7d8Z8	#	#	#	#dGd9e0d:ee,ef d;e j7d,e
de+d<e3d-e3d=e3d'e3ddfd>d?Z9	#	#	#	#dGd@e,d,e
dAe0d=e3d<e3d-e3d'e3de0fdBdCZ:e'dDkrue;dEdS )H    N)partial)Path)system)rmtreewhich)CalledProcessError)version_info)TemporaryDirectory)	AnyCallableDictList
NamedTupleOptionalSequenceTupleUnion)urlparseiX  Windowsz	black.exeblackzgit.exegitwin32c                   @   s6   e Zd ZU i Zeeef ed< i Zeee	f ed< dS )Resultsstatsfailed_projectsN)
__name__
__module____qualname__r   r   strint__annotations__r   r    r!   r!   O/var/www/secure340b-portal/env/lib/python3.10/site-packages/black_primer/lib.pyr   .   s   
 r   cmdtimeoutenvcwdstdinreturnc           	         s   t j| t jjt jjt jj||dI d H }zt |||I d H \}}W n t jy:   |  |	 I d H   w |j
d usBJ |j
dkrUd| }t|j
|||d||fS )N)r'   stdoutstderrr%   r&   r    )outputr*   )asynciocreate_subprocess_exec
subprocessPIPESTDOUTwait_forcommunicateTimeoutErrorkillwait
returncodejoinr   )	r#   r$   r%   r&   r'   processr)   r*   Zcmd_strr!   r!   r"   _gen_check_output3   s.    


r:   project_countresultsc                 C   s  t |jd |  d d}t |jd |  d d}tjddd tj|jd  d|  d	| d
ddd tj|jd  d|  d| dt|jd dd |jd dkrUdnd}td|jd  d| d |jd dkrodnd}td|jd  d| d td|jd  d |jrtjddd |j D ]4\}}td| d td|j	  |j
rtd|j
d   |jrtd!|jd   td q|jd S )"Nfailedd      successu   -- primer results 📊 --
T)boldz / z succeeded (u   %) ✅green)rA   fgz	 FAILED (u   %) 💩reddisabled    sz -  projectz disabled by configwrong_py_verz skipped due to Python versionskipped_long_checkoutz skipped due to long checkoutz
Failed projects:
z## :z - Returned z - stderr:
utf8z - stdout:
)roundr   clickZsechoboolZechor   itemsprintr7   r*   decoder)   )r;   r<   Z
failed_pctZsuccess_pctrH   project_nameZproject_cper!   r!   r"   analyze_resultsW   sB   

rU   cli_argsc                 C   s<   g }| D ]}t |tr|| qd|}|| q|S )zZAllow a user to put long arguments into a list of strs
    to make the JSON human readablerG   )
isinstancer   appendr8   )rV   Z	flat_argsargZargs_as_strr!   r!   r"   _flatten_cli_args   s   


rZ   FrT   	repo_pathproject_configno_diffc                    s  |s|j d  d7  < tdg |  d|  d|j| < dS |  dk}tttg}d|v r=|d r=|t	|d  |
d	 |sI|
d
 d}|rW|
d | }nd|v rc|
|d  n|
d d|v rp|d nt}t }	i tj|	|	d}
|r|jn|}ztd|  dd|  t|||
||dI dH \}}W n tjy   |j d  d7  < td| d| d Y ng ty* } zZ|jdkr|d s|j d  d7  < ||j|j< n	|j d  d7  < W Y d}~W d   dS |jdkr|j d  d7  < ||j|j< W Y d}~W d   dS td|   d}~ww W d   n	1 s6w   Y  |d rV|j d  d7  < td|dd|j|j< dS |j d  d7  < dS )zRun Black and record failuresr=   rF   E   z has no repo_path:     NSTDINZcli_argumentsz--checkz--diff-	base_path.Ztimeout_seconds)XDG_CONFIG_HOMEUSERPROFILEzRunning black for : r+   )r&   r%   r'   r$   z timed out ()Zexpect_formatting_changesr@   zUnknown error with r   s/   Expected formatting changes but didn't get any!)r   r   encoder   upperr   r   BLACK_BINARYextendrZ   rX   
read_bytesTEN_MINUTES_SECONDSr	   osenvironparentLOGdebugr8   r:   r-   r4   errorr7   name)rT   r[   r\   r<   r]   Z
stdin_testr#   r'   r$   Ztmp_pathr%   Zcwd_path_stdout_stderrZcper!   r!   r"   	black_run   s   










 
$rw   rF   )depth	work_pathrebaserx   c             
      s   t tt}|std dS t|d }|jdd jddd}| |d dd }|d	d
t ||d g}| }	|	 rG|rG|ddg}|}	n|	 rM|S zt
||	dI dH \}
}W |S  tjtfy~ } ztd|d  d|  W Y d}~dS d}~ww )zgit Clone project or rebasezNo git binary foundNZgit_clone_urlrF   /)maxsplitz.gitrG   clonez--depthpullz--rebase)r&   zUnable to git clone / pull rf   )r   r   
GIT_BINARYrq   rs   r   pathsplitreplaceexistsr:   r-   r4   r   )ry   r\   rz   rx   Zgit_binZrepo_url_parts
path_partsr[   r#   r&   ru   rv   er!   r!   r"   git_checkout_or_rebase   s.   

r   funcr   excc                 C   sx   |d }t d| d| j d | tjtjfv r;|jtjkr;t d| d t|t	j
t	jB t	jB  | | dS  )a  
    Handle PermissionError during shutil.rmtree.

    This checks if the erroring function is either 'os.rmdir' or 'os.unlink', and that
    the error was EACCES (i.e. Permission denied). If true, the path is set writable,
    readable, and executable by everyone. Finally, it tries the error causing delete
    operation again.

    If the check is false, then the original error will be reraised as this function
    can't handle it.
    rF   z	Handling z from z... zSetting z3 writable, readable, and executable by everyone... N)rq   rr   r   rn   rmdirunlinkerrnoEACCESchmodstatS_IRWXUS_IRWXGS_IRWXO)r   r   r   Zexcvaluer!   r!   r"   handle_PermissionError  s   r   config_pathc                    sx   |  d}t|}W d   n1 sw   Y  t|d  }tjt|d}|D ]
}||I dH  q-||fS )z=Load project config and fill queue with all the project namesrNprojects)maxsize)	openjsonloadsortedkeysr-   Queuelenput)r   ZcfpconfigZproject_namesqueueprojectr!   r!   r"   load_projects_queue  s   r   idxr   r   long_checkoutskeepc	                    s  t  }	td  dtd  }
	 z| }W n t jy+   td|  d Y dS w td|  d	|  |d
 | }d|v rX|d rX|jd  d7  < td| d qd|d vry|
|d vry|jd  d7  < td| d|
  q|s|d r|jd  d7  < td| d qt	t
}| dk}|st|||I dH }|sqt|||||I dH  |s|std|  tt|td}|	d|I dH  td|  q)z5Check out project and run Black on it + record resultr   rc   rF   Tzproject_runner z exitingNzworker z working on r   rE   z	Skipping z as it's disabled via configallZpy_versionsrJ   z as it's not enabled for Zlong_checkoutrK   z& as it's configured as a long checkoutr`   z	Removing )r   onerrorz	Finished )r-   get_event_loopr   
get_nowait
QueueEmptyrq   rr   r   infor   __file__ri   r   rw   r   r   r   run_in_executor)r   r   r   ry   r<   r   rz   r   r]   loop
py_versionrT   r\   r[   Zstdin_projectZrmtree_partialr!   r!   r"   project_runner-  sT   

r   config_fileworkersc           	   	      s   t  djd< djd< djd< djd< djd< tt| I dH \  }|dkr2d	nd
}t| d| d |dk rEdS |dkrKd	nd
}td| d| d tj	 fddt
|D  I dH  td t|S )z
    Process the queue with X workers and evaluate results
    - Success is guaged via the config "expect_formatting_changes"

    Integer return equals the number of failed projects
    r   rE   r=   rK   r@   rJ   NrF   rG   rH   rI   z to run Black overzUsing z parallel workerz to run Blackc                    s$   g | ]}t | 	qS r!   )r   ).0ir   r   r   r]   r   rz   r<   ry   r!   r"   
<listcomp>  s    z!process_queue.<locals>.<listcomp>zAnalyzing results)r   r   r   r   qsizerq   r   rr   r-   gatherrangerU   )	r   ry   r   r   r   rz   r]   r;   rH   r!   r   r"   process_queuel  s,   







r   __main__z!lib is a library, funnily enough.)F)FFFF)<r-   r   r   loggingrn   r   sys	functoolsr   pathlibr   platformr   shutilr   r   r/   r   r   tempfiler	   typingr
   r   r   r   r   r   r   r   r   urllib.parser   rO   rm   WINDOWSrj   r   	getLoggerr   rq   set_event_loopZProactorEventLoopr   r   floatbytesr:   r   rU   rZ   rP   rw   r   r   r   r   r   r   NotImplementedErrorr!   r!   r!   r"   <module>   s   ,




$&(

W

"


	

C

5