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