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