3
zYðiV0  ã               @   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G d	d
„ d
eƒZeƒ ZG d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„Zdd„ Zdd„ Zdd„ Z‡  ZS )Ú
VcsSupportÚsshÚgitÚhgÚbzrÚsftpÚsvnc                s:   t jj| jƒ tt dd ƒr(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-ue6tjl93/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S r   )Ú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   sF   t |dƒstjd|jƒ d S |j| jkrB|| 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   s<   || j kr| j |= n$|| j jƒ kr.| 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   s8   x2| j jƒ D ]$}|j|ƒrtjd||jƒ |jS qW d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| S d S )N)Úlowerr   )r   r*   r   r   r   Úget_backendR   s    
zVcsSupport.get_backendc             C   s   | j |ƒ}|r| j|ƒS d S )N)r6   r8   )r   r4   r5   r   r   r   Úget_backend_from_locationW   s    

z$VcsSupport.get_backend_from_location)NN)r.   Ú
__module__Ú__qualname__r   r   r   r    Úpropertyr#   r(   r)   r1   r2   r6   r8   r9   Ú__classcell__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(„Zed)d*„ ƒZ‡  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   s"   t jj|ƒ\}}|jt jjƒp |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   sz   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ÚnetlocrD   ÚqueryÚfragÚrevr   r   r   Úget_url_rev€   s    zVersionControl.get_url_revc             C   s4   |j dƒj| jƒ s td| ƒ‚| j|ƒ| j|ƒfS )zA
        Returns (url, revision), where both are strings
        rL   zBad directory: %s)ÚrstripÚendswithr$   rV   Ú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.
        rL   )r   Úunquoterb   )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.
        )rh   )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)rQ   )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)rQ   )r   rl   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)rQ   )r   rl   rn   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)rQ   )r   rl   rn   r   r   r   Úcheck_version»   s    zVersionControl.check_versionc       
      C   s´  d}d}t jj|ƒrÔ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ƒ qÔtjd| j| j	t|ƒ|ƒ d}ntjd|| j| j	ƒ d}|�r°tjd| j|ƒ td|d  |d ƒ}|dk�r2tjd| j	t|ƒ||ƒ | j|||ƒ n~|d	k�r>nr|d
k�rftjdt|ƒƒ t|ƒ d}nJ|dk�rœt|ƒ}	tjdt|ƒ|	ƒ tj||	ƒ d}n|dk�r°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   rT   zSwitching %s %s to %s%szDeleting %szBacking up %s to %sÚa©rs   rt   ru   rv   )rr   ry   ©rt   ru   rv   )rw   rz   éÿÿÿÿ)rC   rD   ÚexistsÚjoinr$   rd   rk   r,   r/   Ú	repo_nameÚtitler   rq   Úinforp   r-   r*   r	   ro   r   r   ÚshutilÚmoveÚsysÚexit)
r   rl   r@   rn   Ú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)rC   rD   r|   r   rm   )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)rQ   )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)rQ   )r   r4   r   r   r   rd   )  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)rQ   )r   r4   r   r   r   re   0  s    zVersionControl.get_revisionTÚraisec       	      C   sf   | j g| }yt|||||||ƒS  tk
r` } z$|jtjkrNtd| j  ƒ‚n‚ W Y dd}~X nX d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   s0   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*   rC   rD   r}   r|   )r0   r4   rD   r   r   r   r3   N  s    z VersionControl.controls_location)N)TNrŽ   NNN)r.   r:   r;   r*   r$   r   r   rK   rP   rR   ra   rf   rh   rk   rm   ro   rp   rq   r‹   rŒ   r   rd   re   rš   Úclassmethodr3   r=   r   r   )r   r   r>   a   s2   
U		   
r>   c             C   sZ   t j|ƒ}|rFy|ƒ j| |ƒS  tk
rD   tjd||jƒ | jƒ S X t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�   ÚloggingrC   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 {