B y `Z+ @s:ddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZmZddlmZddlmZddlmZmZmZmZmZmZmZdd lmZddlZe d kZerd nd Zerd ndZ e!e"Z#ej dkre$e%GdddeZ&d0ee'e(eee'e'fee ee)e)fdddZ*e+e&e+dddZ,e ee'efe&ddddZ-d1dde ee'efe.e+ee dd d!Z/ee eeeefdd"d#d$Z0e eee'efej1fd%d&d'Z2d2e+ee'efej1e e&e.e.e.dd( d)d*Z3d3e'e e+e.e.e.e+d+d,d-Z4e"d.kr6e5d/dS)4N)partial)Path)system)rmtreewhich)CalledProcessError) version_info)AnyCallableDict NamedTupleOptionalSequenceTuple)urlparseWindowsz black.exeZblackzgit.exegitwin32c@s6eZdZUiZeeefed<iZeee fed<dS)Resultsstatsfailed_projectsN) __name__ __module__ __qualname__rr strint__annotations__rrrr4/tmp/pip-unpacked-wheel-qq0fnpma/black_primer/lib.pyr$s r,)cmdtimeoutenvcwdreturncstj|tjjtjj||dIdH}yt||IdH\}}Wn.tjk rp|| IdHYnX|j dkrd |}t |j |||d||fS)N)stdoutstderrr"r#r )outputr&) asyncioZcreate_subprocess_exec subprocessPIPESTDOUTwait_for communicate TimeoutErrorkillwait returncodejoinr)r r!r"r#processr%r&Zcmd_strrrr_gen_check_output)s"  r5) project_countresultsr$cCst|jd|dd}t|jd|dd}tjdddtj|jdd|d |d dd d tj|jdd|d |dt|jddd |jddkrdnd}td|jdd|d|jddkrdnd}td|jdd|dtd|jdd|jr.tjdddx||jD]n\}}td|dtd|j |j rtd|j d |j rtd!|j d tdq:W|jdS)"Nfaileddsuccessu-- primer results 📊 -- T)boldz / z succeeded (u%) ✅Zgreen)r<Zfgz FAILED (u%) 💩Zreddisabledsz - z projectz disabled by config wrong_py_verz skipped due to Python versionskipped_long_checkoutz skipped due to long checkoutz Failed projects: z## :z - Returned z - stderr: utf8z - stdout: ) roundrclickZsechoboolZechoritemsprintr2r&decoder%)r6r7Z failed_pctZ success_pctr@ project_nameZ project_cperrranalyze_resultsFs: rL) repo_pathproject_configr7r$c stttg}d|kr,|dr,|j|d|dddgyt||dIdH\}}Wntjk r|jdd7<t d |d |d Ynt k r@}z|j dkr|d s|jdd7<||j |j <n|jd d7<dS|j dkr|jdd7<||j |j <dSt d|Wdd}~XYnX|d rx|jdd7<t d|dd|j |j <dS|jd d7<dS)zRun Black and record failuresZ cli_argumentsz--checkz--diff.)r#Nr8r>zRunning black for z timed out ()Zexpect_formatting_changesr;zUnknown error with rs/Expected formatting changes but didn't get any!)rr BLACK_BINARYextendr5r)r/rLOGerrorrr2rname)rMrNr7r _stdout_stderrZcperrr black_runns8    rYFr>)depth) work_pathrNrebaserZr$c sttt}|stddSt|d}|jddjddd}||ddd}|d d t||dg}|} | r|r|d d g}|} n | r|Syt || d IdH\} } WnBt j t fk r} ztd|dd| dSd} ~ XYnX|S)zgit Clone project or rebasezNo git binary foundNZ git_clone_urlr>/)maxsplitz.gitr?clonez--depthpullz--rebase)r#zUnable to git clone / pull z: )rr GIT_BIANRYrTrUrpathsplitreplaceexistsr5r)r/r) r[rNr\rZZgit_binZrepo_url_parts path_partsrMr r#rWrXerrrgit_checkout_or_rebases(     rh)funcrbexcr$cCsz|d}td|d|jd|tjtjfkrt|jtjkrttd|dt|t j t j Bt j B||ndS)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. r>z Handling z from z... zSetting z3 writable, readable, and executable by everyone... N) rTdebugrosrmdirunlinkerrnoEACCESchmodstatS_IRWXUS_IRWXGS_IRWXO)rirbrjZexcvaluerrrhandle_PermissionErrors rv) config_pathr$c sf|d}t|}WdQRXt|d}tjt|d}x|D]}||IdHqFW||fS)z=Load project config and fill queue with all the project namesrNprojects)maxsize) openjsonloadsortedkeysr)Queuelenput)rwZcfpconfigZ project_namesqueueprojectrrrload_projects_queues  r) idxrrr[r7long_checkoutsr\keepr$cst}tddtd} x|y |} Wn(tjk rVtd|ddSXtd|d| |d | } d | kr| d r|jd d7<td | d q"d | dkr| | dkr|jdd7<td | d| q"|s(| dr(|jdd7<td | dq"t || |IdH} | sBq"t | | |IdH|std| t t | t d} |d| IdHtd| q"WdS)z5Check out project and run Black on it + record resultrrOr>zproject_runner z exitingNzworker z working on ryr=z Skipping z as it's disabled via configallZ py_versionsrAz as it's not enabled for Z long_checkoutrBz& as it's configured as a long checkoutz Removing )rbonerrorz Finished )r)Zget_event_loopr get_nowaitZ QueueEmptyrTrkrinforhrYrrrvZrun_in_executor)rrrr[r7rr\rZloop py_versionrKrNrMZrmtree_partialrrrproject_runnersB      r) config_filer[workersrrr\r$cstdjd<djd<djd<djd<djd<tt|IdH\}|dkrbd nd }t|d |d |dkrd S|dkrd nd }td|d|dtj fddt |DIdHtdt |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 rr=r8rBr;rANr>r?r@z projectz to run Black overzUsing z parallel workerz to run Blackc s"g|]}t|qSr)r).0i)rrrrr\r7r[rr @sz!process_queue..zAnalyzing results) rrrrqsizerTrrkr)ZgatherrangerL)rr[rrrr\r6r@r)rrrrr\r7r[r process_queues&      r__main__z!lib is a library, funnily enough.)rNN)F)FFF)FFF)6r)ror|loggingrlrrsys functoolsrpathlibrplatformrshutilrrr*rrtypingr r r r r rr urllib.parserrFWINDOWSrRra getLoggerrrTZset_event_loopZProactorEventLooprrfloatbytesr5rrLrYrGrhrvrrrrNotImplementedErrorrrrrs\     $      ), 6%