B
    XM\|ÿ  ã               @   s  d dl mZmZmZ d dlmZm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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mZmZmZmZmZmZmZmZm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$Z$d dl%m&Z& d dl'Z'd dl(Z(d dl)Z)yd dl*m+Z+ W n( e,k
rD   d dl*m-Z- e-fZ+Y nX d	d
l.m/Z/m0Z0m1Z1m2Z2 d	dl.m3Z3m4Z4 d	dl.m5Z5m6Z6 d	dl.m7Z7 d	dl.m8Z8 d	dl.m9Z9 d	dl.m:Z:m;Z; d	dl.m<Z< d	dl.m=Z=m>Z> d	dl.m?Z? d dl@mAZB d dlCmDZD d dlEmFZF e3rHd dlGmGZH dØdd„ZGd dlImJZK d dlLmMZN d dlmOZO ePZPeQZQn:d dlRmGZS dÙdd„ZGd dlKZKd dlNZNd dlTmOZO eUZPeUZQe!jVdkZWeƒ p–dZXe!jVdkZWejY e5eWr´dnd ¡ZZeWrÄd nej[Z\eWrÔd nej]Z^eWräd nej_Z`d!Zayd d"lmbZbmcZc W n" edk
r$   d d#lbmcZc Y nX e8d$d%„ ƒZed&d'„ Zfd(d)„ ZgG d*d+„ d+ehƒZid,d-„ ZjG d.d/„ d/ehƒZkd0d1„ Zld2d3„ Zmd4d5„ Znd6d7„ Zod8d9„ Zpejqd:d;„ ƒZrd<d=„ Zsd>d?„ ZtdÚdBdC„ZudÛdDdE„ZvdÜdFdG„ZwejY e5dH¡ejY ejY dIdJ¡¡fZxdÝdKdL„ZydÞdMdN„ZzdßdPdQ„Z{dRZ|dàdTdU„Z}dVdW„ Z~dXdY„ ZdZd[„ Z€d\d]„ Zd^d_„ Z‚d`da„ Zƒdbdc„ Z„ddde„ Z…dfdg„ Z†dhdi„ Z‡djdk„ Zˆdldm„ Z‰dndo„ ZŠdpdq„ Z‹drds„ ZŒdádtdu„Zejqdvdw„ ƒZŽejqdxdy„ ƒZe!jVdkrÌdnd Ze ‘dz¡Z’d{d|„ Z“d}d~„ Z”dd€„ Z•dd‚„ Z–i Z—dƒd„„ Z˜d…d†„ Z™e8d‡dˆ„ ƒZšd‰dŠ„ Z›ejqd‹dŒ„ ƒZœddŽ„ Zdd„ ZžG d‘d’„ d’ehƒZŸd“d”„ Z d•d–„ Z¡G d—d˜„ d˜e¢ƒZ£d™dš„ Z¤e( ¥e£e¤¡ ejqd›dœ„ ƒZ¦ejqdâddž„ƒZ§dŸd „ Z¨d¡d¢„ Z©dãd¥d¦„Zªdäd¨d©„Z«dªd«„ Z¬dåd¬d­„ZAG d®d¯„ d¯ej­ƒZ®G d°d±„ d±ej­ƒZ¯G d²d³„ d³ej­ƒZ°e°ƒ a±e®ej²ƒZ³e¯ej´ƒZµe ¶d´¡ ·ej¸¡ e ¶dµ¡ ·ej¸¡ e ¶d¶¡ ·ej¸¡ e ¶d·¡ ·ej¸¡ d¸d¹„ Z¹ej´ddfdºd»„Zºd¼d½„ Z»dæd¿dÀ„Z¼dÁdÂ„ Z½dÃdÄ„ Z¾dd e^e`B dd fdÅdÆ„Z¿dÇdÈ„ ZÀdçdÉdÊ„ZÁe ‘dË¡ZÂe ‘dÌ¡ZÃdèdÍdÎ„ZÄdÏdÐ„ ZÅdédÑdÒ„ZÆdÓdÔ„ ZÇdêdÖd×„ZÈdS )ëé    )Úabsolute_importÚdivisionÚprint_function)ÚOrderedDictÚdefaultdictN)Úgetpreferredencoding)
ÚdirnameÚgetmtimeÚgetsizeÚisdirÚjoinÚisfileÚabspathÚislinkÚ
expanduserÚ
expandvars)ÚThread)ÚCONDA_TARBALL_EXTENSIONS)ÚCONDA_TARBALL_EXTENSIONé   )Úhashsum_fileÚmd5_fileÚunix_path_to_winÚwin_path_to_unix)ÚPY3Ú	iteritems)Úroot_dirÚ	pkgs_dirs)Ústring_types)Úmemoized)ÚStringIO)ÚVersionOrderÚ	MatchSpec)Úcc_conda_build)Úconda_43ÚDist)Úcontext)Úrm_rf)ÚBuildLockError)Úexternal)ÚglobTc             C   s   t | |dS )N)Ú	recursive)Ú	glob_glob)Úpathnamer+   © r.   ú0lib/python3.7/site-packages/conda_build/utils.pyr*   7   s    r*   )Ú	ExitStackc             C   s   t | |dS )N)r+   )Ú
glob2_glob)r-   r+   r.   r.   r/   r*   C   s    Úwin32zutf-8ÚScriptsÚbinzÑ
# -*- coding: utf-8 -*-
import re
import sys

from %(module)s import %(import_name)s

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(%(func)s())
)ÚscandirÚwalk)r6   c             C   s
   t  | ¡S )N)ÚosÚstat)Úpathr.   r.   r/   Ú	stat_filei   s    r:   c          
   C   s„   d}t ƒ }xtt| ƒD ]h\}}}x\|D ]T}yttj ||¡ƒ}W n tk
rT   w$Y nX |j|krbq$| |j¡ ||j	7 }q$W qW |S )Nr   )
Úsetr6   r:   r7   r9   r   ÚOSErrorÚst_inoÚaddÚst_size)r9   Z
total_sizeÚseenÚrootÚ_ÚfilesÚfr8   r.   r.   r/   Údirectory_size_slown   s    

rE   c          	   C   s   yÜt r d}tj| | ¡dd}nd}tj| | ¡ ¡ tjd}t|dƒrzy|jdd}W n  tt	fk
rx   t rtd	S Y nX t rÎ| 
¡  d
d¡d }d}t || 
¡ ¡ d¡ 
¡ }| dd¡ dd¡ dd¡}n| ¡ d	 }W n tjk
rú   t| ƒ}Y nX yt|ƒS  tk
r   d	S X dS )z
    zdir /s "{}"T)Úshellzdu -s {})ÚstderrÚdecodeÚignore)Úerrorsr   z
é   éþÿÿÿz\s([\d\W]+).+r   ú,Ú Ú.ú N)Úon_winÚ
subprocessÚcheck_outputÚformatÚsplitÚPIPEÚhasattrrH   ÚUnicodeDecodeErrorÚ
IndexErrorÚstripÚrsplitÚreÚsearchÚgroupÚreplaceÚCalledProcessErrorrE   ÚintÚ
ValueError)r9   ZcommandÚoutÚpatternr.   r.   r/   Údirectory_size‚   s2    
re   c               @   s   e Zd Zdd„ ZdS )ÚDummyPsutilProcessc             O   s   g S )Nr.   )ÚselfÚargsÚkwargsr.   r.   r/   Úchildren¨   s    zDummyPsutilProcess.childrenN)Ú__name__Ú
__module__Ú__qualname__rj   r.   r.   r.   r/   rf   §   s   rf   c                sŒ   t ƒ ‰x*t|  ¡ dd„ ddD ]\}}|ˆ|< qW t ¡ \}‰t |d¡‰ tjdkrZd‰nd‰‡ ‡‡‡fd	d
„}t|d}d|_	| 
¡  ˆS )a  Rewrite values of env variables back to $ENV in stdout

    Takes output on the pipe and finds any env value
    and rewrites it as the env key

    Useful for replacing "~/conda/conda-bld/pkg_<date>/_h_place..." with "$PREFIX"

    Returns an FD to be passed to Popen(stdout=...)
    c             S   s   t | d ƒS )Nr   )Úlen)Zkvr.   r.   r/   Ú<lambda>º   s    z%_setup_rewrite_pipe.<locals>.<lambda>T)ÚkeyÚreverseZrtr2   z%{}%z${}c                 s°   xªyZˆ   ¡ } | s&ˆ  ¡  t ˆ¡ d S x&ˆ ¡ D ]\}}|  |ˆ |¡¡} q0W tj | ¡ W q t	k
r¦   y t 
ˆ d¡}tj |p†d¡ W n tk
r    Y nX Y qX qW d S )Ni'  rN   )ÚreadlineÚcloser7   Úitemsr_   rT   ÚsysÚstdoutÚwriterX   ÚreadÚ	TypeError)ÚlineÚsrp   Ztxt)ÚrÚreplacement_tÚreplacementsÚw_fdr.   r/   ÚrewriterÄ   s     
z%_setup_rewrite_pipe.<locals>.rewriter)Útarget)r   Úsortedrt   r7   ÚpipeÚfdopenru   Úplatformr   ZdaemonÚstart)ÚenvÚkÚvZr_fdr€   Útr.   )r|   r}   r~   r   r/   Ú_setup_rewrite_pipe¬   s     

r‹   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚPopenWrapperc             O   s<   d | _ d| _d| _d | _d| _d| _| j||Ž\| _| _d S )Nr   r   )	ÚelapsedÚrssÚvmsÚ
returncodeÚdiskÚ	processesÚ_executerc   Úerr)rg   rh   ri   r.   r.   r/   Ú__init__â   s    zPopenWrapper.__init__c          
   O   sZ  ydd l }|j|j|jf}W nP tk
rl } z2d }ttf}ttƒ}| d 	|¡¡ | d¡ W d d }~X Y nX | 
dd¡}| dtj¡}|rš| t ¡ ¡ntƒ }	ttƒ}
t ¡ }|rÀ|j||Žn
tj||Ž}y>x6| jd krd}d}d}xŠ|	jddD ]z}|
 |ji ¡}yF| ¡ }||j7 }||j7 }| ¡ }|j|d	< |j|d
< ||
|j< W n |k
rj   wúY nX |d7 }qúW t|| jƒ| _t|| j ƒ| _ t!dd„ |
 "¡ D ƒƒ| _#t!dd„ |
 "¡ D ƒƒ| _$t|| j%ƒ| _%tt&|ƒ| j'ƒ| _'t (|¡ t ¡ | | _)| *¡ | _qÔW W n  t+k
r,   | ,¡  ‚ Y nX tt&|ƒ| j'ƒ| _'t ¡ | | _)|j-|j.fS )Nr   z#psutil import failed.  Error was {}zsonly disk usage and time statistics will be available.  Install psutil to get CPU time and memory usage statistics.Útime_intrK   ÚcwdT)r+   ru   Úuserr   c             s   s   | ]}|d  V  qdS )ru   Nr.   )Ú.0Úchildr.   r.   r/   ú	<genexpr>$  s    z(PopenWrapper._execute.<locals>.<genexpr>c             s   s   | ]}|d  V  qdS )r˜   Nr.   )r™   rš   r.   r.   r/   r›   %  s    )/ÚpsutilZNoSuchProcessZAccessDeniedÚImportErrorr<   rb   Ú
get_loggerrk   ÚwarnrT   ÚpopÚgetru   ÚprefixZProcessr7   Úgetpidrf   r   ÚdictÚtimeÚPopenrR   r   rj   ÚpidZmemory_inforŽ   Z	cpu_timesÚsystemr˜   Úmaxr   ÚsumÚvaluesÚcpu_sysÚcpu_userr’   re   r‘   Zsleepr   ZpollÚKeyboardInterruptÚkillrv   rG   )rg   rh   ri   rœ   Zpsutil_exceptionsÚeÚlogr–   Zdisk_usage_dirÚparentZ	cpu_usageZ
start_timeZ_popenrŽ   r   r’   rš   Zchild_cpu_usageZmemZ	cpu_statsr.   r.   r/   r“   ì   s`    




zPopenWrapper._executec          
   C   s*   t | j| j| j| j| j| j| j| jdœƒS )N)r   rŽ   r   r‘   r’   r­   r¬   r   )	Ústrr   rŽ   r   r‘   r’   r­   r¬   r   )rg   r.   r.   r/   Ú__repr__7  s    zPopenWrapper.__repr__N)rk   rl   rm   r•   r“   r´   r.   r.   r.   r/   rŒ   Þ   s   
KrŒ   c       
   
   O   s˜  d|kr(|  ¡ }tj  ¡ }| d|i¡ dd„ |d  ¡ D ƒ|d< g }d|krXtj|d< x\|D ]T}tjj	dk r„t
|dƒr„| t¡}n tjj	dkr¤t
|dƒr¤| t¡}| t|ƒ¡ q^W | d¡}d|krÎ|d= | d	d ¡}|rêt|ƒ|d
< d }|d k	r\t|f|Ž}	| dkr|	j ¡ }|	jdkr2t |	j|¡‚| |	j|	j|	j|	j|	j|	j|	jdœ¡ n8| dkrvtj|f|Ž nd
|kr†|d
= tj |f|Ž}|S )Nr‡   c             S   s   i | ]\}}t |ƒt |ƒ“qS r.   )r³   )r™   rp   Úvaluer.   r.   r/   ú
<dictcomp>G  s    z6_func_defaulting_env_to_os_environ.<locals>.<dictcomp>Ústdiné   ÚencoderH   ÚstatsÚrewrite_stdout_envrv   Úoutputr   )r   r‘   r’   r­   r¬   rŽ   r   Úcall)!Úcopyr7   ÚenvironÚupdatert   rR   rV   ru   Úversion_infoÚmajorrW   r¹   ÚcodecrH   Úappendr³   r¡   r    r‹   rŒ   rc   rx   r   r`   r   r‘   r’   r­   r¬   rŽ   r   Ú
check_callrS   )
ÚfuncÚ	popenargsri   Zenv_copyZ_argsÚargrº   r»   rc   Úprocr.   r.   r/   Ú"_func_defaulting_env_to_os_environB  sP    









rÊ   c             K   s   t d| ž|ŽS )Nr½   )r½   )rÊ   )rÇ   ri   r.   r.   r/   Úcheck_call_envu  s    rË   c             K   s   t d| ždtji|—Ž ¡ S )Nr¼   rv   )r¼   )rÊ   rR   rV   Úrstrip)rÇ   ri   r.   r.   r/   Úcheck_output_envy  s    rÍ   c             C   st   d}i }x(t |ƒD ]\}}d|d d > ||< qW x8t|ƒD ],}| || kr<t| ƒ||  }d||f S q<W d|  S )N)ÚKÚMÚGÚTÚPÚEÚZÚYr   é
   z%.1f%sz%sB)Ú	enumerateÚreversedÚfloat)ÚnZsymbolsr¢   Úir{   rµ   r.   r.   r/   Úbytes2human~  s    rÜ   c             C   sÊ   t s|  tƒ pd¡} t| ƒrŽ|  ¡  t¡s8|  ¡  t¡r|t 	¡ }t
| |ƒ tj |dd¡}t|ƒrvt
|tj |d¡ƒ d}q¨td|  ƒ dS nttj t ¡ | ¡ƒ}d}tj |¡sÂtd |¡ƒ‚||fS )	a  resolve recipe dir as absolute path.  If recipe is a tarball rather than a folder,
    extract it and return the extracted directory.

    Returns the absolute path, and a boolean flag that is true if a tarball has been extracted
    and needs cleanup.
    zutf-8Úinfoz
recipe.tarTzIgnoring non-recipe: %s)NNFz,Package or recipe at path {0} does not exist)r   rH   r   r   ÚlowerÚendswithÚdecompressible_extsr   ÚtempfileZmkdtempÚtar_xfr7   r9   r   Úprintr   ÚgetcwdÚexistsrb   rT   )ZrecipeZ
recipe_dirZrecipe_tarfileZneed_cleanupr.   r.   r/   Úget_recipe_abspath  s"    
ræ   c          	   c   sœ   t   ¡ }xjt   ¡ | |k rjyx| D ]}|jdd q"W W n, tjk
rd   x| D ]}| ¡  qPW Y q
X P q
W tdƒ‚z
dV  W dx| D ]}| ¡  q†W X dS )a2  Try to acquire all locks.

    If any lock can't be immediately acquired, free all locks.
    If the timeout is reached withou acquiring all locks, free all locks and raise.

    http://stackoverflow.com/questions/9814008/multiple-mutex-locking-strategies-and-why-libraries-dont-use-address-comparison
    gš™™™™™¹?)ÚtimeoutzFailed to acquire all locksN)r¥   ÚacquireÚfilelockZTimeoutÚreleaser(   )Úlocksrç   rŠ   Úlockr.   r.   r/   Útry_acquire_locks­  s    	



rí   c             C   s¾   d}xJt jt jt jfD ]6}y|| |ƒ d}P W q tttfk
rJ   wY qX qW |sºy"tjd 	| |¡dtj
tj
d W nB tjk
r¸ } z"tj |¡s¨td 	| ||¡ƒ‚W d d }~X Y nX d S )NFTzcp -a {} {})rF   rG   rv   z'Failed to copy {} to {}.  Error was: {})ÚshutilZcopy2r¾   ZcopyfileÚIOErrorr<   ÚPermissionErrorrR   rÅ   rT   rV   r`   r7   r9   r   )ÚsrcÚdstZ	is_copiedrÆ   r°   r.   r.   r/   Ú_copy_with_shell_fallbackÛ  s    
ró   c             C   sZ   |   tjj¡}|  tjj¡}x$|r@|d |d kr@|d= |d= qW tjj|Ž tjj|Ž fS )Néÿÿÿÿ)rU   r7   r9   Úsepr   )rñ   rò   ZssplitZdsplitr.   r.   r/   Úget_prefix_replacement_pathsí  s    
rö   é„  Fc          
   C   sX  t tƒ}|r¾t| ƒr¾yt tj |¡¡ W n tk
r>   Y nX tj |¡rVt 	|¡ t
| |ƒ\}}	t | ¡}
|
 ||	¡}t ||¡ y&t | ¡}t |j¡}t ||¡ W n   Y nX n–t| ƒràt| ||||||d ntt|ƒrtj |tj | ¡¡}n|}tj | ¡r"tj | ¡}n<tjj|krVtj |¡}tj |¡s^t |¡ nt ¡ }tj | ¡r’tj tj | ¡¡s’| d| ¡ dS |sª|rªt||d}|r¶|gng }t||ƒŠ tj |¡}|rtj |¡syt |¡ W n tk
r
   Y nX yt| |ƒ W n. t j!k
rH   | "dtj | ¡|¡ Y nX W dQ R X dS )z>Copy all the files and directories in src to the directory dst)rç   rì   ÚlockingÚclobberz+path %s is a broken symlink - ignoring copyN)rç   z"skipping %s - already exists in %s)#rž   rk   r   r7   Úmakedirsr9   r   r<   ÚlexistsÚremoverö   Úreadlinkr_   ÚsymlinkÚlstatr8   ÚS_IMODEÚst_modeÚlchmodr   Ú
merge_treer   ÚbasenameÚisabsrõ   rä   rå   ÚrealpathrŸ   Úget_lockrí   ró   rî   ÚErrorÚdebug)rñ   rò   rç   Úsymlinksrì   rø   rù   r±   Zsrc_baseZdst_baseZ
src_targetZsrc_replacedÚstÚmodeZdst_fnZ
src_folderrë   Z
dst_folderr.   r.   r/   Ú	copy_intoö  s`    




$r  c                s@  t j ˆ ¡s"t  ˆ ¡ t | ˆ ¡ t  | ¡}|rL|| |ƒ‰‡fdd„|D ƒ}d|kr^| d¡ ‡ fdd„|D ƒ}|s<xÄt|ƒD ]¸\}}t j 	| |¡}	|| }
|rt j 
|	¡rt j |
¡rÈt  |
¡ t  t  |	¡|
¡ y&t  |	¡}t |j¡}t  |
|¡ W n   Y nX q€t j |	¡r.t|	|
||ƒ q€t|	|
ƒ q€W |S )Nc                s   g | ]}|ˆ kr|‘qS r.   r.   )r™   Úx)Úexclr.   r/   ú
<listcomp>;  s    zcopytree.<locals>.<listcomp>z.conda_lockc                s   g | ]}t j ˆ |¡‘qS r.   )r7   r9   r   )r™   Úitem)rò   r.   r/   r  A  s    )r7   r9   rå   rú   rî   ZcopystatÚlistdirrü   r×   r   r   rû   rþ   rý   rÿ   r8   r   r  r  r   Úcopytreeró   )rñ   rò   r
  rI   Údry_runZlstZdst_lstÚidxr  r{   Údr  r  r.   )rò   r  r/   r  4  s8    





r  c       
   	   C   sÄ   t j t j |¡¡}t j t j | ¡¡} | | ¡rBtd | |¡ƒ‚t| ||dd}dd„ |D ƒ}|r~|s~td | ||d ¡ƒ‚g }	|rœ|s–t	| |d}|g}	t
|	|ƒ t| ||d	 W d
Q R X d
S )zá
    Merge src into dst recursively by copying all files from src into dst.
    Return a list of all files copied.

    Like copytree(src, dst), but raises an error if merging the two trees
    would overwrite any files.
    z{Can't merge/copy source into subdirectory of itself.  Please create separate spaces for these things.
  src: {0}
  dst: {1}T)r
  r  c             S   s   g | ]}t |ƒr|‘qS r.   )r   )r™   rD   r.   r.   r/   r  i  s    zmerge_tree.<locals>.<listcomp>z*Can't merge {0} into {1}: file exists: {2}r   )rç   )r
  N)r7   r9   ÚnormpathÚnormcaseÚ
startswithÚAssertionErrorrT   r  rï   r  rí   )
rñ   rò   r
  rç   rì   rø   rù   Z	new_filesÚexistingrë   r.   r.   r/   r  Y  s     
r  rë   ú~z.conda_build_locksc       	   
   C   sþ   d }yt j t j | ¡¡}W n tk
r4   | }Y nX |}t|dƒrL| ¡ }t |¡ 	¡ }t|dƒrl| 
¡ }xŒtD ]v}yVt j |¡sŽt  |¡ t j ||¡}t|dƒ}| d¡ W d Q R X t ||¡}P W qr ttfk
ræ   wrY qrX qrW tdjtŽ ƒ‚|S )Nr¹   rH   ÚwrN   z^Could not write locks folder to either system location ({0})or user location ({1}).  Aborting.)r7   r9   r   r  r<   rW   r¹   ÚhashlibÚsha256Ú	hexdigestrH   Ú_lock_foldersr   rú   r   Úopenrw   ré   ZFileLockrï   ÚRuntimeErrorrT   )	Úfolderrç   ZflÚlocationZ
b_locationZlock_filenameZ	locks_dirZ	lock_filerD   r.   r.   r/   r    s2    




r  c             C   sx   g }t |ƒ}| rttd d… }|t|ƒ }x8|D ]0}tj |¡sHt |¡ t||d}| |¡ q.W | td|d¡ |S )Nr   )rç   zconda-operation)	Úensure_listr   Úlistr7   r9   r   rú   r  rÄ   )rø   Zbldpkgs_dirsrç   rë   Z
_pkgs_dirsZlocked_foldersr$  rì   r.   r.   r/   Úget_conda_operation_locksŸ  s    

r(  Úlibc             C   s²   |   d¡rt| ƒ‚|  d¡r$t|ƒ‚| d¡ d¡}|dgkrBg }t| ƒ d¡} | dgkr^g } x0|rŽ| rŽ|d | d krŽ| d¡ |  d¡ q`W d | r¦dgt| ƒ ndg| ¡S )Nú/rO   rN   r   z..)r  r  rZ   rU   r   r    r   rn   )rD   r  r.   r.   r/   Úrelative°  s    


r+  )z.7zz.tarz.tar.bz2z.tar.gzz	.tar.lzmaz.tar.xzz.tar.zz.tgzz.whlz.zipz.rpmz.debúr:*c       	      C   sj  |   ¡  d¡rNt d¡}|s&t d¡}|s4t d¡ t|d| gƒ | d d… } ts|  d¡rt d¡}|stt d	¡ t|dd
| gƒ | d d… } t 	| |¡}| 
¡ }x’t|dƒD ]„\}}tj |j¡rØtj |jd¡|_tj |j¡ t ¡ ¡s|j dd¡|_tj |j¡ t ¡ ¡s,t d|j ¡ |||< q°W tsR|j| t¡d n|j|d | ¡  d S )Nz.tar.zÚ
uncompressZgunzipzAuncompress (or gunzip) is required to unarchive .z source files.
z-frL   z.tar.xzÚunxzz0unxz is required to unarchive .xz source files.
z-kéýÿÿÿr   r*  z../rN   ztarball contains unsafe path: )r9   )rÞ   rß   r)   Úfind_executableru   ÚexitrË   r   Útarfiler"  Z
getmembersr×   r7   r9   r  ÚnameÚrelpathr  r  rä   r_   Z
extractallr¹   rÃ   rs   )	ÚtarballÚdir_pathr  r-  r.  rŠ   ÚmembersrÛ   Úmemberr.   r.   r/   Ú_tar_xf_fallbackÅ  s<    


r9  c          	   C   s´   ddl m} ||ƒ}tj | ¡s2tj t ¡ | ¡} d }d}t | ¡T}xL|D ]D}|j	|krL|d7 }x*| 
¡ D ]}|d kr‚t|ƒ}ql||7 }qlW P qLW W d Q R X |t|ƒkr°tƒ ‚|S )Nr   )r&  r   )Zconda_build.utilsr&  r7   r9   r  r   rä   Ú
libarchiveÚfile_readerr3  Z
get_blocksÚbytesrn   ÚKeyError)r5  Úentriesr&  ÚresultZn_foundÚarchiveÚentryÚblockr.   r.   r/   Útar_xf_fileë  s$    


rC  c          	   C   sV   t j | ¡st j t  ¡ | ¡} g }t | ¡ }x|D ]}| |j¡ q4W W d Q R X |S )N)	r7   r9   r  r   rä   r:  r;  rÄ   r3  )r5  r?  r@  rA  r.   r.   r/   Útar_xf_getnames  s    
rD  c          	   C   s    t jjt jjB t jjB t jjB t jjB }tj 	| ¡sFtj 
t ¡ | ¡} y$t|ƒ t  | |¡ W d Q R X W n0 t jjk
rš   |  d¡r”t| |ƒ n‚ Y nX d S )N)z.tarz.tar.gzz.tgzz.tar.bz2z.tar.zz.tar.xz)r:  ÚextractZEXTRACT_TIMEZEXTRACT_PERMZEXTRACT_SECURE_NODOTDOTZEXTRACT_SECURE_SYMLINKSZEXTRACT_SECURE_NOABSOLUTEPATHSr7   r9   r  r   rä   Ú	tmp_chdirZextract_fileZ	exceptionZArchiveErrorrß   r9  )r5  r6  Úflagsr.   r.   r/   râ     s    


râ   c             C   s    t | ƒt| ƒt| dƒt| ƒdœS )Nr  )ÚsizeZmd5r  Úmtime)r
   r   r   r	   )r9   r.   r.   r/   Ú	file_info   s    rJ  c             C   sb   t | ƒst| ƒ} tdd„ ƒ}x|D ]}|| |ƒ |ƒ q"W i }xt|ƒD ]\}}|j||< qHW |S )a   Group a collection by a key function
    >>> names = ['Alice', 'Bob', 'Charlie', 'Dan', 'Edith', 'Frank']
    >>> groupby(len, names)  # doctest: +SKIP
    {3: ['Bob', 'Dan'], 5: ['Alice', 'Edith', 'Frank'], 7: ['Charlie']}
    >>> iseven = lambda x: x % 2 == 0
    >>> groupby(iseven, [1, 2, 3, 4, 5, 6, 7, 8])  # doctest: +SKIP
    {False: [1, 3, 5, 7], True: [2, 4, 6, 8]}
    Non-callable keys imply grouping on a member.
    >>> groupby('gender', [{'name': 'Alice', 'gender': 'F'},
    ...                    {'name': 'Bob', 'gender': 'M'},
    ...                    {'name': 'Charlie', 'gender': 'M'}]) # doctest:+SKIP
    {'F': [{'gender': 'F', 'name': 'Alice'}],
     'M': [{'gender': 'M', 'name': 'Bob'},
           {'gender': 'M', 'name': 'Charlie'}]}
    See Also:
        countby
    c               S   s   g j S )N)rÄ   r.   r.   r.   r/   ro   =  s    zgroupby.<locals>.<lambda>)ÚcallableÚgetterr   r   Ú__self__)rp   Úseqr  r  Úrvrˆ   r‰   r.   r.   r/   Úgroupby)  s    
rP  c                sP   t ˆ tƒrBtˆ ƒdkr*ˆ d ‰ ‡ fdd„S ˆ r8tjˆ Ž S dd„ S n
t ˆ ¡S d S )Nr   r   c                s
   | ˆ  fS )Nr.   )r  )Úindexr.   r/   ro   J  s    zgetter.<locals>.<lambda>c             S   s   dS )Nr.   r.   )r  r.   r.   r/   ro   N  s    )Ú
isinstancer'  rn   ÚoperatorÚ
itemgetter)rQ  r.   )rQ  r/   rL  F  s    


rL  c             C   s4   t | ƒdkrd | ¡S d | dd… ¡d | d  S )zÀ
    Like ', '.join(items) but with and

    Examples:

    >>> comma_join(['a'])
    'a'
    >>> comma_join(['a', 'b'])
    'a and b'
    >>> comma_join(['a', 'b', 'c])
    'a, b, and c'
    rK   z and z, Nrô   z, and )rn   r   )rt   r.   r.   r/   Ú
comma_joinS  s    rU  c              O   sj   |  dd¡}|  dd¡}|  dd¡}tr4tjjj}ntjj}| | ¡| }tjjpTd}|| ||¡ƒ dS )	aG  
    prints unicode strings to stdout using configurable `errors` handler for
    encoding errors

    :param args: unicode strings to print to stdout
    :param sep: separator (defaults to ' ')
    :param end: ending character (defaults to '
')
    :param errors: error handler for encoding errors (defaults to 'replace')
    rõ   rP   ÚendÚ
rJ   r_   Úutf8N)	r    r   ru   rv   Úbufferrw   r   Úencodingr¹   )rh   ri   rõ   rV  rJ   rÆ   rz   rZ  r.   r.   r/   Úsafe_print_unicodec  s    
r[  c                s^   g }xTt | ƒD ]H‰ g }x"|D ]}| t ˆ d |¡¡ qW |r| ‡ fdd„|D ƒ¡ qW |S )NrK   c                s   g | ]}t j ˆ d  |¡‘qS )r   )r7   r9   r   )r™   rD   )Úd_fr.   r/   r  ƒ  s    zrec_glob.<locals>.<listcomp>)r6   ÚextendÚfnmatchÚfilter)r9   Zpatternsr?  Úmrd   r.   )r\  r/   Úrec_globy  s    
ra  c             C   sJ   t  d¡r>d | ¡}tr$t |¡} qFt | ¡ ¡ ¡  d¡} nt	| ƒ} | S )NÚcygpathzcygpath -w {0}ú\)
r)   r0  rT   r   rR   Ú	getoutputrS   rU   rÌ   r   )r9   Úcmdr.   r.   r/   Úconvert_unix_path_to_win‡  s    

rf  c             C   sJ   t  d¡r>d | ¡}tr$t |¡} qFt | ¡ ¡ ¡  d¡} nt	| ƒ} | S )Nrb  zcygpath -u {0}rc  )
r)   r0  rT   r   rR   rd  rS   rU   rÌ   r   )r9   re  r.   r.   r/   Úconvert_win_path_to_unix”  s    

rg  c             C   s   t  dt | ¡¡S )Nzfile:)ÚurlparseZurljoinÚurllibZpathname2url)r9   r.   r.   r/   Úpath2url£  s    rj  c             C   sj   t jdkrtj | d¡}nLtj | d¡}ttj |d¡ƒ}|rRtj ||d ¡}ntj |d |¡¡}|S )Nr2   ZLibr)  z	python?.*r   zpython{})ru   r…   r7   r9   r   r*   rT   )r¢   Úpy_verÚlib_dirZpython_folderr.   r.   r/   Úget_stdlib_dir§  s    
rm  c             C   s   t j t| |ƒd¡S )Nzsite-packages)r7   r9   r   rm  )r¢   rk  r.   r.   r/   Úget_site_packages´  s    rn  c             C   s   t tj | d¡ƒS )Nz4*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*)r*   r7   r9   r   )Zcrootr.   r.   r/   Úget_build_folders¸  s    ro  c             C   s¤   t |tƒtj | d  | d< tjdkr†t |dddƒtj t |dddƒ tj tj t |ddƒ tj t |dƒ tj | d  | d< d}|r |tj | d  | d< | S )	NÚPATHr2   ÚLibraryz	mingw-w64r4   Zusrr3   T)r   Úbin_dirnamer7   Úpathsepru   r…   )r‡   r¢   Zprepend_prefixr.   r.   r/   Úprepend_bin_path½  s    
Nrt  c             c   sŠ   t jd d … }tr.t j dtj | dd¡¡ nDtj | d¡}ttj |d¡ƒ}|rr|d }t j dtj |d¡¡ z
d V  W d |t _X d S )Nr   r)  zsite-packageszpython[0-9\.]*r   )ru   r9   rQ   Úinsertr7   r   r*   )r¢   Zpath_backuprl  Z
python_dirr.   r.   r/   Úsys_path_prependedÏ  s    
rv  c          	   c   sB   t jd }tt j ¡ | dƒd t jd< z
d V  W d |t jd< X d S )Nrp  T)r7   r¿   rt  r¾   )r¢   Zold_pathr.   r.   r/   Úpath_prependedà  s
    

rw  z*\s*([\w\-\.]+)\s*=\s*([\w.]+):([\w.]+)\s*$c             c   s<   x6| D ].}t  |¡}|d kr*t d| ¡ | ¡ V  qW d S )Nz%Error cound not match entry point: %r)Ú	entry_patÚmatchru   r1  Úgroups)rt   r  r`  r.   r.   r/   Úiter_entry_pointsï  s
    

r{  c          	   C   sî   |  d¡d }t|||dœ }tr’t| d dƒZ}tj tj |jd¡¡rT| 	d¡ | 	|¡ t
tttƒd t|jƒ¡ƒ| d	 |jƒ W d Q R X nXtj | ¡r¨t | ¡ t| dƒ&}|jsÊ| 	d
|j ¡ | 	|¡ W d Q R X t | d¡ d S )NrO   r   )ÚmodulerÆ   Úimport_namez
-script.pyr  zpython_d.exez#!python_d
z
cli-{}.exez.exez#!%s
iý  )rU   ÚPY_TMPLrQ   r"  r7   r9   r   r   Úhost_prefixrw   r  r   Ú__file__rT   r³   Z	host_archrç   r   rü   ZnoarchZhost_pythonÚchmod)r9   r|  rÆ   Úconfigr}  ZpyscriptZfor.   r.   r/   Úcreate_entry_point÷  s"    


rƒ  c             C   sV   | sd S t |jtƒ}t|ƒs&t |¡ x*t| ƒD ]\}}}tt ||ƒ|||ƒ q0W d S )N)r   r  rr  r   r7   Úmkdirr{  rƒ  )rt   r‚  Zbin_dirre  r|  rÆ   r.   r.   r/   Úcreate_entry_points  s    
r…  c             c   sD   x>t | ƒD ]2\}}}x&|D ]}| |¡rtj ||¡V  qW q
W d S )N)r6   rß   r7   r9   r   )Z
start_pathrd   rA   rB   rC   rD   r.   r.   r/   Úget_ext_files  s    

r†  c          	   C   s¦   t jdkr|S | tkrPt| dƒ*}| ¡ }t d|¡}|r>dndt| < W dQ R X t|  r¢y"tdd|gƒ ¡ d	  	t
ƒ ¡}W n& tk
r    ttƒ}| d
¡ Y nX |S )zKIf exe is a Cygwin or MSYS2 executable then filters it through `cygpath -u`r2   Úrbs   (cygwin1.dll|msys-2.0.dll)TFNrb  z-ur   zJcygpath executable not found.  Passing native path.  This is OK for msys2.)ru   r…   Ú_posix_exes_cacher"  rx   r\   ÚfindallrÍ   Ú
splitlinesrH   r   ZWindowsErrorrž   rk   r	  )Zexer9   Zexe_fileZ
exe_binaryZmsys2_cygwinr±   r.   r.   r/   Ú convert_path_for_cygwin_or_msys2!  s    
r‹  c                s&   d  ˆ  ¡ ˆ j‡ fdd„ˆ  ¡ D ƒ¡S )NzCSkipped: {} from {} defines build/skip for this configuration ({}).c                s   i | ]}ˆ j j| |“qS r.   )r‚  Úvariant)r™   rˆ   )r`  r.   r/   r¶   7  s    z$get_skip_message.<locals>.<dictcomp>)rT   r3  r9   Zget_used_vars)r`  r.   )r`  r/   Úget_skip_message4  s    
r  c             C   sÊ   yœt ƒ }t|dd€ t | ¡j}y| dd¡}| |¡ ¡ }|S  tk
rT   dS  tk
r„ } zt	d| |f ƒ‚W d d }~X Y nX W d Q R X W d Q R X W n( tj
ttfk
rÄ   t	d|  ƒ‚Y nX d S )Ni„  )rç   rc  r*  FzCould not extract %s (%s)zkCould not extract metadata from %s. File probably corrupt.  Please manually remove this file and try again.)r(  rí   r2  r"  r_   Zextractfilerx   r=  r<   r#  Z	ReadErrorrï   ÚEOFError)Zpackage_pathZ	file_pathrë   rŠ   Útextr°   r.   r.   r/   Úpackage_has_file:  s    :r  c             C   s,   t | tƒst| dƒs(| d k	r$| g} ng } | S )NÚ__iter__)rR  r   rW   )rÈ   r.   r.   r/   r&  N  s
    r&  c          	   c   s.   t  ¡ }zt  | ¡ d V  W d t  |¡ X d S )N)r7   rä   Úchdir)ÚdestÚcurdirr.   r.   r/   rF  W  s
    

rF  c                sì   g }x¬| D ]¤}t j |¡s(t j ||¡}t j |¡r@| |¡ q
t j |¡rX| |¡ q
t j |¡r~| dd„ t	|ƒD ƒ¡ q
t
|ƒ}|s¤ttƒ}| d ||¡¡ | |¡ q
W t dt d|t jjf ¡ ¡‰ ‡ fdd„|D ƒ}t|ƒS )Nc             s   s,   | ]$\}}}|D ]}t j ||¡V  qqd S )N)r7   r9   r   )r™   rA   rB   ZfsrD   r.   r.   r/   r›   k  s    zexpand_globs.<locals>.<genexpr>z$Glob {} did not match in root_dir {}ú^z%s%sc                s   g | ]}ˆ   d |d¡‘qS )rN   r   )Úsub)r™   rD   )Úprefix_path_rer.   r/   r  t  s    z expand_globs.<locals>.<listcomp>)r7   r9   r  r   r   rÄ   r   r   r]  r6   r*   rž   rk   ÚerrorrT   r\   ÚcompileÚescaperõ   r‚   )Ú	path_listr   rC   r9   Z
glob_filesr±   r.   )r—  r/   Úexpand_globsa  s$    
 rœ  c             C   s”   t j | ¡r(t j | ¡dkr(t j | ¡S t| ddgƒ}t|ƒdkr|t j | d¡}||krntt	ƒ 
d¡ |g}qŒtd|  ƒ‚n|sŒtd|  ƒ‚|d S )	zàrecurse through a folder, locating meta.yaml.  Raises error if more than one is found.

    Returns folder containing meta.yaml, to be built.

    If we have a base level meta.yaml and other supplemental ones, use that first)z	meta.yamlz
conda.yamlz	meta.yamlz
conda.yamlr   zVMultiple meta.yaml files found. The meta.yaml file in the base directory will be used.z)More than one meta.yaml files found in %sz,No meta.yaml or conda.yaml files found in %sr   )r7   r9   r   r  r   ra  rn   r   rž   rk   rŸ   rï   )r9   ZresultsZbase_reciper.   r.   r/   Úfind_recipex  s    r  c               @   sV   e Zd Zddddddddd	d
dddddddgZejdddfdd„Zdd„ Zdd„ ZdS )ÚLoggingContextZcondaZbinstarÚinstallzconda.installZfetchzconda.instructionszfetch.progressrã   ZprogressZ	dotupdateZ	stdoutlogZrequestszconda.core.package_cachez
conda.planzconda.gateways.disk.deleteZconda_buildzconda_build.indexNTc             C   s8   || _ i | _|| _|| _tj| _|s.tj| _n|| _d S )N)	ÚlevelÚ
old_levelsÚhandlerrs   r&   Úquietrž  Údefault_loggersÚloggers)rg   r   r¢  rs   r¥  r.   r.   r/   r•   •  s    
zLoggingContext.__init__c             C   sx   xX| j D ]N}t|tƒr t |¡}|j| j|< | d|ksD| jtjk rJ| jn| jd ¡ qW | j	rn| j
 | j	¡ dt_d S )NrŸ  rÖ   T)r¥  rR  r   ÚloggingÚ	getLoggerr   r¡  ÚsetLevelÚINFOr¢  ÚloggerÚ
addHandlerr&   r£  )rg   rª  r±   r.   r.   r/   Ú	__enter__   s    

"zLoggingContext.__enter__c             C   s^   x&| j  ¡ D ]\}}t |¡ |¡ qW | jr<| j | j¡ | jrR| jrR| j ¡  | j	t
_	d S )N)r¡  rt   r¦  r§  r¨  r¢  rª  ZremoveHandlerrs   r£  r&   )rg   ZetZevÚtbrª  r   r.   r.   r/   Ú__exit__¬  s    
zLoggingContext.__exit__)	rk   rl   rm   r¤  r¦  ÚWARNr•   r¬  r®  r.   r.   r.   r/   rž    s   rž  c          
   C   sR   t ƒ }xFttj | dd¡ƒD ].}t|ƒ}t |¡}|||d < W dQ R X qW |S )zˆ
    Scan all json files in 'path' and return a dictionary with their contents.
    Files are assumed to be in 'index.json' format.
    z
conda-metaz*.jsonr3  N)r¤   r*   r7   r9   r   r"  ÚjsonÚload)r9   Z	installedÚfilenameÚfileÚdatar.   r.   r/   Úget_installed_packages¹  s    

rµ  c          	   C   s–   x|   ¡ D ]„\}}t|dƒr.tt|ƒƒ| |< q
t|dƒr
t|tƒs
yttt|ƒƒƒ| |< W q
 t	k
rŒ   tttdd„ |D ƒƒƒƒ| |< Y q
X q
W | S )NÚkeysr‘  c             s   s   | ]}t |ƒV  qd S )N)Útuple)r™   rB   r.   r.   r/   r›   Î  s    z)_convert_lists_to_sets.<locals>.<genexpr>)
rt   rW   ÚHashableDictÚ_convert_lists_to_setsrR  r   r‚   r'  r;   ry   )Z_dictrˆ   r‰   r.   r.   r/   r¹  Æ  s    
(r¹  c                   s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )r¸  zbuse hashable frozen dictionaries for resources and resource types so that they can be in sets
    c                s   t t| ƒj||Ž t| ƒ} d S )N)Úsuperr¸  r•   r¹  )rg   rh   ri   )Ú	__class__r.   r/   r•   Õ  s    zHashableDict.__init__c             C   s   t tj| ddƒS )NT)Z	sort_keys)Úhashr°  Údumps)rg   r.   r.   r/   Ú__hash__Ù  s    zHashableDict.__hash__)rk   rl   rm   Ú__doc__r•   r¾  Ú__classcell__r.   r.   )r»  r/   r¸  Ò  s   r¸  c             C   sJ   g }x6|  ¡ D ]*\}}|  |¡}|  |¡}| ||f¡ qW tj d|¡S )Nztag:yaml.org,2002:map)rt   Zrepresent_datarÄ   ÚyamlZnodesZMappingNode)Zdumperr´  rµ   Zitem_keyZ
item_valueZnode_keyZ
node_valuer.   r.   r/   Úrepresent_hashabledictÝ  s    

rÂ  c           	   c   sn   dd l } | j| j }}z"tƒ tƒ g}|\| _| _|V  W d || | _| _|d  ¡ |d< |d  ¡ |d< X d S )Nr   r   )ru   rv   rG   r    Úgetvalue)ru   ZoldoutZolderrrc   r.   r.   r/   Úcaptureí  s    
rÄ  c          	   c   sf   t | ƒt |ƒ } }tj | ¡}z|tj| < |r4|ƒ  d V  W d |rN|tj| < ntj| = |r`|ƒ  X d S )N)r³   r7   r¿   r¡   )r3  rµ   ÚcallbackZsaved_env_varr.   r.   r/   Úenv_varü  s    

rÆ  c             C   s¶   t ƒ }d}xj|  ¡ D ]^\}}t|dƒr.t|ƒ |tƒ ksR|dksR|d ksR|tƒ kr\| |¡ |s||kr| |¡ qW d| kržtdd„ | d D ƒƒsž| d¡ x|D ]
}| |= q¤W d S )N)ÚfinalZnoarch_pythonÚzip_keysr¶  rN   rÈ  c             s   s   | ]
}|V  qd S )Nr.   )r™   r‰   r.   r.   r/   r›     s    z"trim_empty_keys.<locals>.<genexpr>)r;   rt   rW   Útrim_empty_keysr'  r¤   r>   Úany)Zdict_Z	to_removeZnegative_means_emptyrˆ   r‰   r.   r.   r/   rÉ    s    
$


rÉ  c             C   sP   y&|rd}nd}t t| ƒd ƒ| }W n$ tk
rJ   tt| ƒd ƒ}Y nX |S )NÚaz.0a0r   )r³   ra   rb   ÚchrÚord)ÚversionÚ	alpha_verÚsuffixZlast_versionr.   r.   r/   Ú
_increment#  s    rÑ  úx.x.x.x.x.x.xr  c             C   s¤  dd„ ||fD ƒ}t | ƒjdd … }d }g }x8t|ƒD ],\}}t|tƒrX|}| |¡ q6| |¡ q6W |rŒt| d¡ƒt|ƒkrŒt|ƒ|d< ddg}	xÆt|ƒD ]º\}
}|ržxˆt|d |… ƒD ]t\}}|
dkr||d krt	|t
|t|ƒd ƒ ƒ ¡ }t||ƒ}|	|
  t	|ƒ7  < ||kr¼|	|
  d7  < q¼W |	|
 d dkrž|	|
 d d… |	|
< qžW |	d rvd|	d  |	d< |	d rd	|	d  |	d< d
 dd„ |	D ƒ¡S )Nc             S   s"   g | ]}|rt | d ¡ƒnd‘qS )rO   N)rn   rU   )r™   Úpr.   r.   r/   r  0  s    z)apply_pin_expressions.<locals>.<listcomp>r   rO   rN   rô   r   z>=ú<rM   c             S   s   g | ]}|r|‘qS r.   r.   )r™   r‰   r.   r.   r/   r  Q  s    )r!   rÎ  r×   rR  r'  r]  rÄ   rn   rU   r³   ÚminÚisalpharÑ  r   )rÎ  Zmin_pinZmax_pinZpinsZparsed_versionZnesting_positionZ	flat_listr  r  ZversionsZp_idxZpinZv_idxr‰   rÏ  r.   r.   r/   Úapply_pin_expressions/  s8    



r×  ©z(.*[\\/])?\.git[\\/].*z(.*[\\/])?\.git$z(.*)?\.DS_Store.*z.*\.la$zconda-meta.*c                sB   x.|D ]&}t  |¡}t| ƒtt|j| ƒƒ } qW ‡ fdd„| D ƒS )zIRemove things like the .git directory from the list of files to be copiedc                s<   g | ]4}t j t j ˆ |¡¡r4t j t j ˆ |¡¡r|‘qS r.   )r7   r9   r   r   r   )r™   rD   )r¢   r.   r/   r  ]  s    z filter_files.<locals>.<listcomp>)r\   r™  r;   r_  ry  )Ú
files_listr¢   Úfilter_patternsrd   r|   r.   )r¢   r/   Úfilter_filesT  s    

rÛ  c             C   s   t | |ddS )N)zinfo[\\/]index.jsonzinfo[\\/]fileszinfo[\\/]paths.jsonzinfo[\\/]about.jsonzinfo[\\/]has_prefixzinfo[\\/]hash_input_fileszinfo[\\/]hash_input.jsonzinfo[\\/]run_exports.yamlzinfo[\\/]run_exports.jsonzinfo[\\/]gitzinfo[\\/]recipe[\\/].*zinfo[\\/]recipe_log.jsonzinfo[\\/]recipe.tarzinfo[\\/]test[\\/].*zinfo[\\/]LICENSE.txtzinfo[\\/]requireszinfo[\\/]metazinfo[\\/]platformzinfo[\\/]no_linkzinfo[\\/]link.jsonzinfo[\\/]icon.png)rÚ  )rÛ  )rÙ  r¢   r.   r.   r/   Úfilter_info_filesb  s    rÜ  c          	   C   s¾   t j | ¡rˆyntr(tjd | ¡dd nPyt  d¡ W n   Y nX d}t | | ¡ ¡ ¡ yt	 
d¡ W n   Y nX W n   Y nX tj}|rž|jržtj}t|ƒ t| ƒ W d Q R X d S )Nzrd /s /q {}T)rF   z.emptyzrsync -a --delete .empty {}/)r7   r9   r   rQ   rR   rÅ   rT   rú   rU   rî   Úrmtreer¦  r¯  r	  ÚDEBUGrž  Ú_rm_rf)r9   r‚  Zdel_dir_cmdZconda_log_levelr.   r.   r/   r'   |  s*    


r'   c                   s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )ÚLessThanFilterrN   c                s   t t| ƒ |¡ || _d S )N)rº  rà  r•   Ú	max_level)rg   Zexclusive_maximumr3  )r»  r.   r/   r•     s    zLessThanFilter.__init__c             C   s   |j | jk rdS dS )Nr   r   )Úlevelnorá  )rg   Úrecordr.   r.   r/   r_  ¡  s    zLessThanFilter.filter)rN   )rk   rl   rm   r•   r_  rÀ  r.   r.   )r»  r/   rà  œ  s   rà  c                   s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )ÚGreaterThanFilterrN   c                s   t t| ƒ |¡ || _d S )N)rº  rä  r•   Ú	min_level)rg   Zexclusive_minimumr3  )r»  r.   r/   r•   §  s    zGreaterThanFilter.__init__c             C   s   |j | jkrdS dS )Nr   r   )râ  rå  )rg   rã  r.   r.   r/   r_  «  s    zGreaterThanFilter.filter)rN   )rk   rl   rm   r•   r_  rÀ  r.   r.   )r»  r/   rä  ¦  s   rä  c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚDuplicateFilterc             C   s   t ƒ | _d S )N)r;   Úmsgs)rg   r.   r.   r/   r•   ²  s    zDuplicateFilter.__init__c             C   s"   |j | jk}| j |j ¡ t|ƒS )N)Úmsgrç  r>   ra   )rg   rã  r±   r.   r.   r/   r_  µ  s    zDuplicateFilter.filterN)rk   rl   rm   r•   r_  r.   r.   r.   r/   ræ  ±  s   ræ  ré   zconda.core.linked_datazconda.gateways.disk.deletezconda.gateways.disk.testc               C   s
   t ƒ adS )zŽMost of the time, we want the deduplication.  There are some cases (tests especially)
    where we want to be able to control the duplication.N)ræ  Údedupe_filterr.   r.   r.   r/   Úreset_deduplicatorÈ  s    rê  c       
   	   C   sò   d }t  d¡r$tttt  d¡ƒƒƒ}|rnt|ƒ}t |¡}W d Q R X tj	 
|¡ | di ¡ | i ¡ d|¡}t | ¡}| |¡ |r| t¡ |jsî|rît tj¡}t tj¡}	| t¡ |	 t¡ | |¡ |	 |¡ | |¡ | |	¡ |S )NZlog_config_filer¥  r   )r#   r¡   r   r   r   r"  rÁ  Z	safe_loadr¦  r‚  Z
dictConfigr§  r¨  Z	addFilterré  ZhandlersZStreamHandlerru   rv   rG   Úinfo_debug_stdout_filterÚwarning_error_stderr_filterr«  )
r3  r   ZdedupeZadd_stdout_stderr_handlersZconfig_filerD   Zconfig_dictr±   Zstdout_handlerZstderr_handlerr.   r.   r/   rž   Ï  s,    











rž   c             C   s€   || k}t |tƒr|t | tƒr|tj | ¡sFtj tj tj || ¡¡¡} tj |¡sptj tj tj ||¡¡¡}|| |kO }|S )N)rR  r   r7   r9   r  r   r  r   )Ú
base_valuerµ   r9   Z
equivalentr.   r.   r/   Ú_equivalentì  s    rî  rN   c       
   	   C   sJ  | |kr| S t tƒ}x.| ¡ D ] \}}|| ks6|r |  ||¡}	t|dƒrht|	||||d}	|	| |< q t|dƒrêt|tƒsê|rà|	|kr°y|	 |¡ W n t	k
r®   |}	Y nX yt
|	ƒ| |< W qè t	k
rÜ   |	| |< Y qèX n|| |< q |	r|rt|	||ƒs|r| d ||	|¡¡ |d kr:|| kr:| |= q || |< q W | S )Nr¶  )Úraise_on_clobberr‘  z3clobbering key {} (original value {}) with value {})rž   rk   rt   r¡   rW   Úmerge_or_update_dictrR  r   r]  ry   r'  rî  r	  rT   )
ÚbaseÚnewr9   Úmergerï  Zadd_missing_keysr±   rp   rµ   rí  r.   r.   r/   rð  ÷  s<    






rð  c                s,   t ˆ ƒ ˆ¡}g ‰t‡ ‡‡fdd„|D ƒƒS )zI
    From Alex Martelli: https://stackoverflow.com/a/1495821/3257826
    c             3   s*   | ]"}|ˆ   |ˆ¡ˆ  |ˆ¡ fV  qd S )N)r¡   )r™   rˆ   )Údol1Údol2Únor.   r/   r›   !  s    z'merge_dicts_of_lists.<locals>.<genexpr>)r;   Úunionr¤   )rô  rõ  r¶  r.   )rô  rõ  rö  r/   Úmerge_dicts_of_lists  s    rø  c             C   s˜   t ƒ }x~t| ƒD ]r\}}}x,|D ]$}| t||ƒt| ƒd d… ¡ q W x8|D ]0}t||ƒ}t|ƒrN| |t| ƒd d… ¡ qNW qW t t|| ƒƒ}|S )z/
    Returns a set of all files in prefix.
    r   N)r;   r6   r>   r   rn   r   rœ  )r¢   ZresrA   ÚdirsrC   ÚfnZdnr9   r.   r.   r/   Úprefix_files$  s    
$

"rû  c             C   s^   t r.|rtj| ||||dS tj| ||dS n,|rHtj| |||||dS tj| |||dS dS )a;  
    Hides the differences between mmap.mmap on Windows and Unix.
    Windows has `tagname`.
    Unix does not, but makes up for it with `flags` and `prot`.
    On both, the default value for `access` is determined from how the file
    was opened so must not be passed in at all to get this default behaviour.
    )ÚtagnameÚaccessÚoffset)rü  )rG  Úprotrý  rþ  )rG  rÿ  N)rQ   Úmmap)ÚfilenoÚlengthrü  rG  rÿ  rý  rþ  r.   r.   r/   Ú	mmap_mmap4  s    	r  c             C   sœ   t rtj | d¡}ntj | d¡}tj |¡r˜xht |¡D ]Z}tj ||¡}tj |¡rt| tj¡dkrtt 	|¡ q:tj 
|¡r:| d¡r:t |¡ q:W dS )z9Remove pip created pycache directory from bin or Scripts.r3   r4   Ú__pycache__z.pycN)rQ   r7   r9   r   r   r  rZ   rõ   rî   rÝ  r   rß   rü   )Zbuild_prefixZscripts_pathrA  Z
entry_pathr.   r.   r/   Úremove_pycache_from_scriptsI  s    r  c          	   C   sØ   xÒ|   ¡ D ]Æ\}}t|tƒr„x²| ¡ D ]X}| | | }t|tƒrJt|ƒ q&t|tƒr&d ||¡|kr&tdd„ |D ƒƒr&| ¡  q&W q
t|tƒr
x|D ]}t|tƒr”t|ƒ q”W y| ¡  W q
 t	k
rÎ   Y q
X q
W dS )a6  Recurse through a nested dictionary and sort any lists that are found.

    If the list that is found contains anything but strings, it is skipped
    as we can't compare lists containing different types. The omissions argument
    allows for certain sections of the dictionary to be omitted from sorting.
    z{}/{}c             s   s   | ]}t |tƒV  qd S )N)rR  r³   )r™   r  r.   r.   r/   r›   i  s    z0sort_list_in_nested_structure.<locals>.<genexpr>N)
rt   rR  r¤   r¶  Úsort_list_in_nested_structurer'  rT   ÚallÚsortry   )Z
dictionaryZ	omissionsZfieldrµ   rp   ZsectionÚelementr.   r.   r/   r  Z  s$    






r  zD([\w\d\.\-\_]+)\s+((?<![><=])[\w\d\.\-\_]+?(?!\*))(\s+[\w\d\.\_]+)?$z^([0-9a-zA-Z\.]+)$c             C   sø   t | tƒrtt| dƒrô| jrô|  dd¡sôt t| jƒ¡rôt| jƒdksRt| jƒdkrôtd 	t| jƒt| jƒd ¡ƒ} n€t
 | ¡}|rô| d¡sô| d	¡dkr¶| d
¡dkr¶t
 d| ¡} n>d| krô| d	¡dkrè|rèttƒ}| d 	| ¡¡ t
 d| ¡} | S )NrÎ  ÚbuildrN   )ÚpythonZnumpyzx.xz{} {}z.*r¸   r   rK   z\1 \2Ú*)r  Zvca`  Adding .* to spec '{}' to ensure satisfiability.  Please consider putting {{{{ var_name }}}}.* or some relational operator (>/</>=/<=) on this spec in meta.yaml, or if req is also a build req, using {{{{ pin_compatible() }}}} jinja2 function instead.  See https://conda.io/docs/user-guide/tasks/build-packages/variants.html#pinning-at-the-variant-levelz\1 \2.*)rR  r"   rW   rÎ  r¡   Úspec_ver_needing_star_rery  r³   r3  rT   Úspec_needing_star_rer^   r–  rž   rk   rŸ   )ÚspecrŸ   ry  r±   r.   r.   r/   Úensure_valid_spec„  s     
"
r  c       
         s`  t |  d¡ƒt |  d¡ƒ }t |  |¡ƒ}x¬| ¡ D ] \}}t d| dd¡ ¡‰ ‡ fdd„|D ƒ}t|ƒr4xft|ƒD ]Z\}}	|	rv|dks˜|	 d	¡|krv||= t	|t
ƒs°|d
 }| |td |	 d	¡|f¡ƒ¡ qvW q4W t d¡‰‡fdd„|D ƒ}t|ƒrNxNt|ƒD ]B\}}	|	r||= | |td |	 d	¡| |	 d	¡¡f¡ƒ¡ qW |r\|| |< d S )Nr
  Úhostz^(%s)(?:\s*$)rB   z[-_]c                s   g | ]}ˆ   |¡‘qS r.   )ry  )r™   Úpkg)Úregexr.   r/   r  ¥  s    z+insert_variant_versions.<locals>.<listcomp>)r
  r  r   r   rP   z([0-9a-zA-Z\.\-\_]+)\s+x\.xc                s   g | ]}ˆ   |¡‘qS r.   )ry  )r™   r  )Úxx_rer.   r/   r  °  s    )r&  r¡   rt   r\   r™  r_   rÊ  r×   r^   rR  r   ru  r  r   )
Zrequirements_dictrŒ  r‡   Z
build_depsZreqsrp   ÚvalZmatchesrÛ   r  r.   )r  r  r/   Úinsert_variant_versionsŸ  s,    
(

2r  c             C   s´   |  ¡ | ¡ ddœ}tr\t|d d |d |d |d f¡|d |d t| ¡ pRdƒdd	}|  |¡}d
}|r¬| ¡ }x4| ¡ D ](}||kr€||j	j
| |j	j
| kM }q€W |o²|S )a  target_matchspec comes from the recipe.  target_variant is the variant from the recipe whose
    deps we are matching.  m is the peer job, which must satisfy conda and also have matching keys
    for any keys that are shared between target_variant and m.config.variantrN   )r3  rÎ  r
  r3  ú-rÎ  r
  r   N)r3  Z	dist_namerÎ  Zbuild_stringÚbuild_numberZchannelT)r3  rÎ  r$   r%   r   ra   r  ry  Zget_used_loop_varsr‚  rŒ  )Ztarget_matchspecZother_mZthis_mZ
match_dictZmatchspec_matchesZvariant_matchesZother_m_used_varsr‰   r.   r.   r/   Úmatch_peer_jobº  s(    


 r  c             C   sX   t | dƒs6t| ƒd d … }|r0t|ƒt|ƒdœni } nx| D ]}t| | ƒ| |< q<W | S )Nr¶  )r  Úrun)rW   r&  )Z
reqs_entryZoriginalZsecr.   r.   r/   Úexpand_reqsÕ  s    

r  é   c          	      sZ   t | ƒsd S t ¡ }t| dƒ.‰x&t‡ ‡fdd„dƒD ]}| |¡ q6W W d Q R X | ¡ S )Nr‡  c                  s
   ˆ  ˆ ¡S )N)rx   r.   )Ú
buffersizerD   r.   r/   ro   å  s    z!sha256_checksum.<locals>.<lambda>ó    )r   r  r  r"  ÚiterrÀ   r   )r²  r  r  rB  r.   )r  rD   r/   Úsha256_checksumà  s    r   )T)T)r÷   FNTF)FNF)Fr÷   NTF)r÷   )TNr÷   )r)  )r,  )F)N)rÒ  r  )rØ  )N)rN   TFT)rN   )F)N)r  )ÉZ
__future__r   r   r   Úcollectionsr   r   Ú
contextlibr^  r  r°  Zlocaler   r:  r¦  Zlogging.configr   rS  r7   Úos.pathr   r	   r
   r   r   r   r   r   r   r   r\   r8   rR   ru   rî   r2  rá   Z	threadingr   r¥   rÁ  ré   Zconda.base.constantsr   Ú	Exceptionr   Zconda_interfacer   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   Zconda_build.conda_interfacer'   rß  Zconda_build.exceptionsr(   Zconda_build.os_utilsr)   r*   r,   Zurllib.parseÚparserh  Zurllib.requestZrequestri  r0   rð   ÚFileNotFoundErrorZglob2r1   Zcontextlib2r<   r…   rQ   rÃ   r9   Zroot_script_dirZMAP_PRIVATEZmmap_MAP_PRIVATEZ	PROT_READZmmap_PROT_READZ
PROT_WRITEZmmap_PROT_WRITEr~  r5   r6   r   r:   rE   re   Úobjectrf   r‹   rŒ   rÊ   rË   rÍ   rÜ   ræ   Úcontextmanagerrí   ró   rö   r  r  r  r!  r  r(  r+  rà   r9  rC  rD  râ   rJ  rP  rL  rU  r[  ra  rf  rg  rj  rm  rn  ro  rt  rv  rw  rr  r™  rx  r{  rƒ  r…  r†  rˆ  r‹  r  r  r&  rF  rœ  r  rž  rµ  r¹  r¤   r¸  rÂ  Zadd_representerrÄ  rÆ  rÉ  rÑ  r×  rÛ  rÜ  ZFilterrà  rä  ræ  ré  ZWARNINGrë  r©  rì  r§  r¨  r¯  rê  rž   rî  rð  rø  rû  r  r  r  r  r  r  r  r  r  r   r.   r.   r.   r/   Ú<module>   sN  0



%2d3.	
>
%
"
 


&
	


	
*
%

 




$	

&



