3
_Af1                 @   s   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZmZ d dlZddddgZG d	d
 d
e
ZG dd deeZG dd deZdd Zdd Zdd ZdS )    )print_functionN)Coloring)CommandMirrorSafeCommandbranchdiffZgreplogc               @   s   e Zd Zdd ZdS )ForallColoringc             C   s"   t j| |d | jddd| _d S )NZforallprojectbold)attr)r   __init__printerr
   )selfconfig r   @/home/qytech/356xLinux510-101server/.repo/repo/subcmds/forall.pyr   '   s    zForallColoring.__init__N)__name__
__module____qualname__r   r   r   r   r   r	   &   s   r	   c               @   sL   e Zd ZdZdZdZdZdd Zdd Zd	d
 Z	dd Z
dd Zdd ZdS )ForallFz#Run a shell command in each projectz`
%prog [<project>...] -c <command> [<arg>...]
%prog -r str1 [str2] ... -c <command> [<arg>...]"
a	  
Executes the same shell command in each project.

The -r option allows running the command only on projects matching
regex or wildcard expression.

# Output Formatting

The -p option causes '%prog' to bind pipes to the command's stdin,
stdout and stderr streams, and pipe all output into a continuous
stream that is displayed in a single pager session.  Project headings
are inserted before the output of each command is displayed.  If the
command produces no output in a project, no heading is displayed.

The formatting convention used by -p is very suitable for some
types of searching, e.g. `repo forall -p -c git log -SFoo` will
print all commits that add or remove references to Foo.

The -v option causes '%prog' to display stderr messages if a
command produces output only on stderr.  Normally the -p option
causes command output to be suppressed until the command produces
at least one byte of output on stdout.

# Environment

pwd is the project's working directory.  If the current client is
a mirror client, then pwd is the Git repository.

REPO_PROJECT is set to the unique name of the project.

REPO_PATH is the path relative the the root of the client.

REPO_REMOTE is the name of the remote system from the manifest.

REPO_LREV is the name of the revision from the manifest, translated
to a local tracking branch.  If you need to pass the manifest
revision to a locally executed git command, use REPO_LREV.

REPO_RREV is the name of the revision from the manifest, exactly
as written in the manifest.

REPO_COUNT is the total number of projects being iterated.

REPO_I is the current (1-based) iteration count. Can be used in
conjunction with REPO_COUNT to add a simple progress indicator to your
command.

REPO__* are any extra environment variables, specified by the
"annotation" element under any project element.  This can be useful
for differentiating trees based on user-specific criteria, or simply
annotating tree details.

shell positional arguments ($1, $2, .., $#) are set to any arguments
following <command>.

Example: to list projects:

  %prog -c 'echo $REPO_PROJECT'

Notice that $REPO_PROJECT is quoted to ensure it is expanded in
the context of running <command> instead of in the calling shell.

Unless -p is used, stdin, stdout, stderr are inherited from the
terminal and are not redirected.

If -e is used, when a command exits unsuccessfully, '%prog' will abort
without iterating through the remaining projects.
c          	   C   s   dd }|j dddddd |j d	d
dddd |j ddddd |j ddddd|d |j dddddd |j dddd |jd}|j d d!dd"d |j d#d$d%dd&d |j d'd(d)d*d+d,d-d. d S )/Nc             S   s.   t |j| jt|j x|jr(|jd= qW d S )Nr   )setattrvaluesdestlistrargs)optionopt_strvalueparserr   r   r   cmdy   s    zForall._Options.<locals>.cmdz-rz--regexregex
store_truezJExecute the command only on projects matching regex or wildcard expression)r   actionhelpz-iz--inverse-regexinverse_regexzNExecute the command only on projects not matching regex or wildcard expressionz-gz--groupsgroupszBExecute the command only on projects matching the specified groups)r   r$   z-cz	--commandz"Command (and arguments) to executecommandcallback)r$   r   r#   r(   z-ez--abort-on-errorsabort_on_errorsz'Abort if a command exits unsuccessfullyz--ignore-missingz:Silently skip & do not exit non-zero due missing checkouts)r#   r$   ZOutputz-pproject_headerz"Show project headers before outputz-vz	--verboseverbosezShow command error messagesz-jz--jobsjobsstoreint   z,number of commands to execute simultaneously)r   r#   typedefaultr$   )
add_optionadd_option_group)r   pr    gr   r   r   _Optionsx   s<    
zForall._Optionsc             C   s   |j o|jdkS )Nr/   )r*   r,   )r   optr   r   r   	WantPager   s    zForall.WantPagerc          	   C   sJ   | j js|j }nd}|j|j|jj||jtdd |jD |j	|j
dS )z Serialize a project._GitGetByExec instance.

    project._GitGetByExec is not pickle-able. Instead of trying to pass it
    around between processes, make a dict ourselves containing only the
    attributes that we need.

    Nc             s   s   | ]}|j |jfV  qd S )N)namer   ).0ar   r   r   	<genexpr>   s    z+Forall._SerializeProject.<locals>.<genexpr>)r9   relpathremote_namelrevrrevannotationsgitdirworktree)manifestIsMirrorGetRevisionIdr9   r=   remoterevisionExprdictrA   rB   rC   )r   r
   r?   r   r   r   _SerializeProject   s    
zForall._SerializeProjectc             C   s   |j s| j  d S )N)r'   Usage)r   r7   argsr   r   r   ValidateOptions   s    zForall.ValidateOptionsc             C   s  |j d g}d}tjdj|d r(d}|r:|j|d  |j|j dd   |jr| r|d dkrx$|dd  D ]}|jdstP qtW d }|r|tkrG dd	 d	t	}|| j
jj|jr|j|j|d d
 | j
j}d}d}	tjj| j
jj|	}
tjj|
r| j
j|
 |jr"| j|}n(|jr:| j|dd}n| j||jd}tt|tjd< tj |j!t"}zyf| j
jj}|j#t$| j%||||||}|j&  x2|D ]*}|p|}|dkr|j'rt(dqW W n t)t*fk
r   t+d |j,  |pt-j.}Y nZ t(k
r` } z<t+dt/|j0|f t1j2d |j,  |pNt3|dd}W Y d d }~X nX W d |j  X |dkrt1j4| d S )Nr   Tz^[a-z0-9A-Z_/\.-]+$Fr/   git-c               @   s   e Zd Zdd ZdS )z Forall.Execute.<locals>.ColorCmdc             S   s   t j| || d S )N)r   r   )r   r   r    r   r   r   r      s    z)Forall.Execute.<locals>.ColorCmd.__init__N)r   r   r   r   r   r   r   r   ColorCmd   s   rP   z--colorzsmart_sync_override.xml)inverse)r&   Z
REPO_COUNTzAborting due to previous errorz"Interrupted - terminating the poolz*Got an error, terminating the pool: %s: %s)fileerrno)5r'   recompilematchappendextendr*   
startswith
_CAN_COLORr   rD   manifestProjectr   is_oninsertindexrE   ospathjoinrC   isfileOverrider!   FindProjectsr%   GetProjectsr&   strlenenvironmultiprocessingPoolr,   
InitWorkerimapDoWorkWrapperProjectArgscloser)   	ExceptionKeyboardInterruptWorkerKeyboardInterruptprint	terminaterS   ZEINTRr0   r   sysstderrgetattrexit)r   r7   rL   r    shellZcnrP   mirrorrcZsmart_sync_manifest_nameZsmart_sync_manifest_pathprojectspoolr   Z
results_itrer   r   r   Execute   sn    




(

zForall.Executec             c   s   xt |D ]\}}y| j|}	W n` tk
r` }
 z$td|jt|
j|
f tjd d S d }
~
X n" t	k
r   tdtjd d S X |||||||	gV  q
W d S )Nz(Project list error on project %s: %s: %s)rR   zProject list interrupted)
	enumeraterJ   rp   rs   r9   r0   r   ru   rv   rq   )r   r|   rz   r7   r    ry   r   cntr4   r
   r   r   r   r   rn   
  s    

zForall.ProjectArgsN)r   r   r   commonhelpSummary	helpUsagehelpDescriptionr6   r8   rJ   rM   r   rn   r   r   r   r   r   ,   s   D&Nr   c               @   s   e Zd ZdZdS )rr   z4 Keyboard interrupt exception for worker processes. N)r   r   r   __doc__r   r   r   r   rr     s   rr   c               C   s   t j t jt j d S )N)signalSIGINTSIG_IGNr   r   r   r   rk     s    rk   c             C   sF   | j  }yt|f|  S  tk
r@   td|d   t Y nX dS )z A wrapper around the DoWork() method.

  Catch the KeyboardInterrupt exceptions here and re-raise them as a different,
  ``Exception``-based exception to stop it flooding the console with stacktraces
  and making the parent hang indefinitely.

  z%s: Worker interruptedr9   N)popDoWorkrq   rs   rr   )rL   r
   r   r   r   rm   #  s    rm   c          	      s  t jj   fdd}|d| d  |d| d  |d| d  |d	| d
  |d| d  |dt|d  x&| d D ]}|d| | d |  qxW |r|d| d  | d }	n| d }	t jj|	s |jrdS |jr|js|j rt	d| d  t
jd dS |jrtj}
tj}tj}nd }
d }d }tj||	| |
||d}|jrt|}|jt
j d}d}|jj  tjj }|j|jt
jd |j|jt
jd  x|js|j }x|D ]}|j j }|s|j  |j| q|js|jdkr||7 }q|rx|rx|dks |j  |r0| d }n| d }|jd| |j  |j   |rtt
jj!| t
jj   d}d}|j"j!| |j"j   qW qW |j# }|S )Nc                s   |d krd}| | < d S )N r   )r9   val)envr   r   setenv6  s    zDoWork.<locals>.setenvZREPO_PROJECTr9   Z	REPO_PATHr=   ZREPO_REMOTEr>   Z	REPO_LREVr?   Z	REPO_RREVr@   ZREPO_Ir/   rA   zREPO__%sGIT_DIRrB   rC   r   zskipping %s/)rR   )cwdry   r   stdinstdoutrv   Tr   r   rv   zproject %s/F)$r_   rh   copyrf   r`   existsZignore_missingr*   r+   rs   ru   rv   
subprocessPIPEPopenr	   redirectr   r   ro   platform_utilsFileDescriptorStreamscreateaddis_doneselectreaddecoderemovestd_namenlr
   flushwriter   wait)r
   rz   r7   r    ry   r   r   r   r9   r   r   r   rv   r4   outemptyZerrbufs_inin_readysbufZproject_header_pathr~   r   )r   r   r   3  s    








r   )
__future__r   rS   ri   rT   r_   r   ru   r   colorr   r'   r   r   r   rZ   r	   r   rp   rr   rk   rm   r   r   r   r   r   <module>   s*    o