summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerence Haddock <thaddock@google.com>2011-03-31 12:33:34 +0200
committerShawn O. Pearce <sop@google.com>2011-04-07 16:36:42 -0400
commit4655e81a75f2ea5f1eaf93de1249886171281e61 (patch)
tree81ff7048880220c90c9ab0a7c5346a8dfab32a6d
parent723c5dc3d62fe07ba4faa17434870917ae87ce9d (diff)
downloadgit-repo-4655e81a75f2ea5f1eaf93de1249886171281e61.tar.gz
Add option to check status of projects in parallel.
Change-Id: I6ac653f88573def8bb3d96031d3570ff966251ad
-rw-r--r--project.py16
-rw-r--r--subcmds/status.py64
2 files changed, 70 insertions, 10 deletions
diff --git a/project.py b/project.py
index 4cef856b..9d98041f 100644
--- a/project.py
+++ b/project.py
@@ -650,13 +650,18 @@ class Project(object):
650 650
651 return False 651 return False
652 652
653 def PrintWorkTreeStatus(self): 653 def PrintWorkTreeStatus(self, output_redir=None):
654 """Prints the status of the repository to stdout. 654 """Prints the status of the repository to stdout.
655
656 Args:
657 output: If specified, redirect the output to this object.
655 """ 658 """
656 if not os.path.isdir(self.worktree): 659 if not os.path.isdir(self.worktree):
657 print '' 660 if output_redir == None:
658 print 'project %s/' % self.relpath 661 output_redir = sys.stdout
659 print ' missing (run "repo sync")' 662 print >>output_redir, ''
663 print >>output_redir, 'project %s/' % self.relpath
664 print >>output_redir, ' missing (run "repo sync")'
660 return 665 return
661 666
662 self.work_git.update_index('-q', 667 self.work_git.update_index('-q',
@@ -671,6 +676,8 @@ class Project(object):
671 return 'CLEAN' 676 return 'CLEAN'
672 677
673 out = StatusColoring(self.config) 678 out = StatusColoring(self.config)
679 if not output_redir == None:
680 out.redirect(output_redir)
674 out.project('project %-40s', self.relpath + '/') 681 out.project('project %-40s', self.relpath + '/')
675 682
676 branch = self.CurrentBranch 683 branch = self.CurrentBranch
@@ -720,6 +727,7 @@ class Project(object):
720 else: 727 else:
721 out.write('%s', line) 728 out.write('%s', line)
722 out.nl() 729 out.nl()
730
723 return 'DIRTY' 731 return 'DIRTY'
724 732
725 def PrintWorkTreeDiff(self): 733 def PrintWorkTreeDiff(self):
diff --git a/subcmds/status.py b/subcmds/status.py
index b0d419a7..041bcd0f 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -15,6 +15,15 @@
15 15
16from command import PagedCommand 16from command import PagedCommand
17 17
18try:
19 import threading as _threading
20except ImportError:
21 import dummy_threading as _threading
22
23import itertools
24import sys
25import StringIO
26
18class Status(PagedCommand): 27class Status(PagedCommand):
19 common = True 28 common = True
20 helpSummary = "Show the working tree status" 29 helpSummary = "Show the working tree status"
@@ -27,6 +36,9 @@ and the most recent commit on this branch (HEAD), in each project
27specified. A summary is displayed, one line per file where there 36specified. A summary is displayed, one line per file where there
28is a difference between these three states. 37is a difference between these three states.
29 38
39The -j/--jobs option can be used to run multiple status queries
40in parallel.
41
30Status Display 42Status Display
31-------------- 43--------------
32 44
@@ -60,9 +72,34 @@ the following meanings:
60 72
61""" 73"""
62 74
75 def _Options(self, p):
76 p.add_option('-j', '--jobs',
77 dest='jobs', action='store', type='int', default=2,
78 help="number of projects to check simultaneously")
79
80 def _StatusHelper(self, project, clean_counter, sem, output):
81 """Obtains the status for a specific project.
82
83 Obtains the status for a project, redirecting the output to
84 the specified object. It will release the semaphore
85 when done.
86
87 Args:
88 project: Project to get status of.
89 clean_counter: Counter for clean projects.
90 sem: Semaphore, will call release() when complete.
91 output: Where to output the status.
92 """
93 try:
94 state = project.PrintWorkTreeStatus(output)
95 if state == 'CLEAN':
96 clean_counter.next()
97 finally:
98 sem.release()
99
63 def Execute(self, opt, args): 100 def Execute(self, opt, args):
64 all = self.GetProjects(args) 101 all = self.GetProjects(args)
65 clean = 0 102 counter = itertools.count()
66 103
67 on = {} 104 on = {}
68 for project in all: 105 for project in all:
@@ -77,9 +114,24 @@ the following meanings:
77 for cb in branch_names: 114 for cb in branch_names:
78 print '# on branch %s' % cb 115 print '# on branch %s' % cb
79 116
80 for project in all: 117 if opt.jobs == 1:
81 state = project.PrintWorkTreeStatus() 118 for project in all:
82 if state == 'CLEAN': 119 state = project.PrintWorkTreeStatus()
83 clean += 1 120 if state == 'CLEAN':
84 if len(all) == clean: 121 counter.next()
122 else:
123 sem = _threading.Semaphore(opt.jobs)
124 threads_and_output = []
125 for project in all:
126 sem.acquire()
127 output = StringIO.StringIO()
128 t = _threading.Thread(target=self._StatusHelper,
129 args=(project, counter, sem, output))
130 threads_and_output.append((t, output))
131 t.start()
132 for (t, output) in threads_and_output:
133 t.join()
134 sys.stdout.write(output.getvalue())
135 output.close()
136 if len(all) == counter.next():
85 print 'nothing to commit (working directory clean)' 137 print 'nothing to commit (working directory clean)'