Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(957)

Side by Side Diff: gclient_utils.py

Issue 14826003: Refactor nag functionality in to NagTimer class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix nag_max Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gclient_scm.py ('k') | subprocess2.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 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 """Generic utils.""" 5 """Generic utils."""
6 6
7 import codecs 7 import codecs
8 import logging 8 import logging
9 import os 9 import os
10 import Queue 10 import Queue
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 318
319 319
320 def MakeFileAnnotated(fileobj, include_zero=False): 320 def MakeFileAnnotated(fileobj, include_zero=False):
321 if getattr(fileobj, 'annotated', None): 321 if getattr(fileobj, 'annotated', None):
322 return fileobj 322 return fileobj
323 return Annotated(fileobj) 323 return Annotated(fileobj)
324 324
325 325
326 def CheckCallAndFilter(args, stdout=None, filter_fn=None, 326 def CheckCallAndFilter(args, stdout=None, filter_fn=None,
327 print_stdout=None, call_filter_on_first_line=False, 327 print_stdout=None, call_filter_on_first_line=False,
328 **kwargs): 328 nag_timer=None, nag_max=None, **kwargs):
329 """Runs a command and calls back a filter function if needed. 329 """Runs a command and calls back a filter function if needed.
330 330
331 Accepts all subprocess2.Popen() parameters plus: 331 Accepts all subprocess2.Popen() parameters plus:
332 print_stdout: If True, the command's stdout is forwarded to stdout. 332 print_stdout: If True, the command's stdout is forwarded to stdout.
333 filter_fn: A function taking a single string argument called with each line 333 filter_fn: A function taking a single string argument called with each line
334 of the subprocess2's output. Each line has the trailing newline 334 of the subprocess2's output. Each line has the trailing newline
335 character trimmed. 335 character trimmed.
336 stdout: Can be any bufferable output. 336 stdout: Can be any bufferable output.
337 337
338 stderr is always redirected to stdout. 338 stderr is always redirected to stdout.
339 """ 339 """
340 assert print_stdout or filter_fn 340 assert print_stdout or filter_fn
341 stdout = stdout or sys.stdout 341 stdout = stdout or sys.stdout
342 filter_fn = filter_fn or (lambda x: None) 342 filter_fn = filter_fn or (lambda x: None)
343 kid = subprocess2.Popen( 343 kid = subprocess2.Popen(
344 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT, 344 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT,
345 **kwargs) 345 **kwargs)
346 346
347 # Do a flush of stdout before we begin reading from the subprocess2's stdout 347 # Do a flush of stdout before we begin reading from the subprocess2's stdout
348 stdout.flush() 348 stdout.flush()
349 349
350 nag = None
351 if nag_timer:
352 # Hack thread.index to force correct annotation.
353 index = getattr(threading.currentThread(), 'index', 0)
354 def _nag_cb(elapsed):
355 setattr(threading.currentThread(), 'index', index)
356 stdout.write(' No output for %.0f seconds from command:\n' % elapsed)
357 stdout.write(' %s\n' % kid.cmd_str)
358 if (nag_max and
359 int('%.0f' % (elapsed / nag_timer)) >= nag_max):
360 stdout.write(' ... killing it!\n')
361 kid.kill()
362 nag = subprocess2.NagTimer(nag_timer, _nag_cb)
363 nag.start()
364
350 # Also, we need to forward stdout to prevent weird re-ordering of output. 365 # Also, we need to forward stdout to prevent weird re-ordering of output.
351 # This has to be done on a per byte basis to make sure it is not buffered: 366 # This has to be done on a per byte basis to make sure it is not buffered:
352 # normally buffering is done for each line, but if svn requests input, no 367 # normally buffering is done for each line, but if svn requests input, no
353 # end-of-line character is output after the prompt and it would not show up. 368 # end-of-line character is output after the prompt and it would not show up.
354 try: 369 try:
355 in_byte = kid.stdout.read(1) 370 in_byte = kid.stdout.read(1)
356 if in_byte: 371 if in_byte:
372 if nag:
373 nag.event()
357 if call_filter_on_first_line: 374 if call_filter_on_first_line:
358 filter_fn(None) 375 filter_fn(None)
359 in_line = '' 376 in_line = ''
360 while in_byte: 377 while in_byte:
361 if in_byte != '\r': 378 if in_byte != '\r':
362 if print_stdout: 379 if print_stdout:
363 stdout.write(in_byte) 380 stdout.write(in_byte)
364 if in_byte != '\n': 381 if in_byte != '\n':
365 in_line += in_byte 382 in_line += in_byte
366 else: 383 else:
367 filter_fn(in_line) 384 filter_fn(in_line)
368 in_line = '' 385 in_line = ''
369 else: 386 else:
370 filter_fn(in_line) 387 filter_fn(in_line)
371 in_line = '' 388 in_line = ''
372 in_byte = kid.stdout.read(1) 389 in_byte = kid.stdout.read(1)
390 if in_byte and nag:
391 nag.event()
373 # Flush the rest of buffered output. This is only an issue with 392 # Flush the rest of buffered output. This is only an issue with
374 # stdout/stderr not ending with a \n. 393 # stdout/stderr not ending with a \n.
375 if len(in_line): 394 if len(in_line):
376 filter_fn(in_line) 395 filter_fn(in_line)
377 rv = kid.wait() 396 rv = kid.wait()
378 except KeyboardInterrupt: 397 except KeyboardInterrupt:
379 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) 398 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args)
380 raise 399 raise
400 finally:
401 if nag:
402 nag.cancel()
381 403
382 if rv: 404 if rv:
383 raise subprocess2.CalledProcessError( 405 raise subprocess2.CalledProcessError(
384 rv, args, kwargs.get('cwd', None), None, None) 406 rv, args, kwargs.get('cwd', None), None, None)
385 return 0 407 return 0
386 408
387 409
388 def FindGclientRoot(from_dir, filename='.gclient'): 410 def FindGclientRoot(from_dir, filename='.gclient'):
389 """Tries to find the gclient root.""" 411 """Tries to find the gclient root."""
390 real_from_dir = os.path.realpath(from_dir) 412 real_from_dir = os.path.realpath(from_dir)
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 786
765 Python on OSX 10.6 raises a NotImplementedError exception. 787 Python on OSX 10.6 raises a NotImplementedError exception.
766 """ 788 """
767 try: 789 try:
768 import multiprocessing 790 import multiprocessing
769 return multiprocessing.cpu_count() 791 return multiprocessing.cpu_count()
770 except: # pylint: disable=W0702 792 except: # pylint: disable=W0702
771 # Mac OS 10.6 only 793 # Mac OS 10.6 only
772 # pylint: disable=E1101 794 # pylint: disable=E1101
773 return int(os.sysconf('SC_NPROCESSORS_ONLN')) 795 return int(os.sysconf('SC_NPROCESSORS_ONLN'))
OLDNEW
« no previous file with comments | « gclient_scm.py ('k') | subprocess2.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698