U
    b'                     @   sl  d dl mZmZmZmZ d dlmZ d dl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 d dl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mZm Z m!Z! d dl"Z"dd	l#m$Z$m%Z% dd
l&m'Z'm(Z( ddl)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 e1sddl2m3Z3 e	e4Z5dd Z6dd Z7dd Z8d"ddZ9e9 Z: Z;Z<dd Z=e$fddZ>d d! Z?dS )#    )absolute_importdivisionprint_functionunicode_literals)ENOENTN)	getLogger)environgetcwdmakedirsrenamermdirscandirunlinkwalk)	abspathbasenamedirnameexistsisdirisfilejoinnormpathsplit)CalledProcessErrorSTDOUTcheck_output   )	MAX_TRIESexp_backoff_fn)islinklexists)make_writablerecursive_make_writable   )CONDA_TEMP_EXTENSION)context)on_win)whichc                 O   s  t | } tr^ztd| dtd}W q   zd }ddlm} ddlm} |ddd	d
H}|	d||  |	d |	d||  |	d |j
}W 5 Q R X t|d}| }	| |	kstW 5 Q R X td }
d}t|
dd|gd	d d d |d}W nV tk
rT } z6|jdkr4td||  ntd| W 5 d }~X Y nX Y nX nztd W n   Y nX tdrtd}|rz,t|dddtt dd | d gtd}W n& tk
r   td|  Y nX td t|  d S )NzRD /S /Q "{}" > NUL 2> NULT)shellstderrr   )Utf8NamedTemporaryFile)quote_for_shellwz.batF)modesuffixdeletez	RD /S {}
zchcp 65001
zEXIT 0
rZCOMSPECi   z/dz/c)r(   stdoutr)   stdinZcreationflags   z7Removing folder {} the fast way failed.  Output was: {}z:removing dir contents the fast way failed.  Output was: {}z.emptyrsyncz-az--forcez--delete/r)   z8removing dir contents the fast way failed.  Output was: )r   r&   r   formatr   Zconda.auxlib.compatr*   Zconda.utilsr+   writenameopenreadAssertionErrorr   r   
returncodelogerrordebugr
   r   r'   r   r	   shutilrmtree)pathargskwargsoutr9   r*   r+   Z
batch_filecontentsZcontentZcomspecZCREATE_NO_WINDOWer4    rI   9lib/python3.8/site-packages/conda/gateways/disk/delete.pyrB      sp    


  
  


rB   c                 C   s,  zt |  t|  W n tk
r&   zt| | d  W n tk
r    trttjd}t|d}t|rt	| \}}| d }d}t
|r|jd d| }|d7 }qd}z tdd	|||t|gtd
}W n& tk
r   td| | Y nX ntd| td|  Y nX Y nX dS )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_trashZcondabinzrename_tmp.batr   r   z.conda_trash_{}z	< empty >zcmd.exez/Cr6   z6renaming file path {} to trash failed.  Output was: {}zx{} is missing.  Conda was not installed correctly or has been corrupted.  Please file an issue on the conda github repo.znCould not remove or rename {}.  Please remove this file manually (you may need to reboot to free file handles)N)r!   r   EnvironmentErrorr   r&   r   r%   Zconda_prefixr   r   r   splitextr7   r   r   r   r   r>   r@   warn)rC   Zcondabin_dirZtrash_scriptZ_dirnameZ_fnZdest_fnZcounterrF   rI   rI   rJ   unlink_or_rename_to_trashi   sF    


 rN   c                 C   s4   t | }t|r0tt|d s0t| t |}qd S )N)r   r   nextr   r   )rC   parent_pathrI   rI   rJ   remove_empty_parent_paths   s    rQ   r3   TFc                 O   s   dzPt| } td|  t| r2t| s2t|  nt | rDt|  ntd|  W 5 t | rptd|    dS X  t| rt	|  |rt
|  dS )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.
    zrm_rf failed for %sFNzrm_rf %sz0rm_rf failed. Not a link, file, or directory: %sT)r    r>   infor   tracer   r   backoff_rmdirrN   delete_trashrQ   )rC   Zmax_retriesZtrashZclean_empty_parentsrD   kwrI   rI   rJ   rm_rf   s     

rW   c                    s   | s
t j} tddg t| ddD ]\}}} fdd|D |d d < |D ]x}t|dsjt|dt rJt||}zt| t| W qJ t	t
fk
r } ztd	||j| W 5 d }~X Y qJX qJq"d S )
NZenvsZpkgsTtopdownc                    s   g | ]}| kr|qS rI   rI   ).0dZexcluderI   rJ   
<listcomp>   s      z delete_trash.<locals>.<listcomp>*.conda_trash**z%r errno %d
Cannot unlink %s.)sysprefixsetr   fnmatchr$   r   r   rQ   OSErrorIOErrorr>   r@   errno)ra   rootdirsfilesfnfilenamerH   rI   r\   rJ   rU      s    
rU   c                    st   t | sd S  fdd fdd}zt|  W n   Y nX t| ddD ]"\}}}|D ]}tt|| qZqLd S )Nc                    s4   t |d dd tkrd S tt| d | | d S )Nr   rf   	max_tries)getattrr   r"   r   )funcrC   exc_inforl   rI   rJ   retry   s    zbackoff_rmdir.<locals>.retryc              
      sb   zt |  tt|  d W n@ ttfk
r\ } z|jtkrJtd|  n W 5 d }~X Y nX d S )N)onerrorrm   zno such file or directory: %s)	r"   r   rB   re   rd   rf   r   r>   rS   )rC   rH   rm   rq   rI   rJ   _rmdir   s    
zbackoff_rmdir.<locals>._rmdirFrX   )r   rB   r   rN   r   )dirpathrm   rt   rg   rh   ri   filerI   rs   rJ   rT      s    	rT   c                 C   sT   t |  }|sPt| D ]8\}}}|D ](}t|ds$t|dt s$  dS q$qdS )zSometimes we can't completely remove a path because files are considered in use
    by python (hardlinking confusion).  For our tests, it is sufficient that either the
    folder doesn't exist, or nothing but temporary file copies are left.r^   r_   FT)r   r   rc   r$   )rC   Zcleanrg   rh   Zfnsrj   rI   rI   rJ   path_is_clean   s    
rw   )r3   TF)@Z
__future__r   r   r   r   rf   r   rc   Zloggingr   osr   r	   r
   r   r   r   r   r   os.pathr   r   r   r   r   r   r   r   r   rA   
subprocessr   r   r   r`    r   r   linkr   r    Zpermissionsr!   r"   Zbase.constantsr$   Zbase.contextr%   Zcommon.compatr&   Zcommon.pathr'   __name__r>   rB   rN   rQ   rW   Ztry_rmdir_all_emptyZmove_to_trashZmove_path_to_trashrU   rT   rw   rI   rI   rI   rJ   <module>   s2   (,L*	
