comparison mercurial/localrepo.py @ 39711:cb2dcfa5cade

localrepo: move requirements reasonability testing to own function Just because we know how to handle each listed requirement doesn't mean that set of requirements is reasonable. This commit introduces an extension-wrappable function to validate that a set of requirements makes sense. We could combine this with ensurerequirementsrecognized(). But I think having a line between basic membership testing and compatibility checking is more powerful as it will help differentiate between missing support and buggy behavior. Differential Revision: https://phab.mercurial-scm.org/D4571
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 12 Sep 2018 15:03:17 -0700
parents 5b8e9b2060ef
children 9de1a1c83cd7
comparison
equal deleted inserted replaced
39710:6192980553b4 39711:cb2dcfa5cade
429 pass 429 pass
430 else: 430 else:
431 extensions.loadall(ui) 431 extensions.loadall(ui)
432 432
433 supportedrequirements = gathersupportedrequirements(ui) 433 supportedrequirements = gathersupportedrequirements(ui)
434
435 # We first validate the requirements are known.
434 ensurerequirementsrecognized(requirements, supportedrequirements) 436 ensurerequirementsrecognized(requirements, supportedrequirements)
437
438 # Then we validate that the known set is reasonable to use together.
439 ensurerequirementscompatible(ui, requirements)
435 440
436 # At this point, we know we should be capable of opening the repository. 441 # At this point, we know we should be capable of opening the repository.
437 # Now get on with doing that. 442 # Now get on with doing that.
438 443
439 return localrepository( 444 return localrepository(
491 raise error.RequirementError( 496 raise error.RequirementError(
492 _(b'repository requires features unknown to this Mercurial: %s') % 497 _(b'repository requires features unknown to this Mercurial: %s') %
493 b' '.join(sorted(missing)), 498 b' '.join(sorted(missing)),
494 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement ' 499 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement '
495 b'for more information')) 500 b'for more information'))
501
502 def ensurerequirementscompatible(ui, requirements):
503 """Validates that a set of recognized requirements is mutually compatible.
504
505 Some requirements may not be compatible with others or require
506 config options that aren't enabled. This function is called during
507 repository opening to ensure that the set of requirements needed
508 to open a repository is sane and compatible with config options.
509
510 Extensions can monkeypatch this function to perform additional
511 checking.
512
513 ``error.RepoError`` should be raised on failure.
514 """
515 if b'exp-sparse' in requirements and not sparse.enabled:
516 raise error.RepoError(_(b'repository is using sparse feature but '
517 b'sparse is not enabled; enable the '
518 b'"sparse" extensions to access'))
496 519
497 @interfaceutil.implementer(repository.completelocalrepository) 520 @interfaceutil.implementer(repository.completelocalrepository)
498 class localrepository(object): 521 class localrepository(object):
499 522
500 # obsolete experimental requirements: 523 # obsolete experimental requirements:
622 _('.hg/sharedpath points to nonexistent directory %s') % s) 645 _('.hg/sharedpath points to nonexistent directory %s') % s)
623 self.sharedpath = s 646 self.sharedpath = s
624 except IOError as inst: 647 except IOError as inst:
625 if inst.errno != errno.ENOENT: 648 if inst.errno != errno.ENOENT:
626 raise 649 raise
627
628 if 'exp-sparse' in self.requirements and not sparse.enabled:
629 raise error.RepoError(_('repository is using sparse feature but '
630 'sparse is not enabled; enable the '
631 '"sparse" extensions to access'))
632 650
633 self.store = store.store( 651 self.store = store.store(
634 self.requirements, self.sharedpath, 652 self.requirements, self.sharedpath,
635 lambda base: vfsmod.vfs(base, cacheaudited=True)) 653 lambda base: vfsmod.vfs(base, cacheaudited=True))
636 self.spath = self.store.path 654 self.spath = self.store.path