##// END OF EJS Templates
Removed unused imports of mdiff and templater from ui.py
Thomas Arendsen Hein -
r3385:9e834d03 default
parent child Browse files
Show More
@@ -1,323 +1,323
1 1 # ui.py - user interface bits for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 from i18n import gettext as _
9 9 from demandload import *
10 10 demandload(globals(), "errno getpass os re socket sys tempfile")
11 demandload(globals(), "ConfigParser mdiff templater traceback util")
11 demandload(globals(), "ConfigParser traceback util")
12 12
13 13 def dupconfig(orig):
14 14 new = ConfigParser.SafeConfigParser(orig.defaults())
15 15 updateconfig(orig, new)
16 16 return new
17 17
18 18 def updateconfig(source, dest):
19 19 for section in source.sections():
20 20 if not dest.has_section(section):
21 21 dest.add_section(section)
22 22 for name, value in source.items(section, raw=True):
23 23 dest.set(section, name, value)
24 24
25 25 class ui(object):
26 26 def __init__(self, verbose=False, debug=False, quiet=False,
27 27 interactive=True, traceback=False, parentui=None):
28 28 self.overlay = None
29 29 self.header = []
30 30 self.prev_header = []
31 31 if parentui is None:
32 32 # this is the parent of all ui children
33 33 self.parentui = None
34 34 self.readhooks = []
35 35 self.quiet = quiet
36 36 self.verbose = verbose
37 37 self.debugflag = debug
38 38 self.interactive = interactive
39 39 self.traceback = traceback
40 40 self.cdata = ConfigParser.SafeConfigParser()
41 41 self.readconfig(util.rcpath())
42 42 self.updateopts(verbose, debug, quiet, interactive)
43 43 else:
44 44 # parentui may point to an ui object which is already a child
45 45 self.parentui = parentui.parentui or parentui
46 46 self.readhooks = self.parentui.readhooks[:]
47 47 self.cdata = dupconfig(self.parentui.cdata)
48 48 if self.parentui.overlay:
49 49 self.overlay = dupconfig(self.parentui.overlay)
50 50
51 51 def __getattr__(self, key):
52 52 return getattr(self.parentui, key)
53 53
54 54 def updateopts(self, verbose=False, debug=False, quiet=False,
55 55 interactive=True, traceback=False, config=[]):
56 56 for section, name, value in config:
57 57 self.setconfig(section, name, value)
58 58
59 59 if quiet or verbose or debug:
60 60 self.setconfig('ui', 'quiet', str(bool(quiet)))
61 61 self.setconfig('ui', 'verbose', str(bool(verbose)))
62 62 self.setconfig('ui', 'debug', str(bool(debug)))
63 63
64 64 self.verbosity_constraints()
65 65
66 66 if not interactive:
67 67 self.setconfig('ui', 'interactive', 'False')
68 68 self.interactive = False
69 69
70 70 self.traceback = self.traceback or traceback
71 71
72 72 def verbosity_constraints(self):
73 73 self.quiet = self.configbool('ui', 'quiet')
74 74 self.verbose = self.configbool('ui', 'verbose')
75 75 self.debugflag = self.configbool('ui', 'debug')
76 76
77 77 if self.debugflag:
78 78 self.verbose = True
79 79 self.quiet = False
80 80 elif self.verbose and self.quiet:
81 81 self.quiet = self.verbose = False
82 82
83 83 def readconfig(self, fn, root=None):
84 84 if isinstance(fn, basestring):
85 85 fn = [fn]
86 86 for f in fn:
87 87 try:
88 88 self.cdata.read(f)
89 89 except ConfigParser.ParsingError, inst:
90 90 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
91 91 # override data from config files with data set with ui.setconfig
92 92 if self.overlay:
93 93 updateconfig(self.overlay, self.cdata)
94 94 if root is None:
95 95 root = os.path.expanduser('~')
96 96 self.fixconfig(root=root)
97 97 for hook in self.readhooks:
98 98 hook(self)
99 99
100 100 def addreadhook(self, hook):
101 101 self.readhooks.append(hook)
102 102
103 103 def fixconfig(self, section=None, name=None, value=None, root=None):
104 104 # translate paths relative to root (or home) into absolute paths
105 105 if section is None or section == 'paths':
106 106 if root is None:
107 107 root = os.getcwd()
108 108 items = section and [(name, value)] or []
109 109 for cdata in self.cdata, self.overlay:
110 110 if not cdata: continue
111 111 if not items and cdata.has_section('paths'):
112 112 pathsitems = cdata.items('paths')
113 113 else:
114 114 pathsitems = items
115 115 for n, path in pathsitems:
116 116 if path and "://" not in path and not os.path.isabs(path):
117 117 cdata.set("paths", n, os.path.join(root, path))
118 118
119 119 # update quiet/verbose/debug and interactive status
120 120 if section is None or section == 'ui':
121 121 if name is None or name in ('quiet', 'verbose', 'debug'):
122 122 self.verbosity_constraints()
123 123
124 124 if name is None or name == 'interactive':
125 125 self.interactive = self.configbool("ui", "interactive", True)
126 126
127 127 def setconfig(self, section, name, value):
128 128 if not self.overlay:
129 129 self.overlay = ConfigParser.SafeConfigParser()
130 130 for cdata in (self.overlay, self.cdata):
131 131 if not cdata.has_section(section):
132 132 cdata.add_section(section)
133 133 cdata.set(section, name, value)
134 134 self.fixconfig(section, name, value)
135 135
136 136 def _config(self, section, name, default, funcname):
137 137 if self.cdata.has_option(section, name):
138 138 try:
139 139 func = getattr(self.cdata, funcname)
140 140 return func(section, name)
141 141 except ConfigParser.InterpolationError, inst:
142 142 raise util.Abort(_("Error in configuration section [%s] "
143 143 "parameter '%s':\n%s")
144 144 % (section, name, inst))
145 145 return default
146 146
147 147 def config(self, section, name, default=None):
148 148 return self._config(section, name, default, 'get')
149 149
150 150 def configbool(self, section, name, default=False):
151 151 return self._config(section, name, default, 'getboolean')
152 152
153 153 def configlist(self, section, name, default=None):
154 154 """Return a list of comma/space separated strings"""
155 155 result = self.config(section, name)
156 156 if result is None:
157 157 result = default or []
158 158 if isinstance(result, basestring):
159 159 result = result.replace(",", " ").split()
160 160 return result
161 161
162 162 def has_config(self, section):
163 163 '''tell whether section exists in config.'''
164 164 return self.cdata.has_section(section)
165 165
166 166 def configitems(self, section):
167 167 items = {}
168 168 if self.cdata.has_section(section):
169 169 try:
170 170 items.update(dict(self.cdata.items(section)))
171 171 except ConfigParser.InterpolationError, inst:
172 172 raise util.Abort(_("Error in configuration section [%s]:\n%s")
173 173 % (section, inst))
174 174 x = items.items()
175 175 x.sort()
176 176 return x
177 177
178 178 def walkconfig(self):
179 179 sections = self.cdata.sections()
180 180 sections.sort()
181 181 for section in sections:
182 182 for name, value in self.configitems(section):
183 183 yield section, name, value.replace('\n', '\\n')
184 184
185 185 def extensions(self):
186 186 result = self.configitems("extensions")
187 187 for i, (key, value) in enumerate(result):
188 188 if value:
189 189 result[i] = (key, os.path.expanduser(value))
190 190 return result
191 191
192 192 def hgignorefiles(self):
193 193 result = []
194 194 for key, value in self.configitems("ui"):
195 195 if key == 'ignore' or key.startswith('ignore.'):
196 196 result.append(os.path.expanduser(value))
197 197 return result
198 198
199 199 def configrevlog(self):
200 200 result = {}
201 201 for key, value in self.configitems("revlog"):
202 202 result[key.lower()] = value
203 203 return result
204 204
205 205 def username(self):
206 206 """Return default username to be used in commits.
207 207
208 208 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
209 209 and stop searching if one of these is set.
210 210 Abort if found username is an empty string to force specifying
211 211 the commit user elsewhere, e.g. with line option or repo hgrc.
212 212 If not found, use ($LOGNAME or $USER or $LNAME or
213 213 $USERNAME) +"@full.hostname".
214 214 """
215 215 user = os.environ.get("HGUSER")
216 216 if user is None:
217 217 user = self.config("ui", "username")
218 218 if user is None:
219 219 user = os.environ.get("EMAIL")
220 220 if user is None:
221 221 try:
222 222 user = '%s@%s' % (util.getuser(), socket.getfqdn())
223 223 except KeyError:
224 224 raise util.Abort(_("Please specify a username."))
225 225 return user
226 226
227 227 def shortuser(self, user):
228 228 """Return a short representation of a user name or email address."""
229 229 if not self.verbose: user = util.shortuser(user)
230 230 return user
231 231
232 232 def expandpath(self, loc, default=None):
233 233 """Return repository location relative to cwd or from [paths]"""
234 234 if "://" in loc or os.path.isdir(loc):
235 235 return loc
236 236
237 237 path = self.config("paths", loc)
238 238 if not path and default is not None:
239 239 path = self.config("paths", default)
240 240 return path or loc
241 241
242 242 def write(self, *args):
243 243 if self.header:
244 244 if self.header != self.prev_header:
245 245 self.prev_header = self.header
246 246 self.write(*self.header)
247 247 self.header = []
248 248 for a in args:
249 249 sys.stdout.write(str(a))
250 250
251 251 def write_header(self, *args):
252 252 for a in args:
253 253 self.header.append(str(a))
254 254
255 255 def write_err(self, *args):
256 256 try:
257 257 if not sys.stdout.closed: sys.stdout.flush()
258 258 for a in args:
259 259 sys.stderr.write(str(a))
260 260 except IOError, inst:
261 261 if inst.errno != errno.EPIPE:
262 262 raise
263 263
264 264 def flush(self):
265 265 try: sys.stdout.flush()
266 266 except: pass
267 267 try: sys.stderr.flush()
268 268 except: pass
269 269
270 270 def readline(self):
271 271 return sys.stdin.readline()[:-1]
272 272 def prompt(self, msg, pat=None, default="y"):
273 273 if not self.interactive: return default
274 274 while 1:
275 275 self.write(msg, " ")
276 276 r = self.readline()
277 277 if not pat or re.match(pat, r):
278 278 return r
279 279 else:
280 280 self.write(_("unrecognized response\n"))
281 281 def getpass(self, prompt=None, default=None):
282 282 if not self.interactive: return default
283 283 return getpass.getpass(prompt or _('password: '))
284 284 def status(self, *msg):
285 285 if not self.quiet: self.write(*msg)
286 286 def warn(self, *msg):
287 287 self.write_err(*msg)
288 288 def note(self, *msg):
289 289 if self.verbose: self.write(*msg)
290 290 def debug(self, *msg):
291 291 if self.debugflag: self.write(*msg)
292 292 def edit(self, text, user):
293 293 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
294 294 text=True)
295 295 try:
296 296 f = os.fdopen(fd, "w")
297 297 f.write(text)
298 298 f.close()
299 299
300 300 editor = (os.environ.get("HGEDITOR") or
301 301 self.config("ui", "editor") or
302 302 os.environ.get("EDITOR", "vi"))
303 303
304 304 util.system("%s \"%s\"" % (editor, name),
305 305 environ={'HGUSER': user},
306 306 onerr=util.Abort, errprefix=_("edit failed"))
307 307
308 308 f = open(name)
309 309 t = f.read()
310 310 f.close()
311 311 t = re.sub("(?m)^HG:.*\n", "", t)
312 312 finally:
313 313 os.unlink(name)
314 314
315 315 return t
316 316
317 317 def print_exc(self):
318 318 '''print exception traceback if traceback printing enabled.
319 319 only to call in exception handler. returns true if traceback
320 320 printed.'''
321 321 if self.traceback:
322 322 traceback.print_exc()
323 323 return self.traceback
General Comments 0
You need to be logged in to leave comments. Login now