1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright (c) 2016 Google, Inc 3# 4# 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 18""" 19This class handles output of progress and other useful information 20to the user. It provides for simple verbosity level control and can 21output nothing but errors at verbosity zero. 22 23The idea is that modules set up an Output object early in their years and pass 24it around to other modules that need it. This keeps the output under control 25of a single class. 26 27Public properties: 28 verbose: Verbosity level: 0=silent, 1=progress, 3=full, 4=debug 29""" 30def __enter__(): 31 return 32 33def __exit__(unused1, unused2, unused3): 34 """Clean up and remove any progress message.""" 35 ClearProgress() 36 return False 37 38def UserIsPresent(): 39 """This returns True if it is likely that a user is present. 40 41 Sometimes we want to prompt the user, but if no one is there then this 42 is a waste of time, and may lock a script which should otherwise fail. 43 44 Returns: 45 True if it thinks the user is there, and False otherwise 46 """ 47 return stdout_is_tty and verbose > 0 48 49def ClearProgress(): 50 """Clear any active progress message on the terminal.""" 51 if verbose > 0 and stdout_is_tty: 52 _stdout.write('\r%s\r' % (" " * len (_progress))) 53 _stdout.flush() 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 ClearProgress() 62 if verbose > 0: 63 _progress = msg + trailer 64 if stdout_is_tty: 65 col = _color.YELLOW if warning else _color.GREEN 66 _stdout.write('\r' + _color.Color(col, _progress)) 67 _stdout.flush() 68 else: 69 _stdout.write(_progress + '\n') 70 71def _Output(level, msg, color=None): 72 """Output a message to the terminal. 73 74 Args: 75 level: Verbosity level for this message. It will only be displayed if 76 this as high as the currently selected level. 77 msg; Message to display. 78 error: True if this is an error message, else False. 79 """ 80 if verbose >= level: 81 ClearProgress() 82 if color: 83 msg = _color.Color(color, msg) 84 _stdout.write(msg + '\n') 85 86def DoOutput(level, msg): 87 """Output a message to the terminal. 88 89 Args: 90 level: Verbosity level for this message. It will only be displayed if 91 this as high as the currently selected level. 92 msg; Message to display. 93 """ 94 _Output(level, msg) 95 96def Error(msg): 97 """Display an error message 98 99 Args: 100 msg; Message to display. 101 """ 102 _Output(0, msg, _color.RED) 103 104def Warning(msg): 105 """Display a warning message 106 107 Args: 108 msg; Message to display. 109 """ 110 _Output(1, msg, _color.YELLOW) 111 112def Notice(msg): 113 """Display an important infomation message 114 115 Args: 116 msg; Message to display. 117 """ 118 _Output(2, msg) 119 120def Info(msg): 121 """Display an infomation message 122 123 Args: 124 msg; Message to display. 125 """ 126 _Output(3, msg) 127 128def Debug(msg): 129 """Display a debug message 130 131 Args: 132 msg; Message to display. 133 """ 134 _Output(4, msg) 135 136def UserOutput(msg): 137 """Display a message regardless of the current output level. 138 139 This is used when the output was specifically requested by the user. 140 Args: 141 msg; Message to display. 142 """ 143 _Output(0, msg) 144 145def Init(_verbose=WARNING, stdout=sys.stdout): 146 """Initialize a new output object. 147 148 Args: 149 verbose: Verbosity level (0-4). 150 stdout: File to use for stdout. 151 """ 152 global verbose, _progress, _color, _stdout, stdout_is_tty 153 154 verbose = _verbose 155 _progress = '' # Our last progress message 156 _color = terminal.Color() 157 _stdout = stdout 158 159 # TODO(sjg): Move this into Chromite libraries when we have them 160 stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() 161 162def Uninit(): 163 ClearProgress() 164 165Init() 166