OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly. | 5 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly. |
6 # Derived from https://gist.github.com/aljungberg/626518 | 6 # Derived from https://gist.github.com/aljungberg/626518 |
7 import multiprocessing.pool | 7 import multiprocessing.pool |
8 from multiprocessing.pool import IMapIterator | 8 from multiprocessing.pool import IMapIterator |
9 def wrapper(func): | 9 def wrapper(func): |
10 def wrap(self, timeout=None): | 10 def wrap(self, timeout=None): |
(...skipping 135 matching lines...) Loading... |
146 pool.close() | 146 pool.close() |
147 except: | 147 except: |
148 pool.terminate() | 148 pool.terminate() |
149 raise | 149 raise |
150 finally: | 150 finally: |
151 pool.join() | 151 pool.join() |
152 | 152 |
153 | 153 |
154 class ProgressPrinter(object): | 154 class ProgressPrinter(object): |
155 """Threaded single-stat status message printer.""" | 155 """Threaded single-stat status message printer.""" |
156 def __init__(self, fmt, enabled=None, stream=sys.stderr, period=0.5): | 156 def __init__(self, fmt, enabled=None, fout=sys.stderr, period=0.5): |
157 """Create a ProgressPrinter. | 157 """Create a ProgressPrinter. |
158 | 158 |
159 Use it as a context manager which produces a simple 'increment' method: | 159 Use it as a context manager which produces a simple 'increment' method: |
160 | 160 |
161 with ProgressPrinter('(%%(count)d/%d)' % 1000) as inc: | 161 with ProgressPrinter('(%%(count)d/%d)' % 1000) as inc: |
162 for i in xrange(1000): | 162 for i in xrange(1000): |
163 # do stuff | 163 # do stuff |
164 if i % 10 == 0: | 164 if i % 10 == 0: |
165 inc(10) | 165 inc(10) |
166 | 166 |
167 Args: | 167 Args: |
168 fmt - String format with a single '%(count)d' where the counter value | 168 fmt - String format with a single '%(count)d' where the counter value |
169 should go. | 169 should go. |
170 enabled (bool) - If this is None, will default to True if | 170 enabled (bool) - If this is None, will default to True if |
171 logging.getLogger() is set to INFO or more verbose. | 171 logging.getLogger() is set to INFO or more verbose. |
172 stream (file-like) - The stream to print status messages to. | 172 fout (file-like) - The stream to print status messages to. |
173 period (float) - The time in seconds for the printer thread to wait | 173 period (float) - The time in seconds for the printer thread to wait |
174 between printing. | 174 between printing. |
175 """ | 175 """ |
176 self.fmt = fmt | 176 self.fmt = fmt |
177 if enabled is None: # pragma: no cover | 177 if enabled is None: # pragma: no cover |
178 self.enabled = logging.getLogger().isEnabledFor(logging.INFO) | 178 self.enabled = logging.getLogger().isEnabledFor(logging.INFO) |
179 else: | 179 else: |
180 self.enabled = enabled | 180 self.enabled = enabled |
181 | 181 |
182 self._count = 0 | 182 self._count = 0 |
183 self._dead = False | 183 self._dead = False |
184 self._dead_cond = threading.Condition() | 184 self._dead_cond = threading.Condition() |
185 self._stream = stream | 185 self._stream = fout |
186 self._thread = threading.Thread(target=self._run) | 186 self._thread = threading.Thread(target=self._run) |
187 self._period = period | 187 self._period = period |
188 | 188 |
189 def _emit(self, s): | 189 def _emit(self, s): |
190 if self.enabled: | 190 if self.enabled: |
191 self._stream.write('\r' + s) | 191 self._stream.write('\r' + s) |
192 self._stream.flush() | 192 self._stream.flush() |
193 | 193 |
194 def _run(self): | 194 def _run(self): |
195 with self._dead_cond: | 195 with self._dead_cond: |
(...skipping 53 matching lines...) Loading... |
249 raise BadCommitRefException(commitrefs) | 249 raise BadCommitRefException(commitrefs) |
250 | 250 |
251 | 251 |
252 def run(*cmd, **kwargs): | 252 def run(*cmd, **kwargs): |
253 """Runs a git command. Returns stdout as a string. | 253 """Runs a git command. Returns stdout as a string. |
254 | 254 |
255 If logging is DEBUG, we'll print the command before we run it. | 255 If logging is DEBUG, we'll print the command before we run it. |
256 | 256 |
257 kwargs | 257 kwargs |
258 autostrip (bool) - Strip the output. Defaults to True. | 258 autostrip (bool) - Strip the output. Defaults to True. |
259 Output string is always strip()'d. | |
260 """ | 259 """ |
261 autostrip = kwargs.pop('autostrip', True) | 260 autostrip = kwargs.pop('autostrip', True) |
262 cmd = (GIT_EXE,) + cmd | 261 ret = stream(*cmd, **kwargs).read() |
263 logging.debug('Running %s', ' '.join(repr(tok) for tok in cmd)) | |
264 ret = subprocess2.check_output(cmd, stderr=subprocess2.PIPE, **kwargs) | |
265 if autostrip: | 262 if autostrip: |
266 ret = (ret or '').strip() | 263 ret = (ret or '').strip() |
267 return ret | 264 return ret |
268 | 265 |
269 | 266 |
| 267 def stream(*cmd, **kwargs): |
| 268 """Runs a git command. Returns stdout as a file. |
| 269 |
| 270 If logging is DEBUG, we'll print the command before we run it. |
| 271 """ |
| 272 cmd = (GIT_EXE,) + cmd |
| 273 logging.debug('Running %s', ' '.join(repr(tok) for tok in cmd)) |
| 274 proc = subprocess2.Popen(cmd, stderr=subprocess2.VOID, |
| 275 stdout=subprocess2.PIPE, **kwargs) |
| 276 return proc.stdout |
| 277 |
| 278 |
270 def hash_one(reflike): | 279 def hash_one(reflike): |
271 return run('rev-parse', reflike) | 280 return run('rev-parse', reflike) |
272 | 281 |
273 | 282 |
274 def hash_multi(*reflike): | 283 def hash_multi(*reflike): |
275 return run('rev-parse', *reflike).splitlines() | 284 return run('rev-parse', *reflike).splitlines() |
276 | 285 |
277 | 286 |
278 def intern_f(f, kind='blob'): | 287 def intern_f(f, kind='blob'): |
279 """Interns a file object into the git object store. | 288 """Interns a file object into the git object store. |
(...skipping 67 matching lines...) Loading... |
347 See |tree()| for the values of mode, type, and ref. | 356 See |tree()| for the values of mode, type, and ref. |
348 | 357 |
349 Args: | 358 Args: |
350 treedict - { name: (mode, type, ref) } | 359 treedict - { name: (mode, type, ref) } |
351 """ | 360 """ |
352 with tempfile.TemporaryFile() as f: | 361 with tempfile.TemporaryFile() as f: |
353 for name, (mode, typ, ref) in treedict.iteritems(): | 362 for name, (mode, typ, ref) in treedict.iteritems(): |
354 f.write('%s %s %s\t%s\0' % (mode, typ, ref, name)) | 363 f.write('%s %s %s\t%s\0' % (mode, typ, ref, name)) |
355 f.seek(0) | 364 f.seek(0) |
356 return run('mktree', '-z', stdin=f) | 365 return run('mktree', '-z', stdin=f) |
OLD | NEW |