blob: ff0fd92afcc07efaf759c968f8f513c1b5dc26b0 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glass0faf6142016-07-25 18:59:09 -06002# Copyright (c) 2016 Google, Inc
3#
Simon Glass0faf6142016-07-25 18:59:09 -06004# Terminal output logging.
5#
6
7import sys
8
Simon Glassbf776672020-04-17 18:09:04 -06009from patman import terminal
Simon Glass0faf6142016-07-25 18:59:09 -060010
11# Output verbosity levels that we support
Simon Glassfd073362019-07-20 12:23:35 -060012ERROR, WARNING, NOTICE, INFO, DETAIL, DEBUG = range(6)
Simon Glass0faf6142016-07-25 18:59:09 -060013
Simon Glass008b0302018-10-01 21:12:45 -060014in_progress = False
15
Simon Glass0faf6142016-07-25 18:59:09 -060016"""
17This class handles output of progress and other useful information
18to the user. It provides for simple verbosity level control and can
19output nothing but errors at verbosity zero.
20
21The idea is that modules set up an Output object early in their years and pass
22it around to other modules that need it. This keeps the output under control
23of a single class.
24
25Public properties:
26 verbose: Verbosity level: 0=silent, 1=progress, 3=full, 4=debug
27"""
28def __enter__():
29 return
30
31def __exit__(unused1, unused2, unused3):
32 """Clean up and remove any progress message."""
Simon Glassf3385a52022-01-29 14:14:15 -070033 clear_progress()
Simon Glass0faf6142016-07-25 18:59:09 -060034 return False
35
Simon Glassf3385a52022-01-29 14:14:15 -070036def user_is_present():
Simon Glass0faf6142016-07-25 18:59:09 -060037 """This returns True if it is likely that a user is present.
38
39 Sometimes we want to prompt the user, but if no one is there then this
40 is a waste of time, and may lock a script which should otherwise fail.
41
42 Returns:
43 True if it thinks the user is there, and False otherwise
44 """
45 return stdout_is_tty and verbose > 0
46
Simon Glassf3385a52022-01-29 14:14:15 -070047def clear_progress():
Simon Glass0faf6142016-07-25 18:59:09 -060048 """Clear any active progress message on the terminal."""
Simon Glass008b0302018-10-01 21:12:45 -060049 global in_progress
50 if verbose > 0 and stdout_is_tty and in_progress:
Simon Glass0faf6142016-07-25 18:59:09 -060051 _stdout.write('\r%s\r' % (" " * len (_progress)))
52 _stdout.flush()
Simon Glass008b0302018-10-01 21:12:45 -060053 in_progress = False
Simon Glass0faf6142016-07-25 18:59:09 -060054
Simon Glassf3385a52022-01-29 14:14:15 -070055def progress(msg, warning=False, trailer='...'):
Simon Glass0faf6142016-07-25 18:59:09 -060056 """Display progress information.
57
58 Args:
59 msg: Message to display.
60 warning: True if this is a warning."""
Simon Glass008b0302018-10-01 21:12:45 -060061 global in_progress
Simon Glassf3385a52022-01-29 14:14:15 -070062 clear_progress()
Simon Glass0faf6142016-07-25 18:59:09 -060063 if verbose > 0:
64 _progress = msg + trailer
65 if stdout_is_tty:
66 col = _color.YELLOW if warning else _color.GREEN
Simon Glass252ac582022-01-29 14:14:17 -070067 _stdout.write('\r' + _color.build(col, _progress))
Simon Glass0faf6142016-07-25 18:59:09 -060068 _stdout.flush()
Simon Glass008b0302018-10-01 21:12:45 -060069 in_progress = True
Simon Glass0faf6142016-07-25 18:59:09 -060070 else:
71 _stdout.write(_progress + '\n')
72
Simon Glassf3385a52022-01-29 14:14:15 -070073def _output(level, msg, color=None):
Simon Glass0faf6142016-07-25 18:59:09 -060074 """Output a message to the terminal.
75
76 Args:
77 level: Verbosity level for this message. It will only be displayed if
78 this as high as the currently selected level.
79 msg; Message to display.
80 error: True if this is an error message, else False.
81 """
82 if verbose >= level:
Simon Glassf3385a52022-01-29 14:14:15 -070083 clear_progress()
Simon Glass0faf6142016-07-25 18:59:09 -060084 if color:
Simon Glass252ac582022-01-29 14:14:17 -070085 msg = _color.build(color, msg)
Simon Glass38fdb4c2020-07-09 18:39:39 -060086 if level < NOTICE:
87 print(msg, file=sys.stderr)
88 else:
89 print(msg)
Simon Glass0faf6142016-07-25 18:59:09 -060090
Simon Glassf3385a52022-01-29 14:14:15 -070091def do_output(level, msg):
Simon Glass0faf6142016-07-25 18:59:09 -060092 """Output a message to the terminal.
93
94 Args:
95 level: Verbosity level for this message. It will only be displayed if
96 this as high as the currently selected level.
97 msg; Message to display.
98 """
Simon Glassf3385a52022-01-29 14:14:15 -070099 _output(level, msg)
Simon Glass0faf6142016-07-25 18:59:09 -0600100
Simon Glassf3385a52022-01-29 14:14:15 -0700101def error(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600102 """Display an error message
103
104 Args:
105 msg; Message to display.
106 """
Simon Glassf3385a52022-01-29 14:14:15 -0700107 _output(ERROR, msg, _color.RED)
Simon Glass0faf6142016-07-25 18:59:09 -0600108
Simon Glassf3385a52022-01-29 14:14:15 -0700109def warning(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600110 """Display a warning message
111
112 Args:
113 msg; Message to display.
114 """
Simon Glassf3385a52022-01-29 14:14:15 -0700115 _output(WARNING, msg, _color.YELLOW)
Simon Glass0faf6142016-07-25 18:59:09 -0600116
Simon Glassf3385a52022-01-29 14:14:15 -0700117def notice(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600118 """Display an important infomation message
119
120 Args:
121 msg; Message to display.
122 """
Simon Glassf3385a52022-01-29 14:14:15 -0700123 _output(NOTICE, msg)
Simon Glass0faf6142016-07-25 18:59:09 -0600124
Simon Glassf3385a52022-01-29 14:14:15 -0700125def info(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600126 """Display an infomation message
127
128 Args:
129 msg; Message to display.
130 """
Simon Glassf3385a52022-01-29 14:14:15 -0700131 _output(INFO, msg)
Simon Glass0faf6142016-07-25 18:59:09 -0600132
Simon Glassf3385a52022-01-29 14:14:15 -0700133def detail(msg):
Simon Glasseea264e2019-07-08 14:25:49 -0600134 """Display a detailed message
135
136 Args:
137 msg; Message to display.
138 """
Simon Glassf3385a52022-01-29 14:14:15 -0700139 _output(DETAIL, msg)
Simon Glasseea264e2019-07-08 14:25:49 -0600140
Simon Glassf3385a52022-01-29 14:14:15 -0700141def debug(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600142 """Display a debug message
143
144 Args:
145 msg; Message to display.
146 """
Simon Glassf3385a52022-01-29 14:14:15 -0700147 _output(DEBUG, msg)
Simon Glass0faf6142016-07-25 18:59:09 -0600148
Simon Glassf3385a52022-01-29 14:14:15 -0700149def user_output(msg):
Simon Glass0faf6142016-07-25 18:59:09 -0600150 """Display a message regardless of the current output level.
151
152 This is used when the output was specifically requested by the user.
153 Args:
154 msg; Message to display.
155 """
Simon Glassf3385a52022-01-29 14:14:15 -0700156 _output(0, msg)
Simon Glass0faf6142016-07-25 18:59:09 -0600157
Simon Glassf3385a52022-01-29 14:14:15 -0700158def init(_verbose=WARNING, stdout=sys.stdout):
Simon Glass0faf6142016-07-25 18:59:09 -0600159 """Initialize a new output object.
160
161 Args:
162 verbose: Verbosity level (0-4).
163 stdout: File to use for stdout.
164 """
165 global verbose, _progress, _color, _stdout, stdout_is_tty
166
167 verbose = _verbose
168 _progress = '' # Our last progress message
169 _color = terminal.Color()
170 _stdout = stdout
171
172 # TODO(sjg): Move this into Chromite libraries when we have them
173 stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
Simon Glassb1cca952020-07-09 18:39:40 -0600174 stderr_is_tty = hasattr(sys.stderr, 'isatty') and sys.stderr.isatty()
Simon Glass0faf6142016-07-25 18:59:09 -0600175
Simon Glassf3385a52022-01-29 14:14:15 -0700176def uninit():
177 clear_progress()
Simon Glass0faf6142016-07-25 18:59:09 -0600178
Simon Glassf3385a52022-01-29 14:14:15 -0700179init()