fork chromite.lib.terminal

Since generate_test_report uses the terminal module, fork it into
autotest.  We reformat & strip unused code in the process.

BUG=chromium:1049711
TEST=CQ passes

Change-Id: If63988934aedc6d3470cc9b6e7bf2bcfac2afed7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2042361
Reviewed-by: Jacob Kopczynski <jkop@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/site_utils/generate_test_report b/site_utils/generate_test_report
index 2b79509..a257d4b 100755
--- a/site_utils/generate_test_report
+++ b/site_utils/generate_test_report
@@ -20,17 +20,7 @@
 import sys
 
 import common
-try:
-    # Ensure the chromite site-package is installed.
-    from chromite.lib import terminal
-except ImportError:
-    import subprocess
-    build_externals_path = os.path.join(
-            os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
-            'utils', 'build_externals.py')
-    subprocess.check_call([build_externals_path, 'chromiterepo'])
-    # Restart the script so python now finds the autotest site-packages.
-    sys.exit(os.execv(__file__, sys.argv))
+from autotest_lib.utils import terminal
 
 
 _STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
diff --git a/utils/terminal.py b/utils/terminal.py
new file mode 100644
index 0000000..94298d4
--- /dev/null
+++ b/utils/terminal.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Terminal utilities
+
+This module handles terminal interaction including ANSI color codes.
+"""
+
+from __future__ import print_function
+
+
+class Color(object):
+    """Conditionally wraps text in ANSI color escape sequences."""
+
+    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
+    BOLD = -1
+    COLOR_START = '\033[1;%dm'
+    BOLD_START = '\033[1m'
+    RESET = '\033[0m'
+
+
+    def __init__(self, enabled):
+      """Create a new Color object, optionally disabling color output.
+
+      Args:
+        enabled: True if color output should be enabled. If False then this
+          class will not add color codes at all.
+      """
+      self._enabled = enabled
+
+
+    def Start(self, color):
+      """Returns a start color code.
+
+      Args:
+        color: Color to use, .e.g BLACK, RED, etc.
+
+      Returns:
+        If color is enabled, returns an ANSI sequence to start the given color,
+        otherwise returns empty string
+      """
+      if self._enabled:
+          return self.COLOR_START % (color + 30)
+      return ''
+
+
+    def Stop(self):
+      """Returns a stop color code.
+
+      Returns:
+        If color is enabled, returns an ANSI color reset sequence, otherwise
+        returns empty string
+      """
+      if self._enabled:
+          return self.RESET
+      return ''
+
+    def Color(self, color, text):
+      """Returns text with conditionally added color escape sequences.
+
+      Keyword arguments:
+        color: Text color -- one of the color constants defined in this class.
+        text: The text to color.
+
+      Returns:
+        If self._enabled is False, returns the original text. If it's True,
+        returns text with color escape sequences based on the value of color.
+      """
+      if not self._enabled:
+          return text
+      if color == self.BOLD:
+          start = self.BOLD_START
+      else:
+          start = self.COLOR_START % (color + 30)
+      return start + text + self.RESET