##// END OF EJS Templates
dispatch: catch ConfigError while constructing ui
Martin Geisler -
r9470:ba75830d default
parent child Browse files
Show More
@@ -1,501 +1,504 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as _ui
12 import ui as _ui
13
13
14 def run():
14 def run():
15 "run the command in sys.argv"
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
16 sys.exit(dispatch(sys.argv[1:]))
17
17
18 def dispatch(args):
18 def dispatch(args):
19 "run the command specified in args"
19 "run the command specified in args"
20 try:
20 try:
21 u = _ui.ui()
21 u = _ui.ui()
22 if '--traceback' in args:
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
25 sys.stderr.write(_("abort: %s\n") % inst)
26 return -1
26 return -1
27 except error.ConfigError, inst:
28 sys.stderr.write(_("hg: %s\n") % inst)
29 return -1
27 return _runcatch(u, args)
30 return _runcatch(u, args)
28
31
29 def _runcatch(ui, args):
32 def _runcatch(ui, args):
30 def catchterm(*args):
33 def catchterm(*args):
31 raise error.SignalInterrupt
34 raise error.SignalInterrupt
32
35
33 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
36 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
34 num = getattr(signal, name, None)
37 num = getattr(signal, name, None)
35 if num: signal.signal(num, catchterm)
38 if num: signal.signal(num, catchterm)
36
39
37 try:
40 try:
38 try:
41 try:
39 # enter the debugger before command execution
42 # enter the debugger before command execution
40 if '--debugger' in args:
43 if '--debugger' in args:
41 pdb.set_trace()
44 pdb.set_trace()
42 try:
45 try:
43 return _dispatch(ui, args)
46 return _dispatch(ui, args)
44 finally:
47 finally:
45 ui.flush()
48 ui.flush()
46 except:
49 except:
47 # enter the debugger when we hit an exception
50 # enter the debugger when we hit an exception
48 if '--debugger' in args:
51 if '--debugger' in args:
49 pdb.post_mortem(sys.exc_info()[2])
52 pdb.post_mortem(sys.exc_info()[2])
50 ui.traceback()
53 ui.traceback()
51 raise
54 raise
52
55
53 # Global exception handling, alphabetically
56 # Global exception handling, alphabetically
54 # Mercurial-specific first, followed by built-in and library exceptions
57 # Mercurial-specific first, followed by built-in and library exceptions
55 except error.AmbiguousCommand, inst:
58 except error.AmbiguousCommand, inst:
56 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
59 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
57 (inst.args[0], " ".join(inst.args[1])))
60 (inst.args[0], " ".join(inst.args[1])))
58 except error.ConfigError, inst:
61 except error.ConfigError, inst:
59 ui.warn(_("hg: %s\n") % inst.args[0])
62 ui.warn(_("hg: %s\n") % inst.args[0])
60 except error.LockHeld, inst:
63 except error.LockHeld, inst:
61 if inst.errno == errno.ETIMEDOUT:
64 if inst.errno == errno.ETIMEDOUT:
62 reason = _('timed out waiting for lock held by %s') % inst.locker
65 reason = _('timed out waiting for lock held by %s') % inst.locker
63 else:
66 else:
64 reason = _('lock held by %s') % inst.locker
67 reason = _('lock held by %s') % inst.locker
65 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
68 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
66 except error.LockUnavailable, inst:
69 except error.LockUnavailable, inst:
67 ui.warn(_("abort: could not lock %s: %s\n") %
70 ui.warn(_("abort: could not lock %s: %s\n") %
68 (inst.desc or inst.filename, inst.strerror))
71 (inst.desc or inst.filename, inst.strerror))
69 except error.ParseError, inst:
72 except error.ParseError, inst:
70 if inst.args[0]:
73 if inst.args[0]:
71 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
74 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
72 commands.help_(ui, inst.args[0])
75 commands.help_(ui, inst.args[0])
73 else:
76 else:
74 ui.warn(_("hg: %s\n") % inst.args[1])
77 ui.warn(_("hg: %s\n") % inst.args[1])
75 commands.help_(ui, 'shortlist')
78 commands.help_(ui, 'shortlist')
76 except error.RepoError, inst:
79 except error.RepoError, inst:
77 ui.warn(_("abort: %s!\n") % inst)
80 ui.warn(_("abort: %s!\n") % inst)
78 except error.ResponseError, inst:
81 except error.ResponseError, inst:
79 ui.warn(_("abort: %s") % inst.args[0])
82 ui.warn(_("abort: %s") % inst.args[0])
80 if not isinstance(inst.args[1], basestring):
83 if not isinstance(inst.args[1], basestring):
81 ui.warn(" %r\n" % (inst.args[1],))
84 ui.warn(" %r\n" % (inst.args[1],))
82 elif not inst.args[1]:
85 elif not inst.args[1]:
83 ui.warn(_(" empty string\n"))
86 ui.warn(_(" empty string\n"))
84 else:
87 else:
85 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
88 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
86 except error.RevlogError, inst:
89 except error.RevlogError, inst:
87 ui.warn(_("abort: %s!\n") % inst)
90 ui.warn(_("abort: %s!\n") % inst)
88 except error.SignalInterrupt:
91 except error.SignalInterrupt:
89 ui.warn(_("killed!\n"))
92 ui.warn(_("killed!\n"))
90 except error.UnknownCommand, inst:
93 except error.UnknownCommand, inst:
91 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
94 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
92 commands.help_(ui, 'shortlist')
95 commands.help_(ui, 'shortlist')
93 except util.Abort, inst:
96 except util.Abort, inst:
94 ui.warn(_("abort: %s\n") % inst)
97 ui.warn(_("abort: %s\n") % inst)
95 except ImportError, inst:
98 except ImportError, inst:
96 m = str(inst).split()[-1]
99 m = str(inst).split()[-1]
97 ui.warn(_("abort: could not import module %s!\n") % m)
100 ui.warn(_("abort: could not import module %s!\n") % m)
98 if m in "mpatch bdiff".split():
101 if m in "mpatch bdiff".split():
99 ui.warn(_("(did you forget to compile extensions?)\n"))
102 ui.warn(_("(did you forget to compile extensions?)\n"))
100 elif m in "zlib".split():
103 elif m in "zlib".split():
101 ui.warn(_("(is your Python install correct?)\n"))
104 ui.warn(_("(is your Python install correct?)\n"))
102 except IOError, inst:
105 except IOError, inst:
103 if hasattr(inst, "code"):
106 if hasattr(inst, "code"):
104 ui.warn(_("abort: %s\n") % inst)
107 ui.warn(_("abort: %s\n") % inst)
105 elif hasattr(inst, "reason"):
108 elif hasattr(inst, "reason"):
106 try: # usually it is in the form (errno, strerror)
109 try: # usually it is in the form (errno, strerror)
107 reason = inst.reason.args[1]
110 reason = inst.reason.args[1]
108 except: # it might be anything, for example a string
111 except: # it might be anything, for example a string
109 reason = inst.reason
112 reason = inst.reason
110 ui.warn(_("abort: error: %s\n") % reason)
113 ui.warn(_("abort: error: %s\n") % reason)
111 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
114 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
112 if ui.debugflag:
115 if ui.debugflag:
113 ui.warn(_("broken pipe\n"))
116 ui.warn(_("broken pipe\n"))
114 elif getattr(inst, "strerror", None):
117 elif getattr(inst, "strerror", None):
115 if getattr(inst, "filename", None):
118 if getattr(inst, "filename", None):
116 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
119 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
117 else:
120 else:
118 ui.warn(_("abort: %s\n") % inst.strerror)
121 ui.warn(_("abort: %s\n") % inst.strerror)
119 else:
122 else:
120 raise
123 raise
121 except OSError, inst:
124 except OSError, inst:
122 if getattr(inst, "filename", None):
125 if getattr(inst, "filename", None):
123 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
126 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
124 else:
127 else:
125 ui.warn(_("abort: %s\n") % inst.strerror)
128 ui.warn(_("abort: %s\n") % inst.strerror)
126 except KeyboardInterrupt:
129 except KeyboardInterrupt:
127 try:
130 try:
128 ui.warn(_("interrupted!\n"))
131 ui.warn(_("interrupted!\n"))
129 except IOError, inst:
132 except IOError, inst:
130 if inst.errno == errno.EPIPE:
133 if inst.errno == errno.EPIPE:
131 if ui.debugflag:
134 if ui.debugflag:
132 ui.warn(_("\nbroken pipe\n"))
135 ui.warn(_("\nbroken pipe\n"))
133 else:
136 else:
134 raise
137 raise
135 except MemoryError:
138 except MemoryError:
136 ui.warn(_("abort: out of memory\n"))
139 ui.warn(_("abort: out of memory\n"))
137 except SystemExit, inst:
140 except SystemExit, inst:
138 # Commands shouldn't sys.exit directly, but give a return code.
141 # Commands shouldn't sys.exit directly, but give a return code.
139 # Just in case catch this and and pass exit code to caller.
142 # Just in case catch this and and pass exit code to caller.
140 return inst.code
143 return inst.code
141 except socket.error, inst:
144 except socket.error, inst:
142 ui.warn(_("abort: %s\n") % inst.args[-1])
145 ui.warn(_("abort: %s\n") % inst.args[-1])
143 except:
146 except:
144 ui.warn(_("** unknown exception encountered, details follow\n"))
147 ui.warn(_("** unknown exception encountered, details follow\n"))
145 ui.warn(_("** report bug details to "
148 ui.warn(_("** report bug details to "
146 "http://mercurial.selenic.com/bts/\n"))
149 "http://mercurial.selenic.com/bts/\n"))
147 ui.warn(_("** or mercurial@selenic.com\n"))
150 ui.warn(_("** or mercurial@selenic.com\n"))
148 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
151 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
149 % util.version())
152 % util.version())
150 ui.warn(_("** Extensions loaded: %s\n")
153 ui.warn(_("** Extensions loaded: %s\n")
151 % ", ".join([x[0] for x in extensions.extensions()]))
154 % ", ".join([x[0] for x in extensions.extensions()]))
152 raise
155 raise
153
156
154 return -1
157 return -1
155
158
156 def _findrepo(p):
159 def _findrepo(p):
157 while not os.path.isdir(os.path.join(p, ".hg")):
160 while not os.path.isdir(os.path.join(p, ".hg")):
158 oldp, p = p, os.path.dirname(p)
161 oldp, p = p, os.path.dirname(p)
159 if p == oldp:
162 if p == oldp:
160 return None
163 return None
161
164
162 return p
165 return p
163
166
164 def aliasargs(fn):
167 def aliasargs(fn):
165 if hasattr(fn, 'args'):
168 if hasattr(fn, 'args'):
166 return fn.args
169 return fn.args
167 return []
170 return []
168
171
169 class cmdalias(object):
172 class cmdalias(object):
170 def __init__(self, name, definition, cmdtable):
173 def __init__(self, name, definition, cmdtable):
171 self.name = name
174 self.name = name
172 self.definition = definition
175 self.definition = definition
173 self.args = []
176 self.args = []
174 self.opts = []
177 self.opts = []
175 self.help = ''
178 self.help = ''
176 self.norepo = True
179 self.norepo = True
177
180
178 try:
181 try:
179 cmdutil.findcmd(self.name, cmdtable, True)
182 cmdutil.findcmd(self.name, cmdtable, True)
180 self.shadows = True
183 self.shadows = True
181 except error.UnknownCommand:
184 except error.UnknownCommand:
182 self.shadows = False
185 self.shadows = False
183
186
184 if not self.definition:
187 if not self.definition:
185 def fn(ui, *args):
188 def fn(ui, *args):
186 ui.warn(_("no definition for alias '%s'\n") % self.name)
189 ui.warn(_("no definition for alias '%s'\n") % self.name)
187 return 1
190 return 1
188 self.fn = fn
191 self.fn = fn
189
192
190 return
193 return
191
194
192 args = shlex.split(self.definition)
195 args = shlex.split(self.definition)
193 cmd = args.pop(0)
196 cmd = args.pop(0)
194 opts = []
197 opts = []
195 help = ''
198 help = ''
196
199
197 try:
200 try:
198 self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
201 self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
199 self.args = aliasargs(self.fn) + args
202 self.args = aliasargs(self.fn) + args
200 if cmd not in commands.norepo.split(' '):
203 if cmd not in commands.norepo.split(' '):
201 self.norepo = False
204 self.norepo = False
202 except error.UnknownCommand:
205 except error.UnknownCommand:
203 def fn(ui, *args):
206 def fn(ui, *args):
204 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
207 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
205 % (self.name, cmd))
208 % (self.name, cmd))
206 return 1
209 return 1
207 self.fn = fn
210 self.fn = fn
208 except error.AmbiguousCommand:
211 except error.AmbiguousCommand:
209 def fn(ui, *args):
212 def fn(ui, *args):
210 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
213 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
211 % (self.name, cmd))
214 % (self.name, cmd))
212 return 1
215 return 1
213 self.fn = fn
216 self.fn = fn
214
217
215 def __call__(self, ui, *args, **opts):
218 def __call__(self, ui, *args, **opts):
216 if self.shadows:
219 if self.shadows:
217 ui.debug(_("alias '%s' shadows command\n") % self.name)
220 ui.debug(_("alias '%s' shadows command\n") % self.name)
218
221
219 return self.fn(ui, *args, **opts)
222 return self.fn(ui, *args, **opts)
220
223
221 def addaliases(ui, cmdtable):
224 def addaliases(ui, cmdtable):
222 # aliases are processed after extensions have been loaded, so they
225 # aliases are processed after extensions have been loaded, so they
223 # may use extension commands. Aliases can also use other alias definitions,
226 # may use extension commands. Aliases can also use other alias definitions,
224 # but only if they have been defined prior to the current definition.
227 # but only if they have been defined prior to the current definition.
225 for alias, definition in ui.configitems('alias'):
228 for alias, definition in ui.configitems('alias'):
226 aliasdef = cmdalias(alias, definition, cmdtable)
229 aliasdef = cmdalias(alias, definition, cmdtable)
227 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
230 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
228 if aliasdef.norepo:
231 if aliasdef.norepo:
229 commands.norepo += ' %s' % alias
232 commands.norepo += ' %s' % alias
230
233
231 def _parse(ui, args):
234 def _parse(ui, args):
232 options = {}
235 options = {}
233 cmdoptions = {}
236 cmdoptions = {}
234
237
235 try:
238 try:
236 args = fancyopts.fancyopts(args, commands.globalopts, options)
239 args = fancyopts.fancyopts(args, commands.globalopts, options)
237 except fancyopts.getopt.GetoptError, inst:
240 except fancyopts.getopt.GetoptError, inst:
238 raise error.ParseError(None, inst)
241 raise error.ParseError(None, inst)
239
242
240 if args:
243 if args:
241 cmd, args = args[0], args[1:]
244 cmd, args = args[0], args[1:]
242 aliases, i = cmdutil.findcmd(cmd, commands.table,
245 aliases, i = cmdutil.findcmd(cmd, commands.table,
243 ui.config("ui", "strict"))
246 ui.config("ui", "strict"))
244 cmd = aliases[0]
247 cmd = aliases[0]
245 args = aliasargs(i[0]) + args
248 args = aliasargs(i[0]) + args
246 defaults = ui.config("defaults", cmd)
249 defaults = ui.config("defaults", cmd)
247 if defaults:
250 if defaults:
248 args = shlex.split(defaults) + args
251 args = shlex.split(defaults) + args
249 c = list(i[1])
252 c = list(i[1])
250 else:
253 else:
251 cmd = None
254 cmd = None
252 c = []
255 c = []
253
256
254 # combine global options into local
257 # combine global options into local
255 for o in commands.globalopts:
258 for o in commands.globalopts:
256 c.append((o[0], o[1], options[o[1]], o[3]))
259 c.append((o[0], o[1], options[o[1]], o[3]))
257
260
258 try:
261 try:
259 args = fancyopts.fancyopts(args, c, cmdoptions, True)
262 args = fancyopts.fancyopts(args, c, cmdoptions, True)
260 except fancyopts.getopt.GetoptError, inst:
263 except fancyopts.getopt.GetoptError, inst:
261 raise error.ParseError(cmd, inst)
264 raise error.ParseError(cmd, inst)
262
265
263 # separate global options back out
266 # separate global options back out
264 for o in commands.globalopts:
267 for o in commands.globalopts:
265 n = o[1]
268 n = o[1]
266 options[n] = cmdoptions[n]
269 options[n] = cmdoptions[n]
267 del cmdoptions[n]
270 del cmdoptions[n]
268
271
269 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
272 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
270
273
271 def _parseconfig(ui, config):
274 def _parseconfig(ui, config):
272 """parse the --config options from the command line"""
275 """parse the --config options from the command line"""
273 for cfg in config:
276 for cfg in config:
274 try:
277 try:
275 name, value = cfg.split('=', 1)
278 name, value = cfg.split('=', 1)
276 section, name = name.split('.', 1)
279 section, name = name.split('.', 1)
277 if not section or not name:
280 if not section or not name:
278 raise IndexError
281 raise IndexError
279 ui.setconfig(section, name, value)
282 ui.setconfig(section, name, value)
280 except (IndexError, ValueError):
283 except (IndexError, ValueError):
281 raise util.Abort(_('malformed --config option: %s') % cfg)
284 raise util.Abort(_('malformed --config option: %s') % cfg)
282
285
283 def _earlygetopt(aliases, args):
286 def _earlygetopt(aliases, args):
284 """Return list of values for an option (or aliases).
287 """Return list of values for an option (or aliases).
285
288
286 The values are listed in the order they appear in args.
289 The values are listed in the order they appear in args.
287 The options and values are removed from args.
290 The options and values are removed from args.
288 """
291 """
289 try:
292 try:
290 argcount = args.index("--")
293 argcount = args.index("--")
291 except ValueError:
294 except ValueError:
292 argcount = len(args)
295 argcount = len(args)
293 shortopts = [opt for opt in aliases if len(opt) == 2]
296 shortopts = [opt for opt in aliases if len(opt) == 2]
294 values = []
297 values = []
295 pos = 0
298 pos = 0
296 while pos < argcount:
299 while pos < argcount:
297 if args[pos] in aliases:
300 if args[pos] in aliases:
298 if pos + 1 >= argcount:
301 if pos + 1 >= argcount:
299 # ignore and let getopt report an error if there is no value
302 # ignore and let getopt report an error if there is no value
300 break
303 break
301 del args[pos]
304 del args[pos]
302 values.append(args.pop(pos))
305 values.append(args.pop(pos))
303 argcount -= 2
306 argcount -= 2
304 elif args[pos][:2] in shortopts:
307 elif args[pos][:2] in shortopts:
305 # short option can have no following space, e.g. hg log -Rfoo
308 # short option can have no following space, e.g. hg log -Rfoo
306 values.append(args.pop(pos)[2:])
309 values.append(args.pop(pos)[2:])
307 argcount -= 1
310 argcount -= 1
308 else:
311 else:
309 pos += 1
312 pos += 1
310 return values
313 return values
311
314
312 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
315 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
313 # run pre-hook, and abort if it fails
316 # run pre-hook, and abort if it fails
314 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
317 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
315 if ret:
318 if ret:
316 return ret
319 return ret
317 ret = _runcommand(ui, options, cmd, d)
320 ret = _runcommand(ui, options, cmd, d)
318 # run post-hook, passing command result
321 # run post-hook, passing command result
319 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
322 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
320 result = ret)
323 result = ret)
321 return ret
324 return ret
322
325
323 _loaded = set()
326 _loaded = set()
324 def _dispatch(ui, args):
327 def _dispatch(ui, args):
325 # read --config before doing anything else
328 # read --config before doing anything else
326 # (e.g. to change trust settings for reading .hg/hgrc)
329 # (e.g. to change trust settings for reading .hg/hgrc)
327 _parseconfig(ui, _earlygetopt(['--config'], args))
330 _parseconfig(ui, _earlygetopt(['--config'], args))
328
331
329 # check for cwd
332 # check for cwd
330 cwd = _earlygetopt(['--cwd'], args)
333 cwd = _earlygetopt(['--cwd'], args)
331 if cwd:
334 if cwd:
332 os.chdir(cwd[-1])
335 os.chdir(cwd[-1])
333
336
334 # read the local repository .hgrc into a local ui object
337 # read the local repository .hgrc into a local ui object
335 path = _findrepo(os.getcwd()) or ""
338 path = _findrepo(os.getcwd()) or ""
336 if not path:
339 if not path:
337 lui = ui
340 lui = ui
338 if path:
341 if path:
339 try:
342 try:
340 lui = ui.copy()
343 lui = ui.copy()
341 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
344 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
342 except IOError:
345 except IOError:
343 pass
346 pass
344
347
345 # now we can expand paths, even ones in .hg/hgrc
348 # now we can expand paths, even ones in .hg/hgrc
346 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
349 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
347 if rpath:
350 if rpath:
348 path = lui.expandpath(rpath[-1])
351 path = lui.expandpath(rpath[-1])
349 lui = ui.copy()
352 lui = ui.copy()
350 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
353 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
351
354
352 extensions.loadall(lui)
355 extensions.loadall(lui)
353 for name, module in extensions.extensions():
356 for name, module in extensions.extensions():
354 if name in _loaded:
357 if name in _loaded:
355 continue
358 continue
356
359
357 # setup extensions
360 # setup extensions
358 # TODO this should be generalized to scheme, where extensions can
361 # TODO this should be generalized to scheme, where extensions can
359 # redepend on other extensions. then we should toposort them, and
362 # redepend on other extensions. then we should toposort them, and
360 # do initialization in correct order
363 # do initialization in correct order
361 extsetup = getattr(module, 'extsetup', None)
364 extsetup = getattr(module, 'extsetup', None)
362 if extsetup:
365 if extsetup:
363 extsetup()
366 extsetup()
364
367
365 cmdtable = getattr(module, 'cmdtable', {})
368 cmdtable = getattr(module, 'cmdtable', {})
366 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
369 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
367 if overrides:
370 if overrides:
368 ui.warn(_("extension '%s' overrides commands: %s\n")
371 ui.warn(_("extension '%s' overrides commands: %s\n")
369 % (name, " ".join(overrides)))
372 % (name, " ".join(overrides)))
370 commands.table.update(cmdtable)
373 commands.table.update(cmdtable)
371 _loaded.add(name)
374 _loaded.add(name)
372
375
373 addaliases(lui, commands.table)
376 addaliases(lui, commands.table)
374
377
375 # check for fallback encoding
378 # check for fallback encoding
376 fallback = lui.config('ui', 'fallbackencoding')
379 fallback = lui.config('ui', 'fallbackencoding')
377 if fallback:
380 if fallback:
378 encoding.fallbackencoding = fallback
381 encoding.fallbackencoding = fallback
379
382
380 fullargs = args
383 fullargs = args
381 cmd, func, args, options, cmdoptions = _parse(lui, args)
384 cmd, func, args, options, cmdoptions = _parse(lui, args)
382
385
383 if options["config"]:
386 if options["config"]:
384 raise util.Abort(_("Option --config may not be abbreviated!"))
387 raise util.Abort(_("Option --config may not be abbreviated!"))
385 if options["cwd"]:
388 if options["cwd"]:
386 raise util.Abort(_("Option --cwd may not be abbreviated!"))
389 raise util.Abort(_("Option --cwd may not be abbreviated!"))
387 if options["repository"]:
390 if options["repository"]:
388 raise util.Abort(_(
391 raise util.Abort(_(
389 "Option -R has to be separated from other options (e.g. not -qR) "
392 "Option -R has to be separated from other options (e.g. not -qR) "
390 "and --repository may only be abbreviated as --repo!"))
393 "and --repository may only be abbreviated as --repo!"))
391
394
392 if options["encoding"]:
395 if options["encoding"]:
393 encoding.encoding = options["encoding"]
396 encoding.encoding = options["encoding"]
394 if options["encodingmode"]:
397 if options["encodingmode"]:
395 encoding.encodingmode = options["encodingmode"]
398 encoding.encodingmode = options["encodingmode"]
396 if options["time"]:
399 if options["time"]:
397 def get_times():
400 def get_times():
398 t = os.times()
401 t = os.times()
399 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
402 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
400 t = (t[0], t[1], t[2], t[3], time.clock())
403 t = (t[0], t[1], t[2], t[3], time.clock())
401 return t
404 return t
402 s = get_times()
405 s = get_times()
403 def print_time():
406 def print_time():
404 t = get_times()
407 t = get_times()
405 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
408 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
406 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
409 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
407 atexit.register(print_time)
410 atexit.register(print_time)
408
411
409 if options['verbose'] or options['debug'] or options['quiet']:
412 if options['verbose'] or options['debug'] or options['quiet']:
410 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
413 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
411 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
414 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
412 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
415 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
413 if options['traceback']:
416 if options['traceback']:
414 ui.setconfig('ui', 'traceback', 'on')
417 ui.setconfig('ui', 'traceback', 'on')
415 if options['noninteractive']:
418 if options['noninteractive']:
416 ui.setconfig('ui', 'interactive', 'off')
419 ui.setconfig('ui', 'interactive', 'off')
417
420
418 if options['help']:
421 if options['help']:
419 return commands.help_(ui, cmd, options['version'])
422 return commands.help_(ui, cmd, options['version'])
420 elif options['version']:
423 elif options['version']:
421 return commands.version_(ui)
424 return commands.version_(ui)
422 elif not cmd:
425 elif not cmd:
423 return commands.help_(ui, 'shortlist')
426 return commands.help_(ui, 'shortlist')
424
427
425 repo = None
428 repo = None
426 if cmd not in commands.norepo.split():
429 if cmd not in commands.norepo.split():
427 try:
430 try:
428 repo = hg.repository(ui, path=path)
431 repo = hg.repository(ui, path=path)
429 ui = repo.ui
432 ui = repo.ui
430 if not repo.local():
433 if not repo.local():
431 raise util.Abort(_("repository '%s' is not local") % path)
434 raise util.Abort(_("repository '%s' is not local") % path)
432 ui.setconfig("bundle", "mainreporoot", repo.root)
435 ui.setconfig("bundle", "mainreporoot", repo.root)
433 except error.RepoError:
436 except error.RepoError:
434 if cmd not in commands.optionalrepo.split():
437 if cmd not in commands.optionalrepo.split():
435 if args and not path: # try to infer -R from command args
438 if args and not path: # try to infer -R from command args
436 repos = map(_findrepo, args)
439 repos = map(_findrepo, args)
437 guess = repos[0]
440 guess = repos[0]
438 if guess and repos.count(guess) == len(repos):
441 if guess and repos.count(guess) == len(repos):
439 return _dispatch(ui, ['--repository', guess] + fullargs)
442 return _dispatch(ui, ['--repository', guess] + fullargs)
440 if not path:
443 if not path:
441 raise error.RepoError(_("There is no Mercurial repository"
444 raise error.RepoError(_("There is no Mercurial repository"
442 " here (.hg not found)"))
445 " here (.hg not found)"))
443 raise
446 raise
444 args.insert(0, repo)
447 args.insert(0, repo)
445 elif rpath:
448 elif rpath:
446 ui.warn("warning: --repository ignored\n")
449 ui.warn("warning: --repository ignored\n")
447
450
448 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
451 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
449 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
452 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
450
453
451 def _runcommand(ui, options, cmd, cmdfunc):
454 def _runcommand(ui, options, cmd, cmdfunc):
452 def checkargs():
455 def checkargs():
453 try:
456 try:
454 return cmdfunc()
457 return cmdfunc()
455 except error.SignatureError:
458 except error.SignatureError:
456 raise error.ParseError(cmd, _("invalid arguments"))
459 raise error.ParseError(cmd, _("invalid arguments"))
457
460
458 if options['profile']:
461 if options['profile']:
459 format = ui.config('profiling', 'format', default='text')
462 format = ui.config('profiling', 'format', default='text')
460
463
461 if not format in ['text', 'kcachegrind']:
464 if not format in ['text', 'kcachegrind']:
462 ui.warn(_("unrecognized profiling format '%s'"
465 ui.warn(_("unrecognized profiling format '%s'"
463 " - Ignored\n") % format)
466 " - Ignored\n") % format)
464 format = 'text'
467 format = 'text'
465
468
466 output = ui.config('profiling', 'output')
469 output = ui.config('profiling', 'output')
467
470
468 if output:
471 if output:
469 path = os.path.expanduser(output)
472 path = os.path.expanduser(output)
470 path = ui.expandpath(path)
473 path = ui.expandpath(path)
471 ostream = open(path, 'wb')
474 ostream = open(path, 'wb')
472 else:
475 else:
473 ostream = sys.stderr
476 ostream = sys.stderr
474
477
475 try:
478 try:
476 from mercurial import lsprof
479 from mercurial import lsprof
477 except ImportError:
480 except ImportError:
478 raise util.Abort(_(
481 raise util.Abort(_(
479 'lsprof not available - install from '
482 'lsprof not available - install from '
480 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
483 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
481 p = lsprof.Profiler()
484 p = lsprof.Profiler()
482 p.enable(subcalls=True)
485 p.enable(subcalls=True)
483 try:
486 try:
484 return checkargs()
487 return checkargs()
485 finally:
488 finally:
486 p.disable()
489 p.disable()
487
490
488 if format == 'kcachegrind':
491 if format == 'kcachegrind':
489 import lsprofcalltree
492 import lsprofcalltree
490 calltree = lsprofcalltree.KCacheGrind(p)
493 calltree = lsprofcalltree.KCacheGrind(p)
491 calltree.output(ostream)
494 calltree.output(ostream)
492 else:
495 else:
493 # format == 'text'
496 # format == 'text'
494 stats = lsprof.Stats(p.getstats())
497 stats = lsprof.Stats(p.getstats())
495 stats.sort()
498 stats.sort()
496 stats.pprint(top=10, file=ostream, climit=5)
499 stats.pprint(top=10, file=ostream, climit=5)
497
500
498 if output:
501 if output:
499 ostream.close()
502 ostream.close()
500 else:
503 else:
501 return checkargs()
504 return checkargs()
@@ -1,18 +1,24 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 mkdir t
3 mkdir t
4 cd t
4 cd t
5 hg init
5 hg init
6 echo "invalid" > .hg/hgrc
6 echo "invalid" > .hg/hgrc
7 hg status 2>&1 |sed -e "s:/.*\(/t/.*\):...\1:"
7 hg status 2>&1 |sed -e "s:/.*\(/t/.*\):...\1:"
8
8
9 #issue 1199, escaping
9 #issue 1199, escaping
10
10
11 cd ..
11 cd ..
12 hg init "foo%bar"
12 hg init "foo%bar"
13 hg clone "foo%bar" foobar
13 hg clone "foo%bar" foobar
14 p=`pwd`
14 p=`pwd`
15 cd foobar
15 cd foobar
16 cat .hg/hgrc |sed -e "s:$p:...:"
16 cat .hg/hgrc |sed -e "s:$p:...:"
17 hg paths |sed -e "s:$p:...:"
17 hg paths |sed -e "s:$p:...:"
18 hg showconfig |sed -e "s:$p:...:"
18 hg showconfig |sed -e "s:$p:...:"
19
20 # issue1829: wrong indentation
21 cd ..
22 echo '[foo]' >> $HGRCPATH
23 echo ' x = y' >> $HGRCPATH
24 hg version 2>&1 | sed -e "s|$HGRCPATH|\$HGRCPATH|"
@@ -1,12 +1,13 b''
1 hg: config error at .../t/.hg/hgrc:1: 'invalid'
1 hg: config error at .../t/.hg/hgrc:1: 'invalid'
2 updating working directory
2 updating working directory
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 [paths]
4 [paths]
5 default = .../foo%bar
5 default = .../foo%bar
6 default = .../foo%bar
6 default = .../foo%bar
7 bundle.mainreporoot=.../foobar
7 bundle.mainreporoot=.../foobar
8 defaults.backout=-d "0 0"
8 defaults.backout=-d "0 0"
9 defaults.commit=-d "0 0"
9 defaults.commit=-d "0 0"
10 defaults.tag=-d "0 0"
10 defaults.tag=-d "0 0"
11 paths.default=.../foo%bar
11 paths.default=.../foo%bar
12 ui.slash=True
12 ui.slash=True
13 hg: config error at $HGRCPATH:8: ' x = y'
General Comments 0
You need to be logged in to leave comments. Login now