Mercurial > hg
changeset 33803:707750e5310b
localrepo: use peer interfaces
We now have a formal abstract base class for peers. Let's
transition the peer classes in localrepo to it.
As part of the transition, we reorder methods so they are grouped
by interface and match the order they are defined in the interface.
We also had to change self.ui from an instance attribute to a
property to satisfy the @abstractproperty requirement.
As part of this change, we uncover the first "bug" as part of
enforcing interfaces: stream_out() wasn't implemented on localpeer!
This isn't technically a bug since the repo isn't advertising the
stream capability, so clients shouldn't be attempting to call it.
But I don't think there's a good reason why this is the case.
We implement a dummy method to satisfy the interface requriements.
We can make localpeer instances streamable as a future enhancement.
# no-check-commit
Differential Revision: https://phab.mercurial-scm.org/D335
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 09 Aug 2017 23:52:25 -0700 |
parents | a0aad86b3b6a |
children | 1f8460b55986 |
files | mercurial/localrepo.py |
diffstat | 1 files changed, 63 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Sun Aug 06 16:47:25 2017 -0700 +++ b/mercurial/localrepo.py Wed Aug 09 23:52:25 2017 -0700 @@ -49,6 +49,7 @@ phases, pushkey, pycompat, + repository, repoview, revset, revsetlang, @@ -144,43 +145,52 @@ 'unbundle'} legacycaps = moderncaps.union({'changegroupsubset'}) -class localpeer(peer.peerrepository): +class localpeer(repository.peer): '''peer for a local repo; reflects only the most recent API''' def __init__(self, repo, caps=None): + super(localpeer, self).__init__() + if caps is None: caps = moderncaps.copy() - peer.peerrepository.__init__(self) self._repo = repo.filtered('served') - self.ui = repo.ui + self._ui = repo.ui self._caps = repo._restrictcapabilities(caps) + # Begin of _basepeer interface. + + @util.propertycache + def ui(self): + return self._ui + + def url(self): + return self._repo.url() + + def local(self): + return self._repo + + def peer(self): + return self + + def canpush(self): + return True + def close(self): self._repo.close() - def _capabilities(self): - return self._caps - - def local(self): - return self._repo + # End of _basepeer interface. - def canpush(self): - return True - - def url(self): - return self._repo.url() - - def lookup(self, key): - return self._repo.lookup(key) + # Begin of _basewirecommands interface. def branchmap(self): return self._repo.branchmap() - def heads(self): - return self._repo.heads() + def capabilities(self): + return self._caps - def known(self, nodes): - return self._repo.known(nodes) + def debugwireargs(self, one, two, three=None, four=None, five=None): + """Used to test argument passing over the wire""" + return "%s %s %s %s %s" % (one, two, three, four, five) def getbundle(self, source, heads=None, common=None, bundlecaps=None, **kwargs): @@ -197,8 +207,24 @@ else: return changegroup.getunbundler('01', cb, None) - # TODO We might want to move the next two calls into legacypeer and add - # unbundle instead. + def heads(self): + return self._repo.heads() + + def known(self, nodes): + return self._repo.known(nodes) + + def listkeys(self, namespace): + return self._repo.listkeys(namespace) + + def lookup(self, key): + return self._repo.lookup(key) + + def pushkey(self, namespace, key, old, new): + return self._repo.pushkey(namespace, key, old, new) + + def stream_out(self): + raise error.Abort(_('cannot perform stream clone against local ' + 'peer')) def unbundle(self, cg, heads, url): """apply a bundle on a repo @@ -235,35 +261,38 @@ except error.PushRaced as exc: raise error.ResponseError(_('push failed:'), str(exc)) - def pushkey(self, namespace, key, old, new): - return self._repo.pushkey(namespace, key, old, new) + # End of _basewirecommands interface. - def listkeys(self, namespace): - return self._repo.listkeys(namespace) + # Begin of peer interface. - def debugwireargs(self, one, two, three=None, four=None, five=None): - '''used to test argument passing over the wire''' - return "%s %s %s %s %s" % (one, two, three, four, five) + def iterbatch(self): + return peer.localiterbatcher(self) -class locallegacypeer(localpeer): + # End of peer interface. + +class locallegacypeer(repository.legacypeer, localpeer): '''peer extension which implements legacy methods too; used for tests with restricted capabilities''' def __init__(self, repo): - localpeer.__init__(self, repo, caps=legacycaps) + super(locallegacypeer, self).__init__(repo, caps=legacycaps) + + # Begin of baselegacywirecommands interface. + + def between(self, pairs): + return self._repo.between(pairs) def branches(self, nodes): return self._repo.branches(nodes) - def between(self, pairs): - return self._repo.between(pairs) - def changegroup(self, basenodes, source): return changegroup.changegroup(self._repo, basenodes, source) def changegroupsubset(self, bases, heads, source): return changegroup.changegroupsubset(self._repo, bases, heads, source) + # End of baselegacywirecommands interface. + # Increment the sub-version when the revlog v2 format changes to lock out old # clients. REVLOGV2_REQUIREMENT = 'exp-revlogv2.0'