1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (c) 2016 Google, Inc 3# 4# Terminal output logging. 5# 6 7import sys 8 9from patman import terminal 10 11# Output verbosity levels that we support 12ERROR, WARNING, NOTICE, INFO, DETAIL, DEBUG = range(6) 13 14in_progress = False 15 16""" 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.""" 33 ClearProgress() 34 return False 35 36def UserIsPresent(): 37 """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 47def ClearProgress(): 48 """Clear any active progress message on the terminal.""" 49 global in_progress 50 if verbose > 0 and stdout_is_tty and in_progress: 51 _stdout.write('\r%s\r' % (" " * len (_progress))) 52 _stdout.flush() 53 in_progress = False 54 55def Progress(msg, warning=False, trailer='...'): 56 """Display progress information. 57 58 Args: 59 msg: Message to display. 60 warning: True if this is a warning.""" 61 global in_progress 62 ClearProgress() 63 if verbose > 0: 64 _progress = msg + trailer 65 if stdout_is_tty: 66 col = _color.YELLOW if warning else _color.GREEN 67 _stdout.write('\r' + _color.Color(col, _progress)) 68 _stdout.flush() 69 in_progress = True 70 else: 71 _stdout.write(_progress + '\n') 72 73def _Output(level, msg, color=None): 74 """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: 83 ClearProgress() 84 if color: 85 msg = _color.Color(color, msg) 86 if level < NOTICE: 87 print(msg, file=sys.stderr) 88 else: 89 print(msg) 90 91def DoOutput(level, msg): 92 """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 """ 99 _Output(level, msg) 100 101def Error(msg): 102 """Display an error message 103 104 Args: 105 msg; Message to display. 106 """ 107 _Output(ERROR, msg, _color.RED) 108 109def Warning(msg): 110 """Display a warning message 111 112 Args: 113 msg; Message to display. 114 """ 115 _Output(WARNING, msg, _color.YELLOW) 116 117def Notice(msg): 118 """Display an important infomation message 119 120 Args: 121 msg; Message to display. 122 """ 123 _Output(NOTICE, msg) 124 125def Info(msg): 126 """Display an infomation message 127 128 Args: 129 msg; Message to display. 130 """ 131 _Output(INFO, msg) 132 133def Detail(msg): 134 """Display a detailed message 135 136 Args: 137 msg; Message to display. 138 """ 139 _Output(DETAIL, msg) 140 141def Debug(msg): 142 """Display a debug message 143 144 Args: 145 msg; Message to display. 146 """ 147 _Output(DEBUG, msg) 148 149def UserOutput(msg): 150 """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 """ 156 _Output(0, msg) 157 158def Init(_verbose=WARNING, stdout=sys.stdout): 159 """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() 174 stderr_is_tty = hasattr(sys.stderr, 'isatty') and sys.stderr.isatty() 175 176def Uninit(): 177 ClearProgress() 178 179Init() 180