summaryrefslogtreecommitdiffstats
path: root/subcmds/status.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/status.py')
-rw-r--r--subcmds/status.py86
1 files changed, 66 insertions, 20 deletions
diff --git a/subcmds/status.py b/subcmds/status.py
index b0d419a7..69e2dbfc 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,26 +72,60 @@ 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 if opt.jobs == 1:
68 for project in all: 105 for project in all:
69 cb = project.CurrentBranch 106 state = project.PrintWorkTreeStatus()
70 if cb: 107 if state == 'CLEAN':
71 if cb not in on: 108 counter.next()
72 on[cb] = [] 109 else:
73 on[cb].append(project) 110 sem = _threading.Semaphore(opt.jobs)
74 111 threads_and_output = []
75 branch_names = list(on.keys()) 112 for project in all:
76 branch_names.sort() 113 sem.acquire()
77 for cb in branch_names: 114
78 print '# on branch %s' % cb 115 class BufList(StringIO.StringIO):
79 116 def dump(self, ostream):
80 for project in all: 117 for entry in self.buflist:
81 state = project.PrintWorkTreeStatus() 118 ostream.write(entry)
82 if state == 'CLEAN': 119
83 clean += 1 120 output = BufList()
84 if len(all) == clean: 121
122 t = _threading.Thread(target=self._StatusHelper,
123 args=(project, counter, sem, output))
124 threads_and_output.append((t, output))
125 t.start()
126 for (t, output) in threads_and_output:
127 t.join()
128 output.dump(sys.stdout)
129 output.close()
130 if len(all) == counter.next():
85 print 'nothing to commit (working directory clean)' 131 print 'nothing to commit (working directory clean)'