
    *                        d Z ddlmZ ddlm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 dd	lmZ dd
lmZ ddlmZ ddlZddlZdZdZ G d dej,                        Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zd%dZ G d de      Zd Zd&d!Z d efd"Z! G d# d$e"      Z#y)'z)Wrapper to manipulate GCP git repository.    )absolute_import)division)unicode_literalsN)
exceptions)log)
properties)encoding)files)	platforms)   r      )r      r   c                       e Zd ZdZy)ErrorzExceptions for this module.N__name__
__module____qualname____doc__     (lib/googlecloudsdk/api_lib/source/git.pyr   r   +   s    #r   r   c                       e Zd ZdZy)UnknownRepositoryAliasExceptionzHException to be thrown when a repository alias provided cannot be found.Nr   r   r   r   r   r   /   s    Pr   r   c                       e Zd ZdZy)CannotInitRepositoryExceptionz;Exception to be thrown when a repository cannot be created.Nr   r   r   r   r   r   3       Cr   r   c                       e Zd ZdZy)CannotFetchRepositoryExceptionz;Exception to be thrown when a repository cannot be fetched.Nr   r   r   r   r   r   7   r   r   r   c                   "     e Zd ZdZ fdZ xZS )GitVersionExceptionz+Exceptions for when git version is too old.c                 \    || _         t        t        |   |j	                  ||             y )Ncur_versionmin_version)r$   superr!   __init__format)selffmtstrr$   r%   	__class__s       r   r'   zGitVersionException.__init__>   s,    "D	
t-+;GIr   r   r   r   r   r'   __classcell__r+   s   @r   r!   r!   ;   s    3I Ir   r!   c                       e Zd ZdZy)InvalidGitExceptionz4Exceptions for when git version is empty or invalid.Nr   r   r   r   r0   r0   D   s    <r   r0   c                       e Zd ZdZy)GcloudIsNotInPathz.Exception for when the gcloud cannot be found.Nr   r   r   r   r2   r2   H   s    6r   r2   c                 .   	 t        j                  t        j                  ddg            }|st	        d      |j                  d      st	        d      t        j                  d|      }|st	        d      t        |j                  dd	d
      D cg c]  }t        |       c}      }| r+|| k  r&dj                  d | D              }t        d||      yc c}w # t        $ r-}|j                  t        j                  k(  r
t!                d}~ww xY w)a  Returns true when version of git is >= min_version.

  Args:
    version_lower_bound: (int,int,int), The lowest allowed version, or None to
      just check for the presence of git.

  Returns:
    True if version >= min_version.

  Raises:
    GitVersionException: if `git` was found, but the version is incorrect.
    InvalidGitException: if `git` was found, but the output of `git version` is
      not as expected.
    NoGitException: if `git` was not found.
  gitversionz The git version string is empty.zgit version z4The git version string must start with git version .z(\d+)\.(\d+)\.(\d+)z5The git version string must contain a version number.r   r      .c              3   F   K   | ]  }t        j                  |        y wNsix	text_type.0is     r   	<genexpr>z"CheckGitVersion.<locals>.<genexpr>j   s     K7J!S]]1-7J   !zvYour git version {cur_version} is older than the minimum version {min_version}. Please install a newer version of git.r#   NT)r	   Decode
subprocesscheck_outputr0   
startswithresearchtuplegroupintjoinr!   OSErrorerrnoENOENTNoGitException)version_lower_boundr$   matchitemcurrent_versionr%   es          r   CheckGitVersionrU   L   s    
//*"9"95):L"MNK BCC!!.1 "1 3 3II,k:E !2 3 3 5;;q!Q3GH3G4SY3GHIO1DDHHK7JKKkB!{< < 
 I 
 
ww%,,	
s*   BC C$4C C 	D'(DDc                   "     e Zd ZdZ fdZ xZS )rO   z)Exceptions for when git is not available.c                 R    t         t        |   t        j                  d             y )Na          Cannot find git. Please install git and try again.

        You can find git installers at [http://git-scm.com/downloads], or use
        your favorite package manager to install it on your computer. Make sure
        it can be found on your system PATH.
        )r&   rO   r'   textwrapdedent)r)   r+   s    r   r'   zNoGitException.__init__y   s#    	.$(  	r   r,   r.   s   @r   rO   rO   v   s    1 r   rO   c                 4    t        j                  d| |d      S )zGet the URI for a repository, given its project and alias.

  Args:
    project: str, The project name.
    alias: str, The repository alias.

  Returns:
    str, The repository URI.
  z:https://source.developers.google.com/p/{project}/r/{alias}projectalias)uritemplateexpandr[   s     r   _GetRepositoryURIr`      s"     
		BE*
, ,r   Fc                 Z   t         j                  j                         t         j                  j                  k(  rd}nd}d}t	        j
                  ||g      }|st        d      | r@t        j                  d|      s(t        j                  t        j                  d             |S ||z   S )a  Get name of the gcloud script.

  Args:
    full_path: boolean, True if the gcloud full path should be used if free
      of spaces.

  Returns:
    str, command to use to execute gcloud

  Raises:
    GcloudIsNotInPath: if gcloud is not found in the path
  z.cmd gcloud)pathextzbCould not verify that gcloud is in the PATH. Please make sure the Cloud SDK bin folder is in PATH.z[-a-zA-Z0-9_/]+$z          You specified the option to use the full gcloud path in the git
          credential.helper, but the path contains non alphanumberic characters
          so the credential helper may not work correctly.)r   OperatingSystemCurrentWINDOWSr
   FindExecutableOnPathr2   rF   rQ   r   warningrX   rY   )	full_path
gcloud_extgcloud_namerc   s       r   _GetGcloudScriptrm      s     '')''(JJ+%%kJ<H&	
	@A A 88'0	kk
// > ?@
 M##r   c           	      p    dg}t         j                  j                  j                  j	                         }|r |j                  |j                  d             t         fd|D              rY	 t        |       d	j                  t#        |      t         j                  j                  j$                  j	                  d
            S y# t        $ re}dj                  d |D              }t        j                  t        j                  dj                  |j                   |                   Y d}~yd}~ww xY w)au  Returns the gcloud credential helper command for a remote repository.

  The command will be of the form '!gcloud auth git-helper --account=EMAIL
  --ignore-unknown $@`. See https://git-scm.com/docs/git-config. If the
  installed version of git or the remote repository does not support
  the gcloud credential helper, then returns None.

  Args:
    uri: str, The uri of the remote repository.
    full_path: bool, If true, use the full path to gcloud.
    min_version: minimum git version; if found git is earlier than this, warn
        and return None

  Returns:
    str, The credential helper command if it is available.
  zsource.developers.google.com,c              3   L   K   | ]  }j                  d |z   dz           yw)zhttps:///N)rE   )r>   hosturis     r   r@   z(_GetCredHelperCommand.<locals>.<genexpr>   s*      	N:L$cnnZ$&,-:Ls   !$r7   c              3   F   K   | ]  }t        j                  |        y wr9   r:   r=   s     r   r@   z(_GetCredHelperCommand.<locals>.<genexpr>   s     F+Qa 0+rA   a            You are using a Google-hosted repository with a
          {current} which is older than {min_version}. If you upgrade
          to {min_version} or later, gcloud can handle authentication to
          this repository. Otherwise, to authenticate, use your Google
          account and the password found by running the following command.
           $ gcloud auth print-access-token)currentr%   Nz6!{0} auth git-helper --account={1} --ignore-unknown $@T)required)r   VALUEScore credentialed_hosted_repo_domainsGetextendsplitanyrU   r!   rK   r   ri   rX   rY   r(   r$   rm   account)rs   rj   r%   credentialed_hostsextrarT   helper_min_strs   `      r   _GetCredHelperCommandr      s   " 77



 
 
A
A
E
E
G%
ekk#./ 	N:L	N Nk"  DJJ#&&**D*9; ; 
%  xxF+FFn	kk
// / 06v}}. 06 0BCD s   .C 	D5AD00D5c                   ,    e Zd ZdZddZd ZddZd Zy)	GitzRepresents project git repo.Nc                 v    || _         || _        |xs t        ||      | _        | j                  s
t	               y)a  Constructor.

    Args:
      project_id: str, The name of the project that has a repository associated
          with it.
      repo_name: str, The name of the repository to clone.
      uri: str, The URI of the repository, or None if it will be inferred from
          the name.

    Raises:
      UnknownRepositoryAliasException: If the repo name is not known to be
          associated with the project.
    N)_project_id
_repo_namer`   _urir   )r)   
project_id	repo_namers   s       r   r'   zGit.__init__   s<     "DDO?(Y?DI99+-- r   c                     | j                   S r9   )r   )r)   s    r   GetNamezGit.GetName   s    ??r   c                 >   t         j                  j                  |      }t         j                  j                  |      r*t	                t        j
                  |      rt        d      	 dd| j                  |g}t        }t        j                  j                         t        j                  j                  k(  rt        }t        | j                  ||      }|r|dddd|z   gz  }| j                  ||       |S # t         j"                  $ r}t%        |      d}~ww xY w)a  Clone a git repository into a gcloud workspace.

    If the resulting clone does not have a .gcloud directory, create one. Also,
    sets the credential.helper to use the gcloud credential helper.

    Args:
      destination_path: str, The relative path for the repository clone.
      dry_run: bool, If true do not run but print commands instead.
      full_path: bool, If true use the full path to gcloud.

    Returns:
      str, The absolute path of cloned repository.

    Raises:
      CannotInitRepositoryException: If there is already a file or directory in
          the way of creating this repository.
      CannotFetchRepositoryException: If there is a problem fetching the
          repository from the remote host, or if the repository is otherwise
          misconfigured.
    z0Directory path specified exists and is not emptyr4   clone)rj   r%   z--configz8credential.https://source.developers.google.com/.helper=N)ospathabspathexistsrU   listdirr   r   _HELPER_MINr   re   rf   rg   _WINDOWS_HELPER_MINr   _RunCommandrC   CalledProcessErrorr   )	r)   destination_pathdry_runrj   abs_repository_pathcmdmin_gitcred_helper_commandrT   s	            r   Clonez	Git.Clone  s   * ''//*:;	ww~~)*	'	(+>@ 	@.GTYY(;<cg

#
#
+
+
-

#
#
+
+,%1
))yg?	FF 	
 	
 sG$  (( .*1--.s   *BC9 9DDDc                     t        j                  d|       |r/t         j                  j                  dj	                  |             y t        j                  |       y )NzExecuting %s )r   debugoutPrintrK   rC   
check_call)r)   r   r   s      r   r   zGit._RunCommand6  s9    IInc"	ggmmCHHSM"C r   r9   )FF)r   r   r   r   r'   r   r   r   r   r   r   r   r      s    $.(2h!r   r   r9   )F)$r   
__future__r   r   r   rM   r   rF   rC   rX   googlecloudsdk.corer   r   r   googlecloudsdk.core.utilr	   r
   r   r;   r^   r   r   r   r   r   r   r!   r0   r2   rU   rO   r`   rm   r   objectr   r   r   r   <module>r      s     0 &  '  	 	   * # * - * . 
    $J $Qe QDE DDU DI% I=% =7 7'TU ,$$N */K +\S!& S!r   