
§|jñ  ã               @   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 j e ƒ Z Gd d „  d e ƒ Z Gd	 d
 „  d
 e ƒ Z d S)é    )Úabsolute_importN)Úuses_pycacheÚWINDOWSÚcache_from_source)ÚUninstallationError)ÚrmtreeÚaskÚis_localÚrenamesÚnormalize_path)Ú
indent_logc               @   s…   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-5c7ija6t/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 j | ƒ \ } } t  j j t | ƒ t  j j | ƒ ƒ } t  j j | ƒ sU d  S|  j | ƒ rw |  j j	 | ƒ n |  j
 j	 | ƒ t  j j | ƒ d d k r¼ t r¼ |  j	 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   sh   t  | ƒ } |  j | ƒ rT | |  j k r= t | ƒ |  j | <|  j | j | ƒ n |  j j | ƒ d  S)N)r   r   r   ÚUninstallPthEntriesr!   r   )r   Úpth_fileÚentryr   r   r   Úadd_pth6   s    zUninstallPathSet.add_pthc                sV   t  ƒ  } xF t | d t ƒD]2 ‰  t ‡  f d d †  | Dƒ ƒ s | j ˆ  ƒ q W| S)zÔCompact 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                sJ   g  |  ]@ } ˆ  j  | ƒ oC ˆ  t | j t j j ƒ ƒ t j j k ‘ q Sr   )Ú
startswithÚlenÚrstripr   r   Úsep)Ú.0Ú	shortpath)r   r   r   ú
<listcomp>G   s   	z,UninstallPathSet.compact.<locals>.<listcomp>)r   Úsortedr+   Úanyr!   )r   r   Úshort_pathsr   )r   r   Úcompact?   s    	zUninstallPathSet.compactc             C   s5   t  j j |  j t  j j | ƒ d j t  j j ƒ ƒ S)Nr   )r   r   r   r   Ú
splitdriveÚlstripr-   )r   r   r   r   r   Ú_stashM   s    	zUninstallPathSet._stashFc             C   s¢  |  j  s# t j d |  j j ƒ d St j d |  j j |  j j ƒ t ƒ  �Pt |  j |  j  ƒ ƒ } | rs d } n- x | D] } t j | ƒ qz Wt	 d d ƒ } |  j
 rà t j d ƒ x' |  j |  j
 ƒ D] } t j | ƒ qÉ W| d k r—t j d d	 d
 d ƒ |  _ xJ | D]B } |  j | ƒ } t j d | ƒ |  j j | ƒ t | | ƒ qWx! |  j j ƒ  D] } | j ƒ  qdWt j d |  j j |  j j ƒ Wd QRXd 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)? Únz.Not removing or modifying (outside of prefix):Úsuffixz
-uninstallÚprefixzpip-zRemoving file or directory %szSuccessfully uninstalled %s-%s)r8   r9   )r   ÚloggerÚinfor   Úproject_nameÚversionr   r1   r4   r   r   ÚtempfileÚmkdtempr   r7   Údebugr   Úappendr
   r   ÚvaluesÚremove)r   Úauto_confirmr   Úresponser   Únew_pathr   r   r   r   rE   Q   s@    	
		zUninstallPathSet.removec             C   s§   |  j  d k r) t j d |  j j ƒ d St j d |  j j ƒ x= |  j D]2 } |  j | ƒ } t j d | ƒ t	 | | ƒ qI Wx! |  j
 j ƒ  D] } | j ƒ  q� Wd 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   r>   r=   r   r7   rB   r
   r   rD   Úrollback)r   r   Útmp_pathr   r   r   r   rJ   {   s    zUninstallPathSet.rollbackc             C   s2   |  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)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r!   r(   r4   r7   rE   rJ   rL   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   sD   t  j 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   sU   t  j j | ƒ } t rA t  j j | ƒ d rA | j d d ƒ } |  j j | ƒ d  S)Nr   ú\ú/)r   r   r   r   r5   ÚreplacerS   r!   )r   r'   r   r   r   r!   �   s    zUninstallPthEntries.addc             C   sð   t  j d |  j ƒ t |  j d ƒ � } | j ƒ  } | |  _ Wd  QRXt d d „  | Dƒ ƒ rf d } n d } xT |  j D]I } y. t  j d | ƒ | j | | j	 d ƒ ƒ Wqv t
 k
 r¾ Yqv Xqv Wt |  j d	 ƒ � } | j | ƒ Wd  QRXd  S)
NzRemoving pth entries from %s:Úrbc             s   s   |  ] } d  | k Vq d S)s   
Nr   )r.   Úliner   r   r   ú	<genexpr>­   s    z-UninstallPthEntries.remove.<locals>.<genexpr>z
Ú
zRemoving entry: %szutf-8Úwb)r<   rB   rR   ÚopenÚ	readlinesrT   r2   rS   rE   ÚencodeÚ
ValueErrorÚ
writelines)r   ÚfhÚlinesÚendliner'   r   r   r   rE   §   s    		zUninstallPthEntries.removec          	   C   si   |  j  d  k r& t j d |  j ƒ d St j d |  j ƒ t |  j d ƒ � } | j |  j  ƒ Wd  QRXd S)Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous stater\   T)rT   r<   rI   rR   rB   r]   ra   )r   rb   r   r   r   rJ   º   s    zUninstallPthEntries.rollbackN)rM   rN   rO   r   r!   rE   rJ   r   r   r   r   r%   “   s   	
r%   )Ú
__future__r   Úloggingr   r@   Ú
pip.compatr   r   r   Úpip.exceptionsr   Ú	pip.utilsr   r   r	   r
   r   Úpip.utils.loggingr   Ú	getLoggerrM   r<   Úobjectr   r%   r   r   r   r   Ú<module>   s   (ƒ