D338: wireproto: use new peer interface
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Tue Aug 15 17:51:27 UTC 2017
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGdedab036215d: wireproto: use new peer interface (authored by indygreg).
CHANGED PRIOR TO COMMIT
https://phab.mercurial-scm.org/D338?vs=763&id=937#toc
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D338?vs=763&id=937
REVISION DETAIL
https://phab.mercurial-scm.org/D338
AFFECTED FILES
mercurial/httppeer.py
mercurial/peer.py
mercurial/sshpeer.py
mercurial/wireproto.py
tests/notcapable
tests/test-wireproto.py
CHANGE DETAILS
diff --git a/tests/test-wireproto.py b/tests/test-wireproto.py
--- a/tests/test-wireproto.py
+++ b/tests/test-wireproto.py
@@ -19,7 +19,26 @@
def __init__(self, serverrepo):
self.serverrepo = serverrepo
- def _capabilities(self):
+ @property
+ def ui(self):
+ return self.serverrepo.ui
+
+ def url(self):
+ return 'test'
+
+ def local(self):
+ return None
+
+ def peer(self):
+ return self
+
+ def canpush(self):
+ return True
+
+ def close(self):
+ pass
+
+ def capabilities(self):
return ['batch']
def _call(self, cmd, **args):
diff --git a/tests/notcapable b/tests/notcapable
--- a/tests/notcapable
+++ b/tests/notcapable
@@ -6,9 +6,9 @@
fi
cat > notcapable-$CAP.py << EOF
-from mercurial import extensions, peer, localrepo
+from mercurial import extensions, localrepo, repository
def extsetup():
- extensions.wrapfunction(peer.peerrepository, 'capable', wrapcapable)
+ extensions.wrapfunction(repository.peer, 'capable', wrapcapable)
extensions.wrapfunction(localrepo.localrepository, 'peer', wrappeer)
def wrapcapable(orig, self, name, *args, **kwargs):
if name in '$CAP'.split(' '):
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -27,6 +27,7 @@
peer,
pushkey as pushkeymod,
pycompat,
+ repository,
streamclone,
util,
)
@@ -212,36 +213,15 @@
# client side
-class wirepeer(peer.peerrepository):
+class wirepeer(repository.legacypeer):
"""Client-side interface for communicating with a peer repository.
Methods commonly call wire protocol commands of the same name.
See also httppeer.py and sshpeer.py for protocol-specific
implementations of this interface.
"""
- def _submitbatch(self, req):
- """run batch request <req> on the server
-
- Returns an iterator of the raw responses from the server.
- """
- rsp = self._callstream("batch", cmds=encodebatchcmds(req))
- chunk = rsp.read(1024)
- work = [chunk]
- while chunk:
- while ';' not in chunk and chunk:
- chunk = rsp.read(1024)
- work.append(chunk)
- merged = ''.join(work)
- while ';' in merged:
- one, merged = merged.split(';', 1)
- yield unescapearg(one)
- chunk = rsp.read(1024)
- work = [merged, chunk]
- yield unescapearg(''.join(work))
-
- def _submitone(self, op, args):
- return self._call(op, **args)
+ # Begin of basewirepeer interface.
def iterbatch(self):
return remoteiterbatcher(self)
@@ -293,26 +273,17 @@
except TypeError:
self._abort(error.ResponseError(_("unexpected response:"), d))
- def branches(self, nodes):
- n = encodelist(nodes)
- d = self._call("branches", nodes=n)
- try:
- br = [tuple(decodelist(b)) for b in d.splitlines()]
- return br
- except ValueError:
- self._abort(error.ResponseError(_("unexpected response:"), d))
-
- def between(self, pairs):
- batch = 8 # avoid giant requests
- r = []
- for i in xrange(0, len(pairs), batch):
- n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]])
- d = self._call("between", pairs=n)
- try:
- r.extend(l and decodelist(l) or [] for l in d.splitlines())
- except ValueError:
- self._abort(error.ResponseError(_("unexpected response:"), d))
- return r
+ @batchable
+ def listkeys(self, namespace):
+ if not self.capable('pushkey'):
+ yield {}, None
+ f = future()
+ self.ui.debug('preparing listkeys for "%s"\n' % namespace)
+ yield {'namespace': encoding.fromlocal(namespace)}, f
+ d = f.value
+ self.ui.debug('received listkey for "%s": %i bytes\n'
+ % (namespace, len(d)))
+ yield pushkeymod.decodekeys(d)
@batchable
def pushkey(self, namespace, key, old, new):
@@ -335,34 +306,9 @@
self.ui.status(_('remote: '), l)
yield d
- @batchable
- def listkeys(self, namespace):
- if not self.capable('pushkey'):
- yield {}, None
- f = future()
- self.ui.debug('preparing listkeys for "%s"\n' % namespace)
- yield {'namespace': encoding.fromlocal(namespace)}, f
- d = f.value
- self.ui.debug('received listkey for "%s": %i bytes\n'
- % (namespace, len(d)))
- yield pushkeymod.decodekeys(d)
-
def stream_out(self):
return self._callstream('stream_out')
- def changegroup(self, nodes, kind):
- n = encodelist(nodes)
- f = self._callcompressable("changegroup", roots=n)
- return changegroupmod.cg1unpacker(f, 'UN')
-
- def changegroupsubset(self, bases, heads, kind):
- self.requirecap('changegroupsubset', _('look up remote changes'))
- bases = encodelist(bases)
- heads = encodelist(heads)
- f = self._callcompressable("changegroupsubset",
- bases=bases, heads=heads)
- return changegroupmod.cg1unpacker(f, 'UN')
-
def getbundle(self, source, **kwargs):
self.requirecap('getbundle', _('look up remote changes'))
opts = {}
@@ -433,6 +379,69 @@
ret = bundle2.getunbundler(self.ui, stream)
return ret
+ # End of basewirepeer interface.
+
+ # Begin of baselegacywirepeer interface.
+
+ def branches(self, nodes):
+ n = encodelist(nodes)
+ d = self._call("branches", nodes=n)
+ try:
+ br = [tuple(decodelist(b)) for b in d.splitlines()]
+ return br
+ except ValueError:
+ self._abort(error.ResponseError(_("unexpected response:"), d))
+
+ def between(self, pairs):
+ batch = 8 # avoid giant requests
+ r = []
+ for i in xrange(0, len(pairs), batch):
+ n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]])
+ d = self._call("between", pairs=n)
+ try:
+ r.extend(l and decodelist(l) or [] for l in d.splitlines())
+ except ValueError:
+ self._abort(error.ResponseError(_("unexpected response:"), d))
+ return r
+
+ def changegroup(self, nodes, kind):
+ n = encodelist(nodes)
+ f = self._callcompressable("changegroup", roots=n)
+ return changegroupmod.cg1unpacker(f, 'UN')
+
+ def changegroupsubset(self, bases, heads, kind):
+ self.requirecap('changegroupsubset', _('look up remote changes'))
+ bases = encodelist(bases)
+ heads = encodelist(heads)
+ f = self._callcompressable("changegroupsubset",
+ bases=bases, heads=heads)
+ return changegroupmod.cg1unpacker(f, 'UN')
+
+ # End of baselegacywirepeer interface.
+
+ def _submitbatch(self, req):
+ """run batch request <req> on the server
+
+ Returns an iterator of the raw responses from the server.
+ """
+ rsp = self._callstream("batch", cmds=encodebatchcmds(req))
+ chunk = rsp.read(1024)
+ work = [chunk]
+ while chunk:
+ while ';' not in chunk and chunk:
+ chunk = rsp.read(1024)
+ work.append(chunk)
+ merged = ''.join(work)
+ while ';' in merged:
+ one, merged = merged.split(';', 1)
+ yield unescapearg(one)
+ chunk = rsp.read(1024)
+ work = [merged, chunk]
+ yield unescapearg(''.join(work))
+
+ def _submitone(self, op, args):
+ return self._call(op, **args)
+
def debugwireargs(self, one, two, three=None, four=None, five=None):
# don't pass optional arguments left at their default value
opts = {}
diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py
--- a/mercurial/sshpeer.py
+++ b/mercurial/sshpeer.py
@@ -13,7 +13,6 @@
from . import (
error,
pycompat,
- repository,
util,
wireproto,
)
@@ -115,7 +114,7 @@
def flush(self):
return self._main.flush()
-class sshpeer(wireproto.wirepeer, repository.legacypeer):
+class sshpeer(wireproto.wirepeer):
def __init__(self, ui, path, create=False):
self._url = path
self._ui = ui
@@ -151,9 +150,6 @@
self._validaterepo(sshcmd, args, remotecmd)
- # TODO remove this alias once peerrepository inheritance is removed.
- self._capabilities = self.capabilities
-
# Begin of _basepeer interface.
@util.propertycache
diff --git a/mercurial/peer.py b/mercurial/peer.py
--- a/mercurial/peer.py
+++ b/mercurial/peer.py
@@ -8,7 +8,6 @@
from __future__ import absolute_import
-from .i18n import _
from . import (
error,
util,
@@ -95,46 +94,3 @@
return next(batchable)
setattr(plain, 'batchable', f)
return plain
-
-class peerrepository(object):
- def iterbatch(self):
- """Batch requests but allow iterating over the results.
-
- This is to allow interleaving responses with things like
- progress updates for clients.
- """
- return localiterbatcher(self)
-
- def capable(self, name):
- '''tell whether repo supports named capability.
- return False if not supported.
- if boolean capability, return True.
- if string capability, return string.'''
- caps = self._capabilities()
- if name in caps:
- return True
- name_eq = name + '='
- for cap in caps:
- if cap.startswith(name_eq):
- return cap[len(name_eq):]
- return False
-
- def requirecap(self, name, purpose):
- '''raise an exception if the given capability is not present'''
- if not self.capable(name):
- raise error.CapabilityError(
- _('cannot %s; remote repository does not '
- 'support the %r capability') % (purpose, name))
-
- def local(self):
- '''return peer as a localrepo, or None'''
- return None
-
- def peer(self):
- return self
-
- def canpush(self):
- return True
-
- def close(self):
- pass
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -21,7 +21,6 @@
error,
httpconnection,
pycompat,
- repository,
statichttprepo,
url,
util,
@@ -87,7 +86,7 @@
resp.__class__ = readerproxy
-class httppeer(wireproto.wirepeer, repository.legacypeer):
+class httppeer(wireproto.wirepeer):
def __init__(self, ui, path):
self._path = path
self._caps = None
@@ -107,9 +106,6 @@
self._urlopener = url.opener(ui, authinfo)
self._requestbuilder = urlreq.request
- # TODO remove once peerrepository isn't in inheritance.
- self._capabilities = self.capabilities
-
def __del__(self):
urlopener = getattr(self, '_urlopener', None)
if urlopener:
To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list