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