Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 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 | 02a745c20121 |
children | f7d41b85bbf6 |
comparison
equal
deleted
inserted
replaced
33802:a0aad86b3b6a | 33803:707750e5310b |
---|---|
47 pathutil, | 47 pathutil, |
48 peer, | 48 peer, |
49 phases, | 49 phases, |
50 pushkey, | 50 pushkey, |
51 pycompat, | 51 pycompat, |
52 repository, | |
52 repoview, | 53 repoview, |
53 revset, | 54 revset, |
54 revsetlang, | 55 revsetlang, |
55 scmutil, | 56 scmutil, |
56 sparse, | 57 sparse, |
142 | 143 |
143 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle', | 144 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle', |
144 'unbundle'} | 145 'unbundle'} |
145 legacycaps = moderncaps.union({'changegroupsubset'}) | 146 legacycaps = moderncaps.union({'changegroupsubset'}) |
146 | 147 |
147 class localpeer(peer.peerrepository): | 148 class localpeer(repository.peer): |
148 '''peer for a local repo; reflects only the most recent API''' | 149 '''peer for a local repo; reflects only the most recent API''' |
149 | 150 |
150 def __init__(self, repo, caps=None): | 151 def __init__(self, repo, caps=None): |
152 super(localpeer, self).__init__() | |
153 | |
151 if caps is None: | 154 if caps is None: |
152 caps = moderncaps.copy() | 155 caps = moderncaps.copy() |
153 peer.peerrepository.__init__(self) | |
154 self._repo = repo.filtered('served') | 156 self._repo = repo.filtered('served') |
155 self.ui = repo.ui | 157 self._ui = repo.ui |
156 self._caps = repo._restrictcapabilities(caps) | 158 self._caps = repo._restrictcapabilities(caps) |
159 | |
160 # Begin of _basepeer interface. | |
161 | |
162 @util.propertycache | |
163 def ui(self): | |
164 return self._ui | |
165 | |
166 def url(self): | |
167 return self._repo.url() | |
168 | |
169 def local(self): | |
170 return self._repo | |
171 | |
172 def peer(self): | |
173 return self | |
174 | |
175 def canpush(self): | |
176 return True | |
157 | 177 |
158 def close(self): | 178 def close(self): |
159 self._repo.close() | 179 self._repo.close() |
160 | 180 |
161 def _capabilities(self): | 181 # End of _basepeer interface. |
162 return self._caps | 182 |
163 | 183 # Begin of _basewirecommands interface. |
164 def local(self): | |
165 return self._repo | |
166 | |
167 def canpush(self): | |
168 return True | |
169 | |
170 def url(self): | |
171 return self._repo.url() | |
172 | |
173 def lookup(self, key): | |
174 return self._repo.lookup(key) | |
175 | 184 |
176 def branchmap(self): | 185 def branchmap(self): |
177 return self._repo.branchmap() | 186 return self._repo.branchmap() |
178 | 187 |
179 def heads(self): | 188 def capabilities(self): |
180 return self._repo.heads() | 189 return self._caps |
181 | 190 |
182 def known(self, nodes): | 191 def debugwireargs(self, one, two, three=None, four=None, five=None): |
183 return self._repo.known(nodes) | 192 """Used to test argument passing over the wire""" |
193 return "%s %s %s %s %s" % (one, two, three, four, five) | |
184 | 194 |
185 def getbundle(self, source, heads=None, common=None, bundlecaps=None, | 195 def getbundle(self, source, heads=None, common=None, bundlecaps=None, |
186 **kwargs): | 196 **kwargs): |
187 chunks = exchange.getbundlechunks(self._repo, source, heads=heads, | 197 chunks = exchange.getbundlechunks(self._repo, source, heads=heads, |
188 common=common, bundlecaps=bundlecaps, | 198 common=common, bundlecaps=bundlecaps, |
195 # from it in local peer. | 205 # from it in local peer. |
196 return bundle2.getunbundler(self.ui, cb) | 206 return bundle2.getunbundler(self.ui, cb) |
197 else: | 207 else: |
198 return changegroup.getunbundler('01', cb, None) | 208 return changegroup.getunbundler('01', cb, None) |
199 | 209 |
200 # TODO We might want to move the next two calls into legacypeer and add | 210 def heads(self): |
201 # unbundle instead. | 211 return self._repo.heads() |
212 | |
213 def known(self, nodes): | |
214 return self._repo.known(nodes) | |
215 | |
216 def listkeys(self, namespace): | |
217 return self._repo.listkeys(namespace) | |
218 | |
219 def lookup(self, key): | |
220 return self._repo.lookup(key) | |
221 | |
222 def pushkey(self, namespace, key, old, new): | |
223 return self._repo.pushkey(namespace, key, old, new) | |
224 | |
225 def stream_out(self): | |
226 raise error.Abort(_('cannot perform stream clone against local ' | |
227 'peer')) | |
202 | 228 |
203 def unbundle(self, cg, heads, url): | 229 def unbundle(self, cg, heads, url): |
204 """apply a bundle on a repo | 230 """apply a bundle on a repo |
205 | 231 |
206 This function handles the repo locking itself.""" | 232 This function handles the repo locking itself.""" |
233 bundle2.processbundle(self._repo, b) | 259 bundle2.processbundle(self._repo, b) |
234 raise | 260 raise |
235 except error.PushRaced as exc: | 261 except error.PushRaced as exc: |
236 raise error.ResponseError(_('push failed:'), str(exc)) | 262 raise error.ResponseError(_('push failed:'), str(exc)) |
237 | 263 |
238 def pushkey(self, namespace, key, old, new): | 264 # End of _basewirecommands interface. |
239 return self._repo.pushkey(namespace, key, old, new) | 265 |
240 | 266 # Begin of peer interface. |
241 def listkeys(self, namespace): | 267 |
242 return self._repo.listkeys(namespace) | 268 def iterbatch(self): |
243 | 269 return peer.localiterbatcher(self) |
244 def debugwireargs(self, one, two, three=None, four=None, five=None): | 270 |
245 '''used to test argument passing over the wire''' | 271 # End of peer interface. |
246 return "%s %s %s %s %s" % (one, two, three, four, five) | 272 |
247 | 273 class locallegacypeer(repository.legacypeer, localpeer): |
248 class locallegacypeer(localpeer): | |
249 '''peer extension which implements legacy methods too; used for tests with | 274 '''peer extension which implements legacy methods too; used for tests with |
250 restricted capabilities''' | 275 restricted capabilities''' |
251 | 276 |
252 def __init__(self, repo): | 277 def __init__(self, repo): |
253 localpeer.__init__(self, repo, caps=legacycaps) | 278 super(locallegacypeer, self).__init__(repo, caps=legacycaps) |
279 | |
280 # Begin of baselegacywirecommands interface. | |
281 | |
282 def between(self, pairs): | |
283 return self._repo.between(pairs) | |
254 | 284 |
255 def branches(self, nodes): | 285 def branches(self, nodes): |
256 return self._repo.branches(nodes) | 286 return self._repo.branches(nodes) |
257 | 287 |
258 def between(self, pairs): | |
259 return self._repo.between(pairs) | |
260 | |
261 def changegroup(self, basenodes, source): | 288 def changegroup(self, basenodes, source): |
262 return changegroup.changegroup(self._repo, basenodes, source) | 289 return changegroup.changegroup(self._repo, basenodes, source) |
263 | 290 |
264 def changegroupsubset(self, bases, heads, source): | 291 def changegroupsubset(self, bases, heads, source): |
265 return changegroup.changegroupsubset(self._repo, bases, heads, source) | 292 return changegroup.changegroupsubset(self._repo, bases, heads, source) |
293 | |
294 # End of baselegacywirecommands interface. | |
266 | 295 |
267 # Increment the sub-version when the revlog v2 format changes to lock out old | 296 # Increment the sub-version when the revlog v2 format changes to lock out old |
268 # clients. | 297 # clients. |
269 REVLOGV2_REQUIREMENT = 'exp-revlogv2.0' | 298 REVLOGV2_REQUIREMENT = 'exp-revlogv2.0' |
270 | 299 |