blob: 15acce28cb98c59bda37b7cc82a54879ec7330ec [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glassa2b840a2016-07-25 18:59:09 -06002# Copyright (c) 2016 Google, Inc
3#
Simon Glassa2b840a2016-07-25 18:59:09 -06004# Terminal output logging.
5#
6
7import sys
8
9import terminal
10
11# Output verbosity levels that we support
12ERROR = 0
13WARNING = 1
14NOTICE = 2
15INFO = 3
16DEBUG = 4
17
Simon Glasse6dafb82018-10-01 21:12:45 -060018in_progress = False
19
Simon Glassa2b840a2016-07-25 18:59:09 -060020"""
21This class handles output of progress and other useful information
22to the user. It provides for simple verbosity level control and can
23output nothing but errors at verbosity zero.
24
25The idea is that modules set up an Output object early in their years and pass
26it around to other modules that need it. This keeps the output under control
27of a single class.
28
29Public properties:
30 verbose: Verbosity level: 0=silent, 1=progress, 3=full, 4=debug
31"""
32def __enter__():
33 return
34
35def __exit__(unused1, unused2, unused3):
36 """Clean up and remove any progress message."""
37 ClearProgress()
38 return False
39
40def UserIsPresent():
41 """This returns True if it is likely that a user is present.
42
43 Sometimes we want to prompt the user, but if no one is there then this
44 is a waste of time, and may lock a script which should otherwise fail.
45
46 Returns:
47 True if it thinks the user is there, and False otherwise
48 """
49 return stdout_is_tty and verbose > 0
50
51def ClearProgress():
52 """Clear any active progress message on the terminal."""
Simon Glasse6dafb82018-10-01 21:12:45 -060053 global in_progress
54 if verbose > 0 and stdout_is_tty and in_progress:
Simon Glassa2b840a2016-07-25 18:59:09 -060055 _stdout.write('\r%s\r' % (" " * len (_progress)))
56 _stdout.flush()
Simon Glasse6dafb82018-10-01 21:12:45 -060057 in_progress = False
Simon Glassa2b840a2016-07-25 18:59:09 -060058
59def Progress(msg, warning=False, trailer='...'):
60 """Display progress information.
61
62 Args:
63 msg: Message to display.
64 warning: True if this is a warning."""
Simon Glasse6dafb82018-10-01 21:12:45 -060065 global in_progress
Simon Glassa2b840a2016-07-25 18:59:09 -060066 ClearProgress()
67 if verbose > 0:
68 _progress = msg + trailer
69 if stdout_is_tty:
70 col = _color.YELLOW if warning else _color.GREEN
71 _stdout.write('\r' + _color.Color(col, _progress))
72 _stdout.flush()
Simon Glasse6dafb82018-10-01 21:12:45 -060073 in_progress = True
Simon Glassa2b840a2016-07-25 18:59:09 -060074 else:
75 _stdout.write(_progress + '\n')
76
77def _Output(level, msg, color=None):
78 """Output a message to the terminal.
79
80 Args:
81 level: Verbosity level for this message. It will only be displayed if
82 this as high as the currently selected level.
83 msg; Message to display.
84 error: True if this is an error message, else False.
85 """
86 if verbose >= level:
87 ClearProgress()
88 if color:
89 msg = _color.Color(color, msg)
90 _stdout.write(msg + '\n')
91
92def DoOutput(level, msg):
93 """Output a message to the terminal.
94
95 Args:
96 level: Verbosity level for this message. It will only be displayed if
97 this as high as the currently selected level.
98 msg; Message to display.
99 """
100 _Output(level, msg)
101
102def Error(msg):
103 """Display an error message
104
105 Args:
106 msg; Message to display.
107 """
108 _Output(0, msg, _color.RED)
109
110def Warning(msg):
111 """Display a warning message
112
113 Args:
114 msg; Message to display.
115 """
116 _Output(1, msg, _color.YELLOW)
117
118def Notice(msg):
119 """Display an important infomation message
120
121 Args:
122 msg; Message to display.
123 """
124 _Output(2, msg)
125
126def Info(msg):
127 """Display an infomation message
128
129 Args:
130 msg; Message to display.
131 """
132 _Output(3, msg)
133
Simon Glass233a26a92019-07-08 14:25:49 -0600134def Detail(msg):
135 """Display a detailed message
136
137 Args:
138 msg; Message to display.
139 """
140 _Output(4, msg)
141
Simon Glassa2b840a2016-07-25 18:59:09 -0600142def Debug(msg):
143 """Display a debug message
144
145 Args:
146 msg; Message to display.
147 """
Simon Glass233a26a92019-07-08 14:25:49 -0600148 _Output(5, msg)
Simon Glassa2b840a2016-07-25 18:59:09 -0600149
150def UserOutput(msg):
151 """Display a message regardless of the current output level.
152
153 This is used when the output was specifically requested by the user.
154 Args:
155 msg; Message to display.
156 """
157 _Output(0, msg)
158
159def Init(_verbose=WARNING, stdout=sys.stdout):
160 """Initialize a new output object.
161
162 Args:
163 verbose: Verbosity level (0-4).
164 stdout: File to use for stdout.
165 """
166 global verbose, _progress, _color, _stdout, stdout_is_tty
167
168 verbose = _verbose
169 _progress = '' # Our last progress message
170 _color = terminal.Color()
171 _stdout = stdout
172
173 # TODO(sjg): Move this into Chromite libraries when we have them
174 stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
175
176def Uninit():
177 ClearProgress()
178
179Init()