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: 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/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/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,7 +213,7 @@ # 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. @@ -220,28 +221,7 @@ See also httppeer.py and sshpeer.py for protocol-specific implementations of this interface. """ - def _submitbatch(self, req): - """run batch request 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 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/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/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):