
    	^cA                       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Zddl	Z	ddl
Z
ddlmZmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z.m/Z/ ddl0m1Z1m2Z2m3Z3 d	d
l4m5Z5 dZ6 ej                    Z7e7j8        Z8e7j9        Z9e7j:        Z:e7j;        Z;e7j<        Z=e7>                    ddd           e7>                    ddd           e7>                    ddd           e7>                    ddd           e7>                    ddd           e7>                    ddd           e7>                    ddd	           e7>                    ddd           e7>                    ddd           e7>                    ddd           e7>                    ddd           ddddd d!dd"d#d#d$
Z?d%d&d% ed'          fgZ@e7A                    ed(          d)             ZBdd*ZCd+ ZDd, ZEd- ZFd. ZG eCd/g  ed0          d12          d3             ZHd4 ZI e	jJ        d5          ZK e	jJ        d6e	jL                  ZMd7 ZNd8 ZOd9 ZP G d: d;          ZQ G d< d=          ZRejS         G d> d?eT                      ZUejS         G d@ dA                      ZVejS         G dB dC                      ZWdD ZXdE ZYdF ZZdG Z[dH Z\dIdJdKdLZ]dM Z^dN Z_dO Z`dP ZadQ ZbdR Zc	 	 	 	 	 	 	 ddSZddT ZedU ZfdV Zg eCddWdXg  edY           edZ          fd%d[d1 ed\          fd%d]g  ed^          fd%d_g  ed`          fdadbd% edc          fd%dd edd          fd%ded edf          fg edg          e9jh        h          di             Zi e/jj        g dj          Zkdk Zlh dlZmdm ZndndodpdqdrdsdtdsduZodv Zpdw Zqdx Zrdy Zsdz Ztd{ Zud| Zvd} Zwd~ Zxd Zyd Zz eCdd%dd ed          fg ed          e9jh        d1          d             Z{ eCdd%dd ed          fg ed          e9jh        h          d             Z| eCdd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fd%dd ed          fdadbd% ed          fdWdXd% ed           edZ          fg ed          e9jh        d1          d             Z}e7;                    ddh          d             Z~e7;                    dh d          d             Z e5j        dd          d             ZdS )a  simple Phabricator integration (EXPERIMENTAL)

This extension provides a ``phabsend`` command which sends a stack of
changesets to Phabricator, and a ``phabread`` command which prints a stack of
revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
to update statuses in batch.

A "phabstatus" view for :hg:`show` is also provided; it displays status
information of Phabricator differentials associated with unfinished
changesets.

By default, Phabricator requires ``Test Plan`` which might prevent some
changeset from being sent. The requirement could be disabled by changing
``differential.require-test-plan-field`` config server side.

Config::

    [phabricator]
    # Phabricator URL
    url = https://phab.example.com/

    # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its
    # callsign is "FOO".
    callsign = FOO

    # curl command to use. If not set (default), use builtin HTTP library to
    # communicate. If set, use the specified curl command. This could be useful
    # if you need to specify advanced options that is not easily supported by
    # the internal library.
    curlcmd = curl --connect-timeout 2 --retry 3 --silent

    # retry failed command N time (default 0). Useful when using the extension
    # over flakly connection.
    #
    # We wait `retry.interval` between each retry, in seconds.
    # (default 1 second).
    retry = 3
    retry.interval = 10

    # the retry option can combine well with the http.timeout one.
    #
    # For example to give up on http request after 20 seconds:
    [http]
    timeout=20

    [auth]
    example.schemes = https
    example.prefix = phab.example.com

    # API token. Get it from https://$HOST/conduit/login/
    example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    N)binshort)_)getattr)attr)cmdutilcontextcopiesencodingerror	exthelpergraphmodhttpconnection	localrepo
logcmdutilmatchmdiffobsutilparserpatchphasespycompatrewriteutilscmutilsmartsettagstemplatefilterstemplateutilurlutil)procutil
stringutilurlutil   )shows   ships-with-hg-core   phabricator	   batchsize   default   callsign   curlcmd   debugF   repophid   retry   retry.interval   url   phabsend   confirm
   phabimport   secret   obsoletes   greens   magentas   bolds   magenta dims
   green bolds   yellows   red)
s   phabricator.action.createds   phabricator.action.skippeds   phabricator.action.updated   phabricator.drevs   phabricator.status.abandoneds   phabricator.status.accepteds   phabricator.status.closeds   phabricator.status.needsreviews    phabricator.status.needsrevisions!   phabricator.status.changesplanned    s   test-vcrs   Path to a vcr file. If nonexistent, will record a new vcr transcript, otherwise will mock all http requests using the specified vcr file. (ADVANCED)loadhgrcc                 2   d}i }	 t          j        |                    d                    }	t          j        d t          j        |	                    }d}nS# t          $ r; |                    t          d          |	                    d          z             Y nt          $ r Y nw xY wt          j                    }
d|v r|d         |
d<   d|v r|d         |
d	<   |
r*|                    |
|	                    d          
            | ||||g|R i |p|S )zBLoad ``.arcconfig`` content into a ui instance on repository open.Fs
   .arcconfigc                 X    t          | t                    rt          j        |           n| S N
isinstancestrr   
unitolocalxs    3/usr/lib/python3/dist-packages/hgext/phabricator.py<lambda>z_loadhgrc.<locals>.<lambda>   s%    
1c0B0BIh)!,,, r8   Ts   invalid JSON in %s
s   repository.callsign)r&   r+   s   phabricator.urir&   r1   )source)r   unifromlocalreadr   rapply
json_loads
ValueErrorwarnr   joinIOErrorr    sortdictapplyconfig)origuiwdirvfshgvfsrequirementsargsoptsresult	arcconfig	rawparamscfgs              rC   	_loadhgrcr\      sc    FI)',,}*E*EFF	OII	**
 
	
  J J J
)**W\\--H-HHIIIII    -//C**-67M-N)*Y&&(12D(E$%
 @
s7<<#>#>??? 	R%======Gs   AA AB(	B('B(c                 T    	 |t           z   d d d 	 	fd}|S )Nc                    | j         |j         k    s| j        |j        k    rdS t          j                            | j                  }t          j                            |j                  }|D ]}||vr dS ||         d         }|                    d          rS|                    d          r>t          j	        |          }t          j	        ||         d                   }||k    r dS ||         d         |k    r dS dS )NFr      {   }T)
urimethodr    urlreqparseqsbody
startswithendswithr   rJ   )r1r2r1paramsr2paramskeyvaluer1jsonr2jsons           rC   	hgmatcherzvcrcommand.<locals>.hgmatcher   s   6RVryBI555;&&rw//;&&rw// 	 	C(""uuSM!$E%% %..*>*> !,U33!,Xc]1-=>>V## 55 $#q!U**uu +tr8   c                 F    t          j        dd| j                  | _        | S )Ns   cli-[a-z0-9]+s   cli-hahayouwish)resubre   )requests    rC   sanitiserequestz#vcrcommand.<locals>.sanitiserequest  s&    v2GL
 
 r8   c                 ,    d| d         v r	| d         d= | S )Nz
set-cookieheaders )responses    rC   sanitiseresponsez$vcrcommand.<locals>.sanitiseresponse  s$    8I...#L1r8   c                       	fd}t          j        |d          } j        |_         j        |_         t	          
          |          S )Nc            
         |                     d          }|rt          j        |          }dd l}|                                5  dd l}dd lm} |                    d	
t          d|j
        ft          d|j        fg          }|                    d           |                    |dg          5   | i |cd d d            cd d d            S # 1 swxY w Y   	 d d d            n# 1 swxY w Y    | i |S )	Ntest_vcrr   jsonr   httpsconnection)
serializerbefore_record_requestbefore_record_responsecustom_patchesrp   )match_on)popr   fsdecodehgdemandimportdeactivatedvcr	vcr.stubsstubsVCRurlmodVCRHTTPConnectionVCRHTTPSConnectionregister_matcheruse_cassette)rV   kwargsr   cassetter   vcrmodr   fnrp   ru   rz   s          rC   innerz+vcrcommand.<locals>.decorate.<locals>.inner  s   **Z((C 3#,S11%%%%#//11 3 3((((------ **#).=/? !' 0 % 7 !' 1 % 8(	 %  C" ((i@@@))(k])KK 3 3!r426223 3 3 3 3 3 3-3 3 3 3 3 3 3 3,3 3 3 3 3 3 3 3 3-3 3 3 3 3 3 3 3 3 3 3 3 3 3 30 2t&v&&&s7   A.C,3C;C,C	C,C	C,,C03C0   )depthhelpcategoryoptionalrepo)r    checksignature__name____doc__command)r   r   cmd	fullflagsr   rp   namer   ru   rz   specs   `  rC   decoratezvcrcommand.<locals>.decorate  s    	' 	' 	' 	' 	' 	' 	' 	'@ !%q111{j
w%%
 
 
   	r8   )
_VCR_FLAGS)
r   flagsr   r   r   r   r   rp   ru   rz   s
   ` ``` @@@@rC   
vcrcommandr      s    
"I  &    
+ + + + + + + + + + + +Z Or8   c                     |                      dd          r1| j        }	 d| _         | j        |i | || _        dS # || _        w xY wdS )zwrite debug output for Phabricator if ``phabricator.debug`` is set

    Specifically, this avoids dumping Conduit and HTTP auth chatter that is
    printed with the --debug argument.
    r&   r-   TN)
configbool	debugflagwrite)rR   msgrW   flags       rC   _debugr   I  sl     
}}^X..  |	 BLBHc"T"""BLLL4BL   s	   < 	Ac                     t          j                    fd d|            t          j                                      S )a  like urlencode, but works with nested parameters.

    For example, if params is {'a': ['b', 'c'], 'd': {'e': 'f'}}, it will be
    flattened to {'a[0]': 'b', 'a[1]': 'c', 'd[e]': 'f'} and then passed to
    urlencode. Note: the encoding is consistent with PHP's http_build_query.
    c                 $   t          |t                    rddd|         }d }t          |t          d i                    t          |                    }||| <   d S  ||          D ]%\  }}| r d| |fz  |            ||           &d S )Ns   trues   false)TFc                 4    d t          |           D             S )Nc                 "    g | ]\  }}d |z  |fS )   %drx   ).0kvs      rC   
<listcomp>zFurlencodenested.<locals>.process.<locals>.<lambda>.<locals>.<listcomp>d  s$    DDDtq!UQYNDDDr8   )	enumerate)ls    rC   rD   z2urlencodenested.<locals>.process.<locals>.<lambda>d  s    DDy||DDD r8   c                 *    |                                  S r<   )itemsrA   s    rC   rD   z2urlencodenested.<locals>.process.<locals>.<lambda>e  s    qwwyy r8   s   %s[%s])r>   boollistdictgettype)prefixobjlisterr   r   r   
flatparamsprocesss         rC   r   z urlencodenested.<locals>.processa  s    c4   	8 2237CDDvt%8%89==d3iiHH=!$Jvc

 " "1 "GI3Q7777GAqMMMM	" "r8   r8   )r    rO   r#   rc   	urlencode)paramsr   r   s    @@rC   urlencodenestedr   X  sY     J" " " " " " GC>##J///r8   c                    |                      dd          }|s$t          j        t          d          dz            t	          j        | |t          j        |          j                  }d}|r2|\  }}| 	                    d|z             |
                    d          }|s%t          j        t          d          |fz            ||fS )	zreturn conduit url, token and make sure they exist

    Currently read from [auth] config section. In the future, it might
    make sense to read from .arcconfig and .arcrc as well.
    r&   r1   s   config %s.%s is requiredrE   Ns#   using auth.%s.* for authentication
s	   phabtokens)   Can't find conduit token associated to %s)configr   Abortr   httpconnectionmodreadauthforurir#   r   userdebugr   )rR   r   restokengroupauths         rC   readurltokenr   s  s     ))NF
+
+C 
k)**-EE
 
 	
 
*2sGK4D4D4I
J
JCE
 't
85@AAA&& 
k;<<vE
 
 	
 :r8   c                    t          |           \  }}t          j        d                    |d|g                                                    \  }}|                     d|t          j        |          fz             |                                }d|i|d<   t          j
        |          ddd}t          |          }|                     d	d
          }	|	rmt          j        d|	t          j        |          fz            \  }
}|
                    |           |
                                 |                                }nYt'          j        | |          }t*          j                            t          j        |          |          }|                     d	d          dz   }|                     t6          dd          }t9          |          D ]}	 t;          j        |                    ||                    5 }|                                }ddd           n# 1 swxY w Y    ns# t*          j         j!        $ r\}||dz
  k    r |                     d|dz   ||fz             |                     d	d          }tE          j#        |           Y d}~d}~ww xY w|                     d|z             t          j$        d t          j%        tM          j'        |                              }|(                    d          r4tS          d          |d         |d         fz  }tU          j+        |          |d         S )zEcall Conduit API, params is a dict. return json.loads result, or None   /s   apis   Conduit Call: %s %s
s   token   __conduit__s   jsonr$   )s   paramss   outputr   r&   r,   s   %s -d @- %s)datar/   s   https   timeout)timeoutNs'   Conduit Request failed (try %d/%d): %r
r0   s   Conduit Response: %s
c                 X    t          | t                    rt          j        |           n| S r<   r=   rA   s    rC   rD   zcallconduit.<locals>.<lambda>  %    Jq#,>,>E(%a(((A r8   s
   error_codes   Conduit Error (%s): %ss
   error_infos   result),r   r#   r   rM   authinfor   r   bytereprcopyr   r~   r   r   r!   popen2
shellquoter   closerH   r   openerr    rc   rt   strurl	configint
configwithfloatrange
contextlibclosingopenurlerrurlerrortimesleeprI   rJ   r   rG   r   r   r   r   )rR   r   r   hostr   r   r   rawdatar   curlcmdsinsoutre   	urlopenerrt   max_tryr   	try_countrsperrretry_intervalparsedr   s                          rC   callconduitr     sv   r""KD%K		4*> ? ?@@IIKKMCHH%h.?.G.G(HHIII[[]]F%F> #'// G
 7##Dii
33G +Ogx':3'?'?@@
 
	T 			$		yy{{M"h//	+%%hoc&:&:%FF,,~x881<--w
;;w 	+ 	+I+'NN7GN<<  &88::D& & & & & & & & & & & & & & & ;' 	+ 	+ 	+!++? 1}gs34  
 "$n>O!P!P
>********	+ HH&-..._EEH1$7788 F
 zz-   )**=!=!.
 
 k#)s=   )H+=HH+H"	"H+%H"	&H++J?AJJs   debugcallconduits   METHODT)r   c                 z   t          j        | j                                                  }t	          j        d t	          j        |                    }t	          j        d t          | ||                    }t          j	        |ddd          }| 
                    dt          j        |          z             dS )	zcall Conduit API

    Call parameters are read from stdin as a JSON blob. Result will be written
    to stdout as a JSON blob.
    c                 X    t          | t                    rt          j        |           n| S r<   r=   rA   s    rC   rD   z"debugcallconduit.<locals>.<lambda>  r   r8   c                 X    t          | t                    rt          j        |           n| S r<   )r>   bytesr   rG   rA   s    rC   rD   z"debugcallconduit.<locals>.<lambda>  s%    jE.B.BI('*** r8   Tr   ),z: )	sort_keysindent
separatorss   %s
N)r   rG   finrH   r   rI   rJ   r   r~   dumpsr   r@   )rR   repor   rZ   r   rX   ss          rC   debugcallconduitr    s     %bfkkmm44I_EEI&& F
 _IIBf%% F 	
6T!NNNAHHWx*1---.....r8   c                 N   | j                             dd          }|r|S | j                             dd          }|sdS t          | j         ddd|gii          }t          |d                   d	k    rdS |d         d	         d
         }| j                             dd|           |S )z.given callsign, return repository PHID or Noner&   r.   r+   Ns   diffusion.repository.search   constraintss	   callsigns   datar      phid)rR   r   r   len	setconfig)r  repophidcallsignquerys       rC   getrepophidr    s     w~~nk::H w~~nk::H t&	,
34 E
 5>atW~a )HGnk8<<<Or8   s   \AD([1-9][0-9]*)\Zs>   ^Differential Revision:\s*(?P<url>(?:.*)D(?P<id>[1-9][0-9]*))$c                    |                                  }|j        j        j        }i }t	          j                    }|D ]}||         }t          t          j        |j	        |g                    }|D ]{}	 ||	          rn|
                    |	          D ]U}
t                              |
          }|r7dt          |          t          |                    d                    f||<    nVy nd|t                               |                                          }|r5dt          |          t          |                    d                    f||<   |rd |                                D             }t)          |j        dd|i          }d |                                D ]3\  }\  }fd|                                D             }fd	|D             }|sR|sPd
z  }t/          j        | || j        dddd           |j                            t7          d          z             dx}}|rt9          |d           } |          }t;          |j        dt=          |          t?          j         d tC          |          D                       fz             tE          |          dk    r|d         }|r ||          sd}||f||<   5|S )a  find previous nodes that has been sent to Phabricator

    return {node: (oldnode, Differential diff, Differential Revision ID)}
    for node in nodelist with known previous sent versions, or associated
    Differential Revision IDs. ``oldnode`` and ``Differential diff`` could
    be ``None``.

    Examines commit messages like "Differential Revision:" to get the
    association information.

    If such commit message line is not found, examines all precursors and their
    tags. Tags with format like "D1234" are considered a match and the node
    with that tag, and the number after "D" (ex. 1234) will be returned.

    The ``old node``, if not None, is guaranteed to be the last diff of
    corresponding Differential Revision, and exist in the repo.
    r   r$   idc                     g | ]\  }}}|	S rx   rx   )r   forceprecsdrevs       rC   r   z%getoldnodedrevmap.<locals>.<listcomp>.  s    CCC,%CCCr8      differential.querydiffss   revisionIDsc                 :    fdt          |           D             S )Nc                     g | ]}|v |	S rx   rx   )r   nprecsets     rC   r   z7getoldnodedrevmap.<locals>.getnodes.<locals>.<listcomp>6  s    BBB!Q'\\A\\\r8   )getlocalcommits)dr  s    `rC   getnodesz#getoldnodedrevmap.<locals>.getnodes3  s(     CBBBq11BBBBr8   c                 F    g | ]}t          |d                    k    |S )s
   revisionIDint)r   r  r  s     rC   r   z%getoldnodedrevmap.<locals>.<listcomp>9  s7       Am4D0E0E0M0M0M0M0Mr8   c                 2    h | ]} |          D ]}|S rx   rx   )r   r  r  r   r  s      rC   	<setcomp>z$getoldnodedrevmap.<locals>.<setcomp>>  s2    HHHq88Aw3G3GHHaHHHHr8      D%dNTmessager   datelocals=   D%d: local tag removed - does not match Differential history
c                 ,    t          | d                   S )N   idr"  )r  s    rC   rD   z#getoldnodedrevmap.<locals>.<lambda>Z  s    C%MM r8   )rl   s   %s mapped to old nodes %s
c                 ,    g | ]}t          |          S rx   r   r   r  s     rC   r   z%getoldnodedrevmap.<locals>.<listcomp>b  s    *N*N*N588*N*N*Nr8   )#
unfiltered	changelogindexhas_noder    rO   r   r   allpredecessorsobsstorenodetags_differentialrevisiontagrer   setr#  r   _differentialrevisiondescresearchdescriptionvaluesr   rR   r   r   tagnullidrL   r   maxr   r   r"   pprintsortedr  )r  nodelistunfir3  rX   	toconfirmnodectx	precnodesr  r=  mdrevsalldiffsnewnoder  diffs	phprecsettagnameoldnodelastdiffoldnodesr  r   r  s                         @@@rC   getoldnodedrevmaprR    s   $ ??D~#,HFI J J4j0GGHH	 	J 	JAx{{ ==++  C288==A +,c)nnc!''!**oo*N	$  ,223??3D3DEEA J#$c)nnc!''$--6H6H"I	$  L8CC	0@0@0B0BCCCG/.%1H
 
	C 	C 	C
 09/@/@ A	8 A	8+G+eWd   #??,,  E
 IHHHHEHHHI    4-K     2  	    "&%Gh #u*A*ABBB#8Hg66G2g")*N*NVH=M=M*N*N*NOO  . x==A%%&qkG #88G#4#4 #"G&$7F7OOMr8   c                    i }|D ]}d||<   | |         }t                               |                                          }|r&t          |                    d                    ||<   c|                     |                                          D ]E}t                              |          }|r't          |                    d                    ||<    nF|S )z\Return a dict mapping each rev in `revs` to their Differential Revision
    ID or None.
    Nr  r$   )	r9  r:  r;  r#  r   r6  rE  r7  r   )r  revsrX   revrF  rH  r=  s          rC   
getdrevmaprV  ~  s     F  s3i'..s/@/@AA 	aggdmm,,F3K==,, 	 	C*0055A !!''!**oos Mr8   c                 H   t          j                    }t          j        |                                |                                                                 |                                d|          D ]\  }}|                    |           |                                S )z:plain-text diff without header (user, commit message, etc)NrW   )	r    stringior   diffuir  p1rE  r   getvalue)basectxrF  diffoptsoutputchunk_labels         rC   getdiffrb    s    ]__F

GJJLL%%''T    v 	U??r8   c                   .    e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
DiffChangeTyper$   r                     N)r   
__module____qualname__ADDCHANGEDELETE	MOVE_AWAY	COPY_AWAY	MOVE_HERE	COPY_HERE	MULTICOPYrx   r8   rC   rd  rd    s6        
CFFIIIIIIIr8   rd  c                       e Zd ZdZdZdZdS )DiffFileTyper$   r   re  N)r   rk  rl  TEXTIMAGEBINARYrx   r8   rC   rv  rv    s        DEFFFr8   rv  c                       e Zd ZdZ ej        d          Z ej        d          Z ej        d          Z ej        d          Z	 ej        d          Z
 ej        d          Z ej        d          ZdS )phabhunkzGRepresents a Differential hunk, which is owned by a Differential changer   r)    N)r   rk  rl  r   r   ib	oldOffset	oldLength	newOffset	newLengthcorpusaddLinesdelLinesrx   r8   rC   r{  r{    s        QQ"""I"""I"""I"""ITWR   Ftwq!!!Htwq!!!HHHr8   r{  c                   b   e Zd ZdZ ej        d          Z ej        d          Z ej         ej        e	                    Z
 ej         ej        e                    Z ej         ej        e                    Z ej         ej        e                    Z ej        ej                  Z ej        ej                  Z ej        d          Z ej        d          Z ej        d          Z ej         ej        e	                    Zd Zd Zd Zd ZdS )	
phabchangezRepresents a Differential change, owns Differential hunks and owned by a
    Differential diff.  Each one represents one file in a diff.
    Nr)   r   c                     t          | j                                                  D ]-}|                    dd          }| j        |         | j        |<   .d S )Ns   new:s   old:)r   metadatakeysreplace)selfrl   newkeys      rC   copynewmetadatatooldzphabchange.copynewmetadatatoold  sZ    **,,-- 	7 	7C[['22F$(M#$6DM&!!	7 	7r8   c                     || j         d<   d S Ns   unix:filemode)oldPropertiesr  rm   s     rC   
addoldmodezphabchange.addoldmode      /4+,,,r8   c                     || j         d<   d S r  )newPropertiesr  s     rC   
addnewmodezphabchange.addnewmode  r  r8   c                 (   t          |t                    st          j        d          | j                            t          j        t          j	        |                               | xj
        |j
        z  c_
        | xj        |j        z  c_        d S )Ns'   phabchange.addhunk only takes phabhunks)r>   r{  r   r   hunksappendr   byteskwargsr   asdictr  r  )r  hunks     rC   addhunkzphabchange.addhunk  s{    $)) 	J+HIII
(.t{4/@/@AABBB 	&&r8   )r   rk  rl  r   r   r}  currentPatholdPathFactoryr   	awayPathsr   r  r  r  rd  rn  r   rv  rw  fileType
commitHashr  r  r  r  r  r  r  rx   r8   rC   r  r    s         $'$'''Kdgd###GT 2 2333Itw|t|D11222HDGLDL$6$6777MDGLDL$6$6777M47>0111Dtw|0111H&&&Jtwq!!!Htwq!!!HDGLDL..///E7 7 7
5 5 55 5 5' ' ' ' 'r8   r  c                      e Zd ZdZ ej        d          Z ej        d          Z ej        d          Z ej        d          Z	 ej        d          Z
 ej        d          Z ej        d          Z ej        d	          Z ej        d
          Z ej        d
          Z ej         ej        e                    Z ej        d          Zd ZdS )phabdiffz]Represents a Differential diff, owns Differential changes.  Corresponds
    to a commit.
    r8   r)   r   s(   0000000000000000000000000000000000000000s   hgs   defaultNr2   s   nonec                     t          |t                    st          j        d          t	          j        t          j        |                    | j        |j	        <   d S )Ns)   phabdiff.addchange only takes phabchanges)
r>   r  r   r   r   r  r   r  changesr  )r  changes     rC   	addchangezphabdiff.addchange  sU    &*-- 	L+JKKK+3+?K,
 ,
V'(((r8   )r   rk  rl  r   r   r}  sourceMachine
sourcePathsourceControlBaseRevisionsourceControlPathsourceControlSystembranchbookmarkcreationMethod
lintStatus
unitStatusr  r   r  repositoryPHIDr  rx   r8   rC   r  r    s.        
 DGC(((M&&&J '	 : : :---!$'%000TWZ(((Ftwt$$$HTW[111N)))J)))Jdgldl400111GTWT***N
 
 
 
 
r8   r  c                 j   |                                 }t          j        |g          }t          j        dd          }t          t          j        ||                                |||                    \  }}}	}
|
D ]}|\  \  }}}}}d	                    |dd                   }t          |	          }|                    |           t          j        t          j        t          j        |                              \  }}}}}|                     t#          |||||||                     dS )z'populate the phabchange for a text fileT  gitr	   rX  r8   r$   N)r  r   exactr   r^  nextr   	diffhunksr[  rM   r   extenddiffstatsumdiffstatdatar    	iterlinesr  r{  )pchanger]  rF  fnamer  fmatcherr^  _pfctx_fctxheaderfhunksfhunkr~  r  r  r  linesr  shunk_mf_mtr  r  _hbs                           rC   maketextr    sD   88::D{E7##H~$666H$(gjjllCIII% %!FE66  
 
>C;4Iy)e%)$$VU,1,=t~e4455-
 -
)S(Hc 	 
	
 
	
 
	
 
	

 
r8   c                 ,   |                                  j        }t          |dd|i          }|                    t	          d          t	          d          t          |                    5 }|D ]}|                                 |d         rt          |d                   }t          |d                   }t          |d	||t          j	        | 
                                ||                   d
d           	 ddd           dS # 1 swxY w Y   dS )ztupload large binary files as separate chunks.
    Phab requests chunking over 8MiB, and splits into 4MiB chunks
    s   file.querychunks   filePHIDs   uploading file chunkss   chunks)unittotals   complete	   byteStarts   byteEnds   file.uploadchunks   base64)r  r  r  s   dataEncodingN)r  rR   r   makeprogressr   r  	incrementr#  base64	b64encoder   )fctxfphidrR   chunksprogressr`  bstartbends           rC   uploadchunksr  !  sj    
B0;2FGGF		
"##!I,,c&kk 
 
 
 	 	 	E   [! |,--FuZ())D#!&"(#-diikk&+.FGG%.	 	 	 	 		                 s   ,BD		DDc                    |                                  }|j        }|                                 }|                                 }t	          j        t          j        |                                           	                                          }|||d}t          |d|          }|d         }|d         r|                    t          d          t          |           z             |s;|t          j        |                                           d}	t          |d|	          }n6t!          | |           n%|                    dt          |           z             |s$t%          j        d	t          |           z            |S )
z"upload binary files to Phabricator)   names   contentLengths   contentHashs   file.allocater  s   uploads   uploading %s
)r  s   data_base64s   file.uploads   server already has %s
s   Upload of %s failed.)r  rR   pathsizer   bytestrhashlibsha256r   	hexdigestr   r   r   r   r  r  r  r   r   r   )
r  r  rR   r  r  fhashallocateparams	fileallocr  uploadparamss
             rC   
uploadfiler  <  sc   99;;D	BIIKKE99;;DW^DIIKK88BBDDEEE
  N
 B 0.AAIk"E ;
$%%d3444 	& & 0 = = L  NLAAEEu%%%%
+eDkk9::: Ak1E$KK?@@@Lr8   c                    |r|                     |          r|                                | j        d<   t          j        t          j        |                                                    \  }}|rt          j	        |          | j        d<   t          |          }|| j        d<   dS t          j        | _        |                                  dS )zadd the metadata for the previous version of a binary file to the
    phabchange for the new version

    ``oldfctx`` is the previous version of the file; ``fctx`` is the new
    version of the file, or None if the file is being removed.
    s   old:file:sizes   old:file:mime-types   old:binary-phidN)cmpr  r  	mimetypes
guess_typer   rG   r  r   r  r  rv  rw  r  r  )r  oldfctxr  	mimeguess_encr  s         rC   addoldbinaryr  a  s      '488G$$ '-4\\^^)*#.!',,..11
 
	4  	6>6F7 7G23 7##/4+,,, (,$$&&&&&r8   c                    t           j        | _        t          |          }|| j        d<   |                                | j        d<   t          j        t          j	        |
                                                    \  }}|rFt          j        |          }|| j        d<   |                    d          rt           j        | _        dS dS dS )z)populate the phabchange for a binary files   new:binary-phids   new:file:sizes   new:file:mime-types   image/N)rv  ry  r  r  r  r  r  r  r   rG   r  r   r  rf   rx  )r  r  r  r  r  s        rC   
makebinaryr  z  s    #*GtE+0G'()-G%&*8+@+M+MNNOIt 2$Y//	2;./	** 	2+1G	2 2	2 	2r8   s   120000s   100755s   100644)   l   xr8   c                    	 |                                                      d           dS # t          $ rR |                                 j                            t          d          |                                 z             Y dS w xY w)z[detect non-UTF-8 text files since Phabricator requires them to be marked
    as binary
    zutf-8Fs0   file %s detected as non-UTF-8, marked as binary
T)r   decodeUnicodeDecodeErrorr  rR   r   r   r  )r  s    rC   notutf8r    s    		7###u   		BCCiikk	
 	
 	
 tts   '+ ABBc                 t   |D ]}t          ||t          j                  }|                                |         }|                    t
          |                                                    |                                s!t          |          st          ||||           | 
                    |           dS )z:add removed files to the phabdiff. Shouldn't include moves)r  r  r   N)r  rd  ro  r[  r  gitmoder   isbinaryr  r  r  )pdiffr]  rF  removedr  r  r  s          rC   
addremovedr     s     	! 	!u>3H
 
 
 **,,u%77==??3444  "" 	3gg&6&6 	3WgsE222    	! 	!r8   c                 t   |D ]3}||         }|                                 |         }t          ||          }t          |                                         }t          |                                         }	||	k    r*|                    |	           |                    |           |                                s2t          |          s#|                                st          |          r"t          ||           t          |||           nt          ||||           |                     |           5dS )z"add modified files to the phabdiff)r  r  N)r[  r  r  r   r  r  r  r  r  r  r  r  )
r  r]  rF  modifiedr  r  r  r  filemodeoriginalmodes
             rC   addmodifiedr    s7    ! !5z**,,u%>>>4::<<(w}}/|##|,,,x((( MMOO		3t}}		3 !!		3 w			3 w%%%'40000WgsE222    +! !r8   c                    i }i }i }||k    r't          j        |                                |          }|D ]}||         }	d}
t          |          }t          |	                                         }|r|                    ||          }n0|}|	                                r|	                                d         }||k    }|rd|                                |         }
t          |
                                         }||_        ||v rJt          ||t          j
        |g          }|||<   |                    |           t          j        |_        n||v rIt          j        ||         _        ||         j                            |           t          j        |_        nX||vr!t          |t          j                  }|||<   n||         }|j                            |           t          j        |_        ||k    r*|                    |           |                    |           nC|                    t          |	                                                    t          j        |_        |	                                s4t/          |	          s%|
rG|
                                st/          |
          r$t1          ||	           |rt3          ||
|	           nt5          ||||           |                     |           |                                D ]\  }}|                     |           |                                D ]\  }}|                     |           dS )z>add file adds to the phabdiff, both new files and copies/movesN)r  r   )r  r  r   r  )r  r   )r
   
pathcopiesr[  r  r  r   r   renamedr  rd  rp  removerr  r   rt  r  r  rs  rq  r  r  rm  r  r  r  r  r  r  r   )r  r]  rF  addedr  copiedchangesmovedchangesr   r  r  r  r  r  originalfnamer  r  origpchange_pathcopiedchangemovedchanges                       rC   addaddedr    sq    MLD#~~ s33 @! @!5z///4::<<( 	2 HHUE22MM!M||~~ 2 $q 1=( #	.jjll=1G"7==??3L+GO''( -)'1$g	   /:]+}----7,..3A3K]+0]+5<<UCCC-7 55",$18P# # #K 4?M-00"/">K%,,U333-7<''""<000""8,,,wtzz||4555)-GL MMOO		3t}}		3 		3 %--//		3 4;73C3C		3
 w%%% 5Wgt444WgsE222    ,2244 & &|%%%%*0022 % %{$$$$% %r8   c           	         |                                 }t          |          }t          d|                                                                 z  d|                                z            }|                                                     |          \  }}}}}	}
}t          || |||           t          || ||           t          || ||           |r||_
        t          |j        dt          j        t          j        |                              }|sA| |k    rt#          d          | |fz  }nt#          d          |z  }t%          j        |          |S )zcreate a Differential Diffs   %s)r  r  s   differential.creatediffs   cannot create diff for %s::%ss   cannot create diff for %s)r  r  r  r[  hexr  statusr  r  r   r  r   rR   r   r  r   r  r   r   r   )r]  rF  r  r  r  r  r
  r  _d_u_i_cdiffr   s                 rC   
creatediffr    s[   88::D4  H"''**,,*:*:*<*<"<szz||#  E 07zz||/B/B3/G/G,HeWb"b" UGS%111wX...ugsG,,, ('"T[//00 D
  c>>455#FCC011C7Ck#Kr8   c           
         |                     d|                     d                    }| d         }| d         }|dt          j        |                                d|                                z  |                                |                                |                                                                d          d}t          |	                                j
        d	|           i }| D ]}t          j        |                                          t          j        |                                          t          |                                d                   |                                |                                                                g|                                d
||                                <   |dt          j        |          d}t          |	                                j
        d	|           dS )zwrite metadata to diff so patches could be applied losslessly

    ``ctxs`` is the list of commits that created the diff, in ascending order.
    The list is generally a single commit, but may be several when using
    ``phabsend --fold``.
    s   diffidr,  r      hg:metas   %d %d)   user   date   branch   node   parent)s   diff_idr  r  s   differential.setdiffproperty)   author   authorEmail   time   commit   parentsr!     local:commitsN)r   r   r~   r   r)  r  r  r[  r   r  rR   r"   personemailr#  )ctxsr  diffidr]  tipctxr   commitsrF  s           rC   writediffpropertiesr0  5  s    XXi%11F1gG"XF  %!FKKMM1!==??"::<<++-- 
 
 F !#BFKKKG 
 
!(44&,SXXZZ88A''wwyy(zz||
 
		 ! %g.. F
 !#BFKKKKKr8   c           
      <   | d         }| d         }	|                                 }
|r_t          j        dd          }|
                                }||         }||         }t	          |	||          t	          |||          k    }nd}g }|rIt          |	|          }|                    d|d         d           |r|                    d	|d           n|sJ |}t          | |           |r|                    d
|gd           |r||z  }t          j	                    }t          |           D ]\  }}|                                }t          |
j        dd|i          }dD ]}|d                             |          }|s |dk    r|                                ||<   >|dk    rd}d                    t#          d|                    |          |                                g                    ||<   |                                D ]\  }}|                    ||d           d|i}|||d<   t          |
j        d|          }|sNt'          |           dk    rt)          d          |z  }nt)          d          |	|fz  }t+          j        |          ||fS )a  create or update a Differential Revision

    If revid is None, create a new Differential Revision, otherwise update
    revid. If parentrevphid is not None, set it as a dependency.

    If there is a single commit for the new Differential Revision, ``ctxs`` will
    be a list of that single context.  Otherwise, it is a list that covers the
    range of changes for the differential, where ``ctxs[0]`` is the first change
    to include and ``ctxs[-1]`` is the last.

    If oldnode is not None, check if the patch content (without commit message
    and metadata) has changed before creating another diff.  For a Revision with
    a single commit, ``oldbasenode`` and ``oldnode`` have the same value.  For a
    Revision covering multiple commits, ``oldbasenode`` corresponds to
    ``ctxs[0]`` the previous time this Revision was posted, and ``oldnode``
    corresponds to ``ctxs[-1]``.

    If actions is not None, they will be appended to the transaction.
    r  r   Tr  r  s   updater  s   types   value   comments   parents.sets   differential.parsecommitmessages   corpus)   title   summary   testPlan   fieldsr4  r5     

N   transactions   objectIdentifier   differential.revision.editr$   s   cannot create revision for %ss!   cannot create revision for %s::%s)r  r   r^  r0  rb  r  r  r0  r    rO   r   r;  r   rR   r   rstriprM   filterr   r  r   r   r   )r,  revidparentrevphidoldbasenoderO  olddiffactionscommentrF  r]  r  r^  rC  oldctx
oldbasectxneednewdifftransactionsr  fieldsi_ctxdescinfor   r   r   revisionr   s                               rC   createdifferentialrevisionrN  b  s   : r(C1gG88::D 	>dE:::  g+&
gsH55:
 :
 
 L 
'3''i4=IIJJJ 	J* H HIII
 d###  
$@@	
 	
 	
    ]__FT?? P P4!!G7)T9J
 
 5 	P 	PAY##A&&A Avv HHJJq	h   VD6::a==!((**2M%N%NOOF1II!	P$  7 71a1556666|,F&+"#47$A6JJH t99>>455;CC899WcNJCk#T>r8   c                 8   d |D             }dd|ii}t          | d|          }|d         }d |D             }t          |          |z
  }|rDt          j        t	          d          d                    t          |                    z            d	 |D             S )
zconvert user names to PHIDsc                 6    g | ]}|                                 S rx   lower)r   r   s     rC   r   zuserphids.<locals>.<listcomp>  s     ,,,dTZZ\\,,,r8   r
  s	   usernamess   user.searchr  c                 N    h | ]"}|d          d                                          #S )r7  s   usernamerQ  r   entrys     rC   r%  zuserphids.<locals>.<setcomp>  s.    HHH%i -3355HHHr8   s   unknown username: %s    c                     g | ]
}|d          S )r  rx   rT  s     rC   r   zuserphids.<locals>.<listcomp>  s    ---uE'N---r8   )r   r8  r   r   r   rM   rA  )rR   namesr  rX   r   resolved
unresolveds          rC   	userphidsr[    s    ,,e,,,ElE23E^U33F '?DHH4HHHHUh&J 
k%&&6*3E3E)F)FF
 
 	
 .-----r8   c                 H   |                      t          d          t          d          t          d          d|         d|z            }|                      d|z  d          }t          j        | |d          }|                     t          d	          |||fz             d
S )zprint the ``action`` that occurred when posting ``ctx`` for review

    This is a utility function for the sending phase of ``phabsend``, which
    makes it easier to show a status for all local commits with `--fold``.
       created   skipped   updated)r]  r^  r_  s   phabricator.action.%sr&  r7   r2   s   %s - %s - %s
N)labelr   r   format_changeset_summaryr   )rR   rF  newrevidaction
actiondescdrevdescsummarys          rC   _print_phabsend_actionrg    s     ***	
 	
 		
 	!6) J xx)+>??H.r3DDGHHQ !!Xz7$CCDDDDDr8   c                     t           j        dt          j        d |D                       z             	 t	           fd|D             |           dS # t
          j        j        $ r!  j                            d|z             Y dS w xY w)zupdate the local commit list for the ``diff`` associated with ``drevid``

    This is a utility function for the amend phase of ``phabsend``, which
    converts failures to warning messages.
    s   new commits: %s
c                 ,    g | ]}t          |          S rx   r.  r/  s     rC   r   z*_amend_diff_properties.<locals>.<listcomp>  s    1M1M1Mq%((1M1M1Mr8   c                      g | ]
}|         S rx   rx   )r   rK  rC  s     rC   r   z*_amend_diff_properties.<locals>.<listcomp>
  s    CCCwT']CCCr8   s"   Failed to update metadata for D%d
N)	r   rR   r"   r@  r0  r    r   r   
warnnoi18n)rC  drevidnewnodesr  s   `   rC   _amend_diff_propertiesrn    s     z01M1MH1M1M1MNNN  
LCCCC(CCCTJJJJJ; L L L 	AFJKKKKKKLs   A 1B
	B
   r   revs   revisions to sends   REV   amends   update commit messages   reviewers   specify reviewers   blockers   specify blocking reviewers   mr3  s1   add a comment to Revisions with new/updated Diffss#   ask for confirmation before sending   folds%   combine the revisions into one reviews   REV [OPTIONS])r   c                   1 t          j        |          }t          |          |                    dg           z   }t	          j        |          }|                                 |s!t          j        t          d                    |                    d          rt          j                   fd|D             }t          d |D                       r!t          j        t          d                    fd}                    d|          }t          |          d	k    r ||d
                               d|          }t          |          d	k    r ||d           |                    d          }|rt          |          d	k    r!t          j        t          d                    |                    d          s!t          j        t          d                    d |D             }	t          d |	D                       d	k    r!t          j        t          d                    t          fd|D                       }
|                     dd          }|t#          |                    d                    z  }|r4t%          ||
          }|s!t          j        t          d                    g }|                    dg           }|                    dg           }g }|r(|                    t)          j        |                     |r7|                    t-          d t)          j        |                               |r|                    d|d           g }i }d}|D ]}|rE|                     d|                                |d                                         fz             n*|                     d|                                z             |
                    |                                d           \  }}}|||}}}|r2|
                    |d                                         d           \  }}}||                                k    s|                    d          r t7          |r|n|g|||||||                    d!                    \  }}|r|D ]}|||                                <   n|||                                <   t9          |d"         d#                   }|d"         d$         }|rd%}nd&}|st:                              |                                          } | r&t9          |                      d'                    |k    r2d(|z  }!tC          j"        |!|                                dddd)*           n(tG          j        d+|z            d,         d$         }|}d-}|                    |           |}|rL|D ]G}"|
                    |"                                d           d.         rd%}nd&}tI          | |"||           H ntI          | |||           |                    d          r%                                }#tM          | d/d0|i          }$'                                5  (                                5  )                    d          5  d1 *                    d2||          D             }%|#d3                                         }&i }'g }(|d,         1tW          |          D ]\  })}*|#|*         }+|s||)         11fd4|$D             d,         },tY          |,|+|          }-|+                                |-k    sQ|+-                                                                |'v s)|+.                                                                |'v r|+/                                t`          j1        k    r9| 2                    t          d5          tg          j4        |+          z             |'                    |+-                                                                |+-                                f          d,         |'                    |+.                                                                |+.                                f          d,         g}.tk          j6        |-|'          }-to          j8        |+|.|-|+9                                |+:                                |+;                                6          }/|/<                                }0|0g|'|+                                <   |r|(                    |0           St{          |#1|0g||+                                                    d(1z  }!|!!                                v r tC          j"        |!j>        dddd)*           |r'|(                    |+                                           |rx|(rv||+                                         }|r tU          |(          t          |          k    r&t          | d71z             t{          |#1|(|           n&t          | d81z             n|rt          | d9           |%D ]}+|'                    |+-                                                                |+-                                f          d,         |'                    |+.                                                                |+.                                f          d,         g}.to          j8        |+|.tk          j6        |+                                |'          |+9                                |+:                                |+;                                6          }/|/<                                }0|0|+                                k    r[|0g|'|+                                <   t          | d:t          |+                                          t          |0          fz             t          | d;t          |+                                          z             tg          jB        |'dd)<           |&|'v r!|#C                    |'|&         d,                    ddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   ddd           dS # 1 swxY w Y   dS dS )=a  upload changesets to Phabricator

    If there are multiple revisions specified, they will be send as a stack
    with a linear dependencies relationship using the order specified by the
    revset.

    For the first time uploading changesets, local tags will be created to
    maintain the association. After the first time, phabsend will check
    obsstore and tags information so it can figure out whether to update an
    existing Differential Revision, or create a new one.

    If --amend is set, update commit messages so they have the
    ``Differential Revision`` URL, remove related tags. This is similar to what
    arcanist will do, and is more desired in author-push workflows. Otherwise,
    use local tags to record the ``Differential Revision`` association.

    The --confirm option lets you confirm changesets before sending them. You
    can also add following to your configuration file to make it default
    behaviour::

        [phabsend]
        confirm = true

    By default, a separate review will be created for each commit that is
    selected, and will have the same parent/child relationship in Phabricator.
    If ``--fold`` is set, multiple commits are rolled up into a single review
    as if diffed from the parent of the first revision to the last.  The commit
    messages are concatenated in the summary field on Phabricator.

    phabsend will check obsstore and the above association to decide whether to
    update an existing Differential Revision, or create a new one.
    rp  s(   phabsend requires at least one changesetrq  c                      g | ]
}|         S rx   rx   )r   rU  r  s     rC   r   zphabsend.<locals>.<listcomp>O  s    &&&#DI&&&r8   c              3   B   K   | ]}|                                 |V  d S r<   )obsoleter   cs     rC   	<genexpr>zphabsend.<locals>.<genexpr>Q  s/      
+
+ajjll
+1
+
+
+
+
+
+r8   s,   obsolete commits cannot be posted for reviewc                     fd| D             }t          j        t          d          |t          j        |          fz  t          d                    )Nc                 D    g | ]}|                                          S rx   rE  r   rr  s     rC   r   z:phabsend.<locals>._fail_nonlinear_revs.<locals>.<listcomp>Y  s%    111qDGLLNN111r8   s)   cannot phabsend multiple %s revisions: %ss&   the revisions must form a linear chain)hint)r   r   r   r   nodesummaries)rT  revtypebadnodesr  s      rC   _fail_nonlinear_revsz&phabsend.<locals>._fail_nonlinear_revsX  sg    1111D111k:;;-dH==>?<==
 
 
 	
r8   s
   heads(%ld)r$   s   heads
   roots(%ld)s   rootru  s   cannot fold a single revisions   cannot fold with --no-amendc                 f    g | ].}t                               |                                          /S rx   )r9  r:  r;  )r   rF  s     rC   r   zphabsend.<locals>.<listcomp>|  s@     
 
 
 (..s/@/@AA
 
 
r8   c                 <    h | ]}||                     d           S )r   )r   )r   rH  s     rC   r%  zphabsend.<locals>.<setcomp>  s'    :::1::::r8   s0   cannot fold revisions with different DREV valuesc                 D    g | ]}|                                          S rx   r  r  s     rC   r   zphabsend.<locals>.<listcomp>  s%    %C%C%Cd1gllnn%C%C%Cr8   r2   r3   s   phabsend cancelledrr  rs  c                     d| z  S )Ns   blocking(%s)rx   )phids    rC   rD   zphabsend.<locals>.<lambda>  s    _t3 r8   s   reviewers.addr2  Ns   sending rev %d::%d
r  s   sending rev %d
NNNr3  s   objectr,  r  r_  r]  r  r&  Tr'  r   r   r^  r      differential.query   idsc                     g | ]}|S rx   rx   rz  s     rC   r   zphabsend.<locals>.<listcomp>  s(          r8   s4   (%ld::) - (%ld) - unstable() - obsolete() - public()   .c                 F    g | ]}t          |d                    k    |S )r,  r"  )r   r  rl  s     rC   r   zphabsend.<locals>.<listcomp>  s-    DDDaC%MMV,C,C,C,C,Cr8   s'   warning: not updating public commit %s
)parentstextr   r)  extras#   updating local commit list for D%d
s0   local commit list for D%d is already up-to-date
s   no newnodes to update
s   restabilizing %s as %s
s   not restabilizing unchanged %s
)fixphase)Dr   r  r   r   r   revrangesortr   r   r   r   checkunfinishedanyrT  r  rR  r   r   _confirmbeforesendr  r[  rR   mapr  r   rU  rE  rN  r#  r9  r:  r;  r   r   r=  	querydrevrg  r0  r   wlocklocktransactionr8  r   get_amended_descr[  p2phaser   publicrL   r   formatchangeidr   update_hash_refsr	   metadataonlyctxr   r)  r  commitrn  r>  r  r   r   cleanupnodes
setparents)2rR   r  rT  rW   r,  r  headsrootsfolddrevmatchersoldmapconfirm	confirmedrB  	reviewersblockersphidsdrevidsdiffmaplastrevphidrF  rO  rA  r>  r@  oldbasediffoldbaserevidrM  r  rb  
newrevphidrc  rH  rN  r{  rC  rI  restackwnodemappingrm  rI  rU  oldr  newdescr  newrK  rl  s2    `                                               @rC   phabsendr    s   h %%D::,,,DtT**DIIKKK Jk!GHHIIIxx &%%%&&&&&&&D

+
+d
+
+
+++ Nk!KLLMMM
 
 
 
 
 IImT**E
5zzA~~UG,,,IImT**E
5zzA~~UG,,,88GD t99>>+a @AABBB xx!! 	A+a >??@@@
 

 
 
 :::::;;a??+EFF  
 t%C%C%C%Cd%C%C%CDDFmmK44GtDHHZ(()))G 8&tT6::	 	8+a 566777Gb))Ixx
B''HE 4Ytw	22333 
33$'8,, 	
 	
 	
  E!1UCCDDDGG K K: K: 	6HH,		48<<>>/JJKKKKHH(377994555 #)**SXXZZ9K"L"L%18'5,[ 	5;ZZR!36 62Kl chhjj  DHHX$6$6 7'3%$$	 	NHd  + / /C*.GCHHJJ''/ '+

#8I.u566H!),W5J $##  /66s7H7HII 
C..(::$x/GH

 $!!"    #47EEM::1=gFJHFx     	 @ @::affhh(:;;A> ('FF'F&r1h????Er3&9999 xx Y3  B 57HIIZZ\\ V	3 V	3499;; V	3 V	3(8(8(E(E V	3 V	3 K   G JOO%%EGHQZF#D// F0 F033i ($QZFDDDD5DDDQG*4d;; OO%%00vvxx}}'11vvxx}}'11yy{{fm33IJJ%4S99:   !CFFHHMMOOcffhh[AA!DCFFHHMMOOcffhh[AA!DG *: G
 "1 '$ XXZZ XXZZ!iikk  C "jjllG+2)GCHHJJ' ! !000 *fwi1D  
 %voG$))++-- # K$(!%!%"&     0
 OOCHHJJ///  7 7sxxzz*  #h--?73K3K"K"K2FOPPP*44HHHHL !   
  7r5666
     KK#&&((==a@KK#&&((==a@ -#$5coo//  ))++
 
 
 **,, chhjj((+2)GCHHJJ'3 ,,eGnn=>    ;eCHHJJ>O>OO   
  wdKKKKq 1222mV	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3 V	3Y3 Y3s[   s%s;W#r*s*r..s1r.2s5ss	ss		ss s))r  s   User)r   s   Date)r!  s   Branch)r"  s   Node ID)r#  s   Parent c           
         t          | j                  \  }}| j        }|D ]}| |         }|                    |                                d          \  }}	}
|
r|                    d|
z  d          }n#|                    t          d          d          }|                    t          d          |t          j        ||d          fz             |	                    t          d          |z            rdS d	S )
Nr  r&  r7   s   NEWs   %s - %s
r2   s1   Send the above changes to %s (Y/n)?$$ &Yes $$ &NoFT)
r   rR   r   rE  r`  r   r   r   ra  promptchoice)r  rT  r  r   r   rR   rU  rF  rO  rA  rl  re  s               rC   r  r    s   dg&&JC	B 
 
3i#)::chhjj:L#M#M & 	@xx1DEEHHxx&		+>??H
lOO0S+FF	
 	
 	
 	
 
	
>??#E   u4r8   >      closed   accepted	   abandoned   needsreview   needsrevision   changesplannedc                 ^    | d                              dd                                          S )z7get normalized status name from a Differential Revision
   statusNamerV  r8   )r  rR  )r  s    rC   _getstatusnamer    s)    &&tS1177999r8   )r(   N)   groupr$      )NN)rj  N)	   ancestorsrj  NN)rg  NN)   and_rg  N)rf  NN)   addrf  N)rf  NN)   subrf  N)r   NNNN)r      symbolNNN)   (   :   &   +   -r  r     endc           
   #     K   t          |           }dd}t          |           }||k     rd                    t          j        fdt          j        ||d                                        }|rd||fV  |t          |          z  }n(| ||dz            dk    r| ||dz            d |fV  |dz  }||k     dd |fV  d S )	Ns   ():+-& r   r8   c                     | vS r<   rx   )chspecials    rC   rD   z_tokenize.<locals>.<lambda>  s    2W, r8   r  r$   rV  r  )
memoryviewr  rM   	itertools	takewhiler   iterbytestr)r  viewposlengthsymbolr  s        @rC   	_tokenizer    s     dDG
CYYF
,,,,,,h.B4:.N.N 
 

  	fc****3v;;CCC#'M"d**C#'M*D#66661HC ,, 4
r8   c                     t          j         t                                        t          |                     \  }}|t	          |           k    rt          j        d|          |S )Ns   invalid token)r   	_elementsparser  r  r   
ParseError)r  treer  s      rC   _parser    sS    i((..y??ID#
c$ii/555Kr8   c                     |                      d          r3| dd                                         rt          | dd                   S |                                 rt          |           S dS )z<str -> int or None, ex. 'D45' -> 45; '12' -> 12; 'x' -> None   Dr$   N)rf   isdigitr#  )r  s    rC   
_parsedrevr    so     6!"":#5#5#7#7 6!"":~~ 6{{ r8   c                    t                      }t                      }| d         }|dk    r-t          | d                   }|r|                    |           n|dk    rXt          | d                   \  }}|                    |           |                    |           |                    |           nI| dd         D ]>}t          |          \  }}|                    |           |                    |           ?||fS )z9return ({single-drev-id}, {ancestor-drev-id}) to prefetchr   r  r$   r  N)r8  r  add_prefetchdrevsupdate)r  rI  ancestordrevsopr  ats          rC   r  r    s   EEEEEM	aB	YtAw 	IIaLLL	|		d1g&&1QQQabb 	$ 	$A!!$$DAqLLOOO  ####-r8   c           
      &   	
 
 fdfd	i 
t          |          }t          |          \  }}                     dd          }t          |          }|D ]9}|                    t          t          d||z
            |dz                        :|r dt          |          i           t          t           	t          |                              t          |          z            	
fd
fd |          D             S )	a  return a list of "Differential Revision" dicts

    spec is a string using a simple query language, see docstring in phabread
    for details.

    A "Differential Revision dict" looks like:

        {
            "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
            "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
            "auxiliary": {
              "phabricator:depends-on": [
                "PHID-DREV-gbapp366kutjebt7agcd"
              ]
              "phabricator:projects": [],
            },
            "branch": "default",
            "ccs": [],
            "commits": [],
            "dateCreated": "1499181406",
            "dateModified": "1499182103",
            "diffs": [
              "3",
              "4",
            ],
            "hashes": [],
            "id": "2",
            "lineCount": "2",
            "phid": "PHID-DREV-672qvysjcczopag46qty",
            "properties": {},
            "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
            "reviewers": [],
            "sourcePath": null
            "status": "0",
            "statusName": "Needs Review",
            "summary": "",
            "testPlan": "",
            "title": "example",
            "uri": "https://phab.example.com/D2",
        }
    c                 T   |                      d          p|                      d          pdgd         }|v r|         S t          d|           }|D ]%}||d         <   |t          |d                   <   &|vr$t          j        t          d          | z            |         S )	zparams -> single drev or Noner     phidsNr   r  r  r,  s#   cannot get Differential Revision %r)r   r   r#  r   r   r   )r   rl   rI  r  
prefetchedrR   s       rC   fetchzquerydrev.<locals>.fetch>  s    zz&!!CVZZ%9%9CdVQG*c?"B 5v>> 	0 	0D(,JtG}%+/Js4;''((j  +899FB   #r8   c                     t                      }g }d | D             }|r|                                } 	|          }|d         |v r,|                    |d                    |                    t	          |d                              |                    di           }|                    dg           }|D ]}|                    d|gi           ||                                 t          j        |          S )z6given a top, get a stack from the bottom, [id] -> [id]c                     g | ]}d |giS )r  rx   )r   rI  s     rC   r   z/querydrev.<locals>.getstack.<locals>.<listcomp>R  s    3331&1#333r8   r,  s	   auxiliarys   phabricator:depends-onr  )	r8  r   r  r  r#  r   reverser   baseset)

topdrevidsvisitedrX   queuer   r  	auxiliarydependsr  r  s
            rC   getstackzquerydrev.<locals>.getstackN  s   %%33
333 
	1YY[[F5==DE{g%%KKU$$$MM#d5k**+++r22Imm$=rBBG 1 1h/0000  
	1 	'''r8   r&   r'   r$   r  c                 z     d         }|dk    rt           d                   }|rt          j        |g          S  d         t          v r# fdD             }t          j        |          S t	          j        t          d           d         z            |dv rRt                     dk    sJ  t          t          |            d                     d                             S |d	k    r  d                   S |d
k    r   d                             S t	          j
        d z            )Nr   r  r$   c                 R    g | ]#}t          |                   d          k    !|$S )r$   )r  )r   r  r  r  s     rC   r   z+querydrev.<locals>.walk.<locals>.<listcomp>z  s>       %jm44Q?? ???r8   s   unknown symbol: %s>   r  r  r  re  r   r  r  s   illegal tree: %r)r  r   r   _knownstatusnamesr   r   r   r  r   operatorProgrammingError)r  r  r  rI  r  r  valididswalks   `   rC   r  zquerydrev.<locals>.walks  sa   !W??d1g&&D 
F'///a---    %  
  '...k!$9":":T!W"DEEE,,,t99>>>>(78R((d1gT!WFFF8^^4Q== <8DDaMM***()<t)CDDDr8   c                      g | ]
}|         S rx   rx   )r   r  r  s     rC   r   zquerydrev.<locals>.<listcomp>  s    ...aJqM...r8   )	r  r  r   r8  r  r   r?  r   rA  )rR   r   r  rI  r  	batchsizetofetchr  r  r  r  r  r  s   `       @@@@@rC   r  r    so   \      ( ( ( ( (( J$<<D)$//E= ^\::I %jjG < <uSA	M22AE::;;;; 'vtG}}%&&&c((4#6#677883u::EFFHE E E E E E E E2 /...44::....r8   c           	          | d         }| d                                          }| d                                          }|rd|z  }d| d         z  }d                    t          d||||g                    S )	zget description (commit message) from "Differential Revision"

    This is similar to differential.getcommitmessage API. But we only care
    about limited fields: title, summary, test plan, and URL.
    r4  r5  r6  s   Test Plan:
%s   Differential Revision: %s   urir8  N)r<  rM   r=  )r  titlerf  testplanra   s        rC   getdescfromdrevr    s~     NE:%%''GK ''))H 0$x/
&f
5C<<teWh%DEEFFFr8   c                 B   |st          |           S d| d         z  }t                              |                                          }|s)d                    |                                |g          S t                              ||                                          S )a1  similar to ``getdescfromdrev``, but supports a folded series of commits

    This is used when determining if an individual commit needs to have its
    message amended after posting it for review.  The determination is made for
    each individual commit, even when they were folded into one review.
    r  r  r8  )r  r9  r:  r;  rM   rs   )r  rF  foldedra   rH  s        rC   r  r    s      %t$$$
&f
5C 	$**3??+<+<==A 6||S__..4555&**30A0ABBBr8   c                 &   |                      d          pi }|                     d          pi }t          |          dk    rd |                                D             S t          t	          |                                dd                    pdhS )zkget the set of local commits from a diff object

    See ``getdiffmeta()`` for an example diff object.
    
   propertiesr)  r$   c                 ,    h | ]}t          |          S rx   )r   rz  s     rC   r%  z"getlocalcommits.<locals>.<setcomp>  s    ///1A///r8   r"  r8   N)r   r  r  r   getdiffmeta)r  propsr/  s      rC   r  r    s    
 HH]##)rEii())/RG
7||a////// D!!%%gs3344<==r8   c                    |                      d          pi }|                     d          }|s|                     d          rt          |d                                                   d         }i }d|v rd|v rd|d         |d         fz  |d<   d	|v rd
t          |d	                   z  |d<   d|v r|d         |d<   |                     d|                     d                    }|r||d<   t	          |                     dd                    dk    r|d         d         |d<   ni }d|vrd| v rd| d         z  |d<   d|vr |                      d          r| d         |d<   d|vr |                      d          r| d         |d<   |S )a  get commit metadata (date, node, user, p1) from a diff object

    The metadata could be "hg:meta", sent by phabsend, like:

        "properties": {
          "hg:meta": {
            "branch": "default",
            "date": "1499571514 25200",
            "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
            "user": "Foo Bar <foo@example.com>",
            "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
          }
        }

    Or converted from "local:commits", sent by "arc", like:

        "properties": {
          "local:commits": {
            "98c08acae292b2faf60a279b4189beb6cff1414d": {
              "author": "Foo Bar",
              "authorEmail": "foo@example.com"
              "branch": "default",
              "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
              "local": "1000",
              "message": "...",
              "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
              "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
              "summary": "...",
              "tag": "",
              "time": 1499546314,
            }
          }
        }

    Note: metadata extracted from "local:commits" will lose time zone
    information.
    r  r  r)  r   r$  r%  s   %s <%s>r  r&  s   %d 0r   r!  r'  rp  r"  r(  rx   r$   r#  s   dateCreateds   %s 0s   sourceControlBaseRevision)r   rA  r<  r#  r  )r  r  metar  rE  s        rC   r  r    s   L HH]##)rE99Z  D 99%&& 	E"23::<<==a@FDF""~'?'? *9%>*. !W &   '#fWo*>*> >WF"""("3Y::iF););<<D % $W6::j"--..!33"("4Q"7YDd~55$~"66W)!4!4y/Y*F!G!G;<YKr8   c                     t          |          dk    rAfd}d                    t          j        ||                    }t	          | |          }|r|S t          j        t          d                    )zconvert user supplied DREVSPECs into "Differential Revision" dicts

    See ``hg help phabread`` for how to specify each DREVSPEC.
    r   c                     rd| z  } d| z  S )Ns   :(%s)s   (%s)rx   )r  stacks    rC   _formatspecz_getdrevs.<locals>._formatspec  s     !qLQ;r8   r  s   empty DREVSPEC set)r  rM   r   maplistr  r   r   r   )rR   r"  specsr#  r   rI  s    `    rC   	_getdrevsr&    s    
 5zzA~~	 	 	 	 	
 yy)+u==>>"d## 	L
+a-..
/
//r8   c                 N   t          d |D                       }t          | dd|i          }g }|D ]}|                     t          d          |d         z             t	          d |d         D                       }t          | dd	|i          }t          |          }	d
}
t          |d|z                     }t                                          D ]!}||v r|
dt          |         ||         fz  z  }
"d|
|	|fz  }|	                    |d         |f            ||           dS )a/  generate plain-text patch readable by 'hg import'

    write takes a list of (DREV, bytes), where DREV is the differential number
    (as bytes, without the "D" prefix) and the bytes are the text of a patch
    to be imported. drevs is what "querydrev" returns, results of
    "differential.query".
    c                 L    h | ]!}t          d  |d         D                       "S )c              3   4   K   | ]}t          |          V  d S r<   r"  r   r   s     rC   r|  z&readpatch.<locals>.<setcomp>.<genexpr>+  s(      99Q#a&&999999r8      diffs)r?  )r   r  s     rC   r%  zreadpatch.<locals>.<setcomp>+  s3    LLLdc99$x.99999LLLr8   r  r  s   reading D%s
r,  c              3   4   K   | ]}t          |          V  d S r<   r"  r*  s     rC   r|  zreadpatch.<locals>.<genexpr>4  s(      44SVV444444r8   r+  s   differential.getrawdiffs   diffIDs   # HG changeset patch
r   s   # %s %s
s   %s%s
%sN)
rA  r   noter   r?  r  r  _metanamemapr  r  )rR   rI  r   diffidsrL  patchesr  r-  re   rK  r  r  r   contents                 rC   	readpatchr2  "  sW    LLeLLLMMG68IJJEG  / /
"##d5k122244T(^4444429Iv;NOOt$$*
 5011""$$ 	D 	DADyy,,q/47)CCCt 44UW-.... 
E'NNNNNr8   s   phabread   stacks   read dependenciess   DREVSPEC... [OPTIONS]r   c                      t          j        |          }t           |                    d          |          } fd}t	           ||           dS )a  print patches from Phabricator suitable for importing

    DREVSPEC could be a Differential Revision identity, like ``D123``, or just
    the number ``123``. It could also have common operators like ``+``, ``-``,
    ``&``, ``(``, ``)`` for complex queries. Prefix ``:`` could be used to
    select a stack.  If multiple DREVSPEC values are given, the result is the
    union of each individually evaluated value.  No attempt is currently made
    to reorder the values to run from parent to child.

    ``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision``
    could be used to filter patches by status. For performance reason, they
    only represent a subset of non-status selections and cannot be used alone.

    For example, ``:D6+8-(2+D4)`` selects a stack up to D6, plus D8 and exclude
    D2 and D4. ``:D9 & needsreview`` selects "Needs Review" revisions in a
    stack up to D9.

    If --stack is given, follow dependencies information and read all patches.
    It is equivalent to the ``:`` operator.
    r3  c                 B    | D ]\  }}                     |           d S r<   )r   )r0  r  r1  rR   s      rC   _writezphabread.<locals>._writeg  s5    $ 	 	MD'HHW	 	r8   N)r   r  r&  r   r2  )rR   r  r%  rW   rI  r6  s   `     rC   phabreadr7  H  se    8 %%Db$((8,,e44E     b%     r8   s   import dependencies as wellc                 J    t          j                  dd<   dd<   dd<   dd<                        d	d
          rdd
<                        d	d          rdd<    fd}t                               d          |          }t          j        ||           dS )zimport patches from Phabricator for the specified Differential Revisions

    The patches are read and applied starting at the parent of the working
    directory.

    See ``hg help phabread`` for how to specify DREVSPEC.
    Ts   bypassr$   s   stripr8   s   prefixFr6   r4   r5   c                    	d                                           }	                                5  	                                5  	                    d          5  | D ]\  }}
                    t          d          |z             t          j        
t          j	        |                    5 }t          j        
	||g d           \  }}}|s$t          j        t          d          |z            
                    |dz              	|         g}d d d            n# 1 swxY w Y   	 d d d            n# 1 swxY w Y   d d d            n# 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nr4   s   applying patch from D%s
s   D%s: no diffs found   
)r  r  r  r  r  r   r   extractioBytesIOr   tryimportoner   r   r-  )r0  r  r  contents	patchdatar   rE  rejrW   r  rR   s           rC   r6  zphabimport.<locals>._write  sr   t*$$&&ZZ\\ 	+ 	+499;; 	+ 	+(8(8(G(G 	+ 	+") + +h		!899D@AAA]2rz(';';<< +	%,%9!& &NCs   L#k!,B*C*Cd*JKKKGGC%K(((#DzlG+ + + + + + + + + + + + + + ++	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+s   E)EAD:/A&D!D:!D%%D:(D%)D:.E:D>>ED>EE)E	E)E	E))E-0E-r3  N)r   r  r   r&  r   r2  rR   )rR   r  r%  rW   r6  rI  s   `` `  rC   
phabimportrB  n  s     %%D
 DO DNDOD	}}]I.. Y	}}]K00 ! [+ + + + + + +0 b$((8,,e44Edguf%%%%%r8   s
   phabupdate   accepts   accept revisions   rejects   reject revisions   request-reviews   request review on revisions   abandons   abandon revisions   reclaims   reclaim revisions   closes   close revisions   reopens   reopen revisions   plan-changess   plan changes for revisions   resigns#   resign as a reviewer from revisions
   commandeers   commandeer revisionss   comment on the last revisions   local revision to updates"   [DREVSPEC...| -r REV...] [OPTIONS]c                    t          j                  g d}fd|D             }t          |          dk    r7t          j        t          d          d                    |          z            g }|D ]}|                    |dd                               d          }|r|s!t          j	        t          d	                    |r!t          j	        t          d
                    t          |t          j        ||g                    }	g }g }
|	                                D ];\  }}||
                    ||                    #|                    d|z             <|
r7t          j	        t          d          t          j        ||
          z            t!          |                     d          |          }t#          |          D ]l\  }}|dz   t          |          k    r3                    d          r|                    dd         d           |r|d         |d}t%          | d|           mdS )zrupdate Differential Revision in batch

    DREVSPEC selects revisions. See :hg:`help phabread` for its usage.
    )
rF  rC  rH  rL  rJ  rG  rD  rI  rE  rK  c                 f    g | ]-}                     |                    d d                    +|.S )r     _)r   r  )r   r  rW   s     rC   r   zphabupdate.<locals>.<listcomp>  s8    HHH141F1F(G(GHQHHHr8   r$   s   %s cannot be used togethers   , Tr2  rp  s   --rev requires a repositorys&   cannot specify both DREVSPEC and --revNr&  s-   selected revisions without a Differential: %sr3  r3  r  )r:  r9  r;  )r   r  r  r   r   r   rM   r  r   
InputErrorrV  r   r  r   r   r  r&  r   r   )rR   r  r%  rW   rG  r   rB  frT  drevmapunknownr  r  rI  rI  r  r   s      `             rC   
phabupdaterT    s   2 %%D  L IHHHHHHE
5zzA~~k!9::UZZ=N=NNOOOG 5 5d33444488FD  	F"1%C#D#DEEE 	Q"1%N#O#OPPPT:#6tdV#D#DEEMMOO 	) 	)DAqytAw''''VaZ(((( 	"BCC'g667  
 b$((8,,e44EU## C C4q5CJJ488J#7#7NNZ4
;KLLMMM 	C%)']!( F 96BBBC Cr8   s
   phabreview   ctx)requiresc                 ~    | j         |d          }t                              |                                          }|r@t	          j        |                    d          d|                    d          z  d          S |                                                    |	                                          }|D ]}t                              |          re|                                j                            dd          }|                    d          s|dz  }||z  }t	          j        ||d          c S d	S )
ze:phabreview: Object describing the review for this changeset.
    Has attributes `url` and `id`.
    rU  r   s   D%sr  )r1   r,  r&   r1   r   N)resourcer9  r:  r;  r   
hybriddictr   r  r6  rE  r7  r   rR   r   rg   )r	   r  rF  rH  r   r  r   s          rC   template_reviewrZ    sE   
 '
7F
+
+C#**3??+<+<==A &- 
 
 	
 xxzz""388::.. 	 	A)//22 hhjjm**>6BB||D))  4KCq#. #       4r8   s
   phabstatus>      uirU     repoc                     | j         |d          } | j         |d          } | j         |d          }|                                }	 t          ||g          |         }n# t          $ r Y dS w xY wt	          |dd|gi          }|D ]@}t          |d                   |k    r%t          j        |d         |d	         d
          c S AdS )z8:phabstatus: String. Status of Phabricator differential.rU  r\  r[  Nr  r  r,  r  r  )r1   s   status)rX  rU  rV  KeyErrorr   r#  r   rY  )	r	   r  rF  r  rR   rU  rl  rI  r  s	            rC   template_statusr_  	  s    '
7F
+
+C7GW--D		'5	)	)B
''))CD3%((-   tt1FVH3EFFE  tE{v%%* L#M2      & 4s   	A! !
A/.A/s   work)	csettopicc           	          |                     d          }t          ||          }g t                      i }}}|                                D ]g\  }}	|	K|                    |	           |                    |	t                                                    |           R|                    |           ht           ddt          |          i          }
i |
D ]%}|t          |d                            D ]}||<   & fd}|t          j        |          z  }t          j        ||          }                     ddd	           ||_        t!          j        ||          }t%          j         |||t          j        d
|i           dS )z Phabricator differiential statuszsort(_underway(), topo)Nr  r  r,  c                     |                                           }                    d|z  dt          |          z            }                    d|d         |fz             d S )Ns   %(statusName)ss   phabricator.status.%ss   
%s %s
r  )rU  r`  r  r   )rF  r  r  
drevsbyrevrR   s      rC   
phabstatusz&phabstatusshowview.<locals>.phabstatusF	  sh    #''))$$$~d';';;
 
 	fv 6677777r8   s   experimentals   graphshortenTs   nodelen)r  )rT  rV  r8  r   r  
setdefaultr  r   r   r#  r   r   r   	dagwalkerr  _exthookr%   longestshortestr   displaygraph
asciiedges)rR   r  	displayerrT  rR  unknownrevsr  revsbydrevidrU  rl  rI  r  rd  revdagnodelenrc  s   `              @rC   phabstatusshowviewrp  3	  s    99.//Dt$$G)+SUUB,K}} $ $VKK##FCEE2266s;;;;s####1FDMM3JKKEJ # #DK 0 01 	# 	#C"JsOO	#8 8 8 8 8 8 	H[)))Dd++FLL/4888#I"4..G
7#     r8   )NF)NNNNNNN)r   r  r   r  r<  r  r~   r  r
  rr   r   mercurial.noder   r   mercurial.i18nr   mercurial.pycompatr   mercurial.thirdpartyr   	mercurialr   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   r    mercurial.utilsr!   r"   r#   r|  r%   
testedwithehcmdtabler   configtabletemplatekeywordfinaluisetupuisetup
configitem
colortabler   wrapfunctionr\   r   r   r   r   r   r  r  compiler7  Mr9  rR  rV  rb  rd  rv  r  r   r{  r  r  r  r  r  r  r  r  r  r   r  r  r  r0  rN  r[  rg  rn  CATEGORY_IMPORT_EXPORTr  rO   r.  r  r	  r  r  r  r  r  r  r  r  r  r  r  r&  r2  r7  rB  rT  rZ  r_  showviewrp  rx   r8   rC   <module>r     s  3 3l       				           				  % % % % % % % %       & & & & & & % % % % % %                                                     6         
       #
Y;
*n$
/     
     
               
     
     
 
    
     
     
      $,#-#- %3$1"*'0)/*0 
 			
 	
		
 J''! ! ('!HN N N Nb     0 0 06  <9 9 9x QQy\\EEE/ / FE/,  * (RZ(>?? (bjF  
| | |~  .                 
" 
" 
" 
" 
"t 
" 
" 
" %' %' %' %' %' %' %' %'P 
 
 
 
 
 
 
 
6
 
 
<  6" " "J' ' '22 2 2 ))
<
<  ! ! !! ! !4P% P% P%f  >*L *L *L^ u u u up. . ."E E E&L L L& 	vr11122AAfII>	haa 9::;	k2qq!5667	j"aa =>>?ABCC		
 
j$"H I IJ	guaa HIIJ A/#  &h3 h3' &h3Z t}     6   : : : 6
2
-
,
,
%/'
 
	  *         ,|/ |/ |/~G G GC C C6> > >B B BJ0 0 0*# # #L 	8UAA23345A/  ! ! !> 	8UAA<==>?A/	  4& 4& 4&n 	i"5 6 67	i"5 6 67	*H(I(IJ	j%#7!8!89	j%#7!8!89	hqq!3445	i"5 6 67	ouaa(E&F&FG	i"H I IJ	mUAA&=$>$>?	z3"A B BC	vsAA9::AAfIIF A+,,/%  (9C 9C) (9Cx MVH55  65> M,D,D,DEE  FE. }000' ' 10' ' 'r8   