U
    KQh                     @   s   d dl m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
 d dlmZmZmZmZmZ d dlmZ eeZG dd deZG d	d
 d
eZdS )    )absolute_importN)uses_pycacheWINDOWScache_from_source)UninstallationError)rmtreeaskis_localrenamesnormalize_path)
indent_logc                   @   sZ   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dddZ
dd Zdd ZdS )UninstallPathSetzMA set of file paths to be removed in the uninstallation of a
    requirement.c                 C   s,   t  | _t  | _i | _|| _d | _g | _d S N)setpaths_refusepthdistsave_dir_moved_paths)selfr    r   4/tmp/pip-build-tlro1kwj/pip/pip/req/req_uninstall.py__init__   s    zUninstallPathSet.__init__c                 C   s   t |S )zs
        Return True if the given path is one we are permitted to
        remove/modify, False otherwise.

        )r	   r   pathr   r   r   
_permitted   s    zUninstallPathSet._permittedc                 C   s   t j|\}}t jt|t j|}t j|s:d S | |rR| j	| n| j
	| t j|d dkrtr| 	t| d S )N   z.py)osr   splitjoinr   normcaseexistsr   r   addr   splitextr   r   )r   r   headtailr   r   r   r#   #   s    
zUninstallPathSet.addc                 C   sL   t |}| |r<|| jkr*t|| j|< | j| | n| j| d S r   )r   r   r   UninstallPthEntriesr#   r   )r   pth_fileentryr   r   r   add_pth6   s    

zUninstallPathSet.add_pthc                    s<   t  }t|tdD ]$ t fdd|D s|  q|S )zCompact a path set to contain the minimal number of paths
        necessary to contain all paths in the set. If /a/path/ and
        /a/path/to/a/file.txt are both in the set, leave only the
        shorter path.)keyc                    s4   g | ],}  |o. t|tjj tjjkqS r   )
startswithlenrstripr   r   sep).0	shortpathr   r   r   
<listcomp>F   s   
z,UninstallPathSet.compact.<locals>.<listcomp>)r   sortedr-   anyr#   )r   r   short_pathsr   r2   r   compact?   s    zUninstallPathSet.compactc                 C   s&   t j| jt j|d t jjS )Nr   )r   r   r    r   
splitdrivelstripr/   r   r   r   r   _stashM   s     zUninstallPathSet._stashFc              	   C   s(  | j std| jj dS td| jj| jj t  t| | j }|rRd}n|D ]}t| qVt	dd}| j
rtd | | j
D ]}t| q|dkrtjdd	d
| _|D ]0}| |}td| | j| t|| q| j D ]}|  qtd| jj| jj W 5 Q R X dS )z[Remove paths in ``self.paths`` with confirmation (unless
        ``auto_confirm`` is True).z7Can't uninstall '%s'. No files were found to uninstall.NzUninstalling %s-%s:yzProceed (y/n)? )r;   nz.Not removing or modifying (outside of prefix):z
-uninstallzpip-)suffixprefixzRemoving file or directory %szSuccessfully uninstalled %s-%s)r   loggerinfor   project_nameversionr   r4   r7   r   r   tempfilemkdtempr   r:   debugr   appendr
   r   valuesremove)r   auto_confirmr   responser   new_pathr   r   r   r   rH   Q   sL     




 zUninstallPathSet.removec                 C   sv   | j dkrtd| jj dS td| jj | jD ]$}| |}td| t	|| q4| j
 D ]}|  qddS )z1Rollback the changes previously made by remove().Nz'Can't roll back %s; was not uninstalledFzRolling back uninstall of %szReplacing %s)r   r?   errorr   rA   r@   r   r:   rE   r
   r   rG   rollback)r   r   tmp_pathr   r   r   r   rM   {   s    


zUninstallPathSet.rollbackc                 C   s$   | j dk	r t| j  d| _ g | _dS )z?Remove temporary save dir: rollback will no longer be possible.N)r   r   r   )r   r   r   r   commit   s    

zUninstallPathSet.commitN)F)__name__
__module____qualname____doc__r   r   r#   r*   r7   r:   rH   rM   rO   r   r   r   r   r      s   	
*r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
r'   c                 C   s0   t j|std| || _t | _d | _d S )Nz.Cannot remove entries from nonexistent file %s)r   r   isfiler   filer   entries_saved_lines)r   r(   r   r   r   r      s    zUninstallPthEntries.__init__c                 C   s<   t j|}tr,t j|d s,|dd}| j| d S )Nr   \/)r   r   r!   r   r8   replacerV   r#   )r   r)   r   r   r   r#      s    zUninstallPthEntries.addc              	   C   s   t d| j t| jd}| }|| _W 5 Q R X tdd |D rLd}nd}| jD ]>}z$t d| ||| 	d W qV t
k
r   Y qVX qVt| jd	}|| W 5 Q R X d S )
NzRemoving pth entries from %s:rbc                 s   s   | ]}d |kV  qdS )s   
Nr   )r0   liner   r   r   	<genexpr>   s     z-UninstallPthEntries.remove.<locals>.<genexpr>z

zRemoving entry: %szutf-8wb)r?   rE   rU   open	readlinesrW   r5   rV   rH   encode
ValueError
writelines)r   fhlinesendliner)   r   r   r   rH      s    
zUninstallPthEntries.removec              	   C   sR   | j d krtd| j dS td| j t| jd}|| j  W 5 Q R X dS )Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous stater_   T)rW   r?   rL   rU   rE   r`   rd   )r   re   r   r   r   rM      s    
 zUninstallPthEntries.rollbackN)rP   rQ   rR   r   r#   rH   rM   r   r   r   r   r'      s   	
r'   )
__future__r   loggingr   rC   
pip.compatr   r   r   pip.exceptionsr   	pip.utilsr   r   r	   r
   r   pip.utils.loggingr   	getLoggerrP   r?   objectr   r'   r   r   r   r   <module>   s   
 