# HG changeset patch # User Matt Mackall # Date 2009-04-23 20:40:10 # Node ID 912bfef12ba6d574e2c8cccd6276d5dd11ac4b18 # Parent e40b629bedd1730d4d97d17669380fe072245562 ui: fold readsections into readconfig readconfig now reads only single files readconfig takes an optional list of sections readconfig trusts files we're looking for sections in diff --git a/hgext/acl.py b/hgext/acl.py --- a/hgext/acl.py +++ b/hgext/acl.py @@ -74,7 +74,7 @@ def hook(ui, repo, hooktype, node=None, user = getpass.getuser() cfg = ui.config('acl', 'config') if cfg: - ui.readsections(cfg, 'acl.allow', 'acl.deny') + ui.readconfig(cfg, sections = ['acl.allow', 'acl.deny']) allow = buildmatch(ui, repo, user, 'acl.allow') deny = buildmatch(ui, repo, user, 'acl.deny') diff --git a/hgext/bugzilla.py b/hgext/bugzilla.py --- a/hgext/bugzilla.py +++ b/hgext/bugzilla.py @@ -139,7 +139,7 @@ class bugzilla_2_16(object): timeout = int(self.ui.config('bugzilla', 'timeout', 5)) usermap = self.ui.config('bugzilla', 'usermap') if usermap: - self.ui.readsections(usermap, 'usermap') + self.ui.readconfig(usermap, 'usermap') self.ui.note(_('connecting to %s:%s as %s, password %s\n') % (host, db, user, '*' * len(passwd))) self.conn = MySQLdb.connect(host=host, user=user, passwd=passwd, diff --git a/hgext/notify.py b/hgext/notify.py --- a/hgext/notify.py +++ b/hgext/notify.py @@ -99,7 +99,7 @@ class notifier(object): self.ui = ui cfg = self.ui.config('notify', 'config') if cfg: - self.ui.readsections(cfg, 'usersubs', 'reposubs') + self.ui.readconfig(cfg, sections=['usersubs', 'reposubs']) self.repo = repo self.stripcount = int(self.ui.config('notify', 'strip', 0)) self.root = self.strip(self.repo.root) diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -20,6 +20,8 @@ def updateconfig(source, dest, sections= for section in sections: if not dest.has_section(section): dest.add_section(section) + if not source.has_section(section): + continue for name, value in source.items(section, raw=True): dest.set(section, name, value) @@ -39,7 +41,8 @@ class ui(object): self.ucdata = util.configparser() # we always trust global config files - self.readconfig(util.rcpath(), assumetrusted=True) + for f in util.rcpath(): + self.readconfig(f, assumetrusted=True) else: # parentui may point to an ui object which is already a child self.parentui = parentui.parentui or parentui @@ -51,6 +54,7 @@ class ui(object): # we want the overlay from the parent, not the root self.overlay = dupconfig(parentui.overlay) + self.fixconfig() def __getattr__(self, key): return getattr(self.parentui, key) @@ -84,66 +88,36 @@ class ui(object): 'user %s, group %s\n') % (f, user, group)) return False - def readconfig(self, fn, root=None, assumetrusted=False): - cdata = util.configparser() + def readconfig(self, filename, root=None, assumetrusted=False, + sections = None): + try: + fp = open(filename) + except IOError: + if not sections: # ignore unless we were looking for something + return + raise - if isinstance(fn, basestring): - fn = [fn] - for f in fn: - try: - fp = open(f) - except IOError: - continue - - trusted = assumetrusted or self._is_trusted(fp, f) + cdata = util.configparser() + trusted = sections or assumetrusted or self._is_trusted(fp, filename) - try: - cdata.readfp(fp, f) - except ConfigParser.ParsingError, inst: - msg = _("Failed to parse %s\n%s") % (f, inst) - if trusted: - raise util.Abort(msg) - self.warn(_("Ignored: %s\n") % msg) + try: + cdata.readfp(fp, filename) + except ConfigParser.ParsingError, inst: + msg = _("Failed to parse %s\n%s") % (filename, inst) + if trusted: + raise util.Abort(msg) + self.warn(_("Ignored: %s\n") % msg) - if trusted: - updateconfig(cdata, self.cdata) - updateconfig(self.overlay, self.cdata) - updateconfig(cdata, self.ucdata) - updateconfig(self.overlay, self.ucdata) + if trusted: + updateconfig(cdata, self.cdata, sections) + updateconfig(self.overlay, self.cdata, sections) + updateconfig(cdata, self.ucdata, sections) + updateconfig(self.overlay, self.ucdata, sections) if root is None: root = os.path.expanduser('~') self.fixconfig(root=root) - def readsections(self, filename, *sections): - """Read filename and add only the specified sections to the config data - - The settings are added to the trusted config data. - """ - if not sections: - return - - cdata = util.configparser() - try: - try: - fp = open(filename) - except IOError, inst: - raise util.Abort(_("unable to open %s: %s") % - (filename, getattr(inst, "strerror", inst))) - try: - cdata.readfp(fp, filename) - finally: - fp.close() - except ConfigParser.ParsingError, inst: - raise util.Abort(_("failed to parse %s\n%s") % (filename, inst)) - - for section in sections: - if not cdata.has_section(section): - cdata.add_section(section) - - updateconfig(cdata, self.cdata, sections) - updateconfig(cdata, self.ucdata, sections) - def fixconfig(self, section=None, name=None, value=None, root=None): # translate paths relative to root (or home) into absolute paths if section is None or section == 'paths': diff --git a/tests/test-acl.out b/tests/test-acl.out --- a/tests/test-acl.out +++ b/tests/test-acl.out @@ -473,10 +473,10 @@ adding foo/file.txt revisions adding quux/file.py revisions added 3 changesets with 3 changes to 3 files calling hook pretxnchangegroup.acl: hgext.acl.hook -error: pretxnchangegroup.acl hook failed: unable to open ../acl.config: No such file or directory +error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config' transaction abort! rollback completed -abort: unable to open ../acl.config: No such file or directory +abort: No such file or directory: ../acl.config no rollback information available 0:6675d58eff77 diff --git a/tests/test-notify b/tests/test-notify --- a/tests/test-notify +++ b/tests/test-notify @@ -60,7 +60,7 @@ EOF echo % fail for config file is missing hg --cwd b rollback -hg --cwd b pull ../a 2>&1 | grep 'unable to open.*\.notify\.conf' > /dev/null && echo pull failed +hg --cwd b pull ../a 2>&1 | grep 'error.*\.notify\.conf' > /dev/null && echo pull failed touch "$HGTMP/.notify.conf" diff --git a/tests/test-trusted.py b/tests/test-trusted.py --- a/tests/test-trusted.py +++ b/tests/test-trusted.py @@ -133,13 +133,13 @@ testui(user='abc', group='def', cuser=No print "# prints debug warnings" u = testui(user='abc', group='def', cuser='foo', debug=True) -print "# ui.readsections" +print "# ui.readconfig sections" filename = 'foobar' f = open(filename, 'w') f.write('[foobar]\n') f.write('baz = quux\n') f.close() -u.readsections(filename, 'foobar') +u.readconfig(filename, sections = ['foobar']) print u.config('foobar', 'baz') print diff --git a/tests/test-trusted.py.out b/tests/test-trusted.py.out --- a/tests/test-trusted.py.out +++ b/tests/test-trusted.py.out @@ -165,7 +165,7 @@ untrusted .Ignoring untrusted configuration option paths.local = /another/path . local = /another/path -# ui.readsections +# ui.readconfig sections quux # read trusted, untrusted, new ui, trusted