diff options
author | Guido Günther <agx@sigxcpu.org> | 2010-09-03 13:07:10 +0200 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2010-11-16 13:27:28 +0100 |
commit | 7e79bcd4ab0030db5c5a7998c81f63c48656be80 (patch) | |
tree | 89e8281c518e2ce705d99c3fc1f17aac30ae0124 /gbp | |
parent | c385e767dc713ae8b2d32374cd94d2dc3eae2b6e (diff) |
Add logging functions
This allows us to color and prefix the output.
Closes: #544332
Diffstat (limited to 'gbp')
-rw-r--r-- | gbp/command_wrappers.py | 6 | ||||
-rw-r--r-- | gbp/config.py | 3 | ||||
-rw-r--r-- | gbp/git.py | 5 | ||||
-rw-r--r-- | gbp/log.py | 110 |
4 files changed, 119 insertions, 5 deletions
diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py index f500eee..60a317f 100644 --- a/gbp/command_wrappers.py +++ b/gbp/command_wrappers.py @@ -11,6 +11,7 @@ import sys import os import os.path import signal +import log from errors import GbpError class CommandExecFailed(Exception): @@ -23,8 +24,6 @@ class Command(object): Wraps a shell command, so we don't have to store any kind of command line options in one of the git-buildpackage commands """ - verbose = False - def __init__(self, cmd, args=[], shell=False, extra_env=None): self.cmd = cmd self.args = args @@ -42,8 +41,7 @@ class Command(object): "restore default signal handler (http://bugs.python.org/issue1652)" signal.signal(signal.SIGPIPE, signal.SIG_DFL) - if self.verbose: - print self.cmd, self.args, args + log.debug("%s %s %s" % (self.cmd, self.args, args)) cmd = [ self.cmd ] + self.args + args if self.shell: # subprocess.call only cares about the first argument if shell=True cmd = " ".join(cmd) diff --git a/gbp/config.py b/gbp/config.py index e9c108c..aced5b1 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -78,6 +78,7 @@ class GbpOptionParser(OptionParser): 'dist' : 'sid', 'arch' : '', 'interactive' : 'True', + 'color' : 'auto', } help = { 'debian-branch': @@ -124,6 +125,8 @@ class GbpOptionParser(OptionParser): "Build for this architecture when using git-pbuilder, default is '%(arch)s'", 'interactive': "Run command interactive, default is '%(interactive)s'", + 'color': + "color output, default is '%(color)s'", } config_files = [ '/etc/git-buildpackage/gbp.conf', os.path.expanduser('~/.gbp.conf'), @@ -8,6 +8,7 @@ import subprocess import os.path from command_wrappers import (GitAdd, GitRm, GitCheckoutBranch, GitInit, GitCommand, copy_from) from errors import GbpError +import log import dateutil.parser import calendar @@ -43,7 +44,9 @@ class GitRepository(object): output = [] env = self.__build_env(extra_env) - popen = subprocess.Popen(['git', command] + args, stdout=subprocess.PIPE, env=env) + cmd = ['git', command] + args + log.debug(cmd) + popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env) while popen.poll() == None: output += popen.stdout.readlines() ret = popen.poll() diff --git a/gbp/log.py b/gbp/log.py new file mode 100644 index 0000000..bf8a3e3 --- /dev/null +++ b/gbp/log.py @@ -0,0 +1,110 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2010 Guido Guenther <agx@sigxcpu.org> +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +"""Simple colored logging classes""" + +import sys + +logger = None + +class Logger(object): + + DEBUG, INFO, WARNING, ERROR = range(4) + + COLOR_NONE = 0 + COLOR_BLACK, COLOR_RED, COLOR_GREEN = range(30,33) + + COLOR_SEQ = "\033[%dm" + BOLD_SEQ = "\033[1m" + + + format = ("%(color)s" + "gbp:%(levelname)s: " + "%(message)s" + "%(coloroff)s") + + def __init__(self): + self.levels = { self.DEBUG: [ 'debug', self.COLOR_GREEN ], + self.INFO: [ 'info', self.COLOR_GREEN ], + self.WARNING: [ 'warn', self.COLOR_RED ], + self.ERROR: [ 'error', self.COLOR_RED ], } + self.color = False + self.level = self.INFO + + def set_level(self, level): + self.level = level + + def set_color(self, color): + if type(color) == type(True): + self.color = color + else: + if color.lower() == "on": + self.color = True + elif color.lower() == "auto": + if (sys.stderr.isatty() and + sys.stdout.isatty()): + self.color = True + else: + self.color = False + + if self.color: + self.get_color = self._color + self.get_coloroff = self._color_off + else: + self.get_color = self.get_coloroff = self._color_dummy + + def _color_dummy(self, level=None): + return "" + + def _color(self, level): + return self.COLOR_SEQ % (self.levels[level][1]) + + def _color_off(self): + return self.COLOR_SEQ % self.COLOR_NONE + + + def log(self, level, message): + if level < self.level: + return + + out = [sys.stdout, sys.stderr][level >= self.WARNING] + print >>out, self.format % { 'levelname': self.levels[level][0], + 'color': self.get_color(level), + 'message': message, + 'coloroff': self.get_coloroff()} + + +def err(msg): + logger.log(Logger.ERROR, msg) + +def warn(msg): + logger.log(Logger.WARNING, msg) + +def info(msg): + logger.log(Logger.INFO, msg) + +def debug(msg): + logger.log(Logger.DEBUG, msg) + +def setup(color, verbose): + logger.set_color(color) + if verbose: + logger.set_level(Logger.DEBUG) + +if not logger: + logger = Logger() + |