summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2012-08-02 18:50:11 +0200
committerGuido Günther <agx@sigxcpu.org>2012-08-03 19:18:38 +0200
commit776cbb7a06ea6e6abda8ea6dcc7fa528d302e92d (patch)
treee6dd22ed12fad679665dbf68aa5245473bfe47f4
parent83577af21ebfbd3b94fb51f89627c2c7dd5dbb88 (diff)
Improve error reporting from uscan
by parsing out the warnings and error fields from the dehs output.
-rw-r--r--gbp/deb/uscan.py164
1 files changed, 112 insertions, 52 deletions
diff --git a/gbp/deb/uscan.py b/gbp/deb/uscan.py
index 76bde653..731ea78b 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('<status>up to date</status>')
- >>> u.tarball
- >>> u.uptodate
- True
>>> u._parse('<target>virt-viewer_0.4.0.orig.tar.gz</target>')
>>> 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"<target>(.*)</target>", row)
+ if m:
+ source = '../%s' % m.group(1)
+ break
+ elif row.startswith('<messages>'):
+ 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>(.*)</%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('<status>up to date</status>')
+ >>> u.tarball
+ >>> u.uptodate
+ True
+ >>> u._parse_uptodate('')
+ >>> u.tarball
+ >>> u.uptodate
+ False
+ """
if "<status>up to date</status>" 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"<target>(.*)</target>", row)
- if m:
- source = '../%s' % m.group(1)
- break
- elif row.startswith('<messages>'):
- 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>(.*)</%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("<warnings>uscan warning: "
+ ... "In watchfile debian/watch, reading webpage\n"
+ ... "http://a.b/ failed: 500 Cant connect "
+ ... "to example.com:80 (Bad hostname)</warnings>")
+ 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("<errors>uscan: Can't use --verbose if "
+ ... "you're using --dehs!</errors>")
+ 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>(.*)</%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\:·: