B
    Mt\1                 @   s  d Z ddlZddl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	 G dd dZ
G dd dZG dd	 d	Ze Zd
Zejdkred7 Zed Zg fddZdd ZefddZdd ZG dd de	jZdd ZG dd deZdd ZddZejekreej ejdkZe d ej!Z"d!d" Z#d<d$d%Z$d&d' Z%G d(d) d)e&Z'e d*Z(G d+d, d,e	jZ)G d-d. d.Z*G d/d0 d0e*Z+G d1d2 d2Z,d3d4 Z-e d5fd6d7Z.g fd8d9Z/G d:d; d;Z0dS )=zm
svn-Command based Implementation of a Subversion WorkingCopy Path.

  SvnWCCommandPath  is the main class.

    N)commonc               @   s   e Zd Zi Zi Zi Zi ZdS )cacheN)__name__
__module____qualname__proplistinfoentriesZprop r
   r
   -lib/python3.7/site-packages/py/_path/svnwc.pyr      s   r   c               @   s   e Zd Zdd Zdd ZdS )	RepoEntryc             C   s   || _ || _|| _d S )N)urlrev	timestamp)selfr   r   r   r
   r
   r   __init__   s    zRepoEntry.__init__c             C   s   d| j | j| jf S )Nzrepo: %s;%s  %s)r   r   r   )r   r
   r
   r   __str__    s    zRepoEntry.__str__N)r   r   r   r   r   r
   r
   r
   r   r      s   r   c               @   s6   e Zd ZdZdZdd Zdd Zddd	Zd
d ZdS )	RepoCachez The Repocache manages discovered repository paths
    and their revisions.  If inside a timeout the cache
    will even return the revision of the root.
       c             C   s
   g | _ d S )N)repos)r   r
   r
   r   r   *   s    zRepoCache.__init__c             C   s
   g | _ d S )N)r   )r   r
   r
   r   clear-   s    zRepoCache.clearNc             C   s`   |d krd S |d krt   }x>| jD ]}||jkr$||_||_P q$W t|||}| j| d S )N)timer   r   r   r   r   append)r   r   r   r   entryr
   r
   r   put0   s    
zRepoCache.putc             C   sR   t   }x@| jD ]6}||jr||j| j k r<|j|jfS |jdfS qW |dfS )N)r   r   
startswithr   r   timeoutr   )r   r   Znowr   r
   r
   r   getA   s    zRepoCache.get)N)	r   r   r   __doc__r   r   r   r   r   r
   r
   r
   r   r   #   s   
r   z_ -/\=$.~+%win32:z@:c             C   sX   y| d S  t k
rR   tjd}|  d|dd d }| | |S X d S )Nr   zsvn -q --version.   )
IndexErrorpyprocesscmdexecstripjoinsplitr   )Zvervr
   r
   r   _getsvnversionU   s    
r,   c             C   s&   t | } tjdkr"t | dd} | S )Nr    $z\$)strsysplatformreplace)textr
   r
   r   _escape_helper_   s    
r3   c             C   s,   x&t | D ]}| rq
||kr"q
dS W dS )NTF)r.   isalnum)r2   Zallowed_charscr
   r
   r   _check_for_bad_charse   s    r6   c             C   sN   |  dd\}}|dkrJ| dd\}}t|ts<t|trJtd| f d S )Nz://   file/zbad char in %r)r*   r6   ALLOWED_CHARS_HOSTALLOWED_CHARS
ValueError)r   protoZuriZhostZuripathr
   r
   r   checkbadcharsn   s    

r>   c               @   s   e Zd ZdZdZdd Zeed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G dd  d ejZdS )!SvnPathBasez2 Base implementation for SvnPath implementations. r9   c             C   s   | j S )N)strpath)r   r
   r
   r   _geturl   s    zSvnPathBase._geturlNzurl of this svn-path.c             C   s   | j S )z7 return a string representation (including rev-number) )r@   )r   r
   r
   r   r      s    zSvnPathBase.__str__c             C   s
   t | jS )N)hashr@   )r   r
   r
   r   __hash__   s    zSvnPathBase.__hash__c             K   s   t | j}|d| j|_|d| j|_| d\}}}}d|krdd|ksVd|krtd| n:|d|}|d|}|r|	dsd| }|| |d< |d	| |d
| j
 |d rd| |_n
d| |_|S )a   create a modified version of this path. A 'rev' argument
            indicates a new revision.
            the following keyword arguments modify various path parts::

              http://host.com/repo/path/file.ext
              |-----------------------|          dirname
                                        |------| basename
                                        |--|     purebasename
                                            |--| ext
        r   authz!dirname,basename,purebasename,extbasenamepurebasenameextzinvalid specification %rr"   dirnamesepz%(dirname)s%(sep)s%(basename)sz%(dirname)s)object__new__	__class__r   r   rD   
_getbyspecr<   
setdefaultr   rI   r@   )r   kwobjrH   rE   rF   rG   Zpbr
   r
   r   new   s&    
zSvnPathBase.newc       	      C   s   g }| j | j}x|dD ]}| }|dkrN|| j|dd  q|dkrf||d  q|d }|d}|dkr|d }}n|d| ||d  }}|dkr|| q|d	kr|| qtd
| qW |S )a   get specified parts of the path.  'arg' is a string
            with comma separated path parts. The parts are returned
            in exactly the order of the specification.

            you may specify the following parts:

            http://host.com/repo/path/file.ext
            |-----------------------|          dirname
                                      |------| basename
                                      |--|     purebasename
                                          |--| ext
        ,rH   Nr   rE   r"    rF   rG   zDon't know part %r)r@   r*   rI   r(   r   r)   rfind	NameError)	r   specrespartsnamerE   irF   rG   r
   r
   r   rM      s&    
zSvnPathBase._getbyspecc             C   s(   t | t |ko&| j|jkp&| j|jkS )z3 return true if path and rev attributes each match )r.   r   )r   otherr
   r
   r   __eq__   s    zSvnPathBase.__eq__c             C   s
   | |k S )Nr
   )r   r[   r
   r
   r   __ne__   s    zSvnPathBase.__ne__c                sH   |s S t  fdd|D } jf| }  j| j j}|S )z return a new Path (with the same revision) which is composed
            of the self Path followed by 'args' path components.
        c                s   g | ]}|  jqS r
   )r(   rI   ).0arg)r   r
   r   
<listcomp>   s    z$SvnPathBase.join.<locals>.<listcomp>)tupler@   rL   rI   r)   r   rD   )r   argsrX   newpathr
   )r   r   r)      s    zSvnPathBase.joinc             C   s   |  |}|S )z+ return the content of the given property. )Z_propget)r   rY   valuer
   r
   r   propget   s    
zSvnPathBase.propgetc             C   s   |   }|S )z list all property names. )Z	_proplist)r   contentr
   r
   r   r      s    zSvnPathBase.proplistc             C   s
   |   jS )z2 Return the size of the file content of the Path. )r   size)r   r
   r
   r   rg      s    zSvnPathBase.sizec             C   s
   |   jS )z0 Return the last modification time of the file. )r   mtime)r   r
   r
   r   rh      s    zSvnPathBase.mtimec             C   s   t |S )N)r3   )r   cmdr
   r
   r   _escape   s    zSvnPathBase._escapec               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
zSvnPathBase.Checkersc             C   s2   y| j  jdkS  tjjk
r,   |  S X d S )Ndir)pathr   kindr%   errorError_listdirworks)r   r
   r
   r   rk     s    zSvnPathBase.Checkers.dirc             C   s0   y| j   W n tjjk
r&   dS X dS d S )NFT)rl   listdirr%   rn   ENOENT)r   r
   r
   r   rp     s
    z"SvnPathBase.Checkers._listdirworksc             C   s.   y| j  jdkS  tjjk
r(   dS X d S )Nr8   F)rl   r   rm   r%   rn   rr   )r   r
   r
   r   r8   #  s    zSvnPathBase.Checkers.filec             C   s,   y
| j  S  tjjk
r&   |  S X d S )N)rl   r   r%   rn   rr   rp   )r   r
   r
   r   exists)  s    
zSvnPathBase.Checkers.existsN)r   r   r   rk   rp   r8   rs   r
   r
   r
   r   Checkers  s   rt   )r   r   r   r   rI   rA   propertyr   r   rC   rQ   rM   r\   r]   r)   re   r   rg   rh   rj   r   rt   r
   r
   r
   r   r?   {   s"   "$r?   c             C   s@   |  d}|dkrtd|  | d | } t| d}t|S )Nr"   r   zcould not parse %sz%Y-%m-%dT%H:%M:%S)rT   r<   r   strptimeZmktime)timestrrZ   
parsedtimer
   r
   r   parse_apr_time/  s    
ry   c               @   s    e Zd ZdZdd Zdd ZdS )PropListDictzD a Dictionary which fetches values (InfoSvnCommand instances) lazilyc             C   s    t | dd |D  || _d S )Nc             S   s   g | ]}|d fqS )Nr
   )r^   xr
   r
   r   r`   :  s    z)PropListDict.__init__.<locals>.<listcomp>)dictr   rl   )r   rl   Zkeynamesr
   r
   r   r   9  s    zPropListDict.__init__c             C   s2   t | |}|d kr.| j|}t | || |S )N)r|   __getitem__rl   re   __setitem__)r   keyrd   r
   r
   r   r}   =  s
    zPropListDict.__getitem__N)r   r   r   r   r   r}   r
   r
   r
   r   rz   7  s   rz   c               C   s   t jdkrdS dS )Nr    z	LC_ALL=C rS   )r/   r0   r
   r
   r
   r   	fixlocaleD  s    
r   z* | \ / : < > ? 	 
    z^([a-z]\:\\)?[^:]+$c             C   sd   t d d  }| j}tr2|d t|s2tdx,|D ]$}|tjksN||kr8td|f q8W d S )Nr!   z path may not contain a colon (:)zillegal character %r in path)	ILLEGAL_CHARSr@   	ISWINDOWSremove_reg_allow_diskmatchr<   stringZ	printable)rl   Zillegalspcharr
   r
   r   _check_pathO  s    


r   Tc             C   s>   t |  | j}|r,| jdkr,d|| jf }n|r:d|f }|S )Nr   z%s@%sz%s@HEAD)r   r@   r   )rl   Zaddatr   r
   r
   r   path_to_fspathZ  s    
r   c             C   s   t | d}ddlm} trvt|}|dd}|drld|ddd||t|dd  f }q~||}n||}| j	dkrd	|| j	f }n
d
|f }d|f S )NFr   )quote\r9   r7   z/%s%sr   z%s@%sz%s@HEADz	file://%s)
r   Zurllibr   r   r   r   r1   grouplenr   )rl   fspathr   r   r
   r
   r   url_from_pathc  s    


 


r   c               @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )SvnAuthz/ container for auth information for Subversion Tc             C   s   || _ || _|| _|| _d S )N)usernamepassword
cache_authinteractive)r   r   r   r   r   r
   r
   r   r   x  s    zSvnAuth.__init__c             C   sr   | j dd}| jdd}g }|r4|d|f  |rH|d|f  | jsX|d | jsh|d d|S )N"z\"z--username="%s"z--password="%s"z--no-auth-cachez--non-interactiver   )r   r1   r   r   r   r   r)   )r   unameZpasswdZretr
   r
   r   makecmdoptions~  s    

zSvnAuth.makecmdoptionsc             C   s   d| j f S )Nz<SvnAuth username=%s ...>)r   )r   r
   r
   r   r     s    zSvnAuth.__str__N)TT)r   r   r   r   r   r   r   r
   r
   r
   r   r   v  s   
r   z\s*(\d+)\s*(\S+) (.*)c               @   s  e Zd ZdZejZdnddZedd dddZedd ddd	Z	d
d Z
dd ZeedddZdd Zdd Zdd Zdd Zdd Zdd ZdoddZdd Zdd  Zdpd!d"Zdqd%d&Zdrd(d)Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zdsd5d6Zd7d8 Zd9d: Z d;d< Z!d=d> Z"d?d@ Z#dtdBdCZ$dudDdEZ%dFdG Z&e'(dHe'j)Z*dvdJdKZ+dLdM Z,dNdO Z-dPdQ Z.dwdRdSZ/dxdTdUZ0dVdW Z1dXdY Z2dydZd[Z3dzd\d]Z4d{d_d`Z5dadb Z6G dcdd dde7j8j9j:Z:d|dfdgZ;dhdi Z<djdk Z=dldm Z>dS )}SvnWCCommandPathz path implementation offering access/modification to svn working copies.
        It has methods similar to the functions in os.path and similar to the
        commands of the svn client.
    Nc             C   s\   t | }t|| r(|j| kr"|S |j}tt|trDtd|f t	j
||_||_|S )Nzbad char in wcpath %s)rJ   rK   
isinstancerL   	localpathr6   r.   r;   r<   r%   rl   localrD   )clswcpathrD   r   r
   r
   r   rK     s    


zSvnWCCommandPath.__new__c             C   s
   t | jS )N)r.   r   )r{   r
   r
   r   <lambda>  s    zSvnWCCommandPath.<lambda>zstring pathc             C   s   | j ddjS )Nr   )usecache)r   r   )r{   r
   r
   r   r     s    revisionc             C   s   | j t|dd kS )Nr   )r   getattr)r   r[   r
   r
   r   r\     s    zSvnWCCommandPath.__eq__c             C   s:   t | dd d kr |  }|j| _t| jtjjs4t| jS )N_url)	r   r   r   r   r   r%   builtinZ_basestringAssertionError)r   r   r
   r
   r   rA     s
    zSvnWCCommandPath._geturlzurl of this WC itemc             C   s   t |S )N)r3   )r   ri   r
   r
   r   rj     s    zSvnWCCommandPath._escapec             C   s   | j |S )z! pickle object into path location)r   dump)r   rP   r
   r
   r   r     s    zSvnWCCommandPath.dumpc             C   s   |   }tj|jS )z* return current SvnPath for this WC-item. )r   r%   rl   svnurlr   )r   r   r
   r
   r   r     s    zSvnWCCommandPath.svnurlc             C   s
   d| j  S )Nz	svnwc(%r))r@   )r   r
   r
   r   __repr__  s    zSvnWCCommandPath.__repr__c             C   s
   t | jS )N)r.   r   )r   r
   r
   r   r     s    zSvnWCCommandPath.__str__c             C   s   | j d krdS | j  S )NrS   )rD   r   )r   r
   r
   r   _makeauthoptions  s    
z!SvnWCCommandPath._makeauthoptionsc             C   s.   |rt |pg }||   | j|f| S )N)listr   r   _svn)r   ri   rb   r
   r
   r   _authsvn  s    zSvnWCCommandPath._authsvnc       
   	      sR  d| g} fdd|D }| | |d  j  t d| }yJz*d}tj|}dtj|< t	j
|}W d |r|tj|< ntj|= X W n t	j
jjk
rL   t d }|j }	|	d	d
krt	j n|	dd
krt	j |	dd
ks:|	dd
ks:|	dd
ks:|	dd
krFt	j|	 Y nX |S )Nzsvn %sc                s   g | ]}  |qS r
   )rj   )r^   item)r   r
   r   r`     s    z)SvnWCCommandPath._svn.<locals>.<listcomp>z"%s"r   LC_MESSAGESCr7   z	not foundr   zE200009:zfile existszfile already existszw150002:zcan't create directory)extendr   rj   r@   r   r)   osenvironr   r%   r&   r'   ro   r/   exc_infoerrlowerfindrn   rr   EEXIST)
r   ri   rb   lr   r   ZholdouteZstrerrr
   )r   r   r     s8    



zSvnWCCommandPath._svnc             C   s   |  d|g dS )z switch to given URL. switchN)r   )r   r   r
   r
   r   r     s    zSvnWCCommandPath.switchc             C   s   g }|dkr| j }|dks"|dkr@tjdkrjt dkrj|d7 }n*t dkrX|d| 7 }n|dt|  || | d| dS )	z$ checkout from url to local wcpath. Nr   r    z1.3z@HEADz@%dz-rco)r   r/   r0   r,   r   r.   r   )r   r   r   rb   r
   r
   r   checkout  s    




zSvnWCCommandPath.checkoutHEADTc             C   s&   d|g}|s| d | d| dS )z= update working copy item to given revision. (None -> HEAD). z-rz--non-interactiveZupN)r   r   )r   r   r   Zoptsr
   r
   r   update  s    
zSvnWCCommandPath.updatewc             C   s   | j || dS )z) write content into local filesystem wc. N)r   write)r   rf   moder
   r
   r   r     s    zSvnWCCommandPath.writec             G   s   | j | jj| | jdS )z0 return the directory Path of the current Path. )rD   )rL   r   dirpathrD   )r   rb   r
   r
   r   r     s    zSvnWCCommandPath.dirpathc             C   s4   |   }|jddr|  | jddr0|   | S )Nr   )rk   )r   check_ensuredirsmkdir)r   parentr
   r
   r   r     s    zSvnWCCommandPath._ensuredirsc             O   sd   | j | }| r*|jddr&|  |S |ddr>| S | }|  |d |  |S )z ensure that an args-joined path exists (by default as
            a file). if you specify a keyword argument 'directory=True'
            then the path is forced  to be a directory path.
        F)	versionedrk   r   rS   )r)   r   addr   r   r   r   )r   rb   kwargspr   r
   r
   r   ensure  s    

zSvnWCCommandPath.ensurec             G   s$   |r| j |  S | d | S dS )z1 create & return the directory joined with args. r   N)r)   r   r   )r   rb   r
   r
   r   r   /  s    
zSvnWCCommandPath.mkdirc             C   s   |  d dS )z add ourself to svn r   N)r   )r   r
   r
   r   r   7  s    zSvnWCCommandPath.addr7   c             C   sP   |st d| jdds,tj|   dS g }|r>|d | jd|  dS )z remove a file or a directory tree. 'rec'ursive is
            ignored and considered always true (because of
            underlying svn semantics.
        z!svn cannot remove non-recursivelyT)r   Nz--forcer   )r   )r   r   r%   rl   r   r   r   r   )r   recZforceflagsr
   r
   r   r   ;  s    
zSvnWCCommandPath.removec             C   s    t jdt| t|f  dS )z copy path to target.zsvn copy %s %sN)r%   r&   r'   r.   )r   targetr
   r
   r   copyJ  s    zSvnWCCommandPath.copyc             C   s    t jdt| t|f  dS )z rename this path to target. zsvn move --force %s %sN)r%   r&   r'   r.   )r   r   r
   r
   r   renameN  s    zSvnWCCommandPath.renamec             C   s   |  d }|stddS )z( set a lock (exclusive) on the resource lockz!unknown error in svn lock commandN)r   r(   r<   )r   r   r
   r
   r   r   R  s    zSvnWCCommandPath.lockc             C   s,   |  d }|dr(t|dd dS )z unset a previously set lock unlockzsvn:   N)r   r(   r   	Exception)r   r   r
   r
   r   r   Y  s    
zSvnWCCommandPath.unlockc             C   s   y|    W n   Y nX dS )z$ remove any locks from the resource N)r   )r   r
   r
   r   cleanup`  s    zSvnWCCommandPath.cleanupr   c             C   s   |rt dnd}|rd}nd}|r*d}nd}yd|||f }| |}W nB tjjjk
r   d|||f }| |}t| || }Y nX t| || }|S )z2 return (collective) Status object for this file. z1XXX cannot perform status() on external items yetrS   z--non-recursivez-uz$status -v --xml --no-ignore %s %s %szstatus -v --no-ignore %s %s %s)	r<   r   r%   r&   r'   ro   WCStatus
fromstringXMLWCStatus)r   Zupdatesr   Z	externalsri   r   
rootstatusr
   r
   r   statush  s(    

zSvnWCCommandPath.statusc             C   s*   g }|dk	r| d|  | d|}|S )zj return a diff of the current path against revision rev (defaulting
            to the last one).
        Nz-r %ddiff)r   r   )r   r   rb   r   r
   r
   r   r     s
    zSvnWCCommandPath.diffc             C   s   |  d}g }| }tj| j }x\tt||D ]J\}\}}t	
|}|s`td|f | \}	}
}|t|	|
|f q8W |S )z[ return a list of tuples of three elements:
            (revision, commiter, line)
        blamez:output line %r of svn blame does not match expected format)r   
splitlinesr%   rl   r   r   	readlines	enumeratezip	rex_blamer   r<   groupsr   int)r   r   resultZ
blamelinesZ	reallinesrZ   Z	blamelinelinemr   rY   _r
   r
   r   r     s    


zSvnWCCommandPath.blamez.*Committed revision (\d+)\.$rS   c             C   sl   d| ddf }|s|d7 }| |}ytj| = W n tk
rH   Y nX |rh| j|}t|dS dS )z/ commit with support for non-recursive commits zcommit -m "%s" --force-logr   z\"z -Nr7   N)	r1   r   r   r   KeyError_rex_commitr   r   r   )r   msgr   ri   r   r   r
   r
   r   commit  s    
zSvnWCCommandPath.commitc             G   sN   t jj }z2|d}|| | jd|dt|f|  W d|  X dS )z* set property name to value on this path. rd   propsetz--fileN)	r%   rl   r   Zmkdtempr)   r   r   r.   r   )r   rY   rd   rb   dr   r
   r
   r   r     s    

zSvnWCCommandPath.propsetc             C   s   |  d|}|dd S )z! get property name on this path. re   Nr   )r   )r   rY   rW   r
   r
   r   re     s    zSvnWCCommandPath.propgetc             C   s   |  d|}|dd S )z$ delete property name on this path. propdelNr   )r   )r   rY   rW   r
   r
   r   r     s    zSvnWCCommandPath.propdelc             C   sP   |r|  d}t| |S |  d}|d}dd |dd D }t| |S dS )z return a mapping of property names to property values.
If rec is True, then return a dictionary mapping sub-paths to such mappings.
zproplist -Rr   
c             S   s   g | ]}|  qS r
   )r(   )r^   r{   r
   r
   r   r`     s    z-SvnWCCommandPath.proplist.<locals>.<listcomp>r7   N)r   make_recursive_propdictr*   rz   )r   r   rW   linesr
   r
   r   r     s    



zSvnWCCommandPath.proplistc             C   s   |r|  d}n
|  d}|S )zK revert the local changes of this path. if rec is True, do so
recursively. z	revert -Rrevert)r   )r   r   r   r
   r
   r   r     s    
zSvnWCCommandPath.revertc             K   s*   |r| j jf |}n| j }| j|| jdS )a   create a modified version of this path. A 'rev' argument
            indicates a new revision.
            the following keyword arguments modify various path parts:

              http://host.com/repo/path/file.ext
              |-----------------------|          dirname
                                        |------| basename
                                        |--|     purebasename
                                            |--| ext
        )rD   )r   rQ   rL   rD   )r   rO   r   r
   r
   r   rQ     s    zSvnWCCommandPath.newc             O   s&   |s| S | j j||}| j|| jdS )z return a new Path (with the same revision) which is composed
            of the self Path followed by 'args' path components.
        )rD   )r   r)   rL   rD   )r   rb   r   r   r
   r
   r   r)     s    zSvnWCCommandPath.joinc             C   s  |ot j| }|sy| d}W nj tjjjk
r   t	 d }|j
ddkrhtj| |j
n |j
ddkrtj| |j
 Y nX | dks| ddkrtj| |t|}tjdkr|j| jkrtj| d	d
|j| jf  |t j| < |S )z9 return an Info structure with svn-provided information. r   r7   z$Path is not a working copy directoryr   zis not under version controlrS   znot a versioned resourcer    znot a versioned resource:z	 %s != %s)r   r   r   r   r%   r&   r'   ro   r/   r   r   r   rn   rr   r(   r   InfoSvnWCCommandr0   rl   r   )r   r   r   outputr   r
   r
   r   r     s*    


zSvnWCCommandPath.infoc             C   st   t |trt|}dd }g }xB| j|D ]2}| j|| jd}||r.|rV||r.|| q.W | 	|| |S )z return a sequence of Paths.

        listdir will return either a tuple or a list of paths
        depending on implementation choices.
        c             S   s
   | j dkS )Nz.svn)rE   )rl   r
   r
   r   notsvn$  s    z(SvnWCCommandPath.listdir.<locals>.notsvn)rD   )
r   r.   r   Z	FNMatcherr   rq   rL   rD   r   Z	_sortlist)r   Zfilsortr   pathsr   r   r
   r
   r   rq     s    

zSvnWCCommandPath.listdirrc             C   s   t | j|S )z, return an opened file with the given mode. )openr@   )r   r   r
   r
   r   r   /  s    zSvnWCCommandPath.openc             C   s   | j |S )N)r   rM   )r   rV   r
   r
   r   rM   3  s    zSvnWCCommandPath._getbyspecc               @   s   e Zd Zdd Zdd ZdS )zSvnWCCommandPath.Checkersc             C   s   || _ |j| _d S )N)	svnwcpathr   rl   )r   rl   r
   r
   r   r   7  s    z"SvnWCCommandPath.Checkers.__init__c          	   C   s   y| j  }W nr tjjtjjfk
r.   dS  tjjjk
r   t	
 d }|jddkrbdS |j ddkrzdS  Y nX dS d S )NFr7   zis not a working copyr   znot a versioned resourceT)r   r   r%   rn   rr   r   r&   r'   ro   r/   r   r   r   r   )r   sr   r
   r
   r   r   :  s    z#SvnWCCommandPath.Checkers.versionedN)r   r   r   r   r   r
   r
   r
   r   rt   6  s   rt   Fc             C   s"  |   st|dkrdp|}|dkr(dp*|}|dkrB|dkrBd}nd||f }|rVdpXd}t }|  }|d|||| jf  }tj|tjtjdd	}	|	 \}
}t	j
|
t }
t \}}y||
}W n |k
r   td
Y nX g }x0td|jjD ]}|j|jkr|t| qW |S )z return a list of LogEntry instances for this path.
rev_start is the starting revision (defaulting to the first one).
rev_end is the last revision (defaulting to HEAD).
if verbose is True, then the LogEntry instances also know which files changed.
Nr   r7   rS   z-r %s:%sz-vzsvn log --xml %s %s %s "%s"T)stdoutstderrshellzno such revision)r   r   r   r   r@   
subprocessPopenPIPEZcommunicater%   r   Z_totextr/   getdefaultencoding	importxmlparseStringr<   filter
firstChild
childNodesnodeTypeELEMENT_NODEr   LogEntry)r   Z	rev_startZrev_endverboseZrev_optZverbose_optZ
locale_envZauth_optri   popenr   r   minidom
ExpatErrorZtreer   logentryr
   r
   r   logI  s6    
zSvnWCCommandPath.logc             C   s
   |   jS )z2 Return the size of the file content of the Path. )r   rg   )r   r
   r
   r   rg   s  s    zSvnWCCommandPath.sizec             C   s
   |   jS )z0 Return the last modification time of the file. )r   rh   )r   r
   r
   r   rh   w  s    zSvnWCCommandPath.mtimec             C   s   t | j| j| jfS )N)rB   r@   rL   rD   )r   r
   r
   r   rC   {  s    zSvnWCCommandPath.__hash__)NN)N)NN)r   T)r   )r7   r7   )r   r   r   )N)rS   r7   )r   )r   )r7   )NN)r   )Nr7   F)?r   r   r   r   r   rI   rK   ru   r@   r   r\   rA   r   rj   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   recompileDOTALLr   r   r   re   r   r   r   rQ   r)   r   rq   r   rM   r%   rl   r   rt   r  rg   rh   rC   r
   r
   r
   r   r     sh   

!




&





		



*r   c               @   s@   e Zd ZdZdddZdddZedZdd	d
Z	e
e	Z	dS )r   )modifiedaddedconflict	unchangedexternaldeletedprop_modifiedunknownupdate_available
incompletekindmismatchignoredlockedreplacedNc             C   s8   || _ || _|| _|| _x| jD ]}t| |g  q W d S )N)r   r   modrevauthor	attrnamessetattr)r   r   r   r$  r%  rY   r
   r
   r   r     s    zWCStatus.__init__Tc             K   sX   i }x:| j D ]0}||ks || rxt| |D ]}d||< q,W qW | }|rT|  |S )Nr7   )r&  r   keysr   )r   r   rO   r   rY   rl   r   r
   r
   r   allpath  s    zWCStatus.allpathz$\s+(\d+|-)\s+(\S+)\s+(.+?)\s{2,}(.*)c          	   C   s  t ||||}d}x| dD ]}| s0q |dd |dd  }}	|\}
}}}}}}}|
dkr|ddd }|
dkr|j|dd}|j| q |
dkr|j|jj|dd|jd	}|j	| q |
d
kr |j|dd}|j
| q t j|	}|s|dkr0|	 }|j|dd}|j| q | ddkr\t|	dd  }q | ddkrrq td| n| \}}}}|j|dd}|
dkr|jddstd|j| n|
dks|dkr|j| n|
dkr|j| n|
dkr|j| nl|
dkr6|j| nT|
dkrN|j| n<|
dkrf|j| n$|
 s~|j| ntd|
 |dkr|j| |dks|dkr|j| |dkr|j| ||kr ||_ ||_!||_"|r ||_#q q W |S )z4 return a new WCStatus object from data 's'
        Nr      z?XIr7   ?)absX)rD   I*zagainst revision:r   r!   zstatus on externalzcould not parse line %rM)r8   z3didn't expect a directory with changed content hereA+Dr   ~!Rzreceived flag %rLK)$r   r*   r(   r)   r  r   rL   r   rD   r  r!  _rex_statusr   r  r   r   r   r<   r   r   r   r  r  r  r  r   r  r#  r  NotImplementedErrorr  r"  r   r$  r%  
update_rev)data
rootwcpathr   r$  r%  r   r;  r   r   restZc0Zc1Zc2Zc3Zc4Zc5Zx6Zc7fnr   r   r
   r
   r   r     s    










zWCStatus.fromstring)NNN)T)NNN)r   r   r   r&  r   r)  r  r  r9  r   staticmethodr
   r
   r
   r   r     s   
	


]r   c               @   s   e Zd ZdddZeeZdS )r   Nc             C   s  t ||||}d}t \}}y|| }	W n, |k
rV   t d }
tt|
Y nX |	d}|rv|d d|_	x|	dD ]x}|d}|dd	 }|d
}|dkr|j
|dd}|j| qn|dkr|j|jj
|dd|jd}|j| qnN|dkr0|j
|dd}|j| qn&|dkrV|j
|dd}|j| q|d}|dkst|dkrd}d}d}d}n|dkrn||dd	 }|r|d}d}|d}|rx|d	 jD ]}||j7 }qW d}x$|dd	 jD ]}||j7 }qW |j
|dd}|dks<|jdds<tdddddd ||}t||}|| |d!}|d"kr|j| ||kr||_||_||_||_|d#}|r|d	 }|d
}|d$kr|j| |d%}t|r|j | qW |S )&zL parse 'data' (XML string as outputted by svn st) into a status obj
        Nr7   Zagainstr   r   r   rl   z	wc-statusr   r   unversioned)r,  r  )rD   r!  r  r  none0r+  rS   r#  r   r%  dater  )r8   z2did't expect a directory with changed content herer  r  r  )normalrA  Z
conflictedrB  Zprops)rB  rE  zrepos-status)r  r  r   )!r   r  r  r/   r   r<   r.   ZgetElementsByTagNamegetAttributer;  r)   r  r   rL   r   rD   r  r!  r  r	  	nodeValuer   r   r   r   r  r   r$  r%  rD  r  r   r"  )r<  r=  r   r$  r%  r   r;  r  r  docr   ZurevelsZentryelrl   ZstatuselZ
itemstatusr   rD  ZcommitelZ
author_elsr5   ZitemattrnameattrZpropsstatusZ
rstatuselsZ	rstatuselZritemstatusZlockelsr
   r
   r   r     s    	




















zXMLWCStatus.fromstring)NNN)r   r   r   r   r@  r
   r
   r
   r   r     s   
ir   c               @   s   e Zd Zdd Zdd ZdS )r   c             C   s6  i }xL| dD ]>}| sq| dd\}}| dd}| }|||< qW y|d | _W n tk
r|   tdY nX |d d	krd
p|d | _yt|d | _	W n tk
r   d | _	Y nX t
j|d | _| j | _d|krt|d | _d|kr|d | _d|kr2t|d | _| jd | _d S )Nr   r!   r7   r   rS   r   zNot a versioned resourceZnodekindZ	directoryrk   r   rl   ZlastchangedrevZlastchangedauthorZlastchangeddatei@B )r*   r(   r   r1   r   r   r<   rm   r   r   r%   rl   r   rg   Zcreated_revZlast_authorparse_wcinfotimerh   r   )r   r   r   r   r   rd   r
   r
   r   r   j  s4    


zInfoSvnWCCommand.__init__c             C   s   | j |j kS )N)__dict__)r   r[   r
   r
   r   r\     s    zInfoSvnWCCommand.__eq__N)r   r   r   r   r\   r
   r
   r
   r   r   i  s   )r   c             C   s>   t d| }|std|  | \} }t| d}t|S )z# Returns seconds since epoch, UTC. z&(\d+-\d+-\d+ \d+:\d+:\d+) ([+-]\d+) .*ztimestring %r does not matchz%Y-%m-%d %H:%M:%S)r  r   r<   r   r   rv   calendarZtimegm)rw   r   Ztimezonerx   r
   r
   r   rJ    s    rJ  zProperties on '(.*)':c             C   s   dd | dD }i }x|r|d}||}|sBtd| | d }| j|dd}g }	x.|r|d dr|d }
|	|
 qbW |	st	d	t
||	||< qW |S )
z5 Return a dictionary of path->PropListDict mappings. c             S   s   g | ]}|r|qS r
   r
   )r^   r{   r
   r
   r   r`     s    z+make_recursive_propdict.<locals>.<listcomp>r   r   z could not parse propget-line: %rr7   )r,  z  zmust have found properties!)r*   popr   r<   r   r)   r   r(   r   r   rz   )Zwcrootr   Zrexr   Zpdictr   r   rl   r   Z	propnamesZpropnamer
   r
   r   r     s     

r   c             C   s2   | r| S ddl m} ddlm} | ||g | S )Nr   )r  )r  )Zxml.domr  Zxml.parsers.expatr  r   )r   r  r  r
   r
   r   r    s    r  c               @   s   e Zd Zdd Zdd ZdS )r  c             C   s   t |d| _xtd |jD ]}|j|jkr|jdkrD|jj	| _
q|jdkrh|jr`|jj	| _qd| _q|jdkr|jj	}t|| _q|jdkrg | _x0td |jD ] }|j|jkr| jt| qW qW d S )Nr   r%  r   rS   rD  r   )r   rF  r   r  r	  r
  r  ZnodeNamer  rG  r%  r   ry   rD  Zstrpathsr   Z	PathEntry)r   r  Zlpartrw   Zppartr
   r
   r   r     s"    



zLogEntry.__init__c             C   s   d| j | j| jf S )Nz#<Logentry rev=%d author=%s date=%s>)r   r%  rD  )r   r
   r
   r   r     s    zLogEntry.__repr__N)r   r   r   r   r   r
   r
   r
   r   r    s   r  )T)1r   r   r/   r   r  rL  r%   r  Zpy._pathr   r   r   r   Zrepositoriesr;   r0   r:   r,   r3   r6   r>   ZPathBaser?   ry   r|   rz   r   r*   r   rI   r   r   r  r.  r   r   r   r   rJ   r   r   r   r   r   r   rJ  r   r  r  r
   r
   r
   r   <module>   sT   (		(

	 5


	
   q~l-