From: Avery Pennarun Date: Sat, 13 Feb 2010 21:45:12 +0000 (-0500) Subject: bup join: continue gracefully if one of the requested files does not exist. X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=df48a66afae98769b47382c35c34a1adf5aaad39;p=packages%2Fb%2Fbup.git bup join: continue gracefully if one of the requested files does not exist. This makes it work more like 'cat'. If any of the requested files is missing, the final return code is nonzero. --- diff --git a/client.py b/client.py index f99708b..a9e9c95 100644 --- a/client.py +++ b/client.py @@ -85,7 +85,7 @@ class Client: if rv != None: raise ClientError('server exited unexpectedly with code %r' % rv) try: - self.conn.check_ok() + return self.conn.check_ok() except Exception, e: raise ClientError, e, sys.exc_info()[2] @@ -191,8 +191,10 @@ class Client: sz = struct.unpack('!I', self.conn.read(4))[0] if not sz: break yield self.conn.read(sz) - self.check_ok() + e = self.check_ok() self._not_busy() + if e: + raise KeyError(str(e)) class PackWriter_Remote(git.PackWriter): diff --git a/cmd-join.py b/cmd-join.py index 07dfdcd..26f390c 100755 --- a/cmd-join.py +++ b/cmd-join.py @@ -18,15 +18,22 @@ git.check_repo_or_die() if not extra: extra = linereader(sys.stdin) +ret = 0 + if opt.remote: cli = client.Client(opt.remote) - for id in extra: - for blob in cli.cat(id): - sys.stdout.write(blob) - cli.close() + cat = cli.cat else: cp = git.CatPipe() - for id in extra: - #log('id=%r\n' % id) - for blob in cp.join(id): + cat = cp.join + +for id in extra: + try: + for blob in cat(id): sys.stdout.write(blob) + except KeyError, e: + sys.stdout.flush() + log('error: %s\n' % e) + ret = 1 + +sys.exit(ret) diff --git a/cmd-server.py b/cmd-server.py index 7cc78a3..e849b45 100755 --- a/cmd-server.py +++ b/cmd-server.py @@ -118,11 +118,17 @@ def update_ref(conn, refname): def cat(conn, id): git.check_repo_or_die() - for blob in git.cat(id): - conn.write(struct.pack('!I', len(blob))) - conn.write(blob) - conn.write('\0\0\0\0') - conn.ok() + try: + for blob in git.cat(id): + conn.write(struct.pack('!I', len(blob))) + conn.write(blob) + except KeyError, e: + log('server: error: %s\n' % e) + conn.write('\0\0\0\0') + conn.error(e) + else: + conn.write('\0\0\0\0') + conn.ok() optspec = """ diff --git a/helpers.py b/helpers.py index 8201c31..2bfdd53 100644 --- a/helpers.py +++ b/helpers.py @@ -97,6 +97,9 @@ def hostname(): return _hostname +class NotOk(Exception): + pass + class Conn: def __init__(self, inp, outp): self.inp = inp @@ -125,20 +128,11 @@ class Conn: def ok(self): self.write('\nok\n') - def drain_and_check_ok(self): - self.outp.flush() - rl = '' - for rl in linereader(self.inp): - #log('%d got line: %r\n' % (os.getpid(), rl)) - if not rl: # empty line - continue - elif rl == 'ok': - return True - else: - pass # ignore line - # NOTREACHED + def error(self, s): + s = re.sub(r'\s+', ' ', str(s)) + self.write('\nerror %s\n' % s) - def check_ok(self): + def _check_ok(self, onempty): self.outp.flush() rl = '' for rl in linereader(self.inp): @@ -146,11 +140,24 @@ class Conn: if not rl: # empty line continue elif rl == 'ok': - return True + return None + elif rl.startswith('error '): + #log('client: error: %s\n' % rl[6:]) + return NotOk(rl[6:]) else: - raise Exception('expected "ok", got %r' % rl) + onempty(rl) raise Exception('server exited unexpectedly; see errors above') + def drain_and_check_ok(self): + def onempty(rl): + pass + return self._check_ok(onempty) + + def check_ok(self): + def onempty(rl): + raise Exception('expected "ok", got %r' % rl) + return self._check_ok(onempty) + def linereader(f): while 1: