utr: Use rich for more logging to support multiple platforms
This applies a RichHandler to the root logger and creates a new logger
for most recipe output to prevent parsing of output we don't control.
Also makes the "Running: step name" text to be cyan to help visualize
the flow of the recipe
Bug: 41492688
Change-Id: I075e89e89790db4fd31ec20ec13d4e120733104b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5421151
Reviewed-by: Ben Pastene <[email protected]>
Commit-Queue: Struan Shrimpton <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1282183}
diff --git a/tools/utr/output_adapter.py b/tools/utr/output_adapter.py
index 44937a86..0561d14 100644
--- a/tools/utr/output_adapter.py
+++ b/tools/utr/output_adapter.py
@@ -11,29 +11,17 @@
import re
import sys
-import colorama
-
-
-def as_green(text):
- """Surrounds the text with ANSI codes to color it green."""
- return colorama.Fore.GREEN + text + colorama.Style.RESET_ALL
-
-
-def as_red(text):
- """Surrounds the text with ANSI codes to color it red."""
- return colorama.Fore.RED + text + colorama.Style.RESET_ALL
-
-
-def as_yellow(text):
- """Surrounds the text with ANSI codes to color it yellow."""
- return colorama.Fore.YELLOW + text + colorama.Style.RESET_ALL
-
+# Create a logger that avoids rich formatting as we can't control recipe
+# formatting from here
+basic_logger = logging.getLogger('basic_logger')
+basic_logger.addHandler(logging.StreamHandler(sys.stdout))
+basic_logger.propagate = False
class PassthroughAdapter:
"""Doesn't filter anything, just logs everything from the recipe run."""
def ProcessLine(self, line):
- logging.log(logging.DEBUG, line)
+ basic_logger.log(logging.DEBUG, line)
def GetTestResultsLink(self):
return None
@@ -127,17 +115,17 @@
def _StdoutProcessLine(self, line):
if not line.startswith(self.ANNOTATOR_PREFIX_SUFIX):
# Pass through any non-engine text
- logging.log(self._current_log_level, line)
+ basic_logger.log(self._current_log_level, line)
def _StepNameProcessLine(self, line):
if line.startswith(self.SEED_STEP_TEXT):
# Always print the step name to info
logging.log(self._current_log_level,
- '\nRunning: ' + self._current_step_name)
+ '\n[cyan]Running: ' + self._current_step_name + '[/]')
return
if not line.startswith(self.ANNOTATOR_PREFIX_SUFIX):
# Pass through any non-engine text
- logging.log(self._current_log_level, line)
+ basic_logger.log(self._current_log_level, line)
def _ProcessTriggerLine(self, line):
if line.startswith(self.SEED_STEP_TEXT + self.TRIGGER_STEP_PREFIX):
@@ -152,26 +140,26 @@
matches = self._trigger_link_re.match(line)
if matches:
task_name = self._current_step_name[len(self.TRIGGER_STEP_PREFIX):]
- logging.log(self._current_log_level,
- f'Triggered {task_name}: ' + matches[1])
+ basic_logger.log(self._current_log_level,
+ f'Triggered {task_name}: ' + matches[1])
else:
self._StdoutProcessLine(line)
def _ProcessCompileLine(self, line):
if line.startswith(self.SEED_STEP_TEXT):
- logging.info('\nRunning: ' + self._current_step_name)
+ logging.info('\n[cyan]Running: ' + self._current_step_name + '[/]')
return
matches = self._ninja_status_re.match(line)
if matches:
self._single_line_logger.log(self._current_log_level, '\33[2K\r' + line)
return
if self._last_line.startswith('['):
- logging.log(self._current_log_level, '')
+ basic_logger.log(self._current_log_level, '')
self._StdoutProcessLine(line)
def _ProcessCollectLine(self, line):
if line.startswith(self.SEED_STEP_TEXT):
- logging.info('\nRunning: ' + self._current_step_name)
+ logging.info('\n[cyan]Running: ' + self._current_step_name + '[/]')
matches = self._collect_wait_re.match(line)
if matches:
task_ids = json.loads(matches[2])['task_id']
@@ -184,13 +172,14 @@
if line == self.STEP_CLOSED_TEXT:
self._single_line_logger.log(self._current_log_level,
'\33[2K\rStill waiting on: 0 shard(s)...')
- logging.log(self._current_log_level, '')
+ basic_logger.log(self._current_log_level, '')
def _ProcessResult(self, line):
matches = self._result_links_re.match(line)
if matches:
- logging.log(self._current_log_level, 'Test results for %s shard %s: %s',
- self._current_step_name, matches[1], matches[2])
+ basic_logger.log(self._current_log_level,
+ 'Test results for %s shard %s: %s',
+ self._current_step_name, matches[1], matches[2])
def ProcessLine(self, line):
# If we're in a new step see if it needs to be parsed differently