diff options
Diffstat (limited to 'subcmds/status.py')
-rw-r--r-- | subcmds/status.py | 86 |
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 | ||
16 | from command import PagedCommand | 16 | from command import PagedCommand |
17 | 17 | ||
18 | try: | ||
19 | import threading as _threading | ||
20 | except ImportError: | ||
21 | import dummy_threading as _threading | ||
22 | |||
23 | import itertools | ||
24 | import sys | ||
25 | import StringIO | ||
26 | |||
18 | class Status(PagedCommand): | 27 | class 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 | |||
27 | specified. A summary is displayed, one line per file where there | 36 | specified. A summary is displayed, one line per file where there |
28 | is a difference between these three states. | 37 | is a difference between these three states. |
29 | 38 | ||
39 | The -j/--jobs option can be used to run multiple status queries | ||
40 | in parallel. | ||
41 | |||
30 | Status Display | 42 | Status 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)' |