Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/localrepo.py @ 39708:6a3162ed881d
localrepo: read requirements file in makelocalrepository()
Previously, scmutil.readrequires() loaded the requirements file
and validated its content against what was supported.
Requirements translate to repository features and are critical to
our plans to dynamically create local repository types. So, we must
load them in makelocalrepository() before a repository instance is
constructed.
This commit moves the reading of the .hg/requires file to
makelocalrepository(). Because scmutil.readrequires() was performing
I/O and validation, we inlined the validation into
localrepository.__init__ and removed scmutil.readrequires().
I plan to remove scmutil.readrequires() in a future commit (we can't
do it now because statichttprepo uses it).
Differential Revision: https://phab.mercurial-scm.org/D4568
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 12 Sep 2018 14:45:52 -0700 |
parents | 2f067e365532 |
children | 5b8e9b2060ef |
comparison
equal
deleted
inserted
replaced
39707:2f067e365532 | 39708:6a3162ed881d |
---|---|
406 if e.errno != errno.ENOENT: | 406 if e.errno != errno.ENOENT: |
407 raise | 407 raise |
408 | 408 |
409 raise error.RepoError(_(b'repository %s not found') % path) | 409 raise error.RepoError(_(b'repository %s not found') % path) |
410 | 410 |
411 # .hg/requires file contains a newline-delimited list of | |
412 # features/capabilities the opener (us) must have in order to use | |
413 # the repository. This file was introduced in Mercurial 0.9.2, | |
414 # which means very old repositories may not have one. We assume | |
415 # a missing file translates to no requirements. | |
416 try: | |
417 requirements = set(hgvfs.read(b'requires').splitlines()) | |
418 except IOError as e: | |
419 if e.errno != errno.ENOENT: | |
420 raise | |
421 requirements = set() | |
422 | |
411 # The .hg/hgrc file may load extensions or contain config options | 423 # The .hg/hgrc file may load extensions or contain config options |
412 # that influence repository construction. Attempt to load it and | 424 # that influence repository construction. Attempt to load it and |
413 # process any new extensions that it may have pulled in. | 425 # process any new extensions that it may have pulled in. |
414 try: | 426 try: |
415 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base) | 427 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base) |
422 baseui=baseui, | 434 baseui=baseui, |
423 ui=ui, | 435 ui=ui, |
424 origroot=path, | 436 origroot=path, |
425 wdirvfs=wdirvfs, | 437 wdirvfs=wdirvfs, |
426 hgvfs=hgvfs, | 438 hgvfs=hgvfs, |
439 requirements=requirements, | |
427 intents=intents) | 440 intents=intents) |
428 | 441 |
429 @interfaceutil.implementer(repository.completelocalrepository) | 442 @interfaceutil.implementer(repository.completelocalrepository) |
430 class localrepository(object): | 443 class localrepository(object): |
431 | 444 |
474 # this changeset was introduced. Someone should fix | 487 # this changeset was introduced. Someone should fix |
475 # the remainig bit and drop this line | 488 # the remainig bit and drop this line |
476 'bisect.state', | 489 'bisect.state', |
477 } | 490 } |
478 | 491 |
479 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, intents=None): | 492 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, |
493 intents=None): | |
480 """Create a new local repository instance. | 494 """Create a new local repository instance. |
481 | 495 |
482 Most callers should use ``hg.repository()``, ``localrepo.instance()``, | 496 Most callers should use ``hg.repository()``, ``localrepo.instance()``, |
483 or ``localrepo.makelocalrepository()`` for obtaining a new repository | 497 or ``localrepo.makelocalrepository()`` for obtaining a new repository |
484 object. | 498 object. |
497 wdirvfs | 511 wdirvfs |
498 ``vfs.vfs`` rooted at the working directory. | 512 ``vfs.vfs`` rooted at the working directory. |
499 | 513 |
500 hgvfs | 514 hgvfs |
501 ``vfs.vfs`` rooted at .hg/ | 515 ``vfs.vfs`` rooted at .hg/ |
516 | |
517 requirements | |
518 ``set`` of bytestrings representing repository opening requirements. | |
502 | 519 |
503 intents | 520 intents |
504 ``set`` of system strings indicating what this repo will be used | 521 ``set`` of system strings indicating what this repo will be used |
505 for. | 522 for. |
506 """ | 523 """ |
543 for name in util.compengines: | 560 for name in util.compengines: |
544 engine = util.compengines[name] | 561 engine = util.compengines[name] |
545 if engine.revlogheader(): | 562 if engine.revlogheader(): |
546 self.supported.add('exp-compression-%s' % name) | 563 self.supported.add('exp-compression-%s' % name) |
547 | 564 |
548 try: | 565 # Validate that all seen repository requirements are supported. |
549 self.requirements = scmutil.readrequires(self.vfs, self.supported) | 566 missingrequirements = [] |
550 except IOError as inst: | 567 for r in requirements: |
551 if inst.errno != errno.ENOENT: | 568 if r not in self.supported: |
552 raise | 569 if not r or not r[0:1].isalnum(): |
553 self.requirements = set() | 570 raise error.RequirementError( |
571 _(".hg/requires file is corrupt")) | |
572 missingrequirements.append(r) | |
573 missingrequirements.sort() | |
574 if missingrequirements: | |
575 raise error.RequirementError( | |
576 _("repository requires features unknown to this Mercurial: %s") | |
577 % " ".join(missingrequirements), | |
578 hint=_("see https://mercurial-scm.org/wiki/MissingRequirement" | |
579 " for more information")) | |
580 | |
581 self.requirements = requirements | |
554 | 582 |
555 cachepath = self.vfs.join('cache') | 583 cachepath = self.vfs.join('cache') |
556 self.sharedpath = self.path | 584 self.sharedpath = self.path |
557 try: | 585 try: |
558 sharedpath = self.vfs.read("sharedpath").rstrip('\n') | 586 sharedpath = self.vfs.read("sharedpath").rstrip('\n') |