Source code for gdeps.reporting

#!python3

# Copyright 2007-2017 Gemr. All Rights Reserved.
# Licensed to MIT see LICENSE.txt

import os
import re
import json

__author__ = 'Suryavarman (http://sourceforge.net/u/suryavarman/profile/)'


[docs]class MacroReporting: """ reporting m_Errors = errors dictionary, m_Warnings = warnings dictionary Example : 1) Print each codblocks.workspace errors from the target all. Don't use directly a key name like that. In this case it's to illustrate the key name meaning: for error in aMacroReporting.m_Errors["all - codblocks.workspace"]: print( error ) 2) Test if there a error: assert not aMacroReporting.m_Errors, "There some errors." @link http://www.pyregex.com/ @link https://regex101.com/#python """ def __init__(self): self.m_Errors = {} self.m_Warnings = {}
[docs] def appendIssues(self, inIssues, inReportingId, outDictionary): if not inReportingId in outDictionary: outDictionary[inReportingId] = [] for aIssue in inIssues: outDictionary[inReportingId].append(aIssue)
[docs] def append(self, inReporting, inReportingId, inLogFilePath="output.log", inOnlyError=False): """ send a GDeps.Reporting object, an Id to represent the log file, the log file name and if you want only the errors. """ aReporting = inReporting.get(inLogFilePath, inOnlyError) self.appendIssues(aReporting[0], inReportingId, self.m_Errors) self.appendIssues(aReporting[1], inReportingId, self.m_Warnings)
[docs] def append2(self, inMacroReporting): """ add the report from a GDeps.MacroReporting""" for aId, aErrors in inMacroReporting.m_Errors.items(): self.appendIssues(aErrors, aId, self.m_Errors) for aId, aWarnings in inMacroReporting.m_Warnings.items(): self.appendIssues(aWarnings, aId, self.m_Warnings)
[docs] def getlen(self, inReports): aResult = 0 for aIssues in inReports.values(): aResult += len(aIssues) return aResult
[docs] def getCountReports(self, inReports): """ Warning : You can have an empty reports """ return len(inReports)
[docs] def printIssues(self): print("----------------------------------------------------------------------") print("Total count issues :") print(" - errors : " + str(self.getlen(self.m_Errors))) print(" - warnings : " + str(self.getlen(self.m_Warnings))) print("======================================================================") print("Count errors reports : " + str(self.getCountReports(self.m_Errors))) for aErrorId, aErrorDescs in self.m_Errors.items(): print("----------------------------------------------------------------------") print("Error Report : " + aErrorId) for aErrorDesc in aErrorDescs: print(aErrorDesc) print("======================================================================") print("Count warnings reports : " + str(self.getCountReports(self.m_Warnings))) for aWarningId, aWarningDescs in self.m_Warnings.items(): print("----------------------------------------------------------------------") print("Warning Report : " + aWarningId) for aWarningDesc in aWarningDescs: print(aWarningDesc) print("======================================================================") print("======================================================================")
[docs] def exportJson(self, inFileName='report.json', inPath=r'.\\'): """ Export the reporting to a json file :param inFileName: This is the filename and the wildcard has to be include. :type inFileName: str :param inPath: By default the local path :type inPath: str .. note:: aFullFileName = inPath + '\\' + inFileName :raise if the output file cannot be create """ aReport = {"errors": self.m_Errors, "warnings": self.m_Warnings} aFullFileName = inPath + r'\\' + inFileName with open(aFullFileName, 'w') as aFile: json.dump(aReport, aFile) assert os.path.exists(aFullFileName), 'The file ' + aFullFileName + ' cannot be save.'
[docs]class Reporting: """ Define your expression regular to find the error, warnings in your objects log. """ def __init__(self, inErrorRegEx=r"error", inWarningRegEx=r"warning", inSplitRegexp=r"\n+", inErrorRegexpMultiline="", inWarningRegexpMultiline=""): self.m_SplitRegexp = inSplitRegexp """ slpit the log in group. Each group matching group will be send in the report """ self.m_ErrorRegexp = inErrorRegEx """ if a splitting group match with this expression, this group will be send like a error """ self.m_WarningRegexp = inWarningRegEx """ if a splitting group match with this expression, this group will be send like a warning. """ self.m_ErrorRegexpMultiline = inErrorRegexpMultiline """ if a group match with this expression, this group will be send like a error. @remarks Multi-line mean the search/match will be execute on the entire text. """ self.m_WarningRegexpMultiline = inWarningRegexpMultiline """ if a group match with this expression, this group will be send like a warning. @remarks Multi-line mean the search/match will be execute on the entire text. """
[docs] def get(self, inLogFilePath="output.log", inOnlyError=False): """ Get the errors and the warning from inLogFilePath. return an array of arrays [0][ errors ] [1][ warnings ] """ aReporting = [] aLogFileExist = os.path.exists(inLogFilePath) assert aLogFileExist, "The log file doesn't exist : " + inLogFilePath aErrors = [] aWarnings = [] if aLogFileExist: """ @link https://docs.python.org/3/library/re.html @link http://apprendre-python.com/page-expressions-regulieres-regular-python @link https://stackoverflow.com/questions/5820779/python-regular-expression-to-get-filename-in-a-long-path """ with open(inLogFilePath, "r") as aLog: aLogstr = aLog.read() if self.m_ErrorRegexpMultiline: aErrorSearch = re.search(self.m_ErrorRegexpMultiline, aLogstr) if aErrorSearch and (aErrorSearch.span()[0] != aErrorSearch.span()[1]): aEntrie = aLogstr[aErrorSearch.span()[0]: aErrorSearch.span()[1]] aErrors.append(aEntrie) if self.m_WarningRegexpMultiline: aWarningSearch = re.search(self.m_WarningRegexpMultiline, aLogstr) if aWarningSearch and (aWarningSearch.span()[0] != aWarningSearch.span()[1]): aEntrie = aLogstr[aWarningSearch.span()[0]: aWarningSearch.span()[1]] aWarnings.append(aEntrie) aEntries = re.split(self.m_SplitRegexp, aLogstr) for aEntrie in aEntries: if self.m_ErrorRegexp and re.match(self.m_ErrorRegexp, aEntrie): aErrors.append(aEntrie) if not inOnlyError and self.m_WarningRegexp and re.match(self.m_WarningRegexp, aEntrie): aWarnings.append(aEntrie) aReporting.append(aErrors) aReporting.append(aWarnings) return aReporting
[docs] def printIssues(self, inReportingResult): aErrors = inReportingResult[0] aWarnings = inReportingResult[1] print("----------------------------------------------------------------------") print("Count errors : " + str(len(aErrors))) for aError in aErrors: print(aError) print("----------------------------------------------------------------------") print("Count warnings : " + str(len(aWarnings))) for aWarning in aWarnings: print(aWarning) print("======================================================================") print("======================================================================")
[docs]def getLogFileContent(inLogFilePath): """ Use this function to save the previous log. >>> GDeps.call('call "app1.exe" > "test.log" 2>&1') >>> aContent = GDeps.getLogFileContent('test.log') >>> GDeps.call('call "app2.exe" > "test.log" 2>&1') >>> GDeps.pushFrontLogFileContent('test.log', aContent) """ aResult = '' with open(inLogFilePath) as aFile: aResult = aFile.read() return aResult
[docs]def pushFrontLogFileContent(inLogFilePath, inContent): """ Use this function to save the previous log. >>> GDeps.call('call "app1.exe" > "test.log" 2>&1') >>> aContent = GDeps.getLogFileContent('test.log') >>> GDeps.call('call "app2.exe" > "test.log" 2>&1') >>> GDeps.pushFrontLogFileContent('test.log', aContent) """ with open(inLogFilePath, 'r+') as aFile: aNewContent = aFile.read() aFile.seek(0, 0) aFile.write(inContent) aFile.write(aNewContent)
[docs]def clearLogFile(inLogFilePath): """ Use this function before to the first time to write into the log file. :param inLogFilePath: The log file path. :type inLogFilePath: str """ open(inLogFilePath, 'w').close()