From 47579e693b43690fff5da8ec47c862f6c41cedf6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 26 Mar 2020 04:04:42 -0700 Subject: [PATCH] scons: Use the textwrap module to wrap warnings/errors neatly. Otherwise the error and warning messages get chopped off and wrapped by the terminal wherever they happened to end. That's ugly and hard to read. This mechanism attempts to wrap the text using the console width which it attempts to determine in two ways, first with shutil which should work in python 3.3 and above, and then with the curses python module. If neither of those works, it just falls back to 80 columns which is not ideal but is reasonable. Change-Id: I961936295505f93f5f36eb6d9cebc5073b5f793b Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27128 Reviewed-by: Bobby R. Bruce Maintainer: Gabe Black Tested-by: kokoro --- site_scons/gem5_scons/__init__.py | 42 ++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/site_scons/gem5_scons/__init__.py b/site_scons/gem5_scons/__init__.py index 16bb753af..e7e7a0afc 100644 --- a/site_scons/gem5_scons/__init__.py +++ b/site_scons/gem5_scons/__init__.py @@ -41,6 +41,7 @@ from __future__ import print_function import os +import textwrap from gem5_scons.util import get_termcap import SCons.Script @@ -127,9 +128,48 @@ class Transform(object): return ', '.join(f) return self.format % (com_pfx, fmt(srcs), fmt(tgts)) +# The width warning and error messages should be wrapped at. +text_width = None + +# This should work in python 3.3 and above. +if text_width is None: + try: + import shutil + text_width = shutil.get_terminal_size().columns + except: + pass + +# This should work if the curses python module is installed. +if text_width is None: + try: + import curses + try: + _, text_width = curses.initscr().getmaxyx() + finally: + curses.endwin() + except: + pass + +# If all else fails, default to 80 columns. +if text_width is None: + text_width = 80 + def print_message(prefix, color, message, **kwargs): + # Precompute some useful values. + prefix_len = len(prefix) + wrap_width = text_width - prefix_len + padding = ' ' * prefix_len + + # First split on newlines. lines = message.split('\n') - message = prefix + ('\n' + ' ' * len(prefix)).join(lines) + # Then wrap each line to the required width. + wrapped_lines = [] + for line in lines: + wrapped_lines.extend(textwrap.wrap(line, wrap_width)) + # Finally add the prefix and padding on extra lines, and glue it all back + # together. + message = prefix + ('\n' + padding).join(wrapped_lines) + # Print the message in bold in the requested color. print(color + termcap.Bold + message + termcap.Normal, **kwargs) def warning(*args, **kwargs): -- 2.30.2