Show More
@@ -20,6 +20,9 from .node import ( | |||||
20 | nullid, |
|
20 | nullid, | |
21 | short, |
|
21 | short, | |
22 | ) |
|
22 | ) | |
|
23 | from .thirdparty.zope import ( | |||
|
24 | interface as zi, | |||
|
25 | ) | |||
23 | from . import ( |
|
26 | from . import ( | |
24 | bookmarks, |
|
27 | bookmarks, | |
25 | branchmap, |
|
28 | branchmap, | |
@@ -318,6 +321,7 REVLOGV2_REQUIREMENT = 'exp-revlogv2.0' | |||||
318 | # set to reflect that the extension knows how to handle that requirements. |
|
321 | # set to reflect that the extension knows how to handle that requirements. | |
319 | featuresetupfuncs = set() |
|
322 | featuresetupfuncs = set() | |
320 |
|
323 | |||
|
324 | @zi.implementer(repository.completelocalrepository) | |||
321 | class localrepository(object): |
|
325 | class localrepository(object): | |
322 |
|
326 | |||
323 | # obsolete experimental requirements: |
|
327 | # obsolete experimental requirements: |
@@ -10,6 +10,9 from __future__ import absolute_import | |||||
10 | import abc |
|
10 | import abc | |
11 |
|
11 | |||
12 | from .i18n import _ |
|
12 | from .i18n import _ | |
|
13 | from .thirdparty.zope import ( | |||
|
14 | interface as zi, | |||
|
15 | ) | |||
13 | from . import ( |
|
16 | from . import ( | |
14 | error, |
|
17 | error, | |
15 | ) |
|
18 | ) | |
@@ -266,3 +269,360 class peer(_basepeer, _basewirecommands) | |||||
266 |
|
269 | |||
267 | class legacypeer(peer, _baselegacywirecommands): |
|
270 | class legacypeer(peer, _baselegacywirecommands): | |
268 | """peer but with support for legacy wire protocol commands.""" |
|
271 | """peer but with support for legacy wire protocol commands.""" | |
|
272 | ||||
|
273 | class completelocalrepository(zi.Interface): | |||
|
274 | """Monolithic interface for local repositories. | |||
|
275 | ||||
|
276 | This currently captures the reality of things - not how things should be. | |||
|
277 | """ | |||
|
278 | ||||
|
279 | supportedformats = zi.Attribute( | |||
|
280 | """Set of requirements that apply to stream clone. | |||
|
281 | ||||
|
282 | This is actually a class attribute and is shared among all instances. | |||
|
283 | """) | |||
|
284 | ||||
|
285 | openerreqs = zi.Attribute( | |||
|
286 | """Set of requirements that are passed to the opener. | |||
|
287 | ||||
|
288 | This is actually a class attribute and is shared among all instances. | |||
|
289 | """) | |||
|
290 | ||||
|
291 | supported = zi.Attribute( | |||
|
292 | """Set of requirements that this repo is capable of opening.""") | |||
|
293 | ||||
|
294 | requirements = zi.Attribute( | |||
|
295 | """Set of requirements this repo uses.""") | |||
|
296 | ||||
|
297 | filtername = zi.Attribute( | |||
|
298 | """Name of the repoview that is active on this repo.""") | |||
|
299 | ||||
|
300 | wvfs = zi.Attribute( | |||
|
301 | """VFS used to access the working directory.""") | |||
|
302 | ||||
|
303 | vfs = zi.Attribute( | |||
|
304 | """VFS rooted at the .hg directory. | |||
|
305 | ||||
|
306 | Used to access repository data not in the store. | |||
|
307 | """) | |||
|
308 | ||||
|
309 | svfs = zi.Attribute( | |||
|
310 | """VFS rooted at the store. | |||
|
311 | ||||
|
312 | Used to access repository data in the store. Typically .hg/store. | |||
|
313 | But can point elsewhere if the store is shared. | |||
|
314 | """) | |||
|
315 | ||||
|
316 | root = zi.Attribute( | |||
|
317 | """Path to the root of the working directory.""") | |||
|
318 | ||||
|
319 | path = zi.Attribute( | |||
|
320 | """Path to the .hg directory.""") | |||
|
321 | ||||
|
322 | origroot = zi.Attribute( | |||
|
323 | """The filesystem path that was used to construct the repo.""") | |||
|
324 | ||||
|
325 | auditor = zi.Attribute( | |||
|
326 | """A pathauditor for the working directory. | |||
|
327 | ||||
|
328 | This checks if a path refers to a nested repository. | |||
|
329 | ||||
|
330 | Operates on the filesystem. | |||
|
331 | """) | |||
|
332 | ||||
|
333 | nofsauditor = zi.Attribute( | |||
|
334 | """A pathauditor for the working directory. | |||
|
335 | ||||
|
336 | This is like ``auditor`` except it doesn't do filesystem checks. | |||
|
337 | """) | |||
|
338 | ||||
|
339 | baseui = zi.Attribute( | |||
|
340 | """Original ui instance passed into constructor.""") | |||
|
341 | ||||
|
342 | ui = zi.Attribute( | |||
|
343 | """Main ui instance for this instance.""") | |||
|
344 | ||||
|
345 | sharedpath = zi.Attribute( | |||
|
346 | """Path to the .hg directory of the repo this repo was shared from.""") | |||
|
347 | ||||
|
348 | store = zi.Attribute( | |||
|
349 | """A store instance.""") | |||
|
350 | ||||
|
351 | spath = zi.Attribute( | |||
|
352 | """Path to the store.""") | |||
|
353 | ||||
|
354 | sjoin = zi.Attribute( | |||
|
355 | """Alias to self.store.join.""") | |||
|
356 | ||||
|
357 | cachevfs = zi.Attribute( | |||
|
358 | """A VFS used to access the cache directory. | |||
|
359 | ||||
|
360 | Typically .hg/cache. | |||
|
361 | """) | |||
|
362 | ||||
|
363 | filteredrevcache = zi.Attribute( | |||
|
364 | """Holds sets of revisions to be filtered.""") | |||
|
365 | ||||
|
366 | names = zi.Attribute( | |||
|
367 | """A ``namespaces`` instance.""") | |||
|
368 | ||||
|
369 | def close(): | |||
|
370 | """Close the handle on this repository.""" | |||
|
371 | ||||
|
372 | def peer(): | |||
|
373 | """Obtain an object conforming to the ``peer`` interface.""" | |||
|
374 | ||||
|
375 | def unfiltered(): | |||
|
376 | """Obtain an unfiltered/raw view of this repo.""" | |||
|
377 | ||||
|
378 | def filtered(name, visibilityexceptions=None): | |||
|
379 | """Obtain a named view of this repository.""" | |||
|
380 | ||||
|
381 | obsstore = zi.Attribute( | |||
|
382 | """A store of obsolescence data.""") | |||
|
383 | ||||
|
384 | changelog = zi.Attribute( | |||
|
385 | """A handle on the changelog revlog.""") | |||
|
386 | ||||
|
387 | manifestlog = zi.Attribute( | |||
|
388 | """A handle on the root manifest revlog.""") | |||
|
389 | ||||
|
390 | dirstate = zi.Attribute( | |||
|
391 | """Working directory state.""") | |||
|
392 | ||||
|
393 | narrowpats = zi.Attribute( | |||
|
394 | """Matcher patterns for this repository's narrowspec.""") | |||
|
395 | ||||
|
396 | def narrowmatch(): | |||
|
397 | """Obtain a matcher for the narrowspec.""" | |||
|
398 | ||||
|
399 | def setnarrowpats(newincludes, newexcludes): | |||
|
400 | """Define the narrowspec for this repository.""" | |||
|
401 | ||||
|
402 | def __getitem__(changeid): | |||
|
403 | """Try to resolve a changectx.""" | |||
|
404 | ||||
|
405 | def __contains__(changeid): | |||
|
406 | """Whether a changeset exists.""" | |||
|
407 | ||||
|
408 | def __nonzero__(): | |||
|
409 | """Always returns True.""" | |||
|
410 | return True | |||
|
411 | ||||
|
412 | __bool__ = __nonzero__ | |||
|
413 | ||||
|
414 | def __len__(): | |||
|
415 | """Returns the number of changesets in the repo.""" | |||
|
416 | ||||
|
417 | def __iter__(): | |||
|
418 | """Iterate over revisions in the changelog.""" | |||
|
419 | ||||
|
420 | def revs(expr, *args): | |||
|
421 | """Evaluate a revset. | |||
|
422 | ||||
|
423 | Emits revisions. | |||
|
424 | """ | |||
|
425 | ||||
|
426 | def set(expr, *args): | |||
|
427 | """Evaluate a revset. | |||
|
428 | ||||
|
429 | Emits changectx instances. | |||
|
430 | """ | |||
|
431 | ||||
|
432 | def anyrevs(specs, user=False, localalias=None): | |||
|
433 | """Find revisions matching one of the given revsets.""" | |||
|
434 | ||||
|
435 | def url(): | |||
|
436 | """Returns a string representing the location of this repo.""" | |||
|
437 | ||||
|
438 | def hook(name, throw=False, **args): | |||
|
439 | """Call a hook.""" | |||
|
440 | ||||
|
441 | def tags(): | |||
|
442 | """Return a mapping of tag to node.""" | |||
|
443 | ||||
|
444 | def tagtype(tagname): | |||
|
445 | """Return the type of a given tag.""" | |||
|
446 | ||||
|
447 | def tagslist(): | |||
|
448 | """Return a list of tags ordered by revision.""" | |||
|
449 | ||||
|
450 | def nodetags(node): | |||
|
451 | """Return the tags associated with a node.""" | |||
|
452 | ||||
|
453 | def nodebookmarks(node): | |||
|
454 | """Return the list of bookmarks pointing to the specified node.""" | |||
|
455 | ||||
|
456 | def branchmap(): | |||
|
457 | """Return a mapping of branch to heads in that branch.""" | |||
|
458 | ||||
|
459 | def revbranchcache(): | |||
|
460 | pass | |||
|
461 | ||||
|
462 | def branchtip(branchtip, ignoremissing=False): | |||
|
463 | """Return the tip node for a given branch.""" | |||
|
464 | ||||
|
465 | def lookup(key): | |||
|
466 | """Resolve the node for a revision.""" | |||
|
467 | ||||
|
468 | def lookupbranch(key, remote=None): | |||
|
469 | """Look up the branch name of the given revision or branch name.""" | |||
|
470 | ||||
|
471 | def known(nodes): | |||
|
472 | """Determine whether a series of nodes is known. | |||
|
473 | ||||
|
474 | Returns a list of bools. | |||
|
475 | """ | |||
|
476 | ||||
|
477 | def local(): | |||
|
478 | """Whether the repository is local.""" | |||
|
479 | return True | |||
|
480 | ||||
|
481 | def publishing(): | |||
|
482 | """Whether the repository is a publishing repository.""" | |||
|
483 | ||||
|
484 | def cancopy(): | |||
|
485 | pass | |||
|
486 | ||||
|
487 | def shared(): | |||
|
488 | """The type of shared repository or None.""" | |||
|
489 | ||||
|
490 | def wjoin(f, *insidef): | |||
|
491 | """Calls self.vfs.reljoin(self.root, f, *insidef)""" | |||
|
492 | ||||
|
493 | def file(f): | |||
|
494 | """Obtain a filelog for a tracked path.""" | |||
|
495 | ||||
|
496 | def changectx(changeid): | |||
|
497 | """Obtains a changectx for a revision. | |||
|
498 | ||||
|
499 | Identical to __getitem__. | |||
|
500 | """ | |||
|
501 | ||||
|
502 | def setparents(p1, p2): | |||
|
503 | """Set the parent nodes of the working directory.""" | |||
|
504 | ||||
|
505 | def filectx(path, changeid=None, fileid=None): | |||
|
506 | """Obtain a filectx for the given file revision.""" | |||
|
507 | ||||
|
508 | def getcwd(): | |||
|
509 | """Obtain the current working directory from the dirstate.""" | |||
|
510 | ||||
|
511 | def pathto(f, cwd=None): | |||
|
512 | """Obtain the relative path to a file.""" | |||
|
513 | ||||
|
514 | def adddatafilter(name, fltr): | |||
|
515 | pass | |||
|
516 | ||||
|
517 | def wread(filename): | |||
|
518 | """Read a file from wvfs, using data filters.""" | |||
|
519 | ||||
|
520 | def wwrite(filename, data, flags, backgroundclose=False, **kwargs): | |||
|
521 | """Write data to a file in the wvfs, using data filters.""" | |||
|
522 | ||||
|
523 | def wwritedata(filename, data): | |||
|
524 | """Resolve data for writing to the wvfs, using data filters.""" | |||
|
525 | ||||
|
526 | def currenttransaction(): | |||
|
527 | """Obtain the current transaction instance or None.""" | |||
|
528 | ||||
|
529 | def transaction(desc, report=None): | |||
|
530 | """Open a new transaction to write to the repository.""" | |||
|
531 | ||||
|
532 | def undofiles(): | |||
|
533 | """Returns a list of (vfs, path) for files to undo transactions.""" | |||
|
534 | ||||
|
535 | def recover(): | |||
|
536 | """Roll back an interrupted transaction.""" | |||
|
537 | ||||
|
538 | def rollback(dryrun=False, force=False): | |||
|
539 | """Undo the last transaction. | |||
|
540 | ||||
|
541 | DANGEROUS. | |||
|
542 | """ | |||
|
543 | ||||
|
544 | def updatecaches(tr=None, full=False): | |||
|
545 | """Warm repo caches.""" | |||
|
546 | ||||
|
547 | def invalidatecaches(): | |||
|
548 | """Invalidate cached data due to the repository mutating.""" | |||
|
549 | ||||
|
550 | def invalidatevolatilesets(): | |||
|
551 | pass | |||
|
552 | ||||
|
553 | def invalidatedirstate(): | |||
|
554 | """Invalidate the dirstate.""" | |||
|
555 | ||||
|
556 | def invalidate(clearfilecache=False): | |||
|
557 | pass | |||
|
558 | ||||
|
559 | def invalidateall(): | |||
|
560 | pass | |||
|
561 | ||||
|
562 | def lock(wait=True): | |||
|
563 | """Lock the repository store and return a lock instance.""" | |||
|
564 | ||||
|
565 | def wlock(wait=True): | |||
|
566 | """Lock the non-store parts of the repository.""" | |||
|
567 | ||||
|
568 | def currentwlock(): | |||
|
569 | """Return the wlock if it's held or None.""" | |||
|
570 | ||||
|
571 | def checkcommitpatterns(wctx, vdirs, match, status, fail): | |||
|
572 | pass | |||
|
573 | ||||
|
574 | def commit(text='', user=None, date=None, match=None, force=False, | |||
|
575 | editor=False, extra=None): | |||
|
576 | """Add a new revision to the repository.""" | |||
|
577 | ||||
|
578 | def commitctx(ctx, error=False): | |||
|
579 | """Commit a commitctx instance to the repository.""" | |||
|
580 | ||||
|
581 | def destroying(): | |||
|
582 | """Inform the repository that nodes are about to be destroyed.""" | |||
|
583 | ||||
|
584 | def destroyed(): | |||
|
585 | """Inform the repository that nodes have been destroyed.""" | |||
|
586 | ||||
|
587 | def status(node1='.', node2=None, match=None, ignored=False, | |||
|
588 | clean=False, unknown=False, listsubrepos=False): | |||
|
589 | """Convenience method to call repo[x].status().""" | |||
|
590 | ||||
|
591 | def addpostdsstatus(ps): | |||
|
592 | pass | |||
|
593 | ||||
|
594 | def postdsstatus(): | |||
|
595 | pass | |||
|
596 | ||||
|
597 | def clearpostdsstatus(): | |||
|
598 | pass | |||
|
599 | ||||
|
600 | def heads(start=None): | |||
|
601 | """Obtain list of nodes that are DAG heads.""" | |||
|
602 | ||||
|
603 | def branchheads(branch=None, start=None, closed=False): | |||
|
604 | pass | |||
|
605 | ||||
|
606 | def branches(nodes): | |||
|
607 | pass | |||
|
608 | ||||
|
609 | def between(pairs): | |||
|
610 | pass | |||
|
611 | ||||
|
612 | def checkpush(pushop): | |||
|
613 | pass | |||
|
614 | ||||
|
615 | prepushoutgoinghooks = zi.Attribute( | |||
|
616 | """util.hooks instance.""") | |||
|
617 | ||||
|
618 | def pushkey(namespace, key, old, new): | |||
|
619 | pass | |||
|
620 | ||||
|
621 | def listkeys(namespace): | |||
|
622 | pass | |||
|
623 | ||||
|
624 | def debugwireargs(one, two, three=None, four=None, five=None): | |||
|
625 | pass | |||
|
626 | ||||
|
627 | def savecommitmessage(text): | |||
|
628 | pass |
@@ -2,16 +2,27 | |||||
2 |
|
2 | |||
3 | from __future__ import absolute_import, print_function |
|
3 | from __future__ import absolute_import, print_function | |
4 |
|
4 | |||
|
5 | import os | |||
|
6 | ||||
|
7 | from mercurial.thirdparty.zope import ( | |||
|
8 | interface as zi, | |||
|
9 | ) | |||
|
10 | from mercurial.thirdparty.zope.interface import ( | |||
|
11 | verify as ziverify, | |||
|
12 | ) | |||
5 | from mercurial import ( |
|
13 | from mercurial import ( | |
6 | bundlerepo, |
|
14 | bundlerepo, | |
7 | httppeer, |
|
15 | httppeer, | |
8 | localrepo, |
|
16 | localrepo, | |
|
17 | repository, | |||
9 | sshpeer, |
|
18 | sshpeer, | |
10 | statichttprepo, |
|
19 | statichttprepo, | |
11 | ui as uimod, |
|
20 | ui as uimod, | |
12 | unionrepo, |
|
21 | unionrepo, | |
13 | ) |
|
22 | ) | |
14 |
|
23 | |||
|
24 | rootdir = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) | |||
|
25 | ||||
15 | def checkobject(o): |
|
26 | def checkobject(o): | |
16 | """Verify a constructed object conforms to interface rules. |
|
27 | """Verify a constructed object conforms to interface rules. | |
17 |
|
28 | |||
@@ -41,6 +52,30 def checkobject(o): | |||||
41 | print('public attributes not in abstract interface: %s.%s' % ( |
|
52 | print('public attributes not in abstract interface: %s.%s' % ( | |
42 | name, attr)) |
|
53 | name, attr)) | |
43 |
|
54 | |||
|
55 | def checkzobject(o): | |||
|
56 | """Verify an object with a zope interface.""" | |||
|
57 | ifaces = zi.providedBy(o) | |||
|
58 | if not ifaces: | |||
|
59 | print('%r does not provide any zope interfaces' % o) | |||
|
60 | return | |||
|
61 | ||||
|
62 | # Run zope.interface's built-in verification routine. This verifies that | |||
|
63 | # everything that is supposed to be present is present. | |||
|
64 | for iface in ifaces: | |||
|
65 | ziverify.verifyObject(iface, o) | |||
|
66 | ||||
|
67 | # Now verify that the object provides no extra public attributes that | |||
|
68 | # aren't declared as part of interfaces. | |||
|
69 | allowed = set() | |||
|
70 | for iface in ifaces: | |||
|
71 | allowed |= set(iface.names(all=True)) | |||
|
72 | ||||
|
73 | public = {a for a in dir(o) if not a.startswith('_')} | |||
|
74 | ||||
|
75 | for attr in sorted(public - allowed): | |||
|
76 | print('public attribute not declared in interfaces: %s.%s' % ( | |||
|
77 | o.__class__.__name__, attr)) | |||
|
78 | ||||
44 | # Facilitates testing localpeer. |
|
79 | # Facilitates testing localpeer. | |
45 | class dummyrepo(object): |
|
80 | class dummyrepo(object): | |
46 | def __init__(self): |
|
81 | def __init__(self): | |
@@ -68,6 +103,8 class dummypipe(object): | |||||
68 |
|
103 | |||
69 | def main(): |
|
104 | def main(): | |
70 | ui = uimod.ui() |
|
105 | ui = uimod.ui() | |
|
106 | # Needed so we can open a local repo with obsstore without a warning. | |||
|
107 | ui.setconfig('experimental', 'evolution.createmarkers', True) | |||
71 |
|
108 | |||
72 | checkobject(badpeer()) |
|
109 | checkobject(badpeer()) | |
73 | checkobject(httppeer.httppeer(None, None, None, dummyopener())) |
|
110 | checkobject(httppeer.httppeer(None, None, None, dummyopener())) | |
@@ -80,4 +117,9 def main(): | |||||
80 | checkobject(statichttprepo.statichttppeer(dummyrepo())) |
|
117 | checkobject(statichttprepo.statichttppeer(dummyrepo())) | |
81 | checkobject(unionrepo.unionpeer(dummyrepo())) |
|
118 | checkobject(unionrepo.unionpeer(dummyrepo())) | |
82 |
|
119 | |||
|
120 | ziverify.verifyClass(repository.completelocalrepository, | |||
|
121 | localrepo.localrepository) | |||
|
122 | repo = localrepo.localrepository(ui, rootdir) | |||
|
123 | checkzobject(repo) | |||
|
124 | ||||
83 | main() |
|
125 | main() |
General Comments 0
You need to be logged in to leave comments.
Login now