##// END OF EJS Templates
Fix a pygettext complaint
Matt Mackall -
r3889:a0b18a8e default
parent child Browse files
Show More
@@ -1,451 +1,451 b''
1 # ui.py - user interface bits for mercurial
1 # ui.py - user interface bits for mercurial
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
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 gettext as _
8 from i18n import gettext as _
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 ConfigParser, traceback, util
11
11
12 def dupconfig(orig):
12 def dupconfig(orig):
13 new = util.configparser(orig.defaults())
13 new = util.configparser(orig.defaults())
14 updateconfig(orig, new)
14 updateconfig(orig, new)
15 return new
15 return new
16
16
17 def updateconfig(source, dest, sections=None):
17 def updateconfig(source, dest, sections=None):
18 if not sections:
18 if not sections:
19 sections = source.sections()
19 sections = source.sections()
20 for section in sections:
20 for section in sections:
21 if not dest.has_section(section):
21 if not dest.has_section(section):
22 dest.add_section(section)
22 dest.add_section(section)
23 for name, value in source.items(section, raw=True):
23 for name, value in source.items(section, raw=True):
24 dest.set(section, name, value)
24 dest.set(section, name, value)
25
25
26 class ui(object):
26 class ui(object):
27 def __init__(self, verbose=False, debug=False, quiet=False,
27 def __init__(self, verbose=False, debug=False, quiet=False,
28 interactive=True, traceback=False, report_untrusted=True,
28 interactive=True, traceback=False, report_untrusted=True,
29 parentui=None):
29 parentui=None):
30 self.overlay = None
30 self.overlay = None
31 self.buffers = []
31 self.buffers = []
32 if parentui is None:
32 if parentui is None:
33 # this is the parent of all ui children
33 # this is the parent of all ui children
34 self.parentui = None
34 self.parentui = None
35 self.readhooks = []
35 self.readhooks = []
36 self.quiet = quiet
36 self.quiet = quiet
37 self.verbose = verbose
37 self.verbose = verbose
38 self.debugflag = debug
38 self.debugflag = debug
39 self.interactive = interactive
39 self.interactive = interactive
40 self.traceback = traceback
40 self.traceback = traceback
41 self.report_untrusted = report_untrusted
41 self.report_untrusted = report_untrusted
42 self.trusted_users = {}
42 self.trusted_users = {}
43 self.trusted_groups = {}
43 self.trusted_groups = {}
44 # if ucdata is not None, its keys must be a superset of cdata's
44 # if ucdata is not None, its keys must be a superset of cdata's
45 self.cdata = util.configparser()
45 self.cdata = util.configparser()
46 self.ucdata = None
46 self.ucdata = None
47 # we always trust global config files
47 # we always trust global config files
48 self.check_trusted = False
48 self.check_trusted = False
49 self.readconfig(util.rcpath())
49 self.readconfig(util.rcpath())
50 self.check_trusted = True
50 self.check_trusted = True
51 self.updateopts(verbose, debug, quiet, interactive)
51 self.updateopts(verbose, debug, quiet, interactive)
52 else:
52 else:
53 # parentui may point to an ui object which is already a child
53 # parentui may point to an ui object which is already a child
54 self.parentui = parentui.parentui or parentui
54 self.parentui = parentui.parentui or parentui
55 self.readhooks = self.parentui.readhooks[:]
55 self.readhooks = self.parentui.readhooks[:]
56 self.trusted_users = parentui.trusted_users.copy()
56 self.trusted_users = parentui.trusted_users.copy()
57 self.trusted_groups = parentui.trusted_groups.copy()
57 self.trusted_groups = parentui.trusted_groups.copy()
58 self.cdata = dupconfig(self.parentui.cdata)
58 self.cdata = dupconfig(self.parentui.cdata)
59 if self.parentui.ucdata:
59 if self.parentui.ucdata:
60 self.ucdata = dupconfig(self.parentui.ucdata)
60 self.ucdata = dupconfig(self.parentui.ucdata)
61 if self.parentui.overlay:
61 if self.parentui.overlay:
62 self.overlay = dupconfig(self.parentui.overlay)
62 self.overlay = dupconfig(self.parentui.overlay)
63
63
64 def __getattr__(self, key):
64 def __getattr__(self, key):
65 return getattr(self.parentui, key)
65 return getattr(self.parentui, key)
66
66
67 def updateopts(self, verbose=False, debug=False, quiet=False,
67 def updateopts(self, verbose=False, debug=False, quiet=False,
68 interactive=True, traceback=False, config=[]):
68 interactive=True, traceback=False, config=[]):
69 for section, name, value in config:
69 for section, name, value in config:
70 self.setconfig(section, name, value)
70 self.setconfig(section, name, value)
71
71
72 if quiet or verbose or debug:
72 if quiet or verbose or debug:
73 self.setconfig('ui', 'quiet', str(bool(quiet)))
73 self.setconfig('ui', 'quiet', str(bool(quiet)))
74 self.setconfig('ui', 'verbose', str(bool(verbose)))
74 self.setconfig('ui', 'verbose', str(bool(verbose)))
75 self.setconfig('ui', 'debug', str(bool(debug)))
75 self.setconfig('ui', 'debug', str(bool(debug)))
76
76
77 self.verbosity_constraints()
77 self.verbosity_constraints()
78
78
79 if not interactive:
79 if not interactive:
80 self.setconfig('ui', 'interactive', 'False')
80 self.setconfig('ui', 'interactive', 'False')
81 self.interactive = False
81 self.interactive = False
82
82
83 self.traceback = self.traceback or traceback
83 self.traceback = self.traceback or traceback
84
84
85 def verbosity_constraints(self):
85 def verbosity_constraints(self):
86 self.quiet = self.configbool('ui', 'quiet')
86 self.quiet = self.configbool('ui', 'quiet')
87 self.verbose = self.configbool('ui', 'verbose')
87 self.verbose = self.configbool('ui', 'verbose')
88 self.debugflag = self.configbool('ui', 'debug')
88 self.debugflag = self.configbool('ui', 'debug')
89
89
90 if self.debugflag:
90 if self.debugflag:
91 self.verbose = True
91 self.verbose = True
92 self.quiet = False
92 self.quiet = False
93 elif self.verbose and self.quiet:
93 elif self.verbose and self.quiet:
94 self.quiet = self.verbose = False
94 self.quiet = self.verbose = False
95
95
96 def _is_trusted(self, fp, f, warn=True):
96 def _is_trusted(self, fp, f, warn=True):
97 if not self.check_trusted:
97 if not self.check_trusted:
98 return True
98 return True
99 st = util.fstat(fp)
99 st = util.fstat(fp)
100 if util.isowner(fp, st):
100 if util.isowner(fp, st):
101 return True
101 return True
102 tusers = self.trusted_users
102 tusers = self.trusted_users
103 tgroups = self.trusted_groups
103 tgroups = self.trusted_groups
104 if not tusers:
104 if not tusers:
105 user = util.username()
105 user = util.username()
106 if user is not None:
106 if user is not None:
107 self.trusted_users[user] = 1
107 self.trusted_users[user] = 1
108 self.fixconfig(section='trusted')
108 self.fixconfig(section='trusted')
109 if (tusers or tgroups) and '*' not in tusers and '*' not in tgroups:
109 if (tusers or tgroups) and '*' not in tusers and '*' not in tgroups:
110 user = util.username(st.st_uid)
110 user = util.username(st.st_uid)
111 group = util.groupname(st.st_gid)
111 group = util.groupname(st.st_gid)
112 if user not in tusers and group not in tgroups:
112 if user not in tusers and group not in tgroups:
113 if warn and self.report_untrusted:
113 if warn and self.report_untrusted:
114 self.warn(_('Not trusting file %s from untrusted '
114 self.warn(_('Not trusting file %s from untrusted '
115 'user %s, group %s\n') % (f, user, group))
115 'user %s, group %s\n') % (f, user, group))
116 return False
116 return False
117 return True
117 return True
118
118
119 def readconfig(self, fn, root=None):
119 def readconfig(self, fn, root=None):
120 if isinstance(fn, basestring):
120 if isinstance(fn, basestring):
121 fn = [fn]
121 fn = [fn]
122 for f in fn:
122 for f in fn:
123 try:
123 try:
124 fp = open(f)
124 fp = open(f)
125 except IOError:
125 except IOError:
126 continue
126 continue
127 cdata = self.cdata
127 cdata = self.cdata
128 trusted = self._is_trusted(fp, f)
128 trusted = self._is_trusted(fp, f)
129 if not trusted:
129 if not trusted:
130 if self.ucdata is None:
130 if self.ucdata is None:
131 self.ucdata = dupconfig(self.cdata)
131 self.ucdata = dupconfig(self.cdata)
132 cdata = self.ucdata
132 cdata = self.ucdata
133 elif self.ucdata is not None:
133 elif self.ucdata is not None:
134 # use a separate configparser, so that we don't accidentally
134 # use a separate configparser, so that we don't accidentally
135 # override ucdata settings later on.
135 # override ucdata settings later on.
136 cdata = util.configparser()
136 cdata = util.configparser()
137
137
138 try:
138 try:
139 cdata.readfp(fp, f)
139 cdata.readfp(fp, f)
140 except ConfigParser.ParsingError, inst:
140 except ConfigParser.ParsingError, inst:
141 msg = _("Failed to parse %s\n%s") % (f, inst)
141 msg = _("Failed to parse %s\n%s") % (f, inst)
142 if trusted:
142 if trusted:
143 raise util.Abort(msg)
143 raise util.Abort(msg)
144 self.warn(_("Ignored: %s\n") % msg)
144 self.warn(_("Ignored: %s\n") % msg)
145
145
146 if trusted:
146 if trusted:
147 if cdata != self.cdata:
147 if cdata != self.cdata:
148 updateconfig(cdata, self.cdata)
148 updateconfig(cdata, self.cdata)
149 if self.ucdata is not None:
149 if self.ucdata is not None:
150 updateconfig(cdata, self.ucdata)
150 updateconfig(cdata, self.ucdata)
151 # override data from config files with data set with ui.setconfig
151 # override data from config files with data set with ui.setconfig
152 if self.overlay:
152 if self.overlay:
153 updateconfig(self.overlay, self.cdata)
153 updateconfig(self.overlay, self.cdata)
154 if root is None:
154 if root is None:
155 root = os.path.expanduser('~')
155 root = os.path.expanduser('~')
156 self.fixconfig(root=root)
156 self.fixconfig(root=root)
157 for hook in self.readhooks:
157 for hook in self.readhooks:
158 hook(self)
158 hook(self)
159
159
160 def addreadhook(self, hook):
160 def addreadhook(self, hook):
161 self.readhooks.append(hook)
161 self.readhooks.append(hook)
162
162
163 def readsections(self, filename, *sections):
163 def readsections(self, filename, *sections):
164 """Read filename and add only the specified sections to the config data
164 """Read filename and add only the specified sections to the config data
165
165
166 The settings are added to the trusted config data.
166 The settings are added to the trusted config data.
167 """
167 """
168 if not sections:
168 if not sections:
169 return
169 return
170
170
171 cdata = util.configparser()
171 cdata = util.configparser()
172 try:
172 try:
173 cdata.read(filename)
173 cdata.read(filename)
174 except ConfigParser.ParsingError, inst:
174 except ConfigParser.ParsingError, inst:
175 raise util.Abort(_("failed to parse %s\n%s") % (filename,
175 raise util.Abort(_("failed to parse %s\n%s") % (filename,
176 inst))
176 inst))
177
177
178 for section in sections:
178 for section in sections:
179 if not cdata.has_section(section):
179 if not cdata.has_section(section):
180 cdata.add_section(section)
180 cdata.add_section(section)
181
181
182 updateconfig(cdata, self.cdata, sections)
182 updateconfig(cdata, self.cdata, sections)
183 if self.ucdata:
183 if self.ucdata:
184 updateconfig(cdata, self.ucdata, sections)
184 updateconfig(cdata, self.ucdata, sections)
185
185
186 def fixconfig(self, section=None, name=None, value=None, root=None):
186 def fixconfig(self, section=None, name=None, value=None, root=None):
187 # translate paths relative to root (or home) into absolute paths
187 # translate paths relative to root (or home) into absolute paths
188 if section is None or section == 'paths':
188 if section is None or section == 'paths':
189 if root is None:
189 if root is None:
190 root = os.getcwd()
190 root = os.getcwd()
191 items = section and [(name, value)] or []
191 items = section and [(name, value)] or []
192 for cdata in self.cdata, self.ucdata, self.overlay:
192 for cdata in self.cdata, self.ucdata, self.overlay:
193 if not cdata: continue
193 if not cdata: continue
194 if not items and cdata.has_section('paths'):
194 if not items and cdata.has_section('paths'):
195 pathsitems = cdata.items('paths')
195 pathsitems = cdata.items('paths')
196 else:
196 else:
197 pathsitems = items
197 pathsitems = items
198 for n, path in pathsitems:
198 for n, path in pathsitems:
199 if path and "://" not in path and not os.path.isabs(path):
199 if path and "://" not in path and not os.path.isabs(path):
200 cdata.set("paths", n, os.path.join(root, path))
200 cdata.set("paths", n, os.path.join(root, path))
201
201
202 # update quiet/verbose/debug and interactive status
202 # update quiet/verbose/debug and interactive status
203 if section is None or section == 'ui':
203 if section is None or section == 'ui':
204 if name is None or name in ('quiet', 'verbose', 'debug'):
204 if name is None or name in ('quiet', 'verbose', 'debug'):
205 self.verbosity_constraints()
205 self.verbosity_constraints()
206
206
207 if name is None or name == 'interactive':
207 if name is None or name == 'interactive':
208 self.interactive = self.configbool("ui", "interactive", True)
208 self.interactive = self.configbool("ui", "interactive", True)
209
209
210 # update trust information
210 # update trust information
211 if (section is None or section == 'trusted') and self.trusted_users:
211 if (section is None or section == 'trusted') and self.trusted_users:
212 for user in self.configlist('trusted', 'users'):
212 for user in self.configlist('trusted', 'users'):
213 self.trusted_users[user] = 1
213 self.trusted_users[user] = 1
214 for group in self.configlist('trusted', 'groups'):
214 for group in self.configlist('trusted', 'groups'):
215 self.trusted_groups[group] = 1
215 self.trusted_groups[group] = 1
216
216
217 def setconfig(self, section, name, value):
217 def setconfig(self, section, name, value):
218 if not self.overlay:
218 if not self.overlay:
219 self.overlay = util.configparser()
219 self.overlay = util.configparser()
220 for cdata in (self.overlay, self.cdata, self.ucdata):
220 for cdata in (self.overlay, self.cdata, self.ucdata):
221 if not cdata: continue
221 if not cdata: continue
222 if not cdata.has_section(section):
222 if not cdata.has_section(section):
223 cdata.add_section(section)
223 cdata.add_section(section)
224 cdata.set(section, name, value)
224 cdata.set(section, name, value)
225 self.fixconfig(section, name, value)
225 self.fixconfig(section, name, value)
226
226
227 def _get_cdata(self, untrusted):
227 def _get_cdata(self, untrusted):
228 if untrusted and self.ucdata:
228 if untrusted and self.ucdata:
229 return self.ucdata
229 return self.ucdata
230 return self.cdata
230 return self.cdata
231
231
232 def _config(self, section, name, default, funcname, untrusted, abort):
232 def _config(self, section, name, default, funcname, untrusted, abort):
233 cdata = self._get_cdata(untrusted)
233 cdata = self._get_cdata(untrusted)
234 if cdata.has_option(section, name):
234 if cdata.has_option(section, name):
235 try:
235 try:
236 func = getattr(cdata, funcname)
236 func = getattr(cdata, funcname)
237 return func(section, name)
237 return func(section, name)
238 except ConfigParser.InterpolationError, inst:
238 except ConfigParser.InterpolationError, inst:
239 msg = _("Error in configuration section [%s] "
239 msg = _("Error in configuration section [%s] "
240 "parameter '%s':\n%s") % (section, name, inst)
240 "parameter '%s':\n%s") % (section, name, inst)
241 if abort:
241 if abort:
242 raise util.Abort(msg)
242 raise util.Abort(msg)
243 self.warn(_("Ignored: %s\n") % msg)
243 self.warn(_("Ignored: %s\n") % msg)
244 return default
244 return default
245
245
246 def _configcommon(self, section, name, default, funcname, untrusted):
246 def _configcommon(self, section, name, default, funcname, untrusted):
247 value = self._config(section, name, default, funcname,
247 value = self._config(section, name, default, funcname,
248 untrusted, abort=True)
248 untrusted, abort=True)
249 if self.debugflag and not untrusted and self.ucdata:
249 if self.debugflag and not untrusted and self.ucdata:
250 uvalue = self._config(section, name, None, funcname,
250 uvalue = self._config(section, name, None, funcname,
251 untrusted=True, abort=False)
251 untrusted=True, abort=False)
252 if uvalue is not None and uvalue != value:
252 if uvalue is not None and uvalue != value:
253 self.warn(_("Ignoring untrusted configuration option "
253 self.warn(_("Ignoring untrusted configuration option "
254 "%s.%s = %s\n") % (section, name, uvalue))
254 "%s.%s = %s\n") % (section, name, uvalue))
255 return value
255 return value
256
256
257 def config(self, section, name, default=None, untrusted=False):
257 def config(self, section, name, default=None, untrusted=False):
258 return self._configcommon(section, name, default, 'get', untrusted)
258 return self._configcommon(section, name, default, 'get', untrusted)
259
259
260 def configbool(self, section, name, default=False, untrusted=False):
260 def configbool(self, section, name, default=False, untrusted=False):
261 return self._configcommon(section, name, default, 'getboolean',
261 return self._configcommon(section, name, default, 'getboolean',
262 untrusted)
262 untrusted)
263
263
264 def configlist(self, section, name, default=None, untrusted=False):
264 def configlist(self, section, name, default=None, untrusted=False):
265 """Return a list of comma/space separated strings"""
265 """Return a list of comma/space separated strings"""
266 result = self.config(section, name, untrusted=untrusted)
266 result = self.config(section, name, untrusted=untrusted)
267 if result is None:
267 if result is None:
268 result = default or []
268 result = default or []
269 if isinstance(result, basestring):
269 if isinstance(result, basestring):
270 result = result.replace(",", " ").split()
270 result = result.replace(",", " ").split()
271 return result
271 return result
272
272
273 def has_config(self, section, untrusted=False):
273 def has_config(self, section, untrusted=False):
274 '''tell whether section exists in config.'''
274 '''tell whether section exists in config.'''
275 cdata = self._get_cdata(untrusted)
275 cdata = self._get_cdata(untrusted)
276 return cdata.has_section(section)
276 return cdata.has_section(section)
277
277
278 def _configitems(self, section, untrusted, abort):
278 def _configitems(self, section, untrusted, abort):
279 items = {}
279 items = {}
280 cdata = self._get_cdata(untrusted)
280 cdata = self._get_cdata(untrusted)
281 if cdata.has_section(section):
281 if cdata.has_section(section):
282 try:
282 try:
283 items.update(dict(cdata.items(section)))
283 items.update(dict(cdata.items(section)))
284 except ConfigParser.InterpolationError, inst:
284 except ConfigParser.InterpolationError, inst:
285 msg = _("Error in configuration section [%s]:\n"
285 msg = _("Error in configuration section [%s]:\n"
286 "%s") % (section, inst)
286 "%s") % (section, inst)
287 if abort:
287 if abort:
288 raise util.Abort(msg)
288 raise util.Abort(msg)
289 self.warn(_("Ignored: %s\n") % msg)
289 self.warn(_("Ignored: %s\n") % msg)
290 return items
290 return items
291
291
292 def configitems(self, section, untrusted=False):
292 def configitems(self, section, untrusted=False):
293 items = self._configitems(section, untrusted=untrusted, abort=True)
293 items = self._configitems(section, untrusted=untrusted, abort=True)
294 if self.debugflag and not untrusted and self.ucdata:
294 if self.debugflag and not untrusted and self.ucdata:
295 uitems = self._configitems(section, untrusted=True, abort=False)
295 uitems = self._configitems(section, untrusted=True, abort=False)
296 keys = uitems.keys()
296 keys = uitems.keys()
297 keys.sort()
297 keys.sort()
298 for k in keys:
298 for k in keys:
299 if uitems[k] != items.get(k):
299 if uitems[k] != items.get(k):
300 self.warn(_("Ignoring untrusted configuration option "
300 self.warn(_("Ignoring untrusted configuration option "
301 "%s.%s = %s\n") % (section, k, uitems[k]))
301 "%s.%s = %s\n") % (section, k, uitems[k]))
302 x = items.items()
302 x = items.items()
303 x.sort()
303 x.sort()
304 return x
304 return x
305
305
306 def walkconfig(self, untrusted=False):
306 def walkconfig(self, untrusted=False):
307 cdata = self._get_cdata(untrusted)
307 cdata = self._get_cdata(untrusted)
308 sections = cdata.sections()
308 sections = cdata.sections()
309 sections.sort()
309 sections.sort()
310 for section in sections:
310 for section in sections:
311 for name, value in self.configitems(section, untrusted):
311 for name, value in self.configitems(section, untrusted):
312 yield section, name, value.replace('\n', '\\n')
312 yield section, name, value.replace('\n', '\\n')
313
313
314 def extensions(self):
314 def extensions(self):
315 result = self.configitems("extensions")
315 result = self.configitems("extensions")
316 for i, (key, value) in enumerate(result):
316 for i, (key, value) in enumerate(result):
317 if value:
317 if value:
318 result[i] = (key, os.path.expanduser(value))
318 result[i] = (key, os.path.expanduser(value))
319 return result
319 return result
320
320
321 def hgignorefiles(self):
321 def hgignorefiles(self):
322 result = []
322 result = []
323 for key, value in self.configitems("ui"):
323 for key, value in self.configitems("ui"):
324 if key == 'ignore' or key.startswith('ignore.'):
324 if key == 'ignore' or key.startswith('ignore.'):
325 result.append(os.path.expanduser(value))
325 result.append(os.path.expanduser(value))
326 return result
326 return result
327
327
328 def configrevlog(self):
328 def configrevlog(self):
329 result = {}
329 result = {}
330 for key, value in self.configitems("revlog"):
330 for key, value in self.configitems("revlog"):
331 result[key.lower()] = value
331 result[key.lower()] = value
332 return result
332 return result
333
333
334 def username(self):
334 def username(self):
335 """Return default username to be used in commits.
335 """Return default username to be used in commits.
336
336
337 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
337 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
338 and stop searching if one of these is set.
338 and stop searching if one of these is set.
339 If not found, use ($LOGNAME or $USER or $LNAME or
339 If not found, use ($LOGNAME or $USER or $LNAME or
340 $USERNAME) +"@full.hostname".
340 $USERNAME) +"@full.hostname".
341 """
341 """
342 user = os.environ.get("HGUSER")
342 user = os.environ.get("HGUSER")
343 if user is None:
343 if user is None:
344 user = self.config("ui", "username")
344 user = self.config("ui", "username")
345 if user is None:
345 if user is None:
346 user = os.environ.get("EMAIL")
346 user = os.environ.get("EMAIL")
347 if not user:
347 if not user:
348 try:
348 try:
349 user = '%s@%s' % (util.getuser(), socket.getfqdn())
349 user = '%s@%s' % (util.getuser(), socket.getfqdn())
350 except KeyError:
350 except KeyError:
351 raise util.Abort(_("Please specify a username."))
351 raise util.Abort(_("Please specify a username."))
352 self.warn(_("No username found, using '%s' instead\n" % user))
352 self.warn(_("No username found, using '%s' instead\n") % user)
353 return user
353 return user
354
354
355 def shortuser(self, user):
355 def shortuser(self, user):
356 """Return a short representation of a user name or email address."""
356 """Return a short representation of a user name or email address."""
357 if not self.verbose: user = util.shortuser(user)
357 if not self.verbose: user = util.shortuser(user)
358 return user
358 return user
359
359
360 def expandpath(self, loc, default=None):
360 def expandpath(self, loc, default=None):
361 """Return repository location relative to cwd or from [paths]"""
361 """Return repository location relative to cwd or from [paths]"""
362 if "://" in loc or os.path.isdir(loc):
362 if "://" in loc or os.path.isdir(loc):
363 return loc
363 return loc
364
364
365 path = self.config("paths", loc)
365 path = self.config("paths", loc)
366 if not path and default is not None:
366 if not path and default is not None:
367 path = self.config("paths", default)
367 path = self.config("paths", default)
368 return path or loc
368 return path or loc
369
369
370 def pushbuffer(self):
370 def pushbuffer(self):
371 self.buffers.append([])
371 self.buffers.append([])
372
372
373 def popbuffer(self):
373 def popbuffer(self):
374 return "".join(self.buffers.pop())
374 return "".join(self.buffers.pop())
375
375
376 def write(self, *args):
376 def write(self, *args):
377 if self.buffers:
377 if self.buffers:
378 self.buffers[-1].extend([str(a) for a in args])
378 self.buffers[-1].extend([str(a) for a in args])
379 else:
379 else:
380 for a in args:
380 for a in args:
381 sys.stdout.write(str(a))
381 sys.stdout.write(str(a))
382
382
383 def write_err(self, *args):
383 def write_err(self, *args):
384 try:
384 try:
385 if not sys.stdout.closed: sys.stdout.flush()
385 if not sys.stdout.closed: sys.stdout.flush()
386 for a in args:
386 for a in args:
387 sys.stderr.write(str(a))
387 sys.stderr.write(str(a))
388 except IOError, inst:
388 except IOError, inst:
389 if inst.errno != errno.EPIPE:
389 if inst.errno != errno.EPIPE:
390 raise
390 raise
391
391
392 def flush(self):
392 def flush(self):
393 try: sys.stdout.flush()
393 try: sys.stdout.flush()
394 except: pass
394 except: pass
395 try: sys.stderr.flush()
395 try: sys.stderr.flush()
396 except: pass
396 except: pass
397
397
398 def readline(self):
398 def readline(self):
399 return sys.stdin.readline()[:-1]
399 return sys.stdin.readline()[:-1]
400 def prompt(self, msg, pat=None, default="y"):
400 def prompt(self, msg, pat=None, default="y"):
401 if not self.interactive: return default
401 if not self.interactive: return default
402 while 1:
402 while 1:
403 self.write(msg, " ")
403 self.write(msg, " ")
404 r = self.readline()
404 r = self.readline()
405 if not pat or re.match(pat, r):
405 if not pat or re.match(pat, r):
406 return r
406 return r
407 else:
407 else:
408 self.write(_("unrecognized response\n"))
408 self.write(_("unrecognized response\n"))
409 def getpass(self, prompt=None, default=None):
409 def getpass(self, prompt=None, default=None):
410 if not self.interactive: return default
410 if not self.interactive: return default
411 return getpass.getpass(prompt or _('password: '))
411 return getpass.getpass(prompt or _('password: '))
412 def status(self, *msg):
412 def status(self, *msg):
413 if not self.quiet: self.write(*msg)
413 if not self.quiet: self.write(*msg)
414 def warn(self, *msg):
414 def warn(self, *msg):
415 self.write_err(*msg)
415 self.write_err(*msg)
416 def note(self, *msg):
416 def note(self, *msg):
417 if self.verbose: self.write(*msg)
417 if self.verbose: self.write(*msg)
418 def debug(self, *msg):
418 def debug(self, *msg):
419 if self.debugflag: self.write(*msg)
419 if self.debugflag: self.write(*msg)
420 def edit(self, text, user):
420 def edit(self, text, user):
421 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
421 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
422 text=True)
422 text=True)
423 try:
423 try:
424 f = os.fdopen(fd, "w")
424 f = os.fdopen(fd, "w")
425 f.write(text)
425 f.write(text)
426 f.close()
426 f.close()
427
427
428 editor = (os.environ.get("HGEDITOR") or
428 editor = (os.environ.get("HGEDITOR") or
429 self.config("ui", "editor") or
429 self.config("ui", "editor") or
430 os.environ.get("EDITOR", "vi"))
430 os.environ.get("EDITOR", "vi"))
431
431
432 util.system("%s \"%s\"" % (editor, name),
432 util.system("%s \"%s\"" % (editor, name),
433 environ={'HGUSER': user},
433 environ={'HGUSER': user},
434 onerr=util.Abort, errprefix=_("edit failed"))
434 onerr=util.Abort, errprefix=_("edit failed"))
435
435
436 f = open(name)
436 f = open(name)
437 t = f.read()
437 t = f.read()
438 f.close()
438 f.close()
439 t = re.sub("(?m)^HG:.*\n", "", t)
439 t = re.sub("(?m)^HG:.*\n", "", t)
440 finally:
440 finally:
441 os.unlink(name)
441 os.unlink(name)
442
442
443 return t
443 return t
444
444
445 def print_exc(self):
445 def print_exc(self):
446 '''print exception traceback if traceback printing enabled.
446 '''print exception traceback if traceback printing enabled.
447 only to call in exception handler. returns true if traceback
447 only to call in exception handler. returns true if traceback
448 printed.'''
448 printed.'''
449 if self.traceback:
449 if self.traceback:
450 traceback.print_exc()
450 traceback.print_exc()
451 return self.traceback
451 return self.traceback
General Comments 0
You need to be logged in to leave comments. Login now