Use the existing terminal code to handle ANSI colours. Enable colour by
default if the output is going to a terminal.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 tools/moveconfig.py | 92 +++++++++++++++++++--------------------------
 1 file changed, 38 insertions(+), 54 deletions(-)

diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index f4fb3f46b81..30d8489f7e3 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -33,6 +33,7 @@ import asteval
 from buildman import bsettings
 from buildman import kconfiglib
 from buildman import toolchain
+from u_boot_pylib import terminal
 
 SHOW_GNU_MAKE = 'scripts/show-gnu-make'
 SLEEP_TIME=0.03
@@ -42,23 +43,6 @@ STATE_DEFCONFIG = 1
 STATE_AUTOCONF = 2
 STATE_SAVEDEFCONFIG = 3
 
-COLOR_BLACK        = '0;30'
-COLOR_RED          = '0;31'
-COLOR_GREEN        = '0;32'
-COLOR_BROWN        = '0;33'
-COLOR_BLUE         = '0;34'
-COLOR_PURPLE       = '0;35'
-COLOR_CYAN         = '0;36'
-COLOR_LIGHT_GRAY   = '0;37'
-COLOR_DARK_GRAY    = '1;30'
-COLOR_LIGHT_RED    = '1;31'
-COLOR_LIGHT_GREEN  = '1;32'
-COLOR_YELLOW       = '1;33'
-COLOR_LIGHT_BLUE   = '1;34'
-COLOR_LIGHT_PURPLE = '1;35'
-COLOR_LIGHT_CYAN   = '1;36'
-COLOR_WHITE        = '1;37'
-
 AUTO_CONF_PATH = 'include/config/auto.conf'
 CONFIG_DATABASE = 'moveconfig.db'
 
@@ -189,15 +173,6 @@ def get_all_defconfigs():
 
     return defconfigs
 
-def color_text(color_enabled, color, string):
-    """Return colored string."""
-    if color_enabled:
-        # LF should not be surrounded by the escape sequence.
-        # Otherwise, additional whitespace or line-feed might be printed.
-        return '\n'.join([ '\033[' + color + 'm' + s + '\033[0m' if s else ''
-                           for s in string.split('\n') ])
-    return string
-
 def write_file(fname, data):
     """Write data to a file
 
@@ -385,8 +360,8 @@ class Slot:
     for faster processing.
     """
 
-    def __init__(self, toolchains, args, progress, devnull,
-                make_cmd, reference_src_dir, db_queue):
+    def __init__(self, toolchains, args, progress, devnull, make_cmd,
+                 reference_src_dir, db_queue, col):
         """Create a new process slot.
 
         Args:
@@ -398,6 +373,7 @@ class Slot:
           reference_src_dir: Determine the true starting config state from this
                              source tree.
           db_queue: output queue to write config info for the database
+          col (terminal.Color): Colour object
         """
         self.toolchains = toolchains
         self.args = args
@@ -407,6 +383,7 @@ class Slot:
         self.make_cmd = (make_cmd, 'O=' + self.build_dir)
         self.reference_src_dir = reference_src_dir
         self.db_queue = db_queue
+        self.col = col
         self.parser = KconfigParser(args, self.build_dir)
         self.state = STATE_IDLE
         self.failed_boards = set()
@@ -499,12 +476,11 @@ class Slot:
     def handle_error(self):
         """Handle error cases."""
 
-        self.log.append(color_text(self.args.color, COLOR_LIGHT_RED,
-                                   'Failed to process'))
+        self.log.append(self.col.build(self.col.RED, 'Failed to process',
+                                       bright=True))
         if self.args.verbose:
             for line in self.proc.stderr.read().decode().splitlines():
-                self.log.append(color_text(self.args.color, COLOR_LIGHT_CYAN,
-                                           line))
+                self.log.append(self.col.build(self.col.CYAN, line, True))
         self.finish(False)
 
     def do_defconfig(self):
@@ -524,8 +500,9 @@ class Slot:
         try:
             tchain = self.toolchains.Select(arch)
         except ValueError:
-            self.log.append(color_text(self.args.color, COLOR_YELLOW,
-                    f"Tool chain for '{arch}' is missing: do nothing"))
+            self.log.append(self.col.build(
+                self.col.YELLOW,
+                f"Tool chain for '{arch}' is missing: do nothing"))
             self.finish(False)
             return
         env = tchain.MakeEnvironment(False)
@@ -567,8 +544,8 @@ class Slot:
         updated = not filecmp.cmp(orig_defconfig, new_defconfig)
 
         if updated:
-            self.log.append(color_text(self.args.color, COLOR_LIGHT_BLUE,
-                                       'defconfig updated'))
+            self.log.append(
+                self.col.build(self.col.BLUE, 'defconfig updated', 
bright=True))
 
         if not self.args.dry_run and updated:
             shutil.move(new_defconfig, orig_defconfig)
@@ -614,24 +591,27 @@ class Slots:
 
     """Controller of the array of subprocess slots."""
 
-    def __init__(self, toolchains, args, progress, reference_src_dir, 
db_queue):
+    def __init__(self, toolchains, args, progress, reference_src_dir, db_queue,
+                 col):
         """Create a new slots controller.
 
         Args:
-          toolchains: Toolchains object containing toolchains.
-          args: Program arguments
-          progress: A progress indicator.
-          reference_src_dir: Determine the true starting config state from this
-                             source tree.
-          db_queue: output queue to write config info for the database
+            toolchains (Toolchains): Toolchains object containing toolchains
+            args (Namespace): Program arguments
+            progress (Progress): A progress indicator.
+            reference_src_dir (str): Determine the true starting config state
+                from this source tree (None for none)
+            db_queue (Queue): output queue to write config info for the 
database
+            col (terminal.Color): Colour object
         """
         self.args = args
         self.slots = []
+        self.col = col
         devnull = subprocess.DEVNULL
         make_cmd = get_make_cmd()
         for _ in range(args.jobs):
             self.slots.append(Slot(toolchains, args, progress, devnull,
-                                   make_cmd, reference_src_dir, db_queue))
+                                   make_cmd, reference_src_dir, db_queue, col))
 
     def add(self, defconfig):
         """Add a new subprocess if a vacant slot is found.
@@ -683,8 +663,8 @@ class Slots:
             msg = 'The following boards were not processed due to error:\n'
             msg += boards
             msg += f'(the list has been saved in {output_file})\n'
-            print(color_text(self.args.color, COLOR_LIGHT_RED,
-                                            msg), file=sys.stderr)
+            print(self.col.build(self.col.RED, msg, bright=True),
+                  file=sys.stderr)
 
             write_file(output_file, boards)
 
@@ -723,13 +703,14 @@ class ReferenceSource:
 
         return self.src_dir
 
-def move_config(toolchains, args, db_queue):
+def move_config(toolchains, args, db_queue, col):
     """Build database or sync config options to defconfig files.
 
     Args:
-      toolchains (Toolchains): Toolchains to use
-      args (Namespace): Program arguments
-      db_queue (Queue): Queue for database updates
+        toolchains (Toolchains): Toolchains to use
+        args (Namespace): Program arguments
+        db_queue (Queue): Queue for database updates
+        col (terminal.Color): Colour object
     """
     if args.force_sync:
         print('Syncing defconfigs', end=' ')
@@ -749,7 +730,7 @@ def move_config(toolchains, args, db_queue):
         defconfigs = get_all_defconfigs()
 
     progress = Progress(len(defconfigs))
-    slots = Slots(toolchains, args, progress, reference_src_dir, db_queue)
+    slots = Slots(toolchains, args, progress, reference_src_dir, db_queue, col)
 
     # Main loop to process defconfig files:
     #  Add a new subprocess into a vacant slot.
@@ -1495,8 +1476,8 @@ doc/develop/moveconfig.rst for documentation.'''
                       'implying others')
     parser.add_argument('-b', '--build-db', action='store_true', default=False,
                       help='build a CONFIG database')
-    parser.add_argument('-c', '--color', action='store_true', default=False,
-                      help='display the log in color')
+    parser.add_argument('-C', '--nocolour', action='store_true', default=False,
+                      help="don't display the log in colour")
     parser.add_argument('-d', '--defconfigs', type=str,
                       help='a file containing a list of defconfigs to move, '
                       "one per line (for example 'snow_defconfig') "
@@ -1541,6 +1522,9 @@ doc/develop/moveconfig.rst for documentation.'''
             return 1
         unittest.main()
 
+    col = terminal.Color(terminal.COLOR_NEVER if args.nocolour
+                         else terminal.COLOR_IF_TERMINAL)
+
     if args.scan_source:
         do_scan_source(os.getcwd(), args.update)
         return 0
@@ -1591,7 +1575,7 @@ doc/develop/moveconfig.rst for documentation.'''
     toolchains = toolchain.Toolchains()
     toolchains.GetSettings()
     toolchains.Scan(verbose=False)
-    move_config(toolchains, args, db_queue)
+    move_config(toolchains, args, db_queue, col)
     db_queue.join()
 
     if args.build_db:
-- 
2.41.0.640.ga95def55d0-goog

Reply via email to