From df48a66afae98769b47382c35c34a1adf5aaad39 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 13 Feb 2010 16:45:12 -0500 Subject: [PATCH] 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. --- client.py | 6 ++++-- cmd-join.py | 21 ++++++++++++++------- cmd-server.py | 16 +++++++++++----- helpers.py | 37 ++++++++++++++++++++++--------------- 4 files changed, 51 insertions(+), 29 deletions(-) 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: -- 2.39.2