# 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
#<editor-fold desc="Logging">
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 )
#</editor-fold>
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()