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