
                         `    d Z ddlZddlZddlZd Zd Zd
dZ G d de      Z G d d	e	      Z
y)zSafe access to git files.    Nc                 N    	 t        j                  |        y# t        $ r Y yw xY w)z1Ensure a directory exists, creating if necessary.N)osmakedirsFileExistsError)dirnames    lib/third_party/dulwich/file.pyensure_dir_existsr	      s%    
G s    	$$c                     t         j                  j                  |      s	 t        j                  | |       yddl}	 |j                  d| d      \  }}t        j                  |       t        j                  |       	 t        j                  ||       	 t        j                  | |       t        j                  |       y# t        $ r  w xY w# t        $ r  w xY w# t        $ r  w xY w# t        $ r t        j                  ||        w xY w)zBRename file with temporary backup file to rollback if rename failsNr   z.tmp.)prefixdir)	r   pathexistsrenameOSErrortempfilemkstempcloseremove)oldnamenewnamer   fdtmpfiles        r   _fancy_renamer   $   s    77>>'"	IIgw' 	  ((S(IW

		'

		'7#
		'7# IIg3  		   	    
		'7#s/   C AC ?C C, CCC),!Dc                     d|v rt        d      d|v rt        d      d|vrt        d      d|v rt        | ||      S t        j                  | ||      S )a  Create a file object that obeys the git file locking protocol.

    Returns: a builtin file object or a _GitFile object

    Note: See _GitFile for a description of the file locking protocol.

    Only read-only and write-only (binary) modes are supported; r+, w+, and a
    are not.  To read and write from the same file, you can take advantage of
    the fact that opening a file for write does not actually open the file you
    request.
    az'append mode not supported for Git files+z+read/write mode not supported for Git filesbz%text mode not supported for Git filesw)IOError_GitFileioopen)filenamemodebufsizes      r   GitFiler'   E   sf     d{?@@
d{CDD
$=>>
d{$00wwxw//    c                   "     e Zd ZdZ fdZ xZS )
FileLockedzFile is already locked.c                 J    || _         || _        t        t        |   ||       y N)r$   lockfilenamesuperr*   __init__)selfr$   r-   	__class__s      r   r/   zFileLocked.__init__`   s#     (j$(<@r(   )__name__
__module____qualname____doc__r/   __classcell__)r1   s   @r   r*   r*   ]   s    !A Ar(   r*   c                   L    e Zd ZdZ eg d      ZdZd Zd Zd Z	d Z
d Zd	 Zy
)r!   ap  File that follows the git locking protocol for writes.

    All writes to a file foo will be written into foo.lock in the same
    directory, and the lockfile will be renamed to overwrite the original file
    on close.

    Note: You *must* call close() or abort() on a _GitFile for the lock to be
        released. Typically this will happen in a finally block.
    )closedencodingerrorsr%   namenewlines	softspace)__iter__flushfilenoisattyreadreadline	readlinesseektelltruncatewrite
writelinesc           	      N   || _         t        | j                   t              r| j                   dz   | _        n| j                   dz   | _        	 t	        j
                  | j                  t        j                  t        j                  z  t        j                  z  t        t        dd      z        }t	        j                  |||      | _        d| _        | j                  D ]#  }t!        | |t        | j                  |             % y # t        $ r t        || j                        w xY w)Ns   .lockz.lockO_BINARYr   F)	_filename
isinstancebytes_lockfilenamer   r#   O_RDWRO_CREATO_EXCLgetattrr   r*   fdopen_file_closedPROXY_METHODSsetattr)r0   r$   r%   r&   r   methods         r   r/   z_GitFile.__init__   s    !dnne,!%(!:D!%'!9D	;""		BJJ&2WRQ5OOB YYr41
((FD&'$**f"=> )  	;Xt'9'9::	;s   A"D  D$c                     | j                   ry| j                  j                          	 t        j                  | j
                         d| _         y# t        $ r
 d| _         Y yw xY w)zClose and discard the lockfile without overwriting the target.

        If the file is already closed, this is a no-op.
        NT)rV   rU   r   r   r   rO   FileNotFoundErrorr0   s    r   abortz_GitFile.abort   sR    
 <<

	 IId(()DL  	 DL	 s   &A A#"A#c                 ,   | j                   ryt        j                  | j                  j	                                | j                  j                          	 t        t        dd      +t        j                  | j                  | j                         n^t        j                  dk7  r+t        j                  | j                  | j                         n t        | j                  | j                         | j                          y# | j                          w xY w)a6  Close this file, saving the lockfile over the original.

        Note: If this method fails, it will attempt to delete the lockfile.
            However, it is not guaranteed to do so (e.g. if a filesystem
            becomes suddenly read-only), which will prevent future writes to
            this file until the lockfile is removed manually.
        Raises:
          OSError: if the original file could not be overwritten. The
            lock file is still closed, so further attempts to write to the same
            file object will raise ValueError.
        Nreplacewin32)rV   r   fsyncrU   r@   r   rS   r_   rO   rL   sysplatformr   r   r]   r\   s    r   r   z_GitFile.close   s     <<
""$%

	r9d+7

4--t~~><<7*IId00$..A "$"4"4dnnEJJLDJJLs   BD Dc                     | S r,    r\   s    r   	__enter__z_GitFile.__enter__   s    r(   c                 $    | j                          y r,   )r   )r0   exc_typeexc_valexc_tbs       r   __exit__z_GitFile.__exit__   s    

r(   c                 `    || j                   v rt        | j                  |      S t        |      )z,Proxy property calls to the underlying file.)PROXY_PROPERTIESrS   rU   AttributeError)r0   r;   s     r   __getattr__z_GitFile.__getattr__   s,    4(((4::t,,T""r(   N)r2   r3   r4   r5   setrm   rW   r/   r]   r   rf   rk   ro   re   r(   r   r!   r!   f   s>     	

M?& :#r(   r!   )rb)r5   r"   r   rb   r	   r   r'   	Exceptionr*   objectr!   re   r(   r   <module>ru      s?   *   	 	 
B00A An#v n#r(   