Add option to check status of projects in parallel.

Change-Id: I6ac653f88573def8bb3d96031d3570ff966251ad
This commit is contained in:
Terence Haddock 2011-03-31 12:33:34 +02:00 committed by Shawn O. Pearce
parent 723c5dc3d6
commit 4655e81a75
2 changed files with 70 additions and 10 deletions

View File

@ -650,13 +650,18 @@ class Project(object):
return False return False
def PrintWorkTreeStatus(self): def PrintWorkTreeStatus(self, output_redir=None):
"""Prints the status of the repository to stdout. """Prints the status of the repository to stdout.
Args:
output: If specified, redirect the output to this object.
""" """
if not os.path.isdir(self.worktree): if not os.path.isdir(self.worktree):
print '' if output_redir == None:
print 'project %s/' % self.relpath output_redir = sys.stdout
print ' missing (run "repo sync")' print >>output_redir, ''
print >>output_redir, 'project %s/' % self.relpath
print >>output_redir, ' missing (run "repo sync")'
return return
self.work_git.update_index('-q', self.work_git.update_index('-q',
@ -671,6 +676,8 @@ class Project(object):
return 'CLEAN' return 'CLEAN'
out = StatusColoring(self.config) out = StatusColoring(self.config)
if not output_redir == None:
out.redirect(output_redir)
out.project('project %-40s', self.relpath + '/') out.project('project %-40s', self.relpath + '/')
branch = self.CurrentBranch branch = self.CurrentBranch
@ -720,6 +727,7 @@ class Project(object):
else: else:
out.write('%s', line) out.write('%s', line)
out.nl() out.nl()
return 'DIRTY' return 'DIRTY'
def PrintWorkTreeDiff(self): def PrintWorkTreeDiff(self):

View File

@ -15,6 +15,15 @@
from command import PagedCommand from command import PagedCommand
try:
import threading as _threading
except ImportError:
import dummy_threading as _threading
import itertools
import sys
import StringIO
class Status(PagedCommand): class Status(PagedCommand):
common = True common = True
helpSummary = "Show the working tree status" helpSummary = "Show the working tree status"
@ -27,6 +36,9 @@ and the most recent commit on this branch (HEAD), in each project
specified. A summary is displayed, one line per file where there specified. A summary is displayed, one line per file where there
is a difference between these three states. is a difference between these three states.
The -j/--jobs option can be used to run multiple status queries
in parallel.
Status Display Status Display
-------------- --------------
@ -60,9 +72,34 @@ the following meanings:
""" """
def _Options(self, p):
p.add_option('-j', '--jobs',
dest='jobs', action='store', type='int', default=2,
help="number of projects to check simultaneously")
def _StatusHelper(self, project, clean_counter, sem, output):
"""Obtains the status for a specific project.
Obtains the status for a project, redirecting the output to
the specified object. It will release the semaphore
when done.
Args:
project: Project to get status of.
clean_counter: Counter for clean projects.
sem: Semaphore, will call release() when complete.
output: Where to output the status.
"""
try:
state = project.PrintWorkTreeStatus(output)
if state == 'CLEAN':
clean_counter.next()
finally:
sem.release()
def Execute(self, opt, args): def Execute(self, opt, args):
all = self.GetProjects(args) all = self.GetProjects(args)
clean = 0 counter = itertools.count()
on = {} on = {}
for project in all: for project in all:
@ -77,9 +114,24 @@ the following meanings:
for cb in branch_names: for cb in branch_names:
print '# on branch %s' % cb print '# on branch %s' % cb
if opt.jobs == 1:
for project in all: for project in all:
state = project.PrintWorkTreeStatus() state = project.PrintWorkTreeStatus()
if state == 'CLEAN': if state == 'CLEAN':
clean += 1 counter.next()
if len(all) == clean: else:
sem = _threading.Semaphore(opt.jobs)
threads_and_output = []
for project in all:
sem.acquire()
output = StringIO.StringIO()
t = _threading.Thread(target=self._StatusHelper,
args=(project, counter, sem, output))
threads_and_output.append((t, output))
t.start()
for (t, output) in threads_and_output:
t.join()
sys.stdout.write(output.getvalue())
output.close()
if len(all) == counter.next():
print 'nothing to commit (working directory clean)' print 'nothing to commit (working directory clean)'