summaryrefslogtreecommitdiff
path: root/gbp
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2010-09-03 13:07:10 +0200
committerGuido Günther <agx@sigxcpu.org>2010-11-16 13:27:28 +0100
commit7e79bcd4ab0030db5c5a7998c81f63c48656be80 (patch)
tree89e8281c518e2ce705d99c3fc1f17aac30ae0124 /gbp
parentc385e767dc713ae8b2d32374cd94d2dc3eae2b6e (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.py6
-rw-r--r--gbp/config.py3
-rw-r--r--gbp/git.py5
-rw-r--r--gbp/log.py110
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'),
diff --git a/gbp/git.py b/gbp/git.py
index 917333a..fa29ea0 100644
--- a/gbp/git.py
+++ b/gbp/git.py
@@ -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()
+