##// END OF EJS Templates
dispatch: sort exception handlers
Matt Mackall -
r7645:020a896a default
parent child Browse files
Show More
@@ -1,412 +1,413
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
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 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, lock, fancyopts, extensions, hook, error
10 import util, commands, hg, lock, fancyopts, extensions, hook, error
11 import cmdutil
11 import cmdutil
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(traceback='--traceback' in args)
21 u = _ui.ui(traceback='--traceback' in args)
22 except util.Abort, inst:
22 except util.Abort, inst:
23 sys.stderr.write(_("abort: %s\n") % inst)
23 sys.stderr.write(_("abort: %s\n") % inst)
24 return -1
24 return -1
25 return _runcatch(u, args)
25 return _runcatch(u, args)
26
26
27 def _runcatch(ui, args):
27 def _runcatch(ui, args):
28 def catchterm(*args):
28 def catchterm(*args):
29 raise error.SignalInterrupt
29 raise error.SignalInterrupt
30
30
31 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
31 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
32 num = getattr(signal, name, None)
32 num = getattr(signal, name, None)
33 if num: signal.signal(num, catchterm)
33 if num: signal.signal(num, catchterm)
34
34
35 try:
35 try:
36 try:
36 try:
37 # enter the debugger before command execution
37 # enter the debugger before command execution
38 if '--debugger' in args:
38 if '--debugger' in args:
39 pdb.set_trace()
39 pdb.set_trace()
40 try:
40 try:
41 return _dispatch(ui, args)
41 return _dispatch(ui, args)
42 finally:
42 finally:
43 ui.flush()
43 ui.flush()
44 except:
44 except:
45 # enter the debugger when we hit an exception
45 # enter the debugger when we hit an exception
46 if '--debugger' in args:
46 if '--debugger' in args:
47 pdb.post_mortem(sys.exc_info()[2])
47 pdb.post_mortem(sys.exc_info()[2])
48 ui.print_exc()
48 ui.print_exc()
49 raise
49 raise
50
50
51 except error.ParseError, inst:
51 # Global exception handling, alphabetically
52 if inst.args[0]:
52 # Mercurial-specific first, followed by built-in and library exceptions
53 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
54 commands.help_(ui, inst.args[0])
55 else:
56 ui.warn(_("hg: %s\n") % inst.args[1])
57 commands.help_(ui, 'shortlist')
58 except error.AmbiguousCommand, inst:
53 except error.AmbiguousCommand, inst:
59 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
54 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
60 (inst.args[0], " ".join(inst.args[1])))
55 (inst.args[0], " ".join(inst.args[1])))
61 except error.UnknownCommand, inst:
62 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
63 commands.help_(ui, 'shortlist')
64 except error.RepoError, inst:
65 ui.warn(_("abort: %s!\n") % inst)
66 except error.LockHeld, inst:
56 except error.LockHeld, inst:
67 if inst.errno == errno.ETIMEDOUT:
57 if inst.errno == errno.ETIMEDOUT:
68 reason = _('timed out waiting for lock held by %s') % inst.locker
58 reason = _('timed out waiting for lock held by %s') % inst.locker
69 else:
59 else:
70 reason = _('lock held by %s') % inst.locker
60 reason = _('lock held by %s') % inst.locker
71 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
61 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
72 except error.LockUnavailable, inst:
62 except error.LockUnavailable, inst:
73 ui.warn(_("abort: could not lock %s: %s\n") %
63 ui.warn(_("abort: could not lock %s: %s\n") %
74 (inst.desc or inst.filename, inst.strerror))
64 (inst.desc or inst.filename, inst.strerror))
65 except error.ParseError, inst:
66 if inst.args[0]:
67 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
68 commands.help_(ui, inst.args[0])
69 else:
70 ui.warn(_("hg: %s\n") % inst.args[1])
71 commands.help_(ui, 'shortlist')
72 except error.RepoError, inst:
73 ui.warn(_("abort: %s!\n") % inst)
74 except error.ResponseError, inst:
75 ui.warn(_("abort: %s") % inst.args[0])
76 if not isinstance(inst.args[1], basestring):
77 ui.warn(" %r\n" % (inst.args[1],))
78 elif not inst.args[1]:
79 ui.warn(_(" empty string\n"))
80 else:
81 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
75 except error.RevlogError, inst:
82 except error.RevlogError, inst:
76 ui.warn(_("abort: %s!\n") % inst)
83 ui.warn(_("abort: %s!\n") % inst)
77 except error.SignalInterrupt:
84 except error.SignalInterrupt:
78 ui.warn(_("killed!\n"))
85 ui.warn(_("killed!\n"))
79 except KeyboardInterrupt:
86 except error.UnknownCommand, inst:
80 try:
87 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
81 ui.warn(_("interrupted!\n"))
88 commands.help_(ui, 'shortlist')
82 except IOError, inst:
89 except util.Abort, inst:
83 if inst.errno == errno.EPIPE:
90 ui.warn(_("abort: %s\n") % inst)
84 if ui.debugflag:
91 except ImportError, inst:
85 ui.warn(_("\nbroken pipe\n"))
92 m = str(inst).split()[-1]
86 else:
93 ui.warn(_("abort: could not import module %s!\n") % m)
87 raise
94 if m in "mpatch bdiff".split():
88 except socket.error, inst:
95 ui.warn(_("(did you forget to compile extensions?)\n"))
89 ui.warn(_("abort: %s\n") % inst.args[-1])
96 elif m in "zlib".split():
97 ui.warn(_("(is your Python install correct?)\n"))
90 except IOError, inst:
98 except IOError, inst:
91 if hasattr(inst, "code"):
99 if hasattr(inst, "code"):
92 ui.warn(_("abort: %s\n") % inst)
100 ui.warn(_("abort: %s\n") % inst)
93 elif hasattr(inst, "reason"):
101 elif hasattr(inst, "reason"):
94 try: # usually it is in the form (errno, strerror)
102 try: # usually it is in the form (errno, strerror)
95 reason = inst.reason.args[1]
103 reason = inst.reason.args[1]
96 except: # it might be anything, for example a string
104 except: # it might be anything, for example a string
97 reason = inst.reason
105 reason = inst.reason
98 ui.warn(_("abort: error: %s\n") % reason)
106 ui.warn(_("abort: error: %s\n") % reason)
99 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
107 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
100 if ui.debugflag:
108 if ui.debugflag:
101 ui.warn(_("broken pipe\n"))
109 ui.warn(_("broken pipe\n"))
102 elif getattr(inst, "strerror", None):
110 elif getattr(inst, "strerror", None):
103 if getattr(inst, "filename", None):
111 if getattr(inst, "filename", None):
104 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
112 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
105 else:
113 else:
106 ui.warn(_("abort: %s\n") % inst.strerror)
114 ui.warn(_("abort: %s\n") % inst.strerror)
107 else:
115 else:
108 raise
116 raise
109 except OSError, inst:
117 except OSError, inst:
110 if getattr(inst, "filename", None):
118 if getattr(inst, "filename", None):
111 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
119 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
112 else:
120 else:
113 ui.warn(_("abort: %s\n") % inst.strerror)
121 ui.warn(_("abort: %s\n") % inst.strerror)
114 except error.ResponseError, inst:
122 except KeyboardInterrupt:
115 ui.warn(_("abort: %s") % inst.args[0])
123 try:
116 if not isinstance(inst.args[1], basestring):
124 ui.warn(_("interrupted!\n"))
117 ui.warn(" %r\n" % (inst.args[1],))
125 except IOError, inst:
118 elif not inst.args[1]:
126 if inst.errno == errno.EPIPE:
119 ui.warn(_(" empty string\n"))
127 if ui.debugflag:
128 ui.warn(_("\nbroken pipe\n"))
120 else:
129 else:
121 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
130 raise
122 except ImportError, inst:
123 m = str(inst).split()[-1]
124 ui.warn(_("abort: could not import module %s!\n") % m)
125 if m in "mpatch bdiff".split():
126 ui.warn(_("(did you forget to compile extensions?)\n"))
127 elif m in "zlib".split():
128 ui.warn(_("(is your Python install correct?)\n"))
129
130 except util.Abort, inst:
131 ui.warn(_("abort: %s\n") % inst)
132 except MemoryError:
131 except MemoryError:
133 ui.warn(_("abort: out of memory\n"))
132 ui.warn(_("abort: out of memory\n"))
134 except SystemExit, inst:
133 except SystemExit, inst:
135 # Commands shouldn't sys.exit directly, but give a return code.
134 # Commands shouldn't sys.exit directly, but give a return code.
136 # Just in case catch this and and pass exit code to caller.
135 # Just in case catch this and and pass exit code to caller.
137 return inst.code
136 return inst.code
137 except socket.error, inst:
138 ui.warn(_("abort: %s\n") % inst.args[-1])
138 except:
139 except:
139 ui.warn(_("** unknown exception encountered, details follow\n"))
140 ui.warn(_("** unknown exception encountered, details follow\n"))
140 ui.warn(_("** report bug details to "
141 ui.warn(_("** report bug details to "
141 "http://www.selenic.com/mercurial/bts\n"))
142 "http://www.selenic.com/mercurial/bts\n"))
142 ui.warn(_("** or mercurial@selenic.com\n"))
143 ui.warn(_("** or mercurial@selenic.com\n"))
143 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
144 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
144 % util.version())
145 % util.version())
145 ui.warn(_("** Extensions loaded: %s\n")
146 ui.warn(_("** Extensions loaded: %s\n")
146 % ", ".join([x[0] for x in extensions.extensions()]))
147 % ", ".join([x[0] for x in extensions.extensions()]))
147 raise
148 raise
148
149
149 return -1
150 return -1
150
151
151 def _findrepo(p):
152 def _findrepo(p):
152 while not os.path.isdir(os.path.join(p, ".hg")):
153 while not os.path.isdir(os.path.join(p, ".hg")):
153 oldp, p = p, os.path.dirname(p)
154 oldp, p = p, os.path.dirname(p)
154 if p == oldp:
155 if p == oldp:
155 return None
156 return None
156
157
157 return p
158 return p
158
159
159 def _parse(ui, args):
160 def _parse(ui, args):
160 options = {}
161 options = {}
161 cmdoptions = {}
162 cmdoptions = {}
162
163
163 try:
164 try:
164 args = fancyopts.fancyopts(args, commands.globalopts, options)
165 args = fancyopts.fancyopts(args, commands.globalopts, options)
165 except fancyopts.getopt.GetoptError, inst:
166 except fancyopts.getopt.GetoptError, inst:
166 raise error.ParseError(None, inst)
167 raise error.ParseError(None, inst)
167
168
168 if args:
169 if args:
169 cmd, args = args[0], args[1:]
170 cmd, args = args[0], args[1:]
170 aliases, i = cmdutil.findcmd(cmd, commands.table,
171 aliases, i = cmdutil.findcmd(cmd, commands.table,
171 ui.config("ui", "strict"))
172 ui.config("ui", "strict"))
172 cmd = aliases[0]
173 cmd = aliases[0]
173 defaults = ui.config("defaults", cmd)
174 defaults = ui.config("defaults", cmd)
174 if defaults:
175 if defaults:
175 args = shlex.split(defaults) + args
176 args = shlex.split(defaults) + args
176 c = list(i[1])
177 c = list(i[1])
177 else:
178 else:
178 cmd = None
179 cmd = None
179 c = []
180 c = []
180
181
181 # combine global options into local
182 # combine global options into local
182 for o in commands.globalopts:
183 for o in commands.globalopts:
183 c.append((o[0], o[1], options[o[1]], o[3]))
184 c.append((o[0], o[1], options[o[1]], o[3]))
184
185
185 try:
186 try:
186 args = fancyopts.fancyopts(args, c, cmdoptions)
187 args = fancyopts.fancyopts(args, c, cmdoptions)
187 except fancyopts.getopt.GetoptError, inst:
188 except fancyopts.getopt.GetoptError, inst:
188 raise error.ParseError(cmd, inst)
189 raise error.ParseError(cmd, inst)
189
190
190 # separate global options back out
191 # separate global options back out
191 for o in commands.globalopts:
192 for o in commands.globalopts:
192 n = o[1]
193 n = o[1]
193 options[n] = cmdoptions[n]
194 options[n] = cmdoptions[n]
194 del cmdoptions[n]
195 del cmdoptions[n]
195
196
196 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
197 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
197
198
198 def _parseconfig(config):
199 def _parseconfig(config):
199 """parse the --config options from the command line"""
200 """parse the --config options from the command line"""
200 parsed = []
201 parsed = []
201 for cfg in config:
202 for cfg in config:
202 try:
203 try:
203 name, value = cfg.split('=', 1)
204 name, value = cfg.split('=', 1)
204 section, name = name.split('.', 1)
205 section, name = name.split('.', 1)
205 if not section or not name:
206 if not section or not name:
206 raise IndexError
207 raise IndexError
207 parsed.append((section, name, value))
208 parsed.append((section, name, value))
208 except (IndexError, ValueError):
209 except (IndexError, ValueError):
209 raise util.Abort(_('malformed --config option: %s') % cfg)
210 raise util.Abort(_('malformed --config option: %s') % cfg)
210 return parsed
211 return parsed
211
212
212 def _earlygetopt(aliases, args):
213 def _earlygetopt(aliases, args):
213 """Return list of values for an option (or aliases).
214 """Return list of values for an option (or aliases).
214
215
215 The values are listed in the order they appear in args.
216 The values are listed in the order they appear in args.
216 The options and values are removed from args.
217 The options and values are removed from args.
217 """
218 """
218 try:
219 try:
219 argcount = args.index("--")
220 argcount = args.index("--")
220 except ValueError:
221 except ValueError:
221 argcount = len(args)
222 argcount = len(args)
222 shortopts = [opt for opt in aliases if len(opt) == 2]
223 shortopts = [opt for opt in aliases if len(opt) == 2]
223 values = []
224 values = []
224 pos = 0
225 pos = 0
225 while pos < argcount:
226 while pos < argcount:
226 if args[pos] in aliases:
227 if args[pos] in aliases:
227 if pos + 1 >= argcount:
228 if pos + 1 >= argcount:
228 # ignore and let getopt report an error if there is no value
229 # ignore and let getopt report an error if there is no value
229 break
230 break
230 del args[pos]
231 del args[pos]
231 values.append(args.pop(pos))
232 values.append(args.pop(pos))
232 argcount -= 2
233 argcount -= 2
233 elif args[pos][:2] in shortopts:
234 elif args[pos][:2] in shortopts:
234 # short option can have no following space, e.g. hg log -Rfoo
235 # short option can have no following space, e.g. hg log -Rfoo
235 values.append(args.pop(pos)[2:])
236 values.append(args.pop(pos)[2:])
236 argcount -= 1
237 argcount -= 1
237 else:
238 else:
238 pos += 1
239 pos += 1
239 return values
240 return values
240
241
241 _loaded = {}
242 _loaded = {}
242 def _dispatch(ui, args):
243 def _dispatch(ui, args):
243 # read --config before doing anything else
244 # read --config before doing anything else
244 # (e.g. to change trust settings for reading .hg/hgrc)
245 # (e.g. to change trust settings for reading .hg/hgrc)
245 config = _earlygetopt(['--config'], args)
246 config = _earlygetopt(['--config'], args)
246 if config:
247 if config:
247 ui.updateopts(config=_parseconfig(config))
248 ui.updateopts(config=_parseconfig(config))
248
249
249 # check for cwd
250 # check for cwd
250 cwd = _earlygetopt(['--cwd'], args)
251 cwd = _earlygetopt(['--cwd'], args)
251 if cwd:
252 if cwd:
252 os.chdir(cwd[-1])
253 os.chdir(cwd[-1])
253
254
254 # read the local repository .hgrc into a local ui object
255 # read the local repository .hgrc into a local ui object
255 path = _findrepo(os.getcwd()) or ""
256 path = _findrepo(os.getcwd()) or ""
256 if not path:
257 if not path:
257 lui = ui
258 lui = ui
258 if path:
259 if path:
259 try:
260 try:
260 lui = _ui.ui(parentui=ui)
261 lui = _ui.ui(parentui=ui)
261 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
262 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
262 except IOError:
263 except IOError:
263 pass
264 pass
264
265
265 # now we can expand paths, even ones in .hg/hgrc
266 # now we can expand paths, even ones in .hg/hgrc
266 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
267 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
267 if rpath:
268 if rpath:
268 path = lui.expandpath(rpath[-1])
269 path = lui.expandpath(rpath[-1])
269 lui = _ui.ui(parentui=ui)
270 lui = _ui.ui(parentui=ui)
270 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
271 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
271
272
272 extensions.loadall(lui)
273 extensions.loadall(lui)
273 for name, module in extensions.extensions():
274 for name, module in extensions.extensions():
274 if name in _loaded:
275 if name in _loaded:
275 continue
276 continue
276
277
277 # setup extensions
278 # setup extensions
278 # TODO this should be generalized to scheme, where extensions can
279 # TODO this should be generalized to scheme, where extensions can
279 # redepend on other extensions. then we should toposort them, and
280 # redepend on other extensions. then we should toposort them, and
280 # do initialization in correct order
281 # do initialization in correct order
281 extsetup = getattr(module, 'extsetup', None)
282 extsetup = getattr(module, 'extsetup', None)
282 if extsetup:
283 if extsetup:
283 extsetup()
284 extsetup()
284
285
285 cmdtable = getattr(module, 'cmdtable', {})
286 cmdtable = getattr(module, 'cmdtable', {})
286 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
287 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
287 if overrides:
288 if overrides:
288 ui.warn(_("extension '%s' overrides commands: %s\n")
289 ui.warn(_("extension '%s' overrides commands: %s\n")
289 % (name, " ".join(overrides)))
290 % (name, " ".join(overrides)))
290 commands.table.update(cmdtable)
291 commands.table.update(cmdtable)
291 _loaded[name] = 1
292 _loaded[name] = 1
292 # check for fallback encoding
293 # check for fallback encoding
293 fallback = lui.config('ui', 'fallbackencoding')
294 fallback = lui.config('ui', 'fallbackencoding')
294 if fallback:
295 if fallback:
295 util._fallbackencoding = fallback
296 util._fallbackencoding = fallback
296
297
297 fullargs = args
298 fullargs = args
298 cmd, func, args, options, cmdoptions = _parse(lui, args)
299 cmd, func, args, options, cmdoptions = _parse(lui, args)
299
300
300 if options["config"]:
301 if options["config"]:
301 raise util.Abort(_("Option --config may not be abbreviated!"))
302 raise util.Abort(_("Option --config may not be abbreviated!"))
302 if options["cwd"]:
303 if options["cwd"]:
303 raise util.Abort(_("Option --cwd may not be abbreviated!"))
304 raise util.Abort(_("Option --cwd may not be abbreviated!"))
304 if options["repository"]:
305 if options["repository"]:
305 raise util.Abort(_(
306 raise util.Abort(_(
306 "Option -R has to be separated from other options (i.e. not -qR) "
307 "Option -R has to be separated from other options (i.e. not -qR) "
307 "and --repository may only be abbreviated as --repo!"))
308 "and --repository may only be abbreviated as --repo!"))
308
309
309 if options["encoding"]:
310 if options["encoding"]:
310 util._encoding = options["encoding"]
311 util._encoding = options["encoding"]
311 if options["encodingmode"]:
312 if options["encodingmode"]:
312 util._encodingmode = options["encodingmode"]
313 util._encodingmode = options["encodingmode"]
313 if options["time"]:
314 if options["time"]:
314 def get_times():
315 def get_times():
315 t = os.times()
316 t = os.times()
316 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
317 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
317 t = (t[0], t[1], t[2], t[3], time.clock())
318 t = (t[0], t[1], t[2], t[3], time.clock())
318 return t
319 return t
319 s = get_times()
320 s = get_times()
320 def print_time():
321 def print_time():
321 t = get_times()
322 t = get_times()
322 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
323 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
323 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
324 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
324 atexit.register(print_time)
325 atexit.register(print_time)
325
326
326 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
327 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
327 not options["noninteractive"], options["traceback"])
328 not options["noninteractive"], options["traceback"])
328
329
329 if options['help']:
330 if options['help']:
330 return commands.help_(ui, cmd, options['version'])
331 return commands.help_(ui, cmd, options['version'])
331 elif options['version']:
332 elif options['version']:
332 return commands.version_(ui)
333 return commands.version_(ui)
333 elif not cmd:
334 elif not cmd:
334 return commands.help_(ui, 'shortlist')
335 return commands.help_(ui, 'shortlist')
335
336
336 repo = None
337 repo = None
337 if cmd not in commands.norepo.split():
338 if cmd not in commands.norepo.split():
338 try:
339 try:
339 repo = hg.repository(ui, path=path)
340 repo = hg.repository(ui, path=path)
340 ui = repo.ui
341 ui = repo.ui
341 if not repo.local():
342 if not repo.local():
342 raise util.Abort(_("repository '%s' is not local") % path)
343 raise util.Abort(_("repository '%s' is not local") % path)
343 ui.setconfig("bundle", "mainreporoot", repo.root)
344 ui.setconfig("bundle", "mainreporoot", repo.root)
344 except error.RepoError:
345 except error.RepoError:
345 if cmd not in commands.optionalrepo.split():
346 if cmd not in commands.optionalrepo.split():
346 if args and not path: # try to infer -R from command args
347 if args and not path: # try to infer -R from command args
347 repos = map(_findrepo, args)
348 repos = map(_findrepo, args)
348 guess = repos[0]
349 guess = repos[0]
349 if guess and repos.count(guess) == len(repos):
350 if guess and repos.count(guess) == len(repos):
350 return _dispatch(ui, ['--repository', guess] + fullargs)
351 return _dispatch(ui, ['--repository', guess] + fullargs)
351 if not path:
352 if not path:
352 raise error.RepoError(_("There is no Mercurial repository"
353 raise error.RepoError(_("There is no Mercurial repository"
353 " here (.hg not found)"))
354 " here (.hg not found)"))
354 raise
355 raise
355 args.insert(0, repo)
356 args.insert(0, repo)
356
357
357 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
358 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
358
359
359 # run pre-hook, and abort if it fails
360 # run pre-hook, and abort if it fails
360 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
361 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
361 if ret:
362 if ret:
362 return ret
363 return ret
363 ret = _runcommand(ui, options, cmd, d)
364 ret = _runcommand(ui, options, cmd, d)
364 # run post-hook, passing command result
365 # run post-hook, passing command result
365 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
366 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
366 result = ret)
367 result = ret)
367 return ret
368 return ret
368
369
369 def _runcommand(ui, options, cmd, cmdfunc):
370 def _runcommand(ui, options, cmd, cmdfunc):
370 def checkargs():
371 def checkargs():
371 try:
372 try:
372 return cmdfunc()
373 return cmdfunc()
373 except util.SignatureError:
374 except util.SignatureError:
374 raise error.ParseError(cmd, _("invalid arguments"))
375 raise error.ParseError(cmd, _("invalid arguments"))
375
376
376 if options['profile']:
377 if options['profile']:
377 import hotshot, hotshot.stats
378 import hotshot, hotshot.stats
378 prof = hotshot.Profile("hg.prof")
379 prof = hotshot.Profile("hg.prof")
379 try:
380 try:
380 try:
381 try:
381 return prof.runcall(checkargs)
382 return prof.runcall(checkargs)
382 except:
383 except:
383 try:
384 try:
384 ui.warn(_('exception raised - generating '
385 ui.warn(_('exception raised - generating '
385 'profile anyway\n'))
386 'profile anyway\n'))
386 except:
387 except:
387 pass
388 pass
388 raise
389 raise
389 finally:
390 finally:
390 prof.close()
391 prof.close()
391 stats = hotshot.stats.load("hg.prof")
392 stats = hotshot.stats.load("hg.prof")
392 stats.strip_dirs()
393 stats.strip_dirs()
393 stats.sort_stats('time', 'calls')
394 stats.sort_stats('time', 'calls')
394 stats.print_stats(40)
395 stats.print_stats(40)
395 elif options['lsprof']:
396 elif options['lsprof']:
396 try:
397 try:
397 from mercurial import lsprof
398 from mercurial import lsprof
398 except ImportError:
399 except ImportError:
399 raise util.Abort(_(
400 raise util.Abort(_(
400 'lsprof not available - install from '
401 'lsprof not available - install from '
401 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
402 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
402 p = lsprof.Profiler()
403 p = lsprof.Profiler()
403 p.enable(subcalls=True)
404 p.enable(subcalls=True)
404 try:
405 try:
405 return checkargs()
406 return checkargs()
406 finally:
407 finally:
407 p.disable()
408 p.disable()
408 stats = lsprof.Stats(p.getstats())
409 stats = lsprof.Stats(p.getstats())
409 stats.sort()
410 stats.sort()
410 stats.pprint(top=10, file=sys.stderr, climit=5)
411 stats.pprint(top=10, file=sys.stderr, climit=5)
411 else:
412 else:
412 return checkargs()
413 return checkargs()
General Comments 0
You need to be logged in to leave comments. Login now