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