config: gather the path to edit through rcutil
Using the common logic helps to reduce potential error when it changes
--- a/mercurial/configuration/__init__.py Wed Oct 23 01:32:33 2024 +0200
+++ b/mercurial/configuration/__init__.py Wed Oct 23 02:05:03 2024 +0200
@@ -26,6 +26,11 @@
LEVEL_SHARED,
LEVEL_NON_SHARED,
)
+# levels that can works without a repository
+NO_REPO_EDIT_LEVELS = (
+ LEVEL_USER,
+ LEVEL_GLOBAL,
+)
ConfigItemT = Tuple[bytes, bytes, bytes, bytes]
ResourceIDT = Tuple[bytes, bytes]
--- a/mercurial/configuration/command.py Wed Oct 23 01:32:33 2024 +0200
+++ b/mercurial/configuration/command.py Wed Oct 23 02:05:03 2024 +0200
@@ -16,17 +16,13 @@
requirements,
ui as uimod,
util,
- vfs as vfsmod,
)
from . import (
ConfigLevelT,
EDIT_LEVELS,
- LEVEL_GLOBAL,
- LEVEL_LOCAL,
- LEVEL_NON_SHARED,
LEVEL_SHARED,
- LEVEL_USER,
+ NO_REPO_EDIT_LEVELS,
rcutil,
)
@@ -55,21 +51,14 @@
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:
+ # validate input
+ if repo is None and level not in NO_REPO_EDIT_LEVELS:
+ msg = b"can't use --%s outside a repository" % pycompat.bytestr(level)
+ raise error.InputError(_(msg))
+ if level == LEVEL_SHARED:
if not repo.shared():
- raise error.InputError(
- _(b"repository is not shared; can't use --shared")
- )
+ msg = _(b"repository is not shared; can't use --shared")
+ raise error.InputError(msg)
if requirements.SHARESAFE_REQUIREMENT not in repo.requirements:
raise error.InputError(
_(
@@ -77,24 +66,32 @@
b"unable to edit shared source repository config"
)
)
- paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
- else:
+
+ # find rc files paths
+ repo_path = None
+ if repo is not None:
+ repo_path = repo.root
+ all_rcs = rcutil.all_rc_components(repo_path)
+ rc_by_level = {}
+ for lvl, rc_type, values in all_rcs:
+ if rc_type != b'path':
+ continue
+ rc_by_level.setdefault(lvl, []).append(values)
+
+ if level not in rc_by_level:
msg = 'unknown config level: %s' % level
raise error.ProgrammingError(msg)
+ paths = rc_by_level[level]
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']
+ samplehgrc = uimod.samplehgrcs.get(level)
f = paths[0]
- util.writefile(f, util.tonativeeol(samplehgrc))
+ if samplehgrc is not None:
+ util.writefile(f, util.tonativeeol(samplehgrc))
editor = ui.geteditor()
ui.system(
--- a/mercurial/configuration/rcutil.py Wed Oct 23 01:32:33 2024 +0200
+++ b/mercurial/configuration/rcutil.py Wed Oct 23 02:05:03 2024 +0200
@@ -87,11 +87,12 @@
]
-def rccomponents() -> List[ComponentT]:
+def rccomponents(use_hgrcpath=True) -> List[ComponentT]:
"""return an ordered [(type, obj)] about where to load configs.
respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is
- used. if $HGRCPATH is not set, the platform default will be used.
+ used. if $HGRCPATH is not set, the platform default will be used. If
+ `use_hgrcpath` is False, it is never used.
if a directory is provided, *.rc files under it will be used.
@@ -105,7 +106,7 @@
_rccomponents = []
comp = _rccomponents.append
- if b'HGRCPATH' in encoding.environ:
+ if b'HGRCPATH' in encoding.environ and use_hgrcpath:
# assume HGRCPATH is all about user configs so environments can be
# overridden.
comp(envrc)
@@ -171,6 +172,14 @@
return components
+def all_rc_components(repo_path: Optional[bytes]):
+ components = []
+ components.extend(rccomponents(use_hgrcpath=False))
+ if repo_path is not None:
+ components.extend(repo_components(repo_path))
+ return components
+
+
def defaultpagerenv() -> Dict[bytes, bytes]:
"""return a dict of default environment variables and their values,
intended to be set before starting a pager.