
    I0fCA                        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Zd dlZ	d dl
mZmZmZ d dlmZmZmZ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mZ d dl m!Z!m"Z"m#Z#m$Z$m%Z% d dl&m'Z'm(Z(m)Z)m*Z* d dl+m,Z,m-Z- ej\                  d	k(  Z/ ej`                  e1      Z2d
Z3d Z4d Z5 G d de      Z6d Z7d Z8d$dZ9d Z:d Z;d Z<d%dZ=e=xZ>xZ?Z@d ZAd ZB G d d      ZCe j                  d        ZEd ZF	 d&dZGd ZHd'dZId ZJd  ZKd(d!ZLd(d"ZMd# ZNy))    N)ExecutorProcessPoolExecutorThreadPoolExecutor)EACCESENOENTEPERMEROFS)chain)
abspathbasenamedirnameisdirisfileislinkjoinlexistsnormpathsplit)S_IEXECS_IMODES_ISDIRS_ISREGS_IWRITE)STDOUTCalledProcessErrorcheck_outputlist2cmdline)NamedTemporaryFilemkdtempwin32z.c~c                     ddl m}  ||       S )Nr   )find_executable)distutils.spawnr"   )
executabler"   s     <lib/python3.12/site-packages/conda_package_handling/utils.pywhichr&   "   s    /:&&    c                 f   	 t        j                  |       j                  }t        |      r.t        j                  | t        |      t        z  t        z         yt        |      st        |       r't        j                  | t        |      t        z         yt        j                  d|        y# t        $ ry}t        |dd       }|t        fv rt        j                  d|         |t        t         t"        fv rt        j                  d| |       Y d }~yt        j%                  d| |        d }~ww xY w)Nz path cannot be made writable: %sTerrnoz,tried to make writable, but didn't exist: %sz%tried make writable but failed: %s
%rFz!Error making path writable: %s
%r)oslstatst_moder   chmodr   r   r   r   r   logdebug	Exceptiongetattrr   r   r   r	   warn)pathmodeeenos       r%   make_writabler7   (   s    xx~%%4=HHT74=83g=>
 	 T]fTlHHT74=834  II8$? 
a$'6)IIDdKVUE**II>aHHH94C
s+   AB. <B. B. .	D07AD+D++D0c                       e Zd Zd Zy)DummyExecutorc              '   <   K   |D ]  }|D ]  } ||         y wN )selffunc	iterablesiterablethings        r%   mapzDummyExecutor.map@   s.     ! 	"H! "5k!"	"s   N)__name__
__module____qualname__rB   r<   r'   r%   r9   r9   ?   s    "r'   r9   c                 8    | dk(  r
t               S t        |       S )N   max_workers)r9   r   )	processess    r%   get_executorrK   F   s    '1n=?\2ER[2\\r'   c                     t        |       rQt        j                  |       D ]8  \  }}}t        j                  ||f      D ]  } 	 t        t        ||               : y 	 t        |        y #  Y /xY w#  Y y xY wr;   )r   r*   walkr
   from_iterabler7   r   )r3   rootdirsfiless       r%   recursive_make_writablerR   J   s{     T{!# 	D$++UDM: !$tT"23		$		s   A*A1 *A.1A5c                     |s
t         rdnd}|dk(  rt        |       S g }| D ]@  dv rd}n dv rd}nt        fddD              sd}nd}|j                  |z   |z          B dj	                  |      S )	Ncmd.exebash"'c              3   &   K   | ]  }|v  
 y wr;   r<   ).0_args     r%   	<genexpr>z"quote_for_shell.<locals>.<genexpr>n   s     7ac7s   ) 
 r]   )on_winr   anyappendr   )	argumentsshellquotedquoter[   s       @r%   quote_for_shellrg   \   s    #		I&&   		/Ccz7;77MM%#+-.		/ xxr'   c           
         t        |       } t        r	 t        d|  ddt              }n}	 t        j"                  d       t%        d      }|rZt'        d      rO	 t        |dddt)        t        j*                         d      dz   | dz   gt              }t-        j.                  d       t-        j.                  |        y #  	 d }t	        dd      5 }|j                  dt        | g       d	       |j                  d
       |j                  dt        | g       d	       |j                  d       |j                  }d d d        n# 1 sw Y   nxY wt        |      5 }|j                         }| |v sJ 	 d d d        n# 1 sw Y   nxY wt        j                  d   }d}	t        |dd|gdd d d |	      }nY# t        $ rM}
|
j                  dk7  rt        j                  d|  d         t        j!                  d        Y d }
~
nd }
~
ww xY wY ixY w#  Y xY w# t        $ r t        j!                  d        Y w xY w)Nz
RD /S /Q "z" > NUL 2> NULT)rd   stderr.batF)suffixdeletezRD /S r^   zchcp 65001
zEXIT 0
COMSPECi   z/dz/c)rd   stdoutri   stdincreationflags   zRemoving folder z# the fast way failed.  Output was: z8removing dir contents the fast way failed.  Output was: z.emptyrsyncz-az--forcez--delete/ri   )r   r`   r   r   r   writerg   nameopenreadr*   environr   
returncoder.   errorr/   makedirsr&   r   r   getcwdshutilrmtree)r3   argskwargsoutrv   
batch_filecontentscontentcomspecCREATE_NO_WINDOWr5   rr   s               r%   r   r   v   sF   D>D.	` D6@U[\CL	KK! gU8_\"!"RYY[(3c9s
 "
 MM(#
MM${#	`"`'veD +
$$votf.E-Fb%IJ$$^4$$votf.E-Fb%IJ$$Z0%??D+ + + $Z +8&mmoG7?*?+ + + **Y/#-  #dD$/"2 & `<<1$II 06YZ]Y^_`II XY\X]^__`	$ & \		TUXTYZ[\s   B= H 9H =H F4A-E<	F4E	
F4E=4	F4=F	1F43H4	H
=AH HH

HH!I ?I c                 <   	 t        |        t        j                  |        y# t        $ rn 	 t        j                  | | dz          Y y# t        $ rD t
        rt        d      5 }t        |d      5 }|j                  d       |j                  d       |j                  d       ddd       n# 1 sw Y   nxY wt        |       \  }}| dz   }d	}t        |      r&|j                  d
   d| z   }|d	z  }t        |      r&d}	 t        dd|||t        |      gt              }n4# t        $ r( t         j#                  dj%                  | |             Y nw xY wddd       n# 1 sw Y   nxY wt         j#                  dj%                  |              Y Y yw xY ww xY w)zIf files are in use, especially on windows, we can't remove them.
    The fallback path is to rename them (but keep their folder the same),
    which maintains the file handle validity.  See comments at:
    https://serverfault.com/a/503769
    z.conda_trashrj   )rk   wz@pushd "%1"
z@REM Rename src to destz@ren "%2" "%3" > NUL 2> NUL")NrG   r   z.conda_trash_z	< empty >rT   z/Crt   z6renaming file path {} to trash failed.  Output was: {}znCould not remove or rename {}.  Please remove this file manually (you may need to reboot to free file handles))r7   r*   unlinkOSErrorrenamer`   r   rw   ru   r   r   splitextr   r   r   r   r.   r2   format)r3   trash_scriptf_dirname_fndest_fncounterr   s           r%   unlink_or_rename_to_trashr      s   -d
		$ *)	IIdD>12 '	 (v6 ,lC0 AA0 9: ?@A A A
 %*$KMHc"^3GG /")"2"21"5-y8Q"Q1 !/ &C* ) $ , ( # ( 1 $*
 . T[[ $c3  @ HH;;A6$<I'	*s    # 
FA		F&E#34B0	'	E#0B95AE#E# D&%E#&.E	E#E	E#	F#E,(+FFFFc                     t        |       }t        |      rOt        j                  |      s9t	        |       t        |      }t        |      rt        j                  |      s7y y y y r;   )r   r   r*   listdirrmdir)r3   parent_paths     r%   remove_empty_parent_pathsr      sN    $-K

RZZ%<kk* 
RZZ%<
%<
r'   c                    t        |        	 t        |       } t        |       rt        |       st	        |        n-t        |       rt        |        nt        j                  d|        t        |       rt        j                  d|        yt        |       rt        |        |rt        |        y# t        |       rt        j                  d|         Y yw xY w)z
    Completely delete path
    max_retries is the number of times to retry on failure. The default is 5. This only applies
    to deleting a directory.
    If removing path fails and trash is True, files will be moved to the trash directory.
    z0rm_rf failed. Not a link, file, or directory: %szrm_rf failed for %sFT)rR   r   r   r   r   r   r   r.   r/   infodelete_trashr   )r3   clean_empty_parentsr   kws       r%   rm_rfr     s     D!t};vd|$KT]%d+IIH$O4=HH*D1T{T!$' 4=HH*D1 s   AB- -#CCc           	         | st         j                  } dh}t        j                  | d      D ]  \  }}}|D cg c]	  }||vs| c}|d d  |D ]c  }t	        j                  |d      st	        j                  |dt
        z         s7t        ||      }	 t        j                  |       t        |       e  y c c}w # t        $ r,}t        j                  d||j                  |       Y d }~d }~ww xY w)NenvsTtopdownz*.conda_trash**z%r errno %d
Cannot unlink %s.)sysprefixr*   rM   fnmatchCONDA_TEMP_EXTENSIONr   r   r   r   r.   r/   r)   )	r   excluderO   rP   rQ   dfnfilenamer5   s	            r%   r   r   "  s    hGWWVT: VdE"7aw&617Q 		VBr#34C..9  b>VIIh'-h7		VV7  VII>177HUUVs#   	B7B7 B<<	C1"C,,C1c                     t        |       sy 	 t        |        t        j                  | d      D ]"  \  }}}|D ]  }t	        t        ||              $ y #  Y AxY w)NFr   )r   r   r*   rM   r   r   )dirpathrO   rP   rQ   r   s        r%   r   r   4  sb    >w  WWWe< 5dE 	5A%d4m4	55s   A Ac                   h    e Zd ZdZdZdZdd ej                         fdZd Z	d Z
defd	Zd
 Zd Zy)TemporaryDirectorya+  Create and return a temporary directory.  This has the same
    behavior as mkdtemp but can be used as a context manager.  For
    example:

        with TemporaryDirectory() as tmpdir:
            ...

    Upon exiting the context, the directory and everything contained
    in it are removed.
    NFr_   z.cph_tmpc                 (    t        |||      | _        y r;   )r   rv   )r=   rk   r   dirs       r%   __init__zTemporaryDirectory.__init__T  s    FFC0	r'   c                 P    d| j                   j                   d| j                  dS )N<r]   >)	__class__rC   rv   r=   s    r%   __repr__zTemporaryDirectory.__repr__W  s&    4>>**+1TYYM;;r'   c                     | j                   S r;   )rv   r   s    r%   	__enter__zTemporaryDirectory.__enter__Z  s    yyr'   c                    | j                   r[| j                  sN	 t        | j                          d| _        |r.|j                  r! |j                  d| |j                         y y y y y #   |j                  d| j                   z         Y ]xY w)NzConda-package-handling says: "I tried to clean up, but I could not.  There is a mess in %s that you might want to clean up yourself.  Sorry..."TzImplicitly cleaning up )rv   _closedr   r2   ResourceWarning)r=   _warn	_warningss      r%   cleanupzTemporaryDirectory.cleanup]  s    99T\\dii   DL	-dX6-- (u *9	<>BiiHs   A) )!Bc                 $    | j                          y r;   r   )r=   excvaluetbs       r%   __exit__zTemporaryDirectory.__exit__n  s    r'   c                 (    | j                  d       y )NT)r   r   r   s    r%   __del__zTemporaryDirectory.__del__q  s    4 r'   )rC   rD   rE   __doc__rv   r   r*   r}   r   r   r   r   r   r   r   r<   r'   r%   r   r   D  sG    	 DG  1< "Y "!r'   r   c              #      K   t        j                         }	 t        j                  |        d  t        j                  |       y # t        j                  |       w xY wwr;   )r*   r}   chdir)destcurdirs     r%   	tmp_chdirr   v  s<     YY[F

s   A!A A!AA!c                 P    t        | t              st        | d      s	| | g} | S g } | S )N__iter__)
isinstancestrhasattr)r[   s    r%   ensure_listr     s4    #s73
#;?%C J CJr'   c           	         |D ]B  }t        j                  |      }t        |       t        t        |j                  |             z
  } D | D cg c]~  }t
        j                  j                  t
        j                  j                  ||            s=t
        j                  j                  t
        j                  j                  ||            s| c}S c c}w )zIRemove things like the .git directory from the list of files to be copied)
recompilesetfiltermatchr*   r3   r   r   r   )
files_listr   filter_patternspatternrr   s         r%   filter_filesr     s     # HJJw_s6!'':+F'GG
H
  	rww||FA./rww}}RWW\\RXZ[E\7]	 	
  s   BCc                     t        | |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.*zinfo[\\/]requireszinfo[\\/]metazinfo[\\/]platformzinfo[\\/]no_linkzinfo[\\/]link\.jsonzinfo[\\/]icon\.png)r   )r   )r   r   s     r%   filter_info_filesr     s    
 r'   c                      t        t        |      }|st        d|        |       }t         fdd      D ]  }|j	                  |        |j                         S )NzUnrecognized hash algorithm: c                  &    j                         S r;   )rx   )
buffersizefds   r%   <lambda>z_checksum.<locals>.<lambda>  s    bggj1 r'   r'   )r1   hashlib
ValueErroriterupdate	hexdigest)r   	algorithmr   	hash_implblocks   ` `  r%   	_checksumr     s`    +I8DEEK	137     r'   c                     t        | d      S )Nsha256r   r   s    r%   sha256_checksumr     s    R""r'   c                     t        | d      S )Nmd5r   r   s    r%   md5_checksumr     s    Rr'   c                 `    t        | d      5 }t        |||      cddd       S # 1 sw Y   yxY w)zA
    Calculate a checksum for a filename (not an open file).
    rbN)rw   r   )r   r   r   r   s       r%   checksumr     s0     
b$ 42Y
34 4 4s   $-c           
          t        t        |            5 }|D cg c]  }|j                  t        | ||       }}ddd       D cg c]  }|j	                          c}S c c}w # 1 sw Y   ,xY wc c}w )zB
    Calculate multiple checksums for a filename in parallel.
    rH   N)r   lensubmitr   result)r   
algorithmsr   r5   r   resultsr   s          r%   	checksumsr    sp     
J	8 ^AR\]Y188Hb)Z@]]^ +22FMMO22 ^^ ^ 3s!   A'A"A'A3"A''A0c                 >    d| _         d| _        d| _        d| _        | S )z,
    Remove user id, name from tarinfo.
    r   r_   )uidunamegidgname)tarinfos    r%   anonymize_tarinfor
    s%    
 GKGMGKGMNr'   r;   )F))z(.*[\\\\/])?\.git[\\\\/].*z(.*[\\\\/])?\.git$z(.*)?\.DS_Store.*z.*\.la$zconda-meta.*)i   )i   )O
contextlibr   r   loggingr*   r   r~   r   warningsr   concurrent.futuresr   r   r   r)   r   r   r   r	   	itertoolsr
   os.pathr   r   r   r   r   r   r   r   r   r   statr   r   r   r   r   
subprocessr   r   r   r   tempfiler   r   platformr`   	getLogger__file__r.   r   r&   r7   r9   rK   rR   rg   r   r   r   r   try_rmdir_all_emptymove_to_trashmove_path_to_trashr   r   r   contextmanagerr   r   r   r   r   r   r   r   r  r
  r<   r'   r%   <module>r     s(       	 	  
  P P . .    > = M M 0		 g! '."H "]$ 4L^3l+8 <A @  @m&8V$5 /! /!d  0<!# 43	r'   