protocol: introduce wireproto.py
- add a protocol-independent dispatcher
- move most of the basic commands from sshserver to wireproto
- dispatch through wireproto first
--- a/mercurial/sshserver.py Wed Jul 14 15:25:15 2010 -0500
+++ b/mercurial/sshserver.py Wed Jul 14 15:25:15 2010 -0500
@@ -8,7 +8,7 @@
from i18n import _
from node import bin, hex
-import streamclone, util, hook, pushkey
+import streamclone, util, hook, pushkey, wireproto
import os, sys, tempfile, urllib, copy
class sshserver(object):
@@ -69,7 +69,7 @@
def serve_one(self):
cmd = self.fin.readline()[:-1]
- if cmd:
+ if cmd and not wireproto.dispatch(self.repo, self, cmd):
impl = getattr(self, 'do_' + cmd, None)
if impl:
r = impl()
@@ -78,29 +78,6 @@
else: self.respond("")
return cmd != ''
- def do_lookup(self):
- key = self.getarg('key')
- try:
- r = hex(self.repo.lookup(key))
- success = 1
- except Exception, inst:
- r = str(inst)
- success = 0
- return "%s %s\n" % (success, r)
-
- def do_branchmap(self):
- branchmap = self.repo.branchmap()
- heads = []
- for branch, nodes in branchmap.iteritems():
- branchname = urllib.quote(branch)
- branchnodes = [hex(node) for node in nodes]
- heads.append('%s %s' % (branchname, ' '.join(branchnodes)))
- return '\n'.join(heads)
-
- def do_heads(self):
- h = self.repo.heads()
- return " ".join(map(hex, h)) + "\n"
-
def do_hello(self):
'''the hello command returns a set of lines describing various
interesting things about the server, in an RFC822-like format.
@@ -128,22 +105,6 @@
self.lock = None
return ""
- def do_branches(self):
- nodes = self.getarg('nodes')
- nodes = map(bin, nodes.split(" "))
- r = []
- for b in self.repo.branches(nodes):
- r.append(" ".join(map(hex, b)) + "\n")
- return "".join(r)
-
- def do_between(self):
- pairs = self.getarg('pairs')
- pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
- r = []
- for b in self.repo.between(pairs):
- r.append(" ".join(map(hex, b)) + "\n")
- return "".join(r)
-
def do_changegroup(self):
nodes = []
roots = self.getarg('roots')
@@ -244,15 +205,3 @@
except streamclone.StreamException, inst:
self.fout.write(str(inst))
self.fout.flush()
-
- def do_pushkey(self):
- namespace, key, old, new = self.getargs('namespace key old new')
- r = pushkey.push(self.repo, namespace, key, old, new)
- return '%s\n' % int(r)
-
- def do_listkeys(self):
- namespace = self.getarg('namespace')
- d = pushkey.list(self.repo, namespace).items()
- t = '\n'.join(['%s\t%s' % (k.encode('string-escape'),
- v.encode('string-escape')) for k, v in d])
- return t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/wireproto.py Wed Jul 14 15:25:15 2010 -0500
@@ -0,0 +1,75 @@
+# wireproto.py - generic wire protocol support functions
+#
+# Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from i18n import _
+from node import bin, hex
+import urllib
+import pushkey as pushkey_
+
+def dispatch(repo, proto, command):
+ if command not in commands:
+ return False
+ func, spec = commands[command]
+ args = proto.getargs(spec)
+ proto.respond(func(repo, *args))
+ return True
+
+def between(repo, pairs):
+ pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
+ r = []
+ for b in repo.between(pairs):
+ r.append(" ".join(map(hex, b)) + "\n")
+ return "".join(r)
+
+def branchmap(repo):
+ branchmap = repo.branchmap()
+ heads = []
+ for branch, nodes in branchmap.iteritems():
+ branchname = urllib.quote(branch)
+ branchnodes = [hex(node) for node in nodes]
+ heads.append('%s %s' % (branchname, ' '.join(branchnodes)))
+ return '\n'.join(heads)
+
+def branches(repo, nodes):
+ nodes = map(bin, nodes.split(" "))
+ r = []
+ for b in repo.branches(nodes):
+ r.append(" ".join(map(hex, b)) + "\n")
+ return "".join(r)
+
+def heads(repo):
+ h = repo.heads()
+ return " ".join(map(hex, h)) + "\n"
+
+def listkeys(repo, namespace):
+ d = pushkey_.list(repo, namespace).items()
+ t = '\n'.join(['%s\t%s' % (k.encode('string-escape'),
+ v.encode('string-escape')) for k, v in d])
+ return t
+
+def lookup(repo, key):
+ try:
+ r = hex(repo.lookup(key))
+ success = 1
+ except Exception, inst:
+ r = str(inst)
+ success = 0
+ return "%s %s\n" % (success, r)
+
+def pushkey(repo, namespace, key, old, new):
+ r = pushkey_.push(repo, namespace, key, old, new)
+ return '%s\n' % int(r)
+
+commands = {
+ 'between': (between, 'pairs'),
+ 'branchmap': (branchmap, ''),
+ 'branches': (branches, 'nodes'),
+ 'heads': (heads, ''),
+ 'listkeys': (listkeys, 'namespace'),
+ 'lookup': (lookup, 'key'),
+ 'pushkey': (pushkey, 'namespace key old new'),
+}