##// END OF EJS Templates
ui: introduce new config parser
Matt Mackall -
r8144:fca54469 default
parent child Browse files
Show More
@@ -0,0 +1,93 b''
1 from i18n import _
2 import re, error
3
4 class sortdict(dict):
5 'a simple append-only sorted dictionary'
6 def __init__(self, data=None):
7 self._list = []
8 if data:
9 if hasattr(data, '_list'):
10 self._list = list(data._list)
11 self.update(data)
12 def copy(self):
13 return sortdict(self)
14 def __setitem__(self, key, val):
15 if key in self:
16 self._list.remove(key)
17 self._list.append(key)
18 dict.__setitem__(self, key, val)
19 def __iter__(self):
20 return self._list.__iter__()
21 def update(self, src):
22 for k in src:
23 self[k] = src[k]
24 def items(self):
25 return [(k,self[k]) for k in self._list]
26
27 class config:
28 def __init__(self, data=None):
29 self._data = {}
30 if data:
31 for k in data._data:
32 self._data[k] = data[k].copy()
33 def copy(self):
34 return config(self)
35 def __contains__(self, section):
36 return section in self._data
37 def update(self, src, sections=None):
38 if not sections:
39 sections = src.sections()
40 for s in sections:
41 if s not in src:
42 continue
43 if s not in self:
44 self._data[s] = sortdict()
45 for k in src._data[s]:
46 self._data[s][k] = src._data[s][k]
47 def get(self, section, item, default=None):
48 return self._data.get(section, {}).get(item, (default, ""))[0]
49 def getsource(self, section, item):
50 return self._data.get(section, {}).get(item, (None, ""))[1]
51 def sections(self):
52 return sorted(self._data.keys())
53 def items(self, section):
54 return [(k, v[0]) for k,v in self._data.get(section, {}).items()]
55 def set(self, section, item, value, source=""):
56 if section not in self:
57 self._data[section] = sortdict()
58 self._data[section][item] = (value, source)
59
60 def read(self, path, fp):
61 sectionre = re.compile(r'\[([^\[]+)\]')
62 itemre = re.compile(r'([^=\s]+)\s*=\s*(.*)')
63 contre = re.compile(r'\s+(\S.*)')
64 emptyre = re.compile(r'(;|#|\s*$)')
65 section = ""
66 item = None
67 line = 0
68 cont = 0
69 for l in fp:
70 line += 1
71 if cont:
72 m = contre.match(l)
73 if m:
74 v = self.get(section, item) + "\n" + m.group(1)
75 self.set(section, item, v, "%s:%d" % (path, line))
76 continue
77 item = None
78 if emptyre.match(l):
79 continue
80 m = sectionre.match(l)
81 if m:
82 section = m.group(1)
83 if section not in self:
84 self._data[section] = sortdict()
85 continue
86 m = itemre.match(l)
87 if m:
88 item = m.group(1)
89 self.set(section, item, m.group(2), "%s:%d" % (path, line))
90 cont = 1
91 continue
92 raise error.ConfigError(_('config error at %s:%d: \'%s\'')
93 % (path, line, l.rstrip()))
@@ -55,6 +55,8 b' def _runcatch(ui, args):'
55 except error.AmbiguousCommand, inst:
55 except error.AmbiguousCommand, inst:
56 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
56 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
57 (inst.args[0], " ".join(inst.args[1])))
57 (inst.args[0], " ".join(inst.args[1])))
58 except error.ConfigError, inst:
59 ui.warn(_("hg: %s\n") % inst.args[0])
58 except error.LockHeld, inst:
60 except error.LockHeld, inst:
59 if inst.errno == errno.ETIMEDOUT:
61 if inst.errno == errno.ETIMEDOUT:
60 reason = _('timed out waiting for lock held by %s') % inst.locker
62 reason = _('timed out waiting for lock held by %s') % inst.locker
@@ -28,6 +28,9 b' class LookupError(RevlogError, KeyError)'
28 class ParseError(Exception):
28 class ParseError(Exception):
29 """Exception raised on errors in parsing the command line."""
29 """Exception raised on errors in parsing the command line."""
30
30
31 class ConfigError(Exception):
32 'Exception raised when parsing config files'
33
31 class RepoError(Exception):
34 class RepoError(Exception):
32 pass
35 pass
33
36
@@ -7,27 +7,19 b''
7
7
8 from i18n import _
8 from i18n import _
9 import errno, getpass, os, re, socket, sys, tempfile
9 import errno, getpass, os, re, socket, sys, tempfile
10 import ConfigParser, traceback, util
10 import config, traceback, util, error
11
11
12 def updateconfig(source, dest, sections=None):
12 _booleans = {'1':True, 'yes':True, 'true':True, 'on':True,
13 if not sections:
13 '0':False, 'no':False, 'false':False, 'off':False}
14 sections = source.sections()
15 for section in sections:
16 if not dest.has_section(section):
17 dest.add_section(section)
18 if not source.has_section(section):
19 continue
20 for name, value in source.items(section, raw=True):
21 dest.set(section, name, value)
22
14
23 class ui(object):
15 class ui(object):
24 def __init__(self, parentui=None):
16 def __init__(self, parentui=None):
25 self.buffers = []
17 self.buffers = []
26 self.quiet = self.verbose = self.debugflag = self.traceback = False
18 self.quiet = self.verbose = self.debugflag = self.traceback = False
27 self.interactive = self.report_untrusted = True
19 self.interactive = self.report_untrusted = True
28 self.overlay = util.configparser()
20 self.overlay = config.config()
29 self.cdata = util.configparser()
21 self.cdata = config.config()
30 self.ucdata = util.configparser()
22 self.ucdata = config.config()
31 self.parentui = None
23 self.parentui = None
32 self.trusted_users = {}
24 self.trusted_users = {}
33 self.trusted_groups = {}
25 self.trusted_groups = {}
@@ -35,10 +27,10 b' class ui(object):'
35 if parentui:
27 if parentui:
36 # parentui may point to an ui object which is already a child
28 # parentui may point to an ui object which is already a child
37 self.parentui = parentui.parentui or parentui
29 self.parentui = parentui.parentui or parentui
38 updateconfig(self.parentui.cdata, self.cdata)
30 self.cdata.update(self.parentui.cdata)
39 updateconfig(self.parentui.ucdata, self.ucdata)
31 self.ucdata.update(self.parentui.ucdata)
40 # we want the overlay from the parent, not the root
32 # we want the overlay from the parent, not the root
41 updateconfig(parentui.overlay, self.overlay)
33 self.overlay.update(parentui.overlay)
42 self.buffers = parentui.buffers
34 self.buffers = parentui.buffers
43 self.trusted_users = parentui.trusted_users.copy()
35 self.trusted_users = parentui.trusted_users.copy()
44 self.trusted_groups = parentui.trusted_groups.copy()
36 self.trusted_groups = parentui.trusted_groups.copy()
@@ -89,22 +81,21 b' class ui(object):'
89 return
81 return
90 raise
82 raise
91
83
92 cdata = util.configparser()
84 cdata = config.config()
93 trusted = sections or assumetrusted or self._is_trusted(fp, filename)
85 trusted = sections or assumetrusted or self._is_trusted(fp, filename)
94
86
95 try:
87 try:
96 cdata.readfp(fp, filename)
88 cdata.read(filename, fp)
97 except ConfigParser.ParsingError, inst:
89 except error.ConfigError, inst:
98 msg = _("Failed to parse %s\n%s") % (filename, inst)
99 if trusted:
90 if trusted:
100 raise util.Abort(msg)
91 raise
101 self.warn(_("Ignored: %s\n") % msg)
92 self.warn(_("Ignored: %s\n") % str(inst))
102
93
103 if trusted:
94 if trusted:
104 updateconfig(cdata, self.cdata, sections)
95 self.cdata.update(cdata, sections)
105 updateconfig(self.overlay, self.cdata, sections)
96 self.cdata.update(self.overlay, sections)
106 updateconfig(cdata, self.ucdata, sections)
97 self.ucdata.update(cdata, sections)
107 updateconfig(self.overlay, self.ucdata, sections)
98 self.ucdata.update(self.overlay, sections)
108
99
109 if root is None:
100 if root is None:
110 root = os.path.expanduser('~')
101 root = os.path.expanduser('~')
@@ -117,7 +108,7 b' class ui(object):'
117 root = os.getcwd()
108 root = os.getcwd()
118 items = section and [(name, value)] or []
109 items = section and [(name, value)] or []
119 for cdata in self.cdata, self.ucdata, self.overlay:
110 for cdata in self.cdata, self.ucdata, self.overlay:
120 if not items and cdata.has_section('paths'):
111 if not items and 'paths' in cdata:
121 pathsitems = cdata.items('paths')
112 pathsitems = cdata.items('paths')
122 else:
113 else:
123 pathsitems = items
114 pathsitems = items
@@ -149,8 +140,6 b' class ui(object):'
149
140
150 def setconfig(self, section, name, value):
141 def setconfig(self, section, name, value):
151 for cdata in (self.overlay, self.cdata, self.ucdata):
142 for cdata in (self.overlay, self.cdata, self.ucdata):
152 if not cdata.has_section(section):
153 cdata.add_section(section)
154 cdata.set(section, name, value)
143 cdata.set(section, name, value)
155 self.fixconfig(section, name, value)
144 self.fixconfig(section, name, value)
156
145
@@ -159,37 +148,23 b' class ui(object):'
159 return self.ucdata
148 return self.ucdata
160 return self.cdata
149 return self.cdata
161
150
162 def _config(self, section, name, default, funcname, untrusted, abort):
151 def config(self, section, name, default=None, untrusted=False):
163 cdata = self._get_cdata(untrusted)
152 value = self._get_cdata(untrusted).get(section, name, default)
164 if cdata.has_option(section, name):
165 try:
166 func = getattr(cdata, funcname)
167 return func(section, name)
168 except (ConfigParser.InterpolationError, ValueError), inst:
169 msg = _("Error in configuration section [%s] "
170 "parameter '%s':\n%s") % (section, name, inst)
171 if abort:
172 raise util.Abort(msg)
173 self.warn(_("Ignored: %s\n") % msg)
174 return default
175
176 def _configcommon(self, section, name, default, funcname, untrusted):
177 value = self._config(section, name, default, funcname,
178 untrusted, abort=True)
179 if self.debugflag and not untrusted:
153 if self.debugflag and not untrusted:
180 uvalue = self._config(section, name, None, funcname,
154 uvalue = self.ucdata.get(section, name)
181 untrusted=True, abort=False)
182 if uvalue is not None and uvalue != value:
155 if uvalue is not None and uvalue != value:
183 self.warn(_("Ignoring untrusted configuration option "
156 self.warn(_("Ignoring untrusted configuration option "
184 "%s.%s = %s\n") % (section, name, uvalue))
157 "%s.%s = %s\n") % (section, name, uvalue))
185 return value
158 return value
186
159
187 def config(self, section, name, default=None, untrusted=False):
188 return self._configcommon(section, name, default, 'get', untrusted)
189
190 def configbool(self, section, name, default=False, untrusted=False):
160 def configbool(self, section, name, default=False, untrusted=False):
191 return self._configcommon(section, name, default, 'getboolean',
161 v = self.config(section, name, None, untrusted)
192 untrusted)
162 if v == None:
163 return default
164 if v.lower() not in _booleans:
165 raise error.ConfigError(_("%s.%s not a boolean ('%s')")
166 % (section, name, v))
167 return _booleans[v.lower()]
193
168
194 def configlist(self, section, name, default=None, untrusted=False):
169 def configlist(self, section, name, default=None, untrusted=False):
195 """Return a list of comma/space separated strings"""
170 """Return a list of comma/space separated strings"""
@@ -202,38 +177,20 b' class ui(object):'
202
177
203 def has_section(self, section, untrusted=False):
178 def has_section(self, section, untrusted=False):
204 '''tell whether section exists in config.'''
179 '''tell whether section exists in config.'''
205 cdata = self._get_cdata(untrusted)
180 return section in self._get_cdata(untrusted)
206 return cdata.has_section(section)
207
208 def _configitems(self, section, untrusted, abort):
209 items = {}
210 cdata = self._get_cdata(untrusted)
211 if cdata.has_section(section):
212 try:
213 items.update(dict(cdata.items(section)))
214 except ConfigParser.InterpolationError, inst:
215 msg = _("Error in configuration section [%s]:\n"
216 "%s") % (section, inst)
217 if abort:
218 raise util.Abort(msg)
219 self.warn(_("Ignored: %s\n") % msg)
220 return items
221
181
222 def configitems(self, section, untrusted=False):
182 def configitems(self, section, untrusted=False):
223 items = self._configitems(section, untrusted=untrusted, abort=True)
183 items = self._get_cdata(untrusted).items(section)
224 if self.debugflag and not untrusted:
184 if self.debugflag and not untrusted:
225 uitems = self._configitems(section, untrusted=True, abort=False)
185 for k,v in self.ucdata.items(section):
226 for k in util.sort(uitems):
186 if self.cdata.get(section, k) != v:
227 if uitems[k] != items.get(k):
228 self.warn(_("Ignoring untrusted configuration option "
187 self.warn(_("Ignoring untrusted configuration option "
229 "%s.%s = %s\n") % (section, k, uitems[k]))
188 "%s.%s = %s\n") % (section, k, v))
230 return util.sort(items.items())
189 return items
231
190
232 def walkconfig(self, untrusted=False):
191 def walkconfig(self, untrusted=False):
233 cdata = self._get_cdata(untrusted)
192 cdata = self._get_cdata(untrusted)
234 sections = cdata.sections()
193 for section in cdata.sections():
235 sections.sort()
236 for section in sections:
237 for name, value in self.configitems(section, untrusted):
194 for name, value in self.configitems(section, untrusted):
238 yield section, name, str(value).replace('\n', '\\n')
195 yield section, name, str(value).replace('\n', '\\n')
239
196
@@ -1,16 +1,13 b''
1 abort: Failed to parse .../t/.hg/hgrc
1 hg: config error at .../t/.hg/hgrc:1: 'invalid'
2 File contains no section headers.
3 file: .../t/.hg/hgrc, line: 1
4 'invalid\n'
5 updating working directory
2 updating working directory
6 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 [paths]
4 [paths]
8 default = .../foo%%bar
5 default = .../foo%%bar
9 default = .../foo%bar
6 default = .../foo%%bar
10 bundle.mainreporoot=.../foobar
7 bundle.mainreporoot=.../foobar
11 defaults.backout=-d "0 0"
8 defaults.backout=-d "0 0"
12 defaults.commit=-d "0 0"
9 defaults.commit=-d "0 0"
13 defaults.debugrawcommit=-d "0 0"
10 defaults.debugrawcommit=-d "0 0"
14 defaults.tag=-d "0 0"
11 defaults.tag=-d "0 0"
15 paths.default=.../foo%bar
12 paths.default=.../foo%%bar
16 ui.slash=True
13 ui.slash=True
@@ -3,7 +3,7 b''
3 # monkey-patching some functions in the util module
3 # monkey-patching some functions in the util module
4
4
5 import os
5 import os
6 from mercurial import ui, util
6 from mercurial import ui, util, error
7
7
8 hgrc = os.environ['HGRCPATH']
8 hgrc = os.environ['HGRCPATH']
9 f = open(hgrc)
9 f = open(hgrc)
@@ -85,7 +85,6 b" os.mkdir('.hg')"
85 f = open('.hg/hgrc', 'w')
85 f = open('.hg/hgrc', 'w')
86 f.write('[paths]\n')
86 f.write('[paths]\n')
87 f.write('local = /another/path\n\n')
87 f.write('local = /another/path\n\n')
88 f.write('interpolated = %(global)s%(local)s\n\n')
89 f.close()
88 f.close()
90
89
91 #print '# Everything is run by user foo, group bar\n'
90 #print '# Everything is run by user foo, group bar\n'
@@ -154,10 +153,8 b' util.username = username'
154 u2.readconfig('.hg/hgrc')
153 u2.readconfig('.hg/hgrc')
155 print 'trusted:'
154 print 'trusted:'
156 print u2.config('foobar', 'baz')
155 print u2.config('foobar', 'baz')
157 print u2.config('paths', 'interpolated')
158 print 'untrusted:'
156 print 'untrusted:'
159 print u2.config('foobar', 'baz', untrusted=True)
157 print u2.config('foobar', 'baz', untrusted=True)
160 print u2.config('paths', 'interpolated', untrusted=True)
161
158
162 print
159 print
163 print "# error handling"
160 print "# error handling"
@@ -179,33 +176,15 b" testui(user='abc', group='def', debug=Tr"
179 print
176 print
180 print "# parse error"
177 print "# parse error"
181 f = open('.hg/hgrc', 'w')
178 f = open('.hg/hgrc', 'w')
182 f.write('foo = bar')
179 f.write('foo')
183 f.close()
184 testui(user='abc', group='def', silent=True)
185 assertraises(lambda: testui(debug=True, silent=True))
186
187 print
188 print "# interpolation error"
189 f = open('.hg/hgrc', 'w')
190 f.write('[foo]\n')
191 f.write('bar = %(')
192 f.close()
180 f.close()
193 u = testui(debug=True, silent=True)
194 print '# regular config:'
195 print ' trusted',
196 assertraises(lambda: u.config('foo', 'bar'))
197 print 'untrusted',
198 assertraises(lambda: u.config('foo', 'bar', untrusted=True))
199
181
200 u = testui(user='abc', group='def', debug=True, silent=True)
182 try:
201 print ' trusted ',
183 testui(user='abc', group='def', silent=True)
202 print u.config('foo', 'bar')
184 except error.ConfigError, inst:
203 print 'untrusted',
185 print inst
204 assertraises(lambda: u.config('foo', 'bar', untrusted=True))
205
186
206 print '# configitems:'
187 try:
207 print ' trusted ',
188 testui(debug=True, silent=True)
208 print u.configitems('foo')
189 except error.ConfigError, inst:
209 print 'untrusted',
190 print inst
210 assertraises(lambda: u.configitems('foo', untrusted=True))
211
@@ -1,21 +1,17 b''
1 # same user, same group
1 # same user, same group
2 trusted
2 trusted
3 global = /some/path
3 global = /some/path
4 interpolated = /some/path/another/path
5 local = /another/path
4 local = /another/path
6 untrusted
5 untrusted
7 . . global = /some/path
6 . . global = /some/path
8 . . interpolated = /some/path/another/path
9 . . local = /another/path
7 . . local = /another/path
10
8
11 # same user, different group
9 # same user, different group
12 trusted
10 trusted
13 global = /some/path
11 global = /some/path
14 interpolated = /some/path/another/path
15 local = /another/path
12 local = /another/path
16 untrusted
13 untrusted
17 . . global = /some/path
14 . . global = /some/path
18 . . interpolated = /some/path/another/path
19 . . local = /another/path
15 . . local = /another/path
20
16
21 # different user, same group
17 # different user, same group
@@ -24,17 +20,14 b' trusted'
24 global = /some/path
20 global = /some/path
25 untrusted
21 untrusted
26 . . global = /some/path
22 . . global = /some/path
27 . . interpolated = /some/path/another/path
28 . . local = /another/path
23 . . local = /another/path
29
24
30 # different user, same group, but we trust the group
25 # different user, same group, but we trust the group
31 trusted
26 trusted
32 global = /some/path
27 global = /some/path
33 interpolated = /some/path/another/path
34 local = /another/path
28 local = /another/path
35 untrusted
29 untrusted
36 . . global = /some/path
30 . . global = /some/path
37 . . interpolated = /some/path/another/path
38 . . local = /another/path
31 . . local = /another/path
39
32
40 # different user, different group
33 # different user, different group
@@ -43,70 +36,57 b' trusted'
43 global = /some/path
36 global = /some/path
44 untrusted
37 untrusted
45 . . global = /some/path
38 . . global = /some/path
46 . . interpolated = /some/path/another/path
47 . . local = /another/path
39 . . local = /another/path
48
40
49 # different user, different group, but we trust the user
41 # different user, different group, but we trust the user
50 trusted
42 trusted
51 global = /some/path
43 global = /some/path
52 interpolated = /some/path/another/path
53 local = /another/path
44 local = /another/path
54 untrusted
45 untrusted
55 . . global = /some/path
46 . . global = /some/path
56 . . interpolated = /some/path/another/path
57 . . local = /another/path
47 . . local = /another/path
58
48
59 # different user, different group, but we trust the group
49 # different user, different group, but we trust the group
60 trusted
50 trusted
61 global = /some/path
51 global = /some/path
62 interpolated = /some/path/another/path
63 local = /another/path
52 local = /another/path
64 untrusted
53 untrusted
65 . . global = /some/path
54 . . global = /some/path
66 . . interpolated = /some/path/another/path
67 . . local = /another/path
55 . . local = /another/path
68
56
69 # different user, different group, but we trust the user and the group
57 # different user, different group, but we trust the user and the group
70 trusted
58 trusted
71 global = /some/path
59 global = /some/path
72 interpolated = /some/path/another/path
73 local = /another/path
60 local = /another/path
74 untrusted
61 untrusted
75 . . global = /some/path
62 . . global = /some/path
76 . . interpolated = /some/path/another/path
77 . . local = /another/path
63 . . local = /another/path
78
64
79 # we trust all users
65 # we trust all users
80 # different user, different group
66 # different user, different group
81 trusted
67 trusted
82 global = /some/path
68 global = /some/path
83 interpolated = /some/path/another/path
84 local = /another/path
69 local = /another/path
85 untrusted
70 untrusted
86 . . global = /some/path
71 . . global = /some/path
87 . . interpolated = /some/path/another/path
88 . . local = /another/path
72 . . local = /another/path
89
73
90 # we trust all groups
74 # we trust all groups
91 # different user, different group
75 # different user, different group
92 trusted
76 trusted
93 global = /some/path
77 global = /some/path
94 interpolated = /some/path/another/path
95 local = /another/path
78 local = /another/path
96 untrusted
79 untrusted
97 . . global = /some/path
80 . . global = /some/path
98 . . interpolated = /some/path/another/path
99 . . local = /another/path
81 . . local = /another/path
100
82
101 # we trust all users and groups
83 # we trust all users and groups
102 # different user, different group
84 # different user, different group
103 trusted
85 trusted
104 global = /some/path
86 global = /some/path
105 interpolated = /some/path/another/path
106 local = /another/path
87 local = /another/path
107 untrusted
88 untrusted
108 . . global = /some/path
89 . . global = /some/path
109 . . interpolated = /some/path/another/path
110 . . local = /another/path
90 . . local = /another/path
111
91
112 # we don't get confused by users and groups with the same name
92 # we don't get confused by users and groups with the same name
@@ -116,29 +96,24 b' trusted'
116 global = /some/path
96 global = /some/path
117 untrusted
97 untrusted
118 . . global = /some/path
98 . . global = /some/path
119 . . interpolated = /some/path/another/path
120 . . local = /another/path
99 . . local = /another/path
121
100
122 # list of user names
101 # list of user names
123 # different user, different group, but we trust the user
102 # different user, different group, but we trust the user
124 trusted
103 trusted
125 global = /some/path
104 global = /some/path
126 interpolated = /some/path/another/path
127 local = /another/path
105 local = /another/path
128 untrusted
106 untrusted
129 . . global = /some/path
107 . . global = /some/path
130 . . interpolated = /some/path/another/path
131 . . local = /another/path
108 . . local = /another/path
132
109
133 # list of group names
110 # list of group names
134 # different user, different group, but we trust the group
111 # different user, different group, but we trust the group
135 trusted
112 trusted
136 global = /some/path
113 global = /some/path
137 interpolated = /some/path/another/path
138 local = /another/path
114 local = /another/path
139 untrusted
115 untrusted
140 . . global = /some/path
116 . . global = /some/path
141 . . interpolated = /some/path/another/path
142 . . local = /another/path
117 . . local = /another/path
143
118
144 # Can't figure out the name of the user running this process
119 # Can't figure out the name of the user running this process
@@ -148,20 +123,16 b' trusted'
148 global = /some/path
123 global = /some/path
149 untrusted
124 untrusted
150 . . global = /some/path
125 . . global = /some/path
151 . . interpolated = /some/path/another/path
152 . . local = /another/path
126 . . local = /another/path
153
127
154 # prints debug warnings
128 # prints debug warnings
155 # different user, different group
129 # different user, different group
156 Not trusting file .hg/hgrc from untrusted user abc, group def
130 Not trusting file .hg/hgrc from untrusted user abc, group def
157 trusted
131 trusted
158 Ignoring untrusted configuration option paths.interpolated = /some/path/another/path
159 Ignoring untrusted configuration option paths.local = /another/path
132 Ignoring untrusted configuration option paths.local = /another/path
160 global = /some/path
133 global = /some/path
161 untrusted
134 untrusted
162 . . global = /some/path
135 . . global = /some/path
163 .Ignoring untrusted configuration option paths.interpolated = /some/path/another/path
164 . interpolated = /some/path/another/path
165 .Ignoring untrusted configuration option paths.local = /another/path
136 .Ignoring untrusted configuration option paths.local = /another/path
166 . local = /another/path
137 . local = /another/path
167
138
@@ -173,10 +144,8 b' Not trusting file foobar from untrusted '
173 trusted:
144 trusted:
174 Ignoring untrusted configuration option foobar.baz = quux
145 Ignoring untrusted configuration option foobar.baz = quux
175 None
146 None
176 /some/path/another/path
177 untrusted:
147 untrusted:
178 quux
148 quux
179 /some/path/another/path
180
149
181 # error handling
150 # error handling
182 # file doesn't exist
151 # file doesn't exist
@@ -186,26 +155,6 b' quux'
186 # parse error
155 # parse error
187 # different user, different group
156 # different user, different group
188 Not trusting file .hg/hgrc from untrusted user abc, group def
157 Not trusting file .hg/hgrc from untrusted user abc, group def
189 Ignored: Failed to parse .hg/hgrc
158 Ignored: config error at .hg/hgrc:1: 'foo'
190 File contains no section headers.
191 file: .hg/hgrc, line: 1
192 'foo = bar'
193 # same user, same group
194 raised Abort
195
196 # interpolation error
197 # same user, same group
159 # same user, same group
198 # regular config:
160 config error at .hg/hgrc:1: 'foo'
199 trusted raised Abort
200 untrusted raised Abort
201 # different user, different group
202 Not trusting file .hg/hgrc from untrusted user abc, group def
203 trusted Ignored: Error in configuration section [foo] parameter 'bar':
204 bad interpolation variable reference '%('
205 None
206 untrusted raised Abort
207 # configitems:
208 trusted Ignored: Error in configuration section [foo]:
209 bad interpolation variable reference '%('
210 []
211 untrusted raised Abort
@@ -1,7 +1,6 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 import ConfigParser
3 from mercurial import ui, util, dispatch, error
4 from mercurial import ui, util, dispatch
5
4
6 testui = ui.ui()
5 testui = ui.ui()
7 parsed = dispatch._parseconfig(testui, [
6 parsed = dispatch._parseconfig(testui, [
@@ -12,19 +11,10 b' parsed = dispatch._parseconfig(testui, ['
12 'lists.list2=foo bar baz',
11 'lists.list2=foo bar baz',
13 'lists.list3=alice, bob',
12 'lists.list3=alice, bob',
14 'lists.list4=foo bar baz alice, bob',
13 'lists.list4=foo bar baz alice, bob',
15 'interpolation.value1=hallo',
16 'interpolation.value2=%(value1)s world',
17 'interpolation.value3=%(novalue)s',
18 'interpolation.value4=%(bad)1',
19 'interpolation.value5=%bad2',
20 ])
14 ])
21
15
22 print repr(testui.configitems('values'))
16 print repr(testui.configitems('values'))
23 print repr(testui.configitems('lists'))
17 print repr(testui.configitems('lists'))
24 try:
25 print repr(testui.configitems('interpolation'))
26 except util.Abort, inst:
27 print inst
28 print "---"
18 print "---"
29 print repr(testui.config('values', 'string'))
19 print repr(testui.config('values', 'string'))
30 print repr(testui.config('values', 'bool1'))
20 print repr(testui.config('values', 'bool1'))
@@ -33,7 +23,7 b" print repr(testui.config('values', 'unkn"
33 print "---"
23 print "---"
34 try:
24 try:
35 print repr(testui.configbool('values', 'string'))
25 print repr(testui.configbool('values', 'string'))
36 except util.Abort, inst:
26 except error.ConfigError, inst:
37 print inst
27 print inst
38 print repr(testui.configbool('values', 'bool1'))
28 print repr(testui.configbool('values', 'bool1'))
39 print repr(testui.configbool('values', 'bool2'))
29 print repr(testui.configbool('values', 'bool2'))
@@ -54,37 +44,12 b" print repr(testui.configlist('lists', 'u"
54 print repr(testui.configlist('lists', 'unknown', 'foo, bar'))
44 print repr(testui.configlist('lists', 'unknown', 'foo, bar'))
55 print repr(testui.configlist('lists', 'unknown', ['foo bar']))
45 print repr(testui.configlist('lists', 'unknown', ['foo bar']))
56 print repr(testui.configlist('lists', 'unknown', ['foo', 'bar']))
46 print repr(testui.configlist('lists', 'unknown', ['foo', 'bar']))
57 print "---"
58 print repr(testui.config('interpolation', 'value1'))
59 print repr(testui.config('interpolation', 'value2'))
60 try:
61 print repr(testui.config('interpolation', 'value3'))
62 except util.Abort, inst:
63 print inst
64 try:
65 print repr(testui.config('interpolation', 'value4'))
66 except util.Abort, inst:
67 print inst
68 try:
69 print repr(testui.config('interpolation', 'value5'))
70 except util.Abort, inst:
71 print inst
72 print "---"
73
47
74 cp = util.configparser()
48 print repr(testui.config('values', 'String'))
75 cp.add_section('foo')
76 cp.set('foo', 'bar', 'baz')
77 try:
78 # should fail - keys are case-sensitive
79 cp.get('foo', 'Bar')
80 except ConfigParser.NoOptionError, inst:
81 print inst
82
49
83 def function():
50 def function():
84 pass
51 pass
85
52
86 cp.add_section('hook')
87 # values that aren't strings should work
53 # values that aren't strings should work
88 cp.set('hook', 'commit', function)
54 testui.setconfig('hook', 'commit', function)
89 f = cp.get('hook', 'commit')
55 print function == testui.config('hook', 'commit')
90 print "f %s= function" % (f == function and '=' or '!')
@@ -1,15 +1,12 b''
1 [('bool1', 'true'), ('bool2', 'false'), ('string', 'string value')]
1 [('string', 'string value'), ('bool1', 'true'), ('bool2', 'false')]
2 [('list1', 'foo'), ('list2', 'foo bar baz'), ('list3', 'alice, bob'), ('list4', 'foo bar baz alice, bob')]
2 [('list1', 'foo'), ('list2', 'foo bar baz'), ('list3', 'alice, bob'), ('list4', 'foo bar baz alice, bob')]
3 Error in configuration section [interpolation]:
4 '%' must be followed by '%' or '(', found: '%bad2'
5 ---
3 ---
6 'string value'
4 'string value'
7 'true'
5 'true'
8 'false'
6 'false'
9 None
7 None
10 ---
8 ---
11 Error in configuration section [values] parameter 'string':
9 values.string not a boolean ('string value')
12 Not a boolean: string value
13 True
10 True
14 False
11 False
15 False
12 False
@@ -29,20 +26,5 b' True'
29 ['foo', 'bar']
26 ['foo', 'bar']
30 ['foo bar']
27 ['foo bar']
31 ['foo', 'bar']
28 ['foo', 'bar']
32 ---
29 None
33 'hallo'
30 True
34 'hallo world'
35 Error in configuration section [interpolation] parameter 'value3':
36 Bad value substitution:
37 section: [interpolation]
38 option : value3
39 key : novalue
40 rawval :
41
42 Error in configuration section [interpolation] parameter 'value4':
43 bad interpolation variable reference '%(bad)1'
44 Error in configuration section [interpolation] parameter 'value5':
45 '%' must be followed by '%' or '(', found: '%bad2'
46 ---
47 No option 'Bar' in section: 'foo'
48 f == function
General Comments 0
You need to be logged in to leave comments. Login now