# HG changeset patch # User Alexis S. L. Carvalho # Date 1161023933 10800 # Node ID ec6f400cff4d6ba65f076cc43edfaf2468697109 # Parent 9b1c126b74cd76c2c7aebf823220ca3c5e85821c Use a case-sensitive version of SafeConfigParser everywhere This change has the potential to break existing setups, but the current behaviour (the keys in configuration files are always lower-cased) can bite us in a few places: - no way to use a Command in [defaults] - hgext.Extension doesn't work in [extensions] - you can't use an Upper/case/PATH in the [paths] section of hgweb.config - you can't (easily) protect paths with upper-case letters with the acl extension - you can't specify a /Path/TO/a/rEPO in the [reposubs] section for the notify extension diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -8,7 +8,7 @@ import os from mercurial.demandload import demandload -demandload(globals(), "ConfigParser mimetools cStringIO") +demandload(globals(), "mimetools cStringIO") demandload(globals(), "mercurial:ui,hg,util,templater") demandload(globals(), "mercurial.hgweb.hgweb_mod:hgweb") demandload(globals(), "mercurial.hgweb.common:get_mtime,staticfile,style_map") @@ -30,7 +30,7 @@ class hgwebdir(object): self.repos = cleannames(config.items()) self.repos.sort() else: - cp = ConfigParser.SafeConfigParser() + cp = util.configparser() cp.read(config) self.repos = [] if cp.has_section('web'): diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -11,7 +11,7 @@ demandload(globals(), "errno getpass os demandload(globals(), "ConfigParser traceback util") def dupconfig(orig): - new = ConfigParser.SafeConfigParser(orig.defaults()) + new = util.configparser(orig.defaults()) updateconfig(orig, new) return new @@ -37,7 +37,7 @@ class ui(object): self.debugflag = debug self.interactive = interactive self.traceback = traceback - self.cdata = ConfigParser.SafeConfigParser() + self.cdata = util.configparser() self.readconfig(util.rcpath()) self.updateopts(verbose, debug, quiet, interactive) else: @@ -126,7 +126,7 @@ class ui(object): def setconfig(self, section, name, value): if not self.overlay: - self.overlay = ConfigParser.SafeConfigParser() + self.overlay = util.configparser() for cdata in (self.overlay, self.cdata): if not cdata.has_section(section): cdata.add_section(section) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -15,7 +15,7 @@ platform-specific details from the core. from i18n import gettext as _ from demandload import * demandload(globals(), "cStringIO errno getpass popen2 re shutil sys tempfile") -demandload(globals(), "os threading time calendar") +demandload(globals(), "os threading time calendar ConfigParser") # used by parsedate defaultdateformats = ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', @@ -24,6 +24,11 @@ defaultdateformats = ('%Y-%m-%d %H:%M:%S class SignalInterrupt(Exception): """Exception raised on SIGTERM and SIGHUP.""" +# like SafeConfigParser but with case-sensitive keys +class configparser(ConfigParser.SafeConfigParser): + def optionxform(self, optionstr): + return optionstr + def cachefunc(func): '''cache the result of function calls''' # XXX doesn't handle keywords args diff --git a/tests/test-config-case b/tests/test-config-case new file mode 100755 --- /dev/null +++ b/tests/test-config-case @@ -0,0 +1,7 @@ +#!/bin/sh + +echo '[Section]' >> $HGRCPATH +echo 'KeY = Case Sensitive' >> $HGRCPATH +echo 'key = lower case' >> $HGRCPATH + +hg showconfig diff --git a/tests/test-config-case.out b/tests/test-config-case.out new file mode 100644 --- /dev/null +++ b/tests/test-config-case.out @@ -0,0 +1,2 @@ +Section.KeY=Case Sensitive +Section.key=lower case