Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/ui.py @ 8144:fca54469480e
ui: introduce new config parser
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 23 Apr 2009 15:40:10 -0500 |
parents | 507c49e297e1 |
children | c8cb471fc9c2 |
comparison
equal
deleted
inserted
replaced
8143:507c49e297e1 | 8144:fca54469480e |
---|---|
5 # This software may be used and distributed according to the terms | 5 # This software may be used and distributed according to the terms |
6 # of the GNU General Public License, incorporated herein by reference. | 6 # of the GNU General Public License, incorporated herein by reference. |
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 = {} |
34 | 26 |
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() |
45 self.fixconfig() | 37 self.fixconfig() |
46 else: | 38 else: |
87 except IOError: | 79 except IOError: |
88 if not sections: # ignore unless we were looking for something | 80 if not sections: # ignore unless we were looking for something |
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('~') |
111 self.fixconfig(root=root) | 102 self.fixconfig(root=root) |
112 | 103 |
115 if section is None or section == 'paths': | 106 if section is None or section == 'paths': |
116 if root is None: | 107 if root is None: |
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 |
124 for n, path in pathsitems: | 115 for n, path in pathsitems: |
125 if path and "://" not in path and not os.path.isabs(path): | 116 if path and "://" not in path and not os.path.isabs(path): |
147 for group in self.configlist('trusted', 'groups'): | 138 for group in self.configlist('trusted', 'groups'): |
148 self.trusted_groups[group] = 1 | 139 self.trusted_groups[group] = 1 |
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 |
157 def _get_cdata(self, untrusted): | 146 def _get_cdata(self, untrusted): |
158 if untrusted: | 147 if untrusted: |
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""" |
196 result = self.config(section, name, untrusted=untrusted) | 171 result = self.config(section, name, untrusted=untrusted) |
197 if result is None: | 172 if result is None: |
200 result = result.replace(",", " ").split() | 175 result = result.replace(",", " ").split() |
201 return result | 176 return result |
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) | 181 |
207 | 182 def configitems(self, section, untrusted=False): |
208 def _configitems(self, section, untrusted, abort): | 183 items = self._get_cdata(untrusted).items(section) |
209 items = {} | 184 if self.debugflag and not untrusted: |
210 cdata = self._get_cdata(untrusted) | 185 for k,v in self.ucdata.items(section): |
211 if cdata.has_section(section): | 186 if self.cdata.get(section, k) != v: |
212 try: | 187 self.warn(_("Ignoring untrusted configuration option " |
213 items.update(dict(cdata.items(section))) | 188 "%s.%s = %s\n") % (section, k, v)) |
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 | 189 return items |
221 | |
222 def configitems(self, section, untrusted=False): | |
223 items = self._configitems(section, untrusted=untrusted, abort=True) | |
224 if self.debugflag and not untrusted: | |
225 uitems = self._configitems(section, untrusted=True, abort=False) | |
226 for k in util.sort(uitems): | |
227 if uitems[k] != items.get(k): | |
228 self.warn(_("Ignoring untrusted configuration option " | |
229 "%s.%s = %s\n") % (section, k, uitems[k])) | |
230 return util.sort(items.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 |
240 def username(self): | 197 def username(self): |
241 """Return default username to be used in commits. | 198 """Return default username to be used in commits. |