# HG changeset patch # User Pierre-Yves David # Date 2024-10-21 12:05:14 # Node ID c97e0fd262257f7febe1340aa96f1bfa4ebc5da5 # Parent 0a81f3ef054c700c64410553d3563ce62912584c config: move edition code in its own module We start to move code related to the command outside of the main commands modules for clarity. This also highlight some flaw in this code and the new flag are missing some error handling. However we will deal with them later. This move removes the needs for a few module import in the `commands.py` which I see as a good sign. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -53,7 +53,6 @@ from . import ( phases, pycompat, registrar, - requirements, revsetlang, rewriteutil, scmutil, @@ -61,15 +60,16 @@ from . import ( shelve as shelvemod, state as statemod, tags as tagsmod, - ui as uimod, util, verify as verifymod, - vfs as vfsmod, wireprotoserver, ) from .cmd_impls import graft as graft_impl -from .configuration import rcutil +from .configuration import ( + command as config_command, + rcutil, +) from .utils import ( dateutil, procutil, @@ -2367,58 +2367,9 @@ def config(ui, repo, *values, **opts): Returns 0 on success, 1 if NAME does not exist. """ - - editopts = ('edit', 'local', 'global', 'shared', 'non_shared') - if any(opts.get(o) for o in editopts): - cmdutil.check_at_most_one_arg(opts, *editopts[1:]) - if opts.get('local'): - if not repo: - raise error.InputError( - _(b"can't use --local outside a repository") - ) - paths = [repo.vfs.join(b'hgrc')] - elif opts.get('global'): - paths = rcutil.systemrcpath() - elif opts.get('shared'): - if not repo.shared(): - raise error.InputError( - _(b"repository is not shared; can't use --shared") - ) - if requirements.SHARESAFE_REQUIREMENT not in repo.requirements: - raise error.InputError( - _( - b"share safe feature not enabled; " - b"unable to edit shared source repository config" - ) - ) - paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')] - elif opts.get('non_shared'): - paths = [repo.vfs.join(b'hgrc-not-shared')] - else: - paths = rcutil.userrcpath() - - for f in paths: - if os.path.exists(f): - break - else: - if opts.get('global'): - samplehgrc = uimod.samplehgrcs[b'global'] - elif opts.get('local'): - samplehgrc = uimod.samplehgrcs[b'local'] - else: - samplehgrc = uimod.samplehgrcs[b'user'] - - f = paths[0] - util.writefile(f, util.tonativeeol(samplehgrc)) - - editor = ui.geteditor() - ui.system( - b"%s \"%s\"" % (editor, f), - onerr=error.InputError, - errprefix=_(b"edit failed"), - blockedtag=b'config_edit', - ) - return + edit_level = config_command.find_edit_level(ui, repo, opts) + if edit_level is not None: + return config_command.edit_config(ui, repo, edit_level) ui.pager(b'config') fm = ui.formatter(b'config', pycompat.byteskwargs(opts)) for t, f in rcutil.rccomponents(): diff --git a/mercurial/configuration/command.py b/mercurial/configuration/command.py new file mode 100644 --- /dev/null +++ b/mercurial/configuration/command.py @@ -0,0 +1,108 @@ +# Gather code related to command dealing with configuration. + +from __future__ import annotations + +import os + +from typing import Any, Dict, Optional + +from ..i18n import _ + +from .. import ( + cmdutil, + error, + requirements, + ui as uimod, + util, + vfs as vfsmod, +) + +from . import rcutil + +EDIT_FLAG = 'edit' + + +# keep typing simple for now +ConfigLevelT = str +LEVEL_USER = 'user' # "user" is the default level and never passed explicitly +LEVEL_LOCAL = 'local' +LEVEL_GLOBAL = 'global' +LEVEL_SHARED = 'shared' +LEVEL_NON_SHARED = 'non_shared' +EDIT_LEVELS = ( + LEVEL_USER, + LEVEL_LOCAL, + LEVEL_GLOBAL, + LEVEL_SHARED, + LEVEL_NON_SHARED, +) + + +def find_edit_level( + ui: uimod.ui, repo, opts: Dict[str, Any] +) -> Optional[ConfigLevelT]: + """return the level we should edit, if any. + + Parse the command option to detect when an edit is requested, and if so the + configuration level we should edit. + """ + if opts.get(EDIT_FLAG) or any(opts.get(o) for o in EDIT_LEVELS): + cmdutil.check_at_most_one_arg(opts, *EDIT_LEVELS) + for level in EDIT_LEVELS: + if opts.get(level): + return level + return EDIT_LEVELS[0] + return None + + +def edit_config(ui: uimod.ui, repo, level: ConfigLevelT) -> None: + """let the user edit configuration file for the given level""" + + if level == LEVEL_USER: + paths = rcutil.userrcpath() + elif level == LEVEL_GLOBAL: + paths = rcutil.systemrcpath() + elif level == LEVEL_LOCAL: + if not repo: + raise error.InputError(_(b"can't use --local outside a repository")) + paths = [repo.vfs.join(b'hgrc')] + elif level == LEVEL_NON_SHARED: + paths = [repo.vfs.join(b'hgrc-not-shared')] + elif level == LEVEL_SHARED: + if not repo.shared(): + raise error.InputError( + _(b"repository is not shared; can't use --shared") + ) + if requirements.SHARESAFE_REQUIREMENT not in repo.requirements: + raise error.InputError( + _( + b"share safe feature not enabled; " + b"unable to edit shared source repository config" + ) + ) + paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')] + else: + msg = 'unknown config level: %s' % level + raise error.ProgrammingError(msg) + + for f in paths: + if os.path.exists(f): + break + else: + if LEVEL_GLOBAL: + samplehgrc = uimod.samplehgrcs[b'global'] + elif LEVEL_LOCAL: + samplehgrc = uimod.samplehgrcs[b'local'] + else: + samplehgrc = uimod.samplehgrcs[b'user'] + + f = paths[0] + util.writefile(f, util.tonativeeol(samplehgrc)) + + editor = ui.geteditor() + ui.system( + b"%s \"%s\"" % (editor, f), + onerr=error.InputError, + errprefix=_(b"edit failed"), + blockedtag=b'config_edit', + )