Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 39549:089fc0db0954
hg: allow extra arguments to be passed to repo creation (API)
Currently, repository creation is influenced by consulting the
ui instance and turning config options into requirements. This
means that in order to influence repository creation, you need
to define and set a config option and that the option must translate
to a requirement stored in the .hg/requires file.
This commit introduces a new mechanism to influence repository
creation. hg.repository() and hg.peer() have been taught to
receive a new optional argument defining extra options to apply
to repository creation. This value is passed along to the various
instance() functions and can be used to influence repository
creation. This will allow us to pass rich data directly to repository
creation without having to go through the config layer. It also allows
us to be more explicit about the features requested during repository
creation and provides a natural point to detect unhandled options
influencing repository creation. The new code detects when unknown
creation options are present and aborts in that case.
.. api:: options can now be passed to influence repository creation
The various instance() functions to spawn new peers or repository
instances now receive a ``createopts`` argument that can be a
dict defining additional options to influence repository creation.
localrepo.newreporequirements() also receives this argument.
Differential Revision: https://phab.mercurial-scm.org/D4535
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 11 Sep 2018 17:11:32 -0700 |
parents | 7ce9dea3a14a |
children | 261f1e8dc300 |
comparison
equal
deleted
inserted
replaced
39548:7ce9dea3a14a | 39549:089fc0db0954 |
---|---|
2378 def undoname(fn): | 2378 def undoname(fn): |
2379 base, name = os.path.split(fn) | 2379 base, name = os.path.split(fn) |
2380 assert name.startswith('journal') | 2380 assert name.startswith('journal') |
2381 return os.path.join(base, name.replace('journal', 'undo', 1)) | 2381 return os.path.join(base, name.replace('journal', 'undo', 1)) |
2382 | 2382 |
2383 def instance(ui, path, create, intents=None): | 2383 def instance(ui, path, create, intents=None, createopts=None): |
2384 if create: | 2384 if create: |
2385 vfs = vfsmod.vfs(path, expandpath=True, realpath=True) | 2385 vfs = vfsmod.vfs(path, expandpath=True, realpath=True) |
2386 | 2386 |
2387 if vfs.exists('.hg'): | 2387 if vfs.exists('.hg'): |
2388 raise error.RepoError(_('repository %s already exists') % path) | 2388 raise error.RepoError(_('repository %s already exists') % path) |
2389 | 2389 |
2390 createrepository(ui, vfs) | 2390 createrepository(ui, vfs, createopts=createopts) |
2391 | 2391 |
2392 return localrepository(ui, util.urllocalpath(path), intents=intents) | 2392 return localrepository(ui, util.urllocalpath(path), intents=intents) |
2393 | 2393 |
2394 def islocal(path): | 2394 def islocal(path): |
2395 return True | 2395 return True |
2396 | 2396 |
2397 def newreporequirements(ui): | 2397 def newreporequirements(ui, createopts=None): |
2398 """Determine the set of requirements for a new local repository. | 2398 """Determine the set of requirements for a new local repository. |
2399 | 2399 |
2400 Extensions can wrap this function to specify custom requirements for | 2400 Extensions can wrap this function to specify custom requirements for |
2401 new repositories. | 2401 new repositories. |
2402 """ | 2402 """ |
2403 createopts = createopts or {} | |
2404 | |
2403 requirements = {'revlogv1'} | 2405 requirements = {'revlogv1'} |
2404 if ui.configbool('format', 'usestore'): | 2406 if ui.configbool('format', 'usestore'): |
2405 requirements.add('store') | 2407 requirements.add('store') |
2406 if ui.configbool('format', 'usefncache'): | 2408 if ui.configbool('format', 'usefncache'): |
2407 requirements.add('fncache') | 2409 requirements.add('fncache') |
2438 if ui.configbool('format', 'internal-phase'): | 2440 if ui.configbool('format', 'internal-phase'): |
2439 requirements.add('internal-phase') | 2441 requirements.add('internal-phase') |
2440 | 2442 |
2441 return requirements | 2443 return requirements |
2442 | 2444 |
2443 def createrepository(ui, wdirvfs): | 2445 def filterknowncreateopts(ui, createopts): |
2446 """Filters a dict of repo creation options against options that are known. | |
2447 | |
2448 Receives a dict of repo creation options and returns a dict of those | |
2449 options that we don't know how to handle. | |
2450 | |
2451 This function is called as part of repository creation. If the | |
2452 returned dict contains any items, repository creation will not | |
2453 be allowed, as it means there was a request to create a repository | |
2454 with options not recognized by loaded code. | |
2455 | |
2456 Extensions can wrap this function to filter out creation options | |
2457 they know how to handle. | |
2458 """ | |
2459 return dict(createopts) | |
2460 | |
2461 def createrepository(ui, wdirvfs, createopts=None): | |
2444 """Create a new repository in a vfs. | 2462 """Create a new repository in a vfs. |
2445 | 2463 |
2446 ``wdirvfs`` is a vfs instance pointing at the working directory. | 2464 ``wdirvfs`` is a vfs instance pointing at the working directory. |
2447 ``requirements`` is a set of requirements for the new repository. | 2465 ``requirements`` is a set of requirements for the new repository. |
2448 """ | 2466 """ |
2449 requirements = newreporequirements(ui) | 2467 createopts = createopts or {} |
2468 | |
2469 unknownopts = filterknowncreateopts(ui, createopts) | |
2470 | |
2471 if not isinstance(unknownopts, dict): | |
2472 raise error.ProgrammingError('filterknowncreateopts() did not return ' | |
2473 'a dict') | |
2474 | |
2475 if unknownopts: | |
2476 raise error.Abort(_('unable to create repository because of unknown ' | |
2477 'creation option: %s') % | |
2478 ', '.sorted(unknownopts), | |
2479 hint=_('is a required extension not loaded?')) | |
2480 | |
2481 requirements = newreporequirements(ui, createopts=createopts) | |
2450 | 2482 |
2451 if not wdirvfs.exists(): | 2483 if not wdirvfs.exists(): |
2452 wdirvfs.makedirs() | 2484 wdirvfs.makedirs() |
2453 | 2485 |
2454 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg')) | 2486 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg')) |