OLD | NEW |
---|---|
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 cStringIO | |
8 import logging | 9 import logging |
9 import os | 10 import os |
10 import pipes | 11 import pipes |
11 import Queue | 12 import Queue |
12 import re | 13 import re |
13 import stat | 14 import stat |
14 import subprocess | 15 import subprocess |
15 import sys | 16 import sys |
16 import tempfile | 17 import tempfile |
17 import threading | 18 import threading |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 of the subprocess2's output. Each line has the trailing newline | 422 of the subprocess2's output. Each line has the trailing newline |
422 character trimmed. | 423 character trimmed. |
423 stdout: Can be any bufferable output. | 424 stdout: Can be any bufferable output. |
424 retry: If the process exits non-zero, sleep for a brief interval and try | 425 retry: If the process exits non-zero, sleep for a brief interval and try |
425 again, up to RETRY_MAX times. | 426 again, up to RETRY_MAX times. |
426 | 427 |
427 stderr is always redirected to stdout. | 428 stderr is always redirected to stdout. |
428 """ | 429 """ |
429 assert print_stdout or filter_fn | 430 assert print_stdout or filter_fn |
430 stdout = stdout or sys.stdout | 431 stdout = stdout or sys.stdout |
432 output = cStringIO.StringIO() | |
431 filter_fn = filter_fn or (lambda x: None) | 433 filter_fn = filter_fn or (lambda x: None) |
432 | 434 |
433 sleep_interval = RETRY_INITIAL_SLEEP | 435 sleep_interval = RETRY_INITIAL_SLEEP |
434 run_cwd = kwargs.get('cwd', os.getcwd()) | 436 run_cwd = kwargs.get('cwd', os.getcwd()) |
435 for _ in xrange(RETRY_MAX + 1): | 437 for _ in xrange(RETRY_MAX + 1): |
436 kid = subprocess2.Popen( | 438 kid = subprocess2.Popen( |
437 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT, | 439 args, bufsize=0, stdout=subprocess2.PIPE, stderr=subprocess2.STDOUT, |
438 **kwargs) | 440 **kwargs) |
439 | 441 |
440 GClientChildren.add(kid) | 442 GClientChildren.add(kid) |
441 | 443 |
442 # Do a flush of stdout before we begin reading from the subprocess2's stdout | 444 # Do a flush of stdout before we begin reading from the subprocess2's stdout |
443 stdout.flush() | 445 stdout.flush() |
444 | 446 |
445 # Also, we need to forward stdout to prevent weird re-ordering of output. | 447 # Also, we need to forward stdout to prevent weird re-ordering of output. |
446 # This has to be done on a per byte basis to make sure it is not buffered: | 448 # This has to be done on a per byte basis to make sure it is not buffered: |
447 # normally buffering is done for each line, but if svn requests input, no | 449 # normally buffering is done for each line, but if svn requests input, no |
448 # end-of-line character is output after the prompt and it would not show up. | 450 # end-of-line character is output after the prompt and it would not show up. |
449 try: | 451 try: |
450 in_byte = kid.stdout.read(1) | 452 in_byte = kid.stdout.read(1) |
451 if in_byte: | 453 if in_byte: |
452 if call_filter_on_first_line: | 454 if call_filter_on_first_line: |
453 filter_fn(None) | 455 filter_fn(None) |
454 in_line = '' | 456 in_line = '' |
455 while in_byte: | 457 while in_byte: |
458 output.write(in_byte) | |
459 if print_stdout: | |
460 stdout.write(in_byte) | |
456 if in_byte != '\r': | 461 if in_byte != '\r': |
457 if print_stdout: | |
458 stdout.write(in_byte) | |
459 if in_byte != '\n': | 462 if in_byte != '\n': |
460 in_line += in_byte | 463 in_line += in_byte |
461 else: | 464 else: |
462 filter_fn(in_line) | 465 filter_fn(in_line) |
463 in_line = '' | 466 in_line = '' |
464 else: | 467 else: |
465 filter_fn(in_line) | 468 filter_fn(in_line) |
466 in_line = '' | 469 in_line = '' |
467 in_byte = kid.stdout.read(1) | 470 in_byte = kid.stdout.read(1) |
468 # Flush the rest of buffered output. This is only an issue with | 471 # Flush the rest of buffered output. This is only an issue with |
469 # stdout/stderr not ending with a \n. | 472 # stdout/stderr not ending with a \n. |
470 if len(in_line): | 473 if len(in_line): |
471 filter_fn(in_line) | 474 filter_fn(in_line) |
472 rv = kid.wait() | 475 rv = kid.wait() |
473 | 476 |
474 # Don't put this in a 'finally,' since the child may still run if we get | 477 # Don't put this in a 'finally,' since the child may still run if we get |
475 # an exception. | 478 # an exception. |
476 GClientChildren.remove(kid) | 479 GClientChildren.remove(kid) |
477 | 480 |
478 except KeyboardInterrupt: | 481 except KeyboardInterrupt: |
479 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) | 482 print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) |
480 raise | 483 raise |
481 | 484 |
482 if rv == 0: | 485 if rv == 0: |
483 return 0 | 486 return output.getvalue() |
agable
2014/02/28 02:06:32
Just straight up doing this seems like it could br
Ryan Tseng
2014/02/28 02:22:50
If you check
https://code.google.com/p/chromium/co
| |
484 if not retry: | 487 if not retry: |
485 break | 488 break |
486 print ("WARNING: subprocess '%s' in %s failed; will retry after a short " | 489 print ("WARNING: subprocess '%s' in %s failed; will retry after a short " |
487 'nap...' % (' '.join('"%s"' % x for x in args), run_cwd)) | 490 'nap...' % (' '.join('"%s"' % x for x in args), run_cwd)) |
488 time.sleep(sleep_interval) | 491 time.sleep(sleep_interval) |
489 sleep_interval *= 2 | 492 sleep_interval *= 2 |
490 raise subprocess2.CalledProcessError( | 493 raise subprocess2.CalledProcessError( |
491 rv, args, kwargs.get('cwd', None), None, None) | 494 rv, args, kwargs.get('cwd', None), None, None) |
492 | 495 |
493 | 496 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 | 953 |
951 Python on OSX 10.6 raises a NotImplementedError exception. | 954 Python on OSX 10.6 raises a NotImplementedError exception. |
952 """ | 955 """ |
953 try: | 956 try: |
954 import multiprocessing | 957 import multiprocessing |
955 return multiprocessing.cpu_count() | 958 return multiprocessing.cpu_count() |
956 except: # pylint: disable=W0702 | 959 except: # pylint: disable=W0702 |
957 # Mac OS 10.6 only | 960 # Mac OS 10.6 only |
958 # pylint: disable=E1101 | 961 # pylint: disable=E1101 |
959 return int(os.sysconf('SC_NPROCESSORS_ONLN')) | 962 return int(os.sysconf('SC_NPROCESSORS_ONLN')) |
OLD | NEW |