
§|jV0  ã               @   sú   d  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 m	 Z
 d d l m Z d d l m Z m Z m Z m Z m Z d d g Z e j e ƒ Z Gd	 d
 „  d
 e ƒ Z e ƒ  Z Gd d „  d e ƒ Z d d „  Z d S)z)Handles all VCS (version control) supporté    )Úabsolute_importN)Úparse)Ú
BadCommand)Údisplay_pathÚ
backup_dirÚcall_subprocessÚrmtreeÚask_path_existsÚvcsÚget_src_requirementc                   sÄ   e  Z d  Z i  Z d d d d d d g Z ‡  f d d †  Z d	 d
 „  Z e d d „  ƒ Z e d d „  ƒ Z	 e d d „  ƒ Z
 d d „  Z d d d d „ Z d d „  Z d d „  Z d d „  Z ‡  S)Ú
VcsSupportÚsshÚgitÚhgÚbzrÚsftpÚsvnc                sO   t  j j |  j ƒ t t  d d  ƒ r8 t  j j |  j ƒ t t |  ƒ j ƒ  d  S)NÚuses_fragment)	Úurllib_parseÚuses_netlocÚextendÚschemesÚgetattrr   Úsuperr   Ú__init__)Úself)Ú	__class__© ú//tmp/pip-build-5c7ija6t/pip/pip/vcs/__init__.pyr      s    zVcsSupport.__init__c             C   s   |  j  j ƒ  S)N)Ú	_registryÚ__iter__)r   r   r   r   r    $   s    zVcsSupport.__iter__c             C   s   t  |  j j ƒ  ƒ S)N)Úlistr   Úvalues)r   r   r   r   Úbackends'   s    zVcsSupport.backendsc             C   s   d d „  |  j  Dƒ S)Nc             S   s   g  |  ] } | j  ‘ q Sr   )Údirname)Ú.0Úbackendr   r   r   ú
<listcomp>-   s   	 z'VcsSupport.dirnames.<locals>.<listcomp>)r#   )r   r   r   r   Údirnames+   s    zVcsSupport.dirnamesc             C   s.   g  } x! |  j  D] } | j | j ƒ q W| S)N)r#   r   r   )r   r   r&   r   r   r   Úall_schemes/   s    zVcsSupport.all_schemesc             C   s_   t  | d ƒ s& t j d | j ƒ d  S| j |  j k r[ | |  j | j <t j d | j ƒ d  S)NÚnamezCannot register VCS %szRegistered VCS backend: %s)ÚhasattrÚloggerÚwarningÚ__name__r*   r   Údebug)r   Úclsr   r   r   Úregister6   s    zVcsSupport.registerNc             C   sR   | |  j  k r |  j  | =n2 | |  j  j ƒ  k rA |  j  | j =n t j d ƒ d  S)Nz0Cannot unregister because no class or name given)r   r"   r*   r,   r-   )r   r0   r*   r   r   r   Ú
unregister>   s
    zVcsSupport.unregisterc             C   sJ   xC |  j  j ƒ  D]2 } | j | ƒ r t j d | | j ƒ | j Sq Wd S)z—
        Return the name of the version control backend if found at given
        location, e.g. vcs.get_backend_name('/path/to/vcs/checkout')
        zDetermine that %s uses VCS: %sN)r   r"   Úcontrols_locationr,   r/   r*   )r   ÚlocationÚvc_typer   r   r   Úget_backend_nameF   s    	zVcsSupport.get_backend_namec             C   s*   | j  ƒ  } | |  j k r& |  j | Sd  S)N)Úlowerr   )r   r*   r   r   r   Úget_backendR   s    zVcsSupport.get_backendc             C   s&   |  j  | ƒ } | r" |  j | ƒ Sd  S)N)r6   r8   )r   r4   r5   r   r   r   Úget_backend_from_locationW   s    z$VcsSupport.get_backend_from_location)r.   Ú
__module__Ú__qualname__r   r   r   r    Úpropertyr#   r(   r)   r1   r2   r6   r8   r9   r   r   )r   r   r      s   	r   c                   s'  e  Z d  Z d Z d Z f  Z d ‡  f d d † Z d d „  Z d d „  Z d	 d
 „  Z	 d d „  Z
 d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d „  Z d d  „  Z d! d" „  Z d# d$ „  Z d% d d& d d d d' d( „ Z e d) d* „  ƒ Z ‡  S)+ÚVersionControlÚ Nc                s&   | |  _  t t |  ƒ j | | Ž  d  S)N)Úurlr   r=   r   )r   r?   ÚargsÚkwargs)r   r   r   r   g   s    	zVersionControl.__init__c             C   s1   t  j j | ƒ \ } } | j t  j j ƒ p0 | S)zy
           posix absolute paths start with os.path.sep,
           win32 ones start with drive (like c:\folder)
        )ÚosÚpathÚ
splitdriveÚ
startswithÚsep)r   ÚrepoÚdriveÚtailr   r   r   Ú_is_local_repositoryk   s    z#VersionControl._is_local_repositoryc             C   s   | j  d d ƒ S)Nú/Ú_)Úreplace)r   Úsurnamer   r   r   Útranslate_egg_surnameu   s    z$VersionControl.translate_egg_surnamec             C   s
   t  ‚ d S)z�
        Export the repository at the url to the destination location
        i.e. only download the files, without vcs informations
        N)ÚNotImplementedError)r   r4   r   r   r   Úexporty   s    zVersionControl.exportc       	      C   s±   d } d |  j  k s( t | |  j  ƒ ‚ |  j  j d d ƒ d } t j | ƒ \ } } } } } d } d | k r‰ | j d d ƒ \ } } t j | | | | d f ƒ } | | f S)zm
        Returns the correct repository URL and revision by parsing the given
        repository URL
        zvSorry, '%s' is a malformed VCS url. The format is <vcs>+<protocol>://<url>, e.g. svn+http://myrepo/svn/MyApp#egg=MyAppú+é   Nú@r>   )r?   ÚAssertionErrorÚsplitr   ÚurlsplitÚrsplitÚ
urlunsplit)	r   Úerror_messager?   ÚschemeÚnetlocrC   ÚqueryÚfragÚrevr   r   r   Úget_url_rev€   s    "zVersionControl.get_url_revc             C   sH   | j  d ƒ j |  j ƒ s, t d | ƒ ‚ |  j | ƒ |  j | ƒ f S)zA
        Returns (url, revision), where both are strings
        rK   zBad directory: %s)ÚrstripÚendswithr$   rU   Úget_urlÚget_revision)r   r4   r   r   r   Úget_info“   s    zVersionControl.get_infoc             C   s   t  j | ƒ j d ƒ S)zi
        Normalize a URL for comparison by unquoting it and removing any
        trailing slash.
        rK   )r   Úunquotera   )r   r?   r   r   r   Únormalize_url›   s    zVersionControl.normalize_urlc             C   s   |  j  | ƒ |  j  | ƒ k S)zV
        Compare two repo URLs for identity, ignoring incidental differences.
        )rg   )r   Úurl1Úurl2r   r   r   Úcompare_urls¢   s    zVersionControl.compare_urlsc             C   s
   t  ‚ d S)zx
        Called when installing or updating an editable package, takes the
        source path of the checkout.
        N)rP   )r   Údestr   r   r   Úobtain¨   s    zVersionControl.obtainc             C   s
   t  ‚ d S)zB
        Switch the repo at ``dest`` to point to ``URL``.
        N)rP   )r   rk   r?   Úrev_optionsr   r   r   Úswitch¯   s    zVersionControl.switchc             C   s
   t  ‚ d S)zO
        Update an already-existing repo to the given ``rev_options``.
        N)rP   )r   rk   rm   r   r   r   Úupdateµ   s    zVersionControl.updatec             C   s
   t  ‚ d S)zp
        Return True if the version is identical to what exists and
        doesn't need to be updated.
        N)rP   )r   rk   rm   r   r   r   Úcheck_version»   s    zVersionControl.check_versionc       
      C   sX  d } d } t  j j | ƒ r2d } t  j j t  j j | |  j ƒ ƒ r|  j | ƒ } |  j | | ƒ râ t j d |  j	 j
 ƒ  t | ƒ | ƒ |  j | | ƒ sÒ t j d t | ƒ |  j	 | ƒ |  j | | ƒ qt j d ƒ q2t j d |  j |  j	 t | ƒ | ƒ d } n" t j d | |  j |  j	 ƒ d } | rTt j d |  j | ƒ t d | d | d ƒ } | d k r­t j d |  j	 t | ƒ | | ƒ |  j | | | ƒ n§ | d	 k r¼n˜ | d
 k rñt j d t | ƒ ƒ t | ƒ d } nc | d k r;t | ƒ }	 t j d t | ƒ |	 ƒ t j | |	 ƒ d } n | d k rTt j d ƒ | S)z­
        Prepare a location to receive a checkout/clone.

        Return True if the location is ready for (and requires) a
        checkout/clone, False otherwise.
        TFz)%s in %s exists, and has correct URL (%s)zUpdating %s %s%sz$Skipping because already up-to-date.z%s %s in %s exists with URL %sú%(s)witch, (i)gnore, (w)ipe, (b)ackup ÚsÚiÚwÚbz0Directory %s already exists, and is not a %s %s.ú(i)gnore, (w)ipe, (b)ackup z+The plan is to install the %s repository %szWhat to do?  %sr   rS   zSwitching %s %s to %s%szDeleting %szBacking up %s to %sÚa©rr   rs   rt   ru   )rq   rx   ©rs   rt   ru   )rv   ry   éÿÿÿÿ)rB   rC   ÚexistsÚjoinr$   rc   rj   r,   r/   Ú	repo_nameÚtitler   rp   Úinforo   r-   r*   r	   rn   r   r   ÚshutilÚmoveÚsysÚexit)
r   rk   r?   rm   Úrev_displayÚcheckoutÚpromptÚexisting_urlÚresponseÚdest_dirr   r   r   Úcheck_destinationÂ   s‚    $		
	 	
	
		z VersionControl.check_destinationc             C   s-   t  j j | ƒ r t | ƒ |  j | ƒ d S)zq
        Clean up current location and download the url repository
        (and vcs infos) into location
        N)rB   rC   r{   r   rl   )r   r4   r   r   r   Úunpack  s    
zVersionControl.unpackc             C   s
   t  ‚ d S)zê
        Return a string representing the requirement needed to
        redownload the files currently present in location, something
        like:
          {repository_url}@{revision}#egg={project_name}-{version_identifier}
        N)rP   )r   Údistr4   r   r   r   r      s    z"VersionControl.get_src_requirementc             C   s
   t  ‚ d S)z_
        Return the url used at location
        Used in get_info or check_destination
        N)rP   )r   r4   r   r   r   rc   )  s    zVersionControl.get_urlc             C   s
   t  ‚ d S)z_
        Return the current revision of the files at location
        Used in get_info
        N)rP   )r   r4   r   r   r   rd   0  s    zVersionControl.get_revisionTÚraisec       	      C   s‡   |  j  g | } y  t | | | | | | | ƒ SWnP t k
 r‚ } z0 | j t j k rm t d |  j  ƒ ‚ n ‚  WYd d } ~ Xn Xd S)z«
        Run a VCS subcommand
        This is simply a wrapper around call_subprocess that adds the VCS
        command name, and checks that the VCS is available
        zCannot find command %rN)r*   r   ÚOSErrorÚerrnoÚENOENTr   )	r   ÚcmdÚshow_stdoutÚcwdÚon_returncodeÚcommand_descÚextra_environÚspinnerÚer   r   r   Úrun_command7  s    	zVersionControl.run_commandc             C   sD   t  j d | |  j |  j ƒ t j j | |  j ƒ } t j j | ƒ S)z¨
        Check if a location is controlled by the vcs.
        It is meant to be overridden to implement smarter detection
        mechanisms for specific vcs.
        zChecking in %s for %s (%s)...)r,   r/   r$   r*   rB   rC   r|   r{   )r0   r4   rC   r   r   r   r3   N  s    	z VersionControl.controls_location)r.   r:   r;   r*   r$   r   r   rJ   rO   rQ   r`   re   rg   rj   rl   rn   ro   rp   rŠ   r‹   r   rc   rd   r™   Úclassmethodr3   r   r   )r   r   r=   a   s2   
U		r=   c             C   s{   t  j | ƒ } | ra y | ƒ  j |  | ƒ SWn2 t k
 r` t j d | | j ƒ |  j ƒ  SYn Xt j d | ƒ |  j ƒ  S)NzPcannot determine version of editable source in %s (%s command not found in path)ztcannot determine version of editable source in %s (is not SVN checkout, Git clone, Mercurial clone or Bazaar branch))r
   r9   r   r   r,   r-   r*   Úas_requirement)rŒ   r4   Úversion_controlr   r   r   r   [  s    
)Ú__doc__Ú
__future__r   r�   ÚloggingrB   r€   r‚   Zpip._vendor.six.moves.urllibr   r   Úpip.exceptionsr   Ú	pip.utilsr   r   r   r   r	   Ú__all__Ú	getLoggerr.   r,   Úobjectr   r
   r=   r   r   r   r   r   Ú<module>   s   (G	ú