1############################################################################### 2# Copyright (c) 2013 INRIA 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License version 2 as 6# published by the Free Software Foundation; 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16# 17# Authors: Daniel Camara <daniel.camara@inria.fr> 18# Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 19############################################################################### 20''' 21 ModuleLogger.py 22 23 This file stores the logger implementation. The logger is responsible for 24 logging the messages and control the level of information showed to the 25 user. 26''' 27 28import sys 29import os 30from bake.Exceptions import NotImplemented 31 32class ModuleLogger: 33 """ The logger class. The logger is responsible for logging the messages 34 and control the level of information showed to the user. 35 """ 36 sendToFile=None 37 38 def __init__(self): 39 """ Initializes the used variables.""" 40 41 self._verbose = None 42 self._command_file = open(os.devnull, 'w') 43 self._std_file = None 44 self._dump_file = None 45 46 def _update_file(self, f): 47 """ Opens/changes the output devices accordingly to the verbose level.""" 48 49 if self._verbose == 0: 50 self._command_file = open(os.devnull, 'w') 51 self._std_file = open(os.devnull, 'w') 52 elif self._verbose == 1: 53 self._command_file = f 54 self._std_file = open(os.devnull, 'w') 55 elif self._verbose == 2: 56 self._command_file = f 57 self._std_file = f 58 59 if self.sendToFile : 60 self._dump_file = open(self.sendToFile, 'w') 61 62 def set_verbose(self, verbose): 63 """ Sets verbosity level.""" 64 65 self._verbose = verbose if verbose <= 2 else 2 66 67 # empty implementations, to be re-implemented by the descendants 68 def set_current_module(self, name): 69 raise NotImplemented() 70 def clear_current_module(self): 71 raise NotImplemented() 72 73 @property 74 def stdout(self): 75 """ Returns the in use standard out put.""" 76 77 return self._std_file 78 @property 79 def stderr(self): 80 """ Returns the in use error out put.""" 81 82 return self._std_file 83 @property 84 def commands(self): 85 return self._command_file 86 87 88class StdoutModuleLogger(ModuleLogger): 89 """ The Standard output logger, where all the outputs go to the stdout.""" 90 91 def __init__(self): 92 """ Initializes the used variables.""" 93 94 ModuleLogger.__init__(self) 95 self._file=sys.__stdout__ 96 self._update_file(self._file) 97 98 def set_current_module(self, name): 99 """ Sets stdout as the output as the output for the module.""" 100 101 self._update_file(sys.__stdout__) 102 103 def clear_current_module(self): 104 """ Not implemented, as the output is always the same, one does 105 not need to reset it. 106 """ 107 pass 108 109class LogfileModuleLogger(ModuleLogger): 110 """ The file output logger, all the outputs go to the same log file.""" 111 112 def __init__(self, filename): 113 """ Initializes the used variables.""" 114 115 ModuleLogger.__init__(self) 116 self._file = open(filename, 'w') 117 118 def set_current_module(self, name): 119 """ Sets the file the output as the output for the module.""" 120 121 self._update_file(self._file) 122 123 def clear_current_module(self): 124 """ Not implemented, as the output is always the same, one does 125 not need to reset it. 126 """ 127 pass 128 129class LogdirModuleLogger(ModuleLogger): 130 """ Logs the output for a repository, i.e. one log file per module.""" 131 132 def __init__(self, dirname): 133 """ Initializes the used variables.""" 134 135 if not os.path.isdir(dirname): 136 os.mkdir(dirname) 137 self._dirname = dirname 138 self._file = None 139 140 def set_current_module(self, name): 141 """ Sets the output file in accordance to the module in use, so that 142 the log outputs will be separated by module. 143 """ 144 145 # XXX: we should be checking for other reserved characters 146 import re 147 filename = re.sub('/', '_', name) 148 assert self._file is None 149 self._file = open(os.path.join(self._dirname, filename + '.log'), 'w') 150 self._update_file(self._file) 151 152 def clear_current_module(self): 153 """ Cleans the output for the next module.""" 154 155 self._file.close() 156 self._file = None 157 158