Index: scripts/common/annotator.py |
diff --git a/scripts/common/annotator.py b/scripts/common/annotator.py |
index 14d4ed7aacadd2ef13a4d0b3ddcda06c70202902..4c3466d9627edf63c2a261694d0f7fd0ef262994 100755 |
--- a/scripts/common/annotator.py |
+++ b/scripts/common/annotator.py |
@@ -13,20 +13,29 @@ executes those lines while annotating the output. The input is json: |
""" |
+import itertools |
import json |
import optparse |
import os |
import re |
+import subprocess |
import sys |
+import threading |
import traceback |
-from common import chromium_utils |
- |
def emit(line, stream, flush_before=None): |
if flush_before: |
flush_before.flush() |
- print >> stream, '\n' + line |
+ print >> stream |
+ # WinDOS can only handle 64kb of output to the console at a time, per process. |
+ if sys.platform.startswith('win'): |
+ lim = 2**15 |
+ while line: |
+ to_print, line = line[:lim], line[lim:] |
+ stream.write(to_print) |
+ else: |
+ print >> stream, line |
stream.flush() |
@@ -413,25 +422,44 @@ def run_step(stream, build_failure, |
for step_name in (seed_steps or []): |
stream.seed_step(step_name) |
- filter_obj = None |
- if not allow_subannotations: |
- class AnnotationFilter(chromium_utils.RunCommandFilter): |
- # Missing __init__ |
- # Method could be a function (but not really since it's an override) |
- # pylint: disable=W0232,R0201 |
- def FilterLine(self, line): |
- return line.replace('@@@', '###') |
- filter_obj = AnnotationFilter() |
- |
ret = None |
with stream.step(name) as s: |
print_step(step_dict) |
try: |
- ret = chromium_utils.RunCommand(command=cmd, |
- cwd=cwd, |
- env=_merge_envs(os.environ, env), |
- filter_obj=filter_obj, |
- print_cmd=False) |
+ proc = subprocess.Popen( |
+ cmd, |
+ env=_merge_envs(os.environ, env), |
+ cwd=cwd, |
+ stdout=subprocess.PIPE, |
+ stderr=subprocess.PIPE) |
+ |
+ outlock = threading.Lock() |
+ def filter_lines(lock, allow_subannotations, inhandle, outhandle): |
+ while True: |
+ line = inhandle.readline() |
+ if not line: |
+ break |
+ lock.acquire() |
+ try: |
+ if not allow_subannotations: |
+ outhandle.write('!') |
+ outhandle.write(line) |
+ outhandle.flush() |
+ finally: |
+ lock.release() |
+ |
+ outthread = threading.Thread( |
+ target=filter_lines, |
+ args=(outlock, allow_subannotations, proc.stdout, sys.stdout)) |
+ errthread = threading.Thread( |
+ target=filter_lines, |
+ args=(outlock, allow_subannotations, proc.stderr, sys.stderr)) |
+ outthread.start() |
+ errthread.start() |
+ proc.wait() |
+ outthread.join() |
+ errthread.join() |
+ ret = proc.returncode |
except OSError: |
# File wasn't found, error will be reported to stream when the exception |
# crosses the context manager. |
@@ -489,11 +517,33 @@ def main(): |
steps = [] |
+ def force_list_str(lst): |
+ ret = [] |
+ for v in lst: |
+ if isinstance(v, basestring): |
+ v = str(v) |
+ elif isinstance(v, list): |
+ v = force_list_str(v) |
agable
2013/06/25 21:26:35
you want elif isinstance(v, dict) up here too, for
|
+ ret.append(v) |
+ return ret |
+ |
+ def force_dict_strs(obj): |
+ ret = {} |
+ for k, v in obj.iteritems(): |
+ if isinstance(v, basestring): |
+ v = str(v) |
+ elif isinstance(v, list): |
+ v = force_list_str(v) |
+ elif isinstance(v, dict): |
+ v = force_dict_strs(v) |
+ ret[str(k)] = v |
+ return ret |
+ |
if args[0] == '-': |
- steps.extend(json.load(sys.stdin)) |
+ steps.extend(json.load(sys.stdin, object_hook=force_dict_strs)) |
else: |
with open(args[0], 'rb') as f: |
- steps.extend(json.load(f)) |
+ steps.extend(json.load(f, object_hook=force_dict_strs)) |
return 1 if run_steps(steps, False)[0] else 0 |