summaryrefslogtreecommitdiffstats
path: root/subcmds/status.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/status.py')
-rw-r--r--subcmds/status.py96
1 files changed, 39 insertions, 57 deletions
diff --git a/subcmds/status.py b/subcmds/status.py
index 63972d72..5b669547 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -1,5 +1,3 @@
1# -*- coding:utf-8 -*-
2#
3# Copyright (C) 2008 The Android Open Source Project 1# Copyright (C) 2008 The Android Open Source Project
4# 2#
5# Licensed under the Apache License, Version 2.0 (the "License"); 3# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,25 +12,19 @@
14# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
15# limitations under the License. 13# limitations under the License.
16 14
17from __future__ import print_function 15import functools
18
19from command import PagedCommand
20
21try:
22 import threading as _threading
23except ImportError:
24 import dummy_threading as _threading
25
26import glob 16import glob
27 17import io
28import itertools
29import os 18import os
30 19
20from command import DEFAULT_LOCAL_JOBS, PagedCommand
21
31from color import Coloring 22from color import Coloring
32import platform_utils 23import platform_utils
33 24
25
34class Status(PagedCommand): 26class Status(PagedCommand):
35 common = True 27 COMMON = True
36 helpSummary = "Show the working tree status" 28 helpSummary = "Show the working tree status"
37 helpUsage = """ 29 helpUsage = """
38%prog [<project>...] 30%prog [<project>...]
@@ -84,36 +76,29 @@ the following meanings:
84 d: deleted ( in index, not in work tree ) 76 d: deleted ( in index, not in work tree )
85 77
86""" 78"""
79 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
87 80
88 def _Options(self, p): 81 def _Options(self, p):
89 p.add_option('-j', '--jobs',
90 dest='jobs', action='store', type='int', default=2,
91 help="number of projects to check simultaneously")
92 p.add_option('-o', '--orphans', 82 p.add_option('-o', '--orphans',
93 dest='orphans', action='store_true', 83 dest='orphans', action='store_true',
94 help="include objects in working directory outside of repo projects") 84 help="include objects in working directory outside of repo projects")
95 p.add_option('-q', '--quiet', action='store_true',
96 help="only print the name of modified projects")
97 85
98 def _StatusHelper(self, project, clean_counter, sem, quiet): 86 def _StatusHelper(self, quiet, project):
99 """Obtains the status for a specific project. 87 """Obtains the status for a specific project.
100 88
101 Obtains the status for a project, redirecting the output to 89 Obtains the status for a project, redirecting the output to
102 the specified object. It will release the semaphore 90 the specified object.
103 when done.
104 91
105 Args: 92 Args:
93 quiet: Where to output the status.
106 project: Project to get status of. 94 project: Project to get status of.
107 clean_counter: Counter for clean projects. 95
108 sem: Semaphore, will call release() when complete. 96 Returns:
109 output: Where to output the status. 97 The status of the project.
110 """ 98 """
111 try: 99 buf = io.StringIO()
112 state = project.PrintWorkTreeStatus(quiet=quiet) 100 ret = project.PrintWorkTreeStatus(quiet=quiet, output_redir=buf)
113 if state == 'CLEAN': 101 return (ret, buf.getvalue())
114 next(clean_counter)
115 finally:
116 sem.release()
117 102
118 def _FindOrphans(self, dirs, proj_dirs, proj_dirs_parents, outstring): 103 def _FindOrphans(self, dirs, proj_dirs, proj_dirs_parents, outstring):
119 """find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'""" 104 """find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'"""
@@ -126,34 +111,31 @@ the following meanings:
126 continue 111 continue
127 if item in proj_dirs_parents: 112 if item in proj_dirs_parents:
128 self._FindOrphans(glob.glob('%s/.*' % item) + 113 self._FindOrphans(glob.glob('%s/.*' % item) +
129 glob.glob('%s/*' % item), 114 glob.glob('%s/*' % item),
130 proj_dirs, proj_dirs_parents, outstring) 115 proj_dirs, proj_dirs_parents, outstring)
131 continue 116 continue
132 outstring.append(''.join([status_header, item, '/'])) 117 outstring.append(''.join([status_header, item, '/']))
133 118
134 def Execute(self, opt, args): 119 def Execute(self, opt, args):
135 all_projects = self.GetProjects(args) 120 all_projects = self.GetProjects(args)
136 counter = itertools.count()
137 121
138 if opt.jobs == 1: 122 def _ProcessResults(_pool, _output, results):
139 for project in all_projects: 123 ret = 0
140 state = project.PrintWorkTreeStatus(quiet=opt.quiet) 124 for (state, output) in results:
125 if output:
126 print(output, end='')
141 if state == 'CLEAN': 127 if state == 'CLEAN':
142 next(counter) 128 ret += 1
143 else: 129 return ret
144 sem = _threading.Semaphore(opt.jobs) 130
145 threads = [] 131 counter = self.ExecuteInParallel(
146 for project in all_projects: 132 opt.jobs,
147 sem.acquire() 133 functools.partial(self._StatusHelper, opt.quiet),
148 134 all_projects,
149 t = _threading.Thread(target=self._StatusHelper, 135 callback=_ProcessResults,
150 args=(project, counter, sem, opt.quiet)) 136 ordered=True)
151 threads.append(t) 137
152 t.daemon = True 138 if not opt.quiet and len(all_projects) == counter:
153 t.start()
154 for t in threads:
155 t.join()
156 if not opt.quiet and len(all_projects) == next(counter):
157 print('nothing to commit (working directory clean)') 139 print('nothing to commit (working directory clean)')
158 140
159 if opt.orphans: 141 if opt.orphans:
@@ -170,8 +152,8 @@ the following meanings:
170 class StatusColoring(Coloring): 152 class StatusColoring(Coloring):
171 def __init__(self, config): 153 def __init__(self, config):
172 Coloring.__init__(self, config, 'status') 154 Coloring.__init__(self, config, 'status')
173 self.project = self.printer('header', attr = 'bold') 155 self.project = self.printer('header', attr='bold')
174 self.untracked = self.printer('untracked', fg = 'red') 156 self.untracked = self.printer('untracked', fg='red')
175 157
176 orig_path = os.getcwd() 158 orig_path = os.getcwd()
177 try: 159 try:
@@ -179,11 +161,11 @@ the following meanings:
179 161
180 outstring = [] 162 outstring = []
181 self._FindOrphans(glob.glob('.*') + 163 self._FindOrphans(glob.glob('.*') +
182 glob.glob('*'), 164 glob.glob('*'),
183 proj_dirs, proj_dirs_parents, outstring) 165 proj_dirs, proj_dirs_parents, outstring)
184 166
185 if outstring: 167 if outstring:
186 output = StatusColoring(self.manifest.globalConfig) 168 output = StatusColoring(self.client.globalConfig)
187 output.project('Objects not within a project (orphans)') 169 output.project('Objects not within a project (orphans)')
188 output.nl() 170 output.nl()
189 for entry in outstring: 171 for entry in outstring: