From 776cbb7a06ea6e6abda8ea6dcc7fa528d302e92d Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 2 Aug 2012 18:50:11 +0200 Subject: Improve error reporting from uscan by parsing out the warnings and error fields from the dehs output. --- gbp/deb/uscan.py | 164 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 52 deletions(-) diff --git a/gbp/deb/uscan.py b/gbp/deb/uscan.py index 76bde65..731ea78 100644 --- a/gbp/deb/uscan.py +++ b/gbp/deb/uscan.py @@ -45,10 +45,6 @@ class Uscan(object): @type out: string >>> u = Uscan('http://example.com/') - >>> u._parse('up to date') - >>> u.tarball - >>> u.uptodate - True >>> u._parse('virt-viewer_0.4.0.orig.tar.gz') >>> u.tarball '../virt-viewer_0.4.0.orig.tar.gz' @@ -60,59 +56,116 @@ class Uscan(object): UscanError: Couldn't find 'upstream-url' in uscan output """ source = None + self._uptodate = False + + # Check if uscan downloaded something + for row in out.split("\n"): + # uscan >= 2.10.70 has a target element: + m = re.match(r"(.*)", row) + if m: + source = '../%s' % m.group(1) + break + elif row.startswith(''): + m = re.match(r".*symlinked ([^\s]+) to it", row) + if m: + source = "../%s" % m.group(1) + break + m = re.match(r"Successfully downloaded updated package " + "([^<]+)", row) + if m: + source = "../%s" % m.group(1) + break + # Try to determine the already downloaded sources name + else: + d = {} + + try: + for row in out.split("\n"): + for n in ('package', + 'upstream-version', + 'upstream-url'): + m = re.match("<%s>(.*)" % (n,n), row) + if m: + d[n] = m.group(1) + d["ext"] = os.path.splitext(d['upstream-url'])[1] + # We want the name of the orig tarball if possible + source = ("../%(package)s_%(upstream-version)s." + "orig.tar%(ext)s" % d) + + # Fall back to the upstream source name otherwise + if not os.path.exists(source): + source = "../%s" % d['upstream-url'].rsplit('/',1)[1] + if not os.path.exists(source): + raise UscanError("Couldn't find tarball at '%s'" % + source) + except KeyError as e: + raise UscanError("Couldn't find '%s' in uscan output" % + e.args[0]) + self._tarball = source + + def _parse_uptodate(self, out): + """ + Check if the uscan reports that we're up to date. + + @param out: uscan output + @type out: string + >>> u = Uscan('http://example.com/') + >>> u._parse_uptodate('up to date') + >>> u.tarball + >>> u.uptodate + True + >>> u._parse_uptodate('') + >>> u.tarball + >>> u.uptodate + False + """ if "up to date" in out: self._uptodate = True - self._tarball = None - return else: self._uptodate = False - # Check if uscan downloaded something - for row in out.split("\n"): - # uscan >= 2.10.70 has a target element: - m = re.match(r"(.*)", row) - if m: - source = '../%s' % m.group(1) - break - elif row.startswith(''): - m = re.match(r".*symlinked ([^\s]+) to it", row) - if m: - source = "../%s" % m.group(1) - break - m = re.match(r"Successfully downloaded updated package " - "([^<]+)", row) - if m: - source = "../%s" % m.group(1) - break - - # Try to determine the already downloaded sources name - else: - d = {} - - try: - for row in out.split("\n"): - for n in ('package', - 'upstream-version', - 'upstream-url'): - m = re.match("<%s>(.*)" % (n,n), row) - if m: - d[n] = m.group(1) - d["ext"] = os.path.splitext(d['upstream-url'])[1] - # We want the name of the orig tarball if possible - source = ("../%(package)s_%(upstream-version)s." - "orig.tar%(ext)s" % d) - - # Fall back to the upstream source name otherwise - if not os.path.exists(source): - source = "../%s" % d['upstream-url'].rsplit('/',1)[1] - if not os.path.exists(source): - raise UscanError("Couldn't find tarball at '%s'" % - source) - except KeyError as e: - raise UscanError("Couldn't find '%s' in uscan output" % - e.args[0]) - self._tarball = source + def _raise_error(self, out): + r""" + Parse the uscan output for errors and warnings and raise + a L{UscanError} exception based on this. If no error detail + is found a generic error message is used. + + @param out: uscan output + @type out: string + @raises UscanError: exception raised + + >>> u = Uscan('http://example.com/') + >>> u._raise_error("uscan warning: " + ... "In watchfile debian/watch, reading webpage\n" + ... "http://a.b/ failed: 500 Cant connect " + ... "to example.com:80 (Bad hostname)") + Traceback (most recent call last): + ... + UscanError: Uscan failed: uscan warning: In watchfile debian/watch, reading webpage + http://a.b/ failed: 500 Cant connect to example.com:80 (Bad hostname) + >>> u._raise_error("uscan: Can't use --verbose if " + ... "you're using --dehs!") + Traceback (most recent call last): + ... + UscanError: Uscan failed: uscan: Can't use --verbose if you're using --dehs! + >>> u = u._raise_error('') + Traceback (most recent call last): + ... + UscanError: Uscan failed - debug by running 'uscan --verbose' + """ + msg = None + + for n in ('errors', 'warnings'): + m = re.search("<%s>(.*)" % (n,n), out, re.DOTALL) + if m: + msg = "Uscan failed: %s" % m.group(1) + break + + if not msg: + msg = "Uscan failed - debug by running 'uscan --verbose'" + raise UscanError(msg) + def scan(self, destdir='..'): """Invoke uscan to fetch a new upstream version""" @@ -121,6 +174,13 @@ class Uscan(object): cwd=self._dir, stdout=subprocess.PIPE) out = p.communicate()[0] - return self._parse(out) + # uscan exits with 1 in case of uptodate and when an error occured. + # Don't fail in the uptodate case: + self._parse_uptodate(out) + if not self.uptodate: + if p.returncode: + self._raise_error(out) + else: + self._parse(out) # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: -- cgit v1.2.3