# Copyright (C) 2013 Jaedyn K. Draper # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """ **Logging Module** """ import threading import time import math import sys from . import _shared_globals from . import terminfo # logMutex = threading.Lock() def LOG_MSG( color, level, msg, quietThreshold ): """Print a message to stdout""" with logMutex: if _shared_globals.quiet < quietThreshold: if _shared_globals.color_supported: terminfo.TermInfo.SetColor( color ) sys.stdout.write( "{}: ".format( level ) ) sys.stdout.flush() terminfo.TermInfo.ResetColor( ) sys.stdout.write( msg ) sys.stdout.write( "\n" ) else: print("{0}: {1}".format( level, msg )) sys.stdout.flush() if _shared_globals.logFile: _shared_globals.logFile.write("{0}: {1}\n".format( level, msg )) def LOG_ERROR( msg ): """ Log an error message :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.RED, "ERROR", msg, 3 ) _shared_globals.errors.append( msg ) def LOG_WARN( msg ): """ Log a warning :param msg: Text to log :type msg: str """ LOG_WARN_NOPUSH( msg ) _shared_globals.warnings.append( msg ) def LOG_WARN_NOPUSH( msg ): """ Log a warning, don't push it to the list of warnings to be echoed at the end of compilation. :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.YELLOW, "WARN", msg, 3 ) def LOG_INFO( msg ): """ Log general info. This info only appears with -v specified. :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.CYAN, "INFO", msg, 1 ) def LOG_BUILD( msg ): """ Log info related to building :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.MAGENTA, "BUILD", msg, 2 ) def LOG_LINKER( msg ): """ Log info related to linking :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.GREEN, "LINKER", msg, 2 ) def LOG_THREAD( msg ): """ Log info related to threads, particularly stalls caused by waiting on another thread to finish :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.BLUE, "THREAD", msg, 2 ) def LOG_INSTALL( msg ): """ Log info related to the installer :param msg: Text to log :type msg: str """ LOG_MSG( terminfo.TermColor.WHITE, "INSTALL", msg, 2 ) # class stdoutWriter( object ): def __init__( self, oldstdout ): self.stdout = oldstdout self.barPresent = False self.mutex = threading.Lock() def write( self, text ): if not text: return with self.mutex: if self.barPresent: self.stdout.write( "\r" + " " * _shared_globals.columns + "\r" ) self.stdout.write(text) if _shared_globals.forceProgressBar == "on": _shared_globals.columns = 80 elif _shared_globals.forceProgressBar == "off": _shared_globals.columns = 0 else: _shared_globals.columns = terminfo.TermInfo.GetNumColumns( ) if text.endswith("\n") and _shared_globals.columns != 0 and not _shared_globals.buildFinished and _shared_globals.total_compiles > 0: self.barPresent = True curtime = time.time( ) - _shared_globals.starttime if _shared_globals.columns > 0: minutes = math.floor( curtime / 60 ) seconds = math.floor( curtime % 60 ) totalCompletedCompiles = 0 for project in _shared_globals.sortedProjects: totalCompletedCompiles += project.compilationCompleted perc = 1 if _shared_globals.total_compiles == 0 else float(totalCompletedCompiles)/float(_shared_globals.total_compiles) num = int( math.floor( perc * (_shared_globals.columns - 10) ) ) if num >= _shared_globals.columns - 10: num = _shared_globals.columns - 11 perc = int(round(perc * 100)) if perc == 100: perc = 99 self.stdout.write( "[" + "=" * num + " " * ( ( _shared_globals.columns - 10 ) - num ) + "](~{2: 3}%)".format( int( minutes ), int( seconds ), perc ) ) self.stdout.flush( ) else: self.barPresent = False def flush(self): self.stdout.flush()