##// END OF EJS Templates
Don't expand empty [paths] so later interpolation can do the right thing....
Thomas Arendsen Hein -
r1921:acce3f7e default
parent child Browse files
Show More
@@ -1,224 +1,224
1 # ui.py - user interface bits for mercurial
1 # ui.py - user interface bits for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 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 import ConfigParser
8 import ConfigParser
9 from i18n import gettext as _
9 from i18n import gettext as _
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "os re socket sys util")
11 demandload(globals(), "os re socket sys util")
12
12
13 class ui(object):
13 class ui(object):
14 def __init__(self, verbose=False, debug=False, quiet=False,
14 def __init__(self, verbose=False, debug=False, quiet=False,
15 interactive=True, parentui=None):
15 interactive=True, parentui=None):
16 self.overlay = {}
16 self.overlay = {}
17 if parentui is None:
17 if parentui is None:
18 # this is the parent of all ui children
18 # this is the parent of all ui children
19 self.parentui = None
19 self.parentui = None
20 self.cdata = ConfigParser.SafeConfigParser()
20 self.cdata = ConfigParser.SafeConfigParser()
21 self.readconfig(util.rcpath)
21 self.readconfig(util.rcpath)
22
22
23 self.quiet = self.configbool("ui", "quiet")
23 self.quiet = self.configbool("ui", "quiet")
24 self.verbose = self.configbool("ui", "verbose")
24 self.verbose = self.configbool("ui", "verbose")
25 self.debugflag = self.configbool("ui", "debug")
25 self.debugflag = self.configbool("ui", "debug")
26 self.interactive = self.configbool("ui", "interactive", True)
26 self.interactive = self.configbool("ui", "interactive", True)
27
27
28 self.updateopts(verbose, debug, quiet, interactive)
28 self.updateopts(verbose, debug, quiet, interactive)
29 self.diffcache = None
29 self.diffcache = None
30 else:
30 else:
31 # parentui may point to an ui object which is already a child
31 # parentui may point to an ui object which is already a child
32 self.parentui = parentui.parentui or parentui
32 self.parentui = parentui.parentui or parentui
33 parent_cdata = self.parentui.cdata
33 parent_cdata = self.parentui.cdata
34 self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
34 self.cdata = ConfigParser.SafeConfigParser(parent_cdata.defaults())
35 # make interpolation work
35 # make interpolation work
36 for section in parent_cdata.sections():
36 for section in parent_cdata.sections():
37 self.cdata.add_section(section)
37 self.cdata.add_section(section)
38 for name, value in parent_cdata.items(section, raw=True):
38 for name, value in parent_cdata.items(section, raw=True):
39 self.cdata.set(section, name, value)
39 self.cdata.set(section, name, value)
40
40
41 def __getattr__(self, key):
41 def __getattr__(self, key):
42 return getattr(self.parentui, key)
42 return getattr(self.parentui, key)
43
43
44 def updateopts(self, verbose=False, debug=False, quiet=False,
44 def updateopts(self, verbose=False, debug=False, quiet=False,
45 interactive=True):
45 interactive=True):
46 self.quiet = (self.quiet or quiet) and not verbose and not debug
46 self.quiet = (self.quiet or quiet) and not verbose and not debug
47 self.verbose = (self.verbose or verbose) or debug
47 self.verbose = (self.verbose or verbose) or debug
48 self.debugflag = (self.debugflag or debug)
48 self.debugflag = (self.debugflag or debug)
49 self.interactive = (self.interactive and interactive)
49 self.interactive = (self.interactive and interactive)
50
50
51 def readconfig(self, fn, root=None):
51 def readconfig(self, fn, root=None):
52 if isinstance(fn, basestring):
52 if isinstance(fn, basestring):
53 fn = [fn]
53 fn = [fn]
54 for f in fn:
54 for f in fn:
55 try:
55 try:
56 self.cdata.read(f)
56 self.cdata.read(f)
57 except ConfigParser.ParsingError, inst:
57 except ConfigParser.ParsingError, inst:
58 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
58 raise util.Abort(_("Failed to parse %s\n%s") % (f, inst))
59 # translate paths relative to root (or home) into absolute paths
59 # translate paths relative to root (or home) into absolute paths
60 if root is None:
60 if root is None:
61 root = os.path.expanduser('~')
61 root = os.path.expanduser('~')
62 for name, path in self.configitems("paths"):
62 for name, path in self.configitems("paths"):
63 if path.find("://") == -1 and not os.path.isabs(path):
63 if path and path.find("://") == -1 and not os.path.isabs(path):
64 self.cdata.set("paths", name, os.path.join(root, path))
64 self.cdata.set("paths", name, os.path.join(root, path))
65
65
66 def setconfig(self, section, name, val):
66 def setconfig(self, section, name, val):
67 self.overlay[(section, name)] = val
67 self.overlay[(section, name)] = val
68
68
69 def config(self, section, name, default=None):
69 def config(self, section, name, default=None):
70 if self.overlay.has_key((section, name)):
70 if self.overlay.has_key((section, name)):
71 return self.overlay[(section, name)]
71 return self.overlay[(section, name)]
72 if self.cdata.has_option(section, name):
72 if self.cdata.has_option(section, name):
73 try:
73 try:
74 return self.cdata.get(section, name)
74 return self.cdata.get(section, name)
75 except ConfigParser.InterpolationError, inst:
75 except ConfigParser.InterpolationError, inst:
76 raise util.Abort(_("Error in configuration:\n%s") % inst)
76 raise util.Abort(_("Error in configuration:\n%s") % inst)
77 if self.parentui is None:
77 if self.parentui is None:
78 return default
78 return default
79 else:
79 else:
80 return self.parentui.config(section, name, default)
80 return self.parentui.config(section, name, default)
81
81
82 def configbool(self, section, name, default=False):
82 def configbool(self, section, name, default=False):
83 if self.overlay.has_key((section, name)):
83 if self.overlay.has_key((section, name)):
84 return self.overlay[(section, name)]
84 return self.overlay[(section, name)]
85 if self.cdata.has_option(section, name):
85 if self.cdata.has_option(section, name):
86 try:
86 try:
87 return self.cdata.getboolean(section, name)
87 return self.cdata.getboolean(section, name)
88 except ConfigParser.InterpolationError, inst:
88 except ConfigParser.InterpolationError, inst:
89 raise util.Abort(_("Error in configuration:\n%s") % inst)
89 raise util.Abort(_("Error in configuration:\n%s") % inst)
90 if self.parentui is None:
90 if self.parentui is None:
91 return default
91 return default
92 else:
92 else:
93 return self.parentui.configbool(section, name, default)
93 return self.parentui.configbool(section, name, default)
94
94
95 def configitems(self, section):
95 def configitems(self, section):
96 items = {}
96 items = {}
97 if self.parentui is not None:
97 if self.parentui is not None:
98 items = dict(self.parentui.configitems(section))
98 items = dict(self.parentui.configitems(section))
99 if self.cdata.has_section(section):
99 if self.cdata.has_section(section):
100 try:
100 try:
101 items.update(dict(self.cdata.items(section)))
101 items.update(dict(self.cdata.items(section)))
102 except ConfigParser.InterpolationError, inst:
102 except ConfigParser.InterpolationError, inst:
103 raise util.Abort(_("Error in configuration:\n%s") % inst)
103 raise util.Abort(_("Error in configuration:\n%s") % inst)
104 x = items.items()
104 x = items.items()
105 x.sort()
105 x.sort()
106 return x
106 return x
107
107
108 def walkconfig(self, seen=None):
108 def walkconfig(self, seen=None):
109 if seen is None:
109 if seen is None:
110 seen = {}
110 seen = {}
111 for (section, name), value in self.overlay.iteritems():
111 for (section, name), value in self.overlay.iteritems():
112 yield section, name, value
112 yield section, name, value
113 seen[section, name] = 1
113 seen[section, name] = 1
114 for section in self.cdata.sections():
114 for section in self.cdata.sections():
115 for name, value in self.cdata.items(section):
115 for name, value in self.cdata.items(section):
116 if (section, name) in seen: continue
116 if (section, name) in seen: continue
117 yield section, name, value.replace('\n', '\\n')
117 yield section, name, value.replace('\n', '\\n')
118 seen[section, name] = 1
118 seen[section, name] = 1
119 if self.parentui is not None:
119 if self.parentui is not None:
120 for parent in self.parentui.walkconfig(seen):
120 for parent in self.parentui.walkconfig(seen):
121 yield parent
121 yield parent
122
122
123 def extensions(self):
123 def extensions(self):
124 return self.configitems("extensions")
124 return self.configitems("extensions")
125
125
126 def diffopts(self):
126 def diffopts(self):
127 if self.diffcache:
127 if self.diffcache:
128 return self.diffcache
128 return self.diffcache
129 ret = { 'showfunc' : True, 'ignorews' : False}
129 ret = { 'showfunc' : True, 'ignorews' : False}
130 for x in self.configitems("diff"):
130 for x in self.configitems("diff"):
131 k = x[0].lower()
131 k = x[0].lower()
132 v = x[1]
132 v = x[1]
133 if v:
133 if v:
134 v = v.lower()
134 v = v.lower()
135 if v == 'true':
135 if v == 'true':
136 value = True
136 value = True
137 else:
137 else:
138 value = False
138 value = False
139 ret[k] = value
139 ret[k] = value
140 self.diffcache = ret
140 self.diffcache = ret
141 return ret
141 return ret
142
142
143 def username(self):
143 def username(self):
144 return (os.environ.get("HGUSER") or
144 return (os.environ.get("HGUSER") or
145 self.config("ui", "username") or
145 self.config("ui", "username") or
146 os.environ.get("EMAIL") or
146 os.environ.get("EMAIL") or
147 (os.environ.get("LOGNAME",
147 (os.environ.get("LOGNAME",
148 os.environ.get("USERNAME", "unknown"))
148 os.environ.get("USERNAME", "unknown"))
149 + '@' + socket.getfqdn()))
149 + '@' + socket.getfqdn()))
150
150
151 def shortuser(self, user):
151 def shortuser(self, user):
152 """Return a short representation of a user name or email address."""
152 """Return a short representation of a user name or email address."""
153 if not self.verbose:
153 if not self.verbose:
154 f = user.find('@')
154 f = user.find('@')
155 if f >= 0:
155 if f >= 0:
156 user = user[:f]
156 user = user[:f]
157 f = user.find('<')
157 f = user.find('<')
158 if f >= 0:
158 if f >= 0:
159 user = user[f+1:]
159 user = user[f+1:]
160 return user
160 return user
161
161
162 def expandpath(self, loc):
162 def expandpath(self, loc):
163 """Return repository location relative to cwd or from [paths]"""
163 """Return repository location relative to cwd or from [paths]"""
164 if loc.find("://") != -1 or os.path.exists(loc):
164 if loc.find("://") != -1 or os.path.exists(loc):
165 return loc
165 return loc
166
166
167 return self.config("paths", loc, loc)
167 return self.config("paths", loc, loc)
168
168
169 def write(self, *args):
169 def write(self, *args):
170 for a in args:
170 for a in args:
171 sys.stdout.write(str(a))
171 sys.stdout.write(str(a))
172
172
173 def write_err(self, *args):
173 def write_err(self, *args):
174 if not sys.stdout.closed: sys.stdout.flush()
174 if not sys.stdout.closed: sys.stdout.flush()
175 for a in args:
175 for a in args:
176 sys.stderr.write(str(a))
176 sys.stderr.write(str(a))
177
177
178 def flush(self):
178 def flush(self):
179 try:
179 try:
180 sys.stdout.flush()
180 sys.stdout.flush()
181 finally:
181 finally:
182 sys.stderr.flush()
182 sys.stderr.flush()
183
183
184 def readline(self):
184 def readline(self):
185 return sys.stdin.readline()[:-1]
185 return sys.stdin.readline()[:-1]
186 def prompt(self, msg, pat, default="y"):
186 def prompt(self, msg, pat, default="y"):
187 if not self.interactive: return default
187 if not self.interactive: return default
188 while 1:
188 while 1:
189 self.write(msg, " ")
189 self.write(msg, " ")
190 r = self.readline()
190 r = self.readline()
191 if re.match(pat, r):
191 if re.match(pat, r):
192 return r
192 return r
193 else:
193 else:
194 self.write(_("unrecognized response\n"))
194 self.write(_("unrecognized response\n"))
195 def status(self, *msg):
195 def status(self, *msg):
196 if not self.quiet: self.write(*msg)
196 if not self.quiet: self.write(*msg)
197 def warn(self, *msg):
197 def warn(self, *msg):
198 self.write_err(*msg)
198 self.write_err(*msg)
199 def note(self, *msg):
199 def note(self, *msg):
200 if self.verbose: self.write(*msg)
200 if self.verbose: self.write(*msg)
201 def debug(self, *msg):
201 def debug(self, *msg):
202 if self.debugflag: self.write(*msg)
202 if self.debugflag: self.write(*msg)
203 def edit(self, text):
203 def edit(self, text):
204 import tempfile
204 import tempfile
205 (fd, name) = tempfile.mkstemp("hg")
205 (fd, name) = tempfile.mkstemp("hg")
206 f = os.fdopen(fd, "w")
206 f = os.fdopen(fd, "w")
207 f.write(text)
207 f.write(text)
208 f.close()
208 f.close()
209
209
210 editor = (os.environ.get("HGEDITOR") or
210 editor = (os.environ.get("HGEDITOR") or
211 self.config("ui", "editor") or
211 self.config("ui", "editor") or
212 os.environ.get("EDITOR", "vi"))
212 os.environ.get("EDITOR", "vi"))
213
213
214 os.environ["HGUSER"] = self.username()
214 os.environ["HGUSER"] = self.username()
215 util.system("%s \"%s\"" % (editor, name),
215 util.system("%s \"%s\"" % (editor, name),
216 environ={'HGUSER': self.username()},
216 environ={'HGUSER': self.username()},
217 onerr=util.Abort, errprefix=_("edit failed"))
217 onerr=util.Abort, errprefix=_("edit failed"))
218
218
219 t = open(name).read()
219 t = open(name).read()
220 t = re.sub("(?m)^HG:.*\n", "", t)
220 t = re.sub("(?m)^HG:.*\n", "", t)
221
221
222 os.unlink(name)
222 os.unlink(name)
223
223
224 return t
224 return t
General Comments 0
You need to be logged in to leave comments. Login now