configs: validate config during all load paths

Summary:
An earlier diff moved all dynamicconfig loadding into Rust, but it lost
some of the config validation along the way. This allowed dynamicconfig values
to take precedence over system rcs when they shouldn't yet. Most notably the
remotefilelog.cachepath value.

Let's ensure validation is run on all load paths. A future diff will go a step
farther and move dynamicconfigs to be loaded before system configs so we can
ensure system configs always take precedence, until we can remove them entirely.

Reviewed By: quark-zju

Differential Revision: D23305712

fbshipit-source-id: 33a6b4c56d97fa2e2e8f3acc343a8a8868b797ef
This commit is contained in:
Durham Goode 2020-08-25 07:31:29 -07:00 committed by Facebook GitHub Bot
parent 6aa932cd5a
commit a0184dde57
5 changed files with 12 additions and 8 deletions

View File

@ -999,8 +999,6 @@ def _getlocal(ui, rpath):
if path:
lui.reloadconfigs(path)
uiconfig.validatedynamicconfig(lui)
return path, lui

View File

@ -432,7 +432,6 @@ class localrepository(object):
# If the repo already exists, load the existing configs
if self.localvfs.isdir():
self.ui.reloadconfigs(self.root)
uiconfig.validatedynamicconfig(self.ui)
elif create:
# If we're in the process of creating the repo, load the dynamic configs in
# memory only. They will be written to disk later once the localvfs

View File

@ -254,12 +254,12 @@ class ui(object):
def load(cls, repopath=None):
"""Create a ui and load global and user configs"""
u = cls()
u._uiconfig = uiconfig.uiconfig.load(repopath)
uiconfig.uiconfig.load(u, repopath)
return u
def reloadconfigs(self, repopath=None):
# repopath should be the non-shared repo path without .hg/
self._uiconfig.reload(repopath)
self._uiconfig.reload(self, repopath)
def copy(self):
return self.__class__(self)

View File

@ -117,7 +117,7 @@ class uiconfig(object):
self._knownconfig = configitems.coreitems
@classmethod
def load(cls, repopath):
def load(cls, ui, repopath):
"""Create a uiconfig and load global and user configs"""
u = cls()
try:
@ -126,14 +126,20 @@ class uiconfig(object):
rcfg = configparser.config.load(dothgpath)
except Exception as ex:
raise error.ParseError(str(ex))
u._rcfg = localrcfg(rcfg)
ui._uiconfig = u
if repopath is not None:
validatedynamicconfig(ui)
root = os.path.expanduser("~")
u.fixconfig(root=repopath or root)
return u
def reload(self, repopath):
def reload(self, ui, repopath):
# The actual config expects the non-shared .hg directory.
self._rcfg.reload(os.path.join(repopath, ".hg"), list(self._pinnedconfigs))
validatedynamicconfig(ui)
# fixconfig expects the non-shard repo root, without the .hg.
self.fixconfig(root=repopath)

View File

@ -153,6 +153,7 @@ Verify we load and verify dynamicconfigs during clone
> EOF
$ hg clone ssh://user@dummy/server client2 --configfile $TESTTMP/good_hgrc --config configs.testdynamicconfigsubset=good_hgrc --config configs.validatedynamicconfig=True --config configs.mismatchwarn=True --config configs.legacylist=foo.bar
Config mismatch: foo.bar has 'None' (dynamic) vs 'True' (file)
Config mismatch: foo.bar has 'None' (dynamic) vs 'True' (file)
no changes found
Hook ran!
updating to branch default