httppeer: basic implementation of capabilities interface
This is a bit crude. The capabilities mechanism for version 2 of
the wire protocol is a bit different from version 1. And code
in core is relying on strings passed to capable() matching strings
advertised by the "capabilities" wire protocol command. I may
refactor the internal checking mechanism to be a bit more
abstract or based on interfaces. Time will tell...
Differential Revision: https://phab.mercurial-scm.org/D3256
--- a/mercurial/httppeer.py Tue Apr 10 18:47:09 2018 -0700
+++ b/mercurial/httppeer.py Tue Apr 10 19:09:35 2018 -0700
@@ -517,7 +517,7 @@
raise exception
# TODO implement interface for version 2 peers
-@zi.implementer(repository.ipeerconnection)
+@zi.implementer(repository.ipeerconnection, repository.ipeercapabilities)
class httpv2peer(object):
def __init__(self, ui, repourl, apipath, opener, requestbuilder,
apidescriptor):
@@ -552,6 +552,33 @@
# End of ipeerconnection.
+ # Start of ipeercapabilities.
+
+ def capable(self, name):
+ # The capabilities used internally historically map to capabilities
+ # advertised from the "capabilities" wire protocol command. However,
+ # version 2 of that command works differently.
+
+ # Maps to commands that are available.
+ if name in ('branchmap', 'getbundle', 'known', 'lookup', 'pushkey'):
+ return True
+
+ # Other concepts.
+ if name in ('bundle2',):
+ return True
+
+ return False
+
+ def requirecap(self, name, purpose):
+ if self.capable(name):
+ return
+
+ raise error.CapabilityError(
+ _('cannot %s; client or remote repository does not support the %r '
+ 'capability') % (purpose, name))
+
+ # End of ipeercapabilities.
+
# TODO require to be part of a batched primitive, use futures.
def _call(self, name, **args):
"""Call a wire protocol command with arguments."""
--- a/tests/test-check-interfaces.py Tue Apr 10 18:47:09 2018 -0700
+++ b/tests/test-check-interfaces.py Tue Apr 10 19:09:35 2018 -0700
@@ -94,6 +94,8 @@
ziverify.verifyClass(repository.ipeerconnection,
httppeer.httpv2peer)
+ ziverify.verifyClass(repository.ipeercapabilities,
+ httppeer.httpv2peer)
checkzobject(httppeer.httpv2peer(None, '', None, None, None, None))
ziverify.verifyClass(repository.ipeerbase,