##// END OF EJS Templates
a socket error might be a tuple or a singleton
Benoit Boissinot -
r6993:b9d012ce default
parent child Browse files
Show More
@@ -1,417 +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 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 raise
149 raise
150
150
151 return -1
151 return -1
152
152
153 def _findrepo(p):
153 def _findrepo(p):
154 while not os.path.isdir(os.path.join(p, ".hg")):
154 while not os.path.isdir(os.path.join(p, ".hg")):
155 oldp, p = p, os.path.dirname(p)
155 oldp, p = p, os.path.dirname(p)
156 if p == oldp:
156 if p == oldp:
157 return None
157 return None
158
158
159 return p
159 return p
160
160
161 def _parse(ui, args):
161 def _parse(ui, args):
162 options = {}
162 options = {}
163 cmdoptions = {}
163 cmdoptions = {}
164
164
165 try:
165 try:
166 args = fancyopts.fancyopts(args, commands.globalopts, options)
166 args = fancyopts.fancyopts(args, commands.globalopts, options)
167 except fancyopts.getopt.GetoptError, inst:
167 except fancyopts.getopt.GetoptError, inst:
168 raise ParseError(None, inst)
168 raise ParseError(None, inst)
169
169
170 if args:
170 if args:
171 cmd, args = args[0], args[1:]
171 cmd, args = args[0], args[1:]
172 aliases, i = cmdutil.findcmd(ui, cmd, commands.table)
172 aliases, i = cmdutil.findcmd(ui, cmd, commands.table)
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)
187 args = fancyopts.fancyopts(args, c, cmdoptions)
188 except fancyopts.getopt.GetoptError, inst:
188 except fancyopts.getopt.GetoptError, inst:
189 raise ParseError(cmd, inst)
189 raise 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 _loaded = {}
242 _loaded = {}
243 def _dispatch(ui, args):
243 def _dispatch(ui, args):
244 # read --config before doing anything else
244 # read --config before doing anything else
245 # (e.g. to change trust settings for reading .hg/hgrc)
245 # (e.g. to change trust settings for reading .hg/hgrc)
246 config = _earlygetopt(['--config'], args)
246 config = _earlygetopt(['--config'], args)
247 if config:
247 if config:
248 ui.updateopts(config=_parseconfig(config))
248 ui.updateopts(config=_parseconfig(config))
249
249
250 # check for cwd
250 # check for cwd
251 cwd = _earlygetopt(['--cwd'], args)
251 cwd = _earlygetopt(['--cwd'], args)
252 if cwd:
252 if cwd:
253 os.chdir(cwd[-1])
253 os.chdir(cwd[-1])
254
254
255 # read the local repository .hgrc into a local ui object
255 # read the local repository .hgrc into a local ui object
256 path = _findrepo(os.getcwd()) or ""
256 path = _findrepo(os.getcwd()) or ""
257 if not path:
257 if not path:
258 lui = ui
258 lui = ui
259 if path:
259 if path:
260 try:
260 try:
261 lui = _ui.ui(parentui=ui)
261 lui = _ui.ui(parentui=ui)
262 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
262 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
263 except IOError:
263 except IOError:
264 pass
264 pass
265
265
266 # now we can expand paths, even ones in .hg/hgrc
266 # now we can expand paths, even ones in .hg/hgrc
267 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
267 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
268 if rpath:
268 if rpath:
269 path = lui.expandpath(rpath[-1])
269 path = lui.expandpath(rpath[-1])
270 lui = _ui.ui(parentui=ui)
270 lui = _ui.ui(parentui=ui)
271 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
271 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
272
272
273 extensions.loadall(lui)
273 extensions.loadall(lui)
274 for name, module in extensions.extensions():
274 for name, module in extensions.extensions():
275 if name in _loaded:
275 if name in _loaded:
276 continue
276 continue
277
277
278 # setup extensions
278 # setup extensions
279 # TODO this should be generalized to scheme, where extensions can
279 # TODO this should be generalized to scheme, where extensions can
280 # redepend on other extensions. then we should toposort them, and
280 # redepend on other extensions. then we should toposort them, and
281 # do initialization in correct order
281 # do initialization in correct order
282 extsetup = getattr(module, 'extsetup', None)
282 extsetup = getattr(module, 'extsetup', None)
283 if extsetup:
283 if extsetup:
284 extsetup()
284 extsetup()
285
285
286 cmdtable = getattr(module, 'cmdtable', {})
286 cmdtable = getattr(module, 'cmdtable', {})
287 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
287 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
288 if overrides:
288 if overrides:
289 ui.warn(_("extension '%s' overrides commands: %s\n")
289 ui.warn(_("extension '%s' overrides commands: %s\n")
290 % (name, " ".join(overrides)))
290 % (name, " ".join(overrides)))
291 commands.table.update(cmdtable)
291 commands.table.update(cmdtable)
292 _loaded[name] = 1
292 _loaded[name] = 1
293 # check for fallback encoding
293 # check for fallback encoding
294 fallback = lui.config('ui', 'fallbackencoding')
294 fallback = lui.config('ui', 'fallbackencoding')
295 if fallback:
295 if fallback:
296 util._fallbackencoding = fallback
296 util._fallbackencoding = fallback
297
297
298 fullargs = args
298 fullargs = args
299 cmd, func, args, options, cmdoptions = _parse(lui, args)
299 cmd, func, args, options, cmdoptions = _parse(lui, args)
300
300
301 if options["config"]:
301 if options["config"]:
302 raise util.Abort(_("Option --config may not be abbreviated!"))
302 raise util.Abort(_("Option --config may not be abbreviated!"))
303 if options["cwd"]:
303 if options["cwd"]:
304 raise util.Abort(_("Option --cwd may not be abbreviated!"))
304 raise util.Abort(_("Option --cwd may not be abbreviated!"))
305 if options["repository"]:
305 if options["repository"]:
306 raise util.Abort(_(
306 raise util.Abort(_(
307 "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) "
308 "and --repository may only be abbreviated as --repo!"))
308 "and --repository may only be abbreviated as --repo!"))
309
309
310 if options["encoding"]:
310 if options["encoding"]:
311 util._encoding = options["encoding"]
311 util._encoding = options["encoding"]
312 if options["encodingmode"]:
312 if options["encodingmode"]:
313 util._encodingmode = options["encodingmode"]
313 util._encodingmode = options["encodingmode"]
314 if options["time"]:
314 if options["time"]:
315 def get_times():
315 def get_times():
316 t = os.times()
316 t = os.times()
317 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()
318 t = (t[0], t[1], t[2], t[3], time.clock())
318 t = (t[0], t[1], t[2], t[3], time.clock())
319 return t
319 return t
320 s = get_times()
320 s = get_times()
321 def print_time():
321 def print_time():
322 t = get_times()
322 t = get_times()
323 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") %
324 (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]))
325 atexit.register(print_time)
325 atexit.register(print_time)
326
326
327 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
327 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
328 not options["noninteractive"], options["traceback"])
328 not options["noninteractive"], options["traceback"])
329
329
330 if options['help']:
330 if options['help']:
331 return commands.help_(ui, cmd, options['version'])
331 return commands.help_(ui, cmd, options['version'])
332 elif options['version']:
332 elif options['version']:
333 return commands.version_(ui)
333 return commands.version_(ui)
334 elif not cmd:
334 elif not cmd:
335 return commands.help_(ui, 'shortlist')
335 return commands.help_(ui, 'shortlist')
336
336
337 repo = None
337 repo = None
338 if cmd not in commands.norepo.split():
338 if cmd not in commands.norepo.split():
339 try:
339 try:
340 repo = hg.repository(ui, path=path)
340 repo = hg.repository(ui, path=path)
341 ui = repo.ui
341 ui = repo.ui
342 if not repo.local():
342 if not repo.local():
343 raise util.Abort(_("repository '%s' is not local") % path)
343 raise util.Abort(_("repository '%s' is not local") % path)
344 ui.setconfig("bundle", "mainreporoot", repo.root)
344 ui.setconfig("bundle", "mainreporoot", repo.root)
345 except RepoError:
345 except RepoError:
346 if cmd not in commands.optionalrepo.split():
346 if cmd not in commands.optionalrepo.split():
347 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
348 repos = map(_findrepo, args)
348 repos = map(_findrepo, args)
349 guess = repos[0]
349 guess = repos[0]
350 if guess and repos.count(guess) == len(repos):
350 if guess and repos.count(guess) == len(repos):
351 return _dispatch(ui, ['--repository', guess] + fullargs)
351 return _dispatch(ui, ['--repository', guess] + fullargs)
352 if not path:
352 if not path:
353 raise RepoError(_("There is no Mercurial repository here"
353 raise RepoError(_("There is no Mercurial repository here"
354 " (.hg not found)"))
354 " (.hg not found)"))
355 raise
355 raise
356 d = lambda: func(ui, repo, *args, **cmdoptions)
356 d = lambda: func(ui, repo, *args, **cmdoptions)
357 else:
357 else:
358 d = lambda: func(ui, *args, **cmdoptions)
358 d = lambda: func(ui, *args, **cmdoptions)
359
359
360 # run pre-hook, and abort if it fails
360 # run pre-hook, and abort if it fails
361 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))
362 if ret:
362 if ret:
363 return ret
363 return ret
364 ret = _runcommand(ui, options, cmd, d)
364 ret = _runcommand(ui, options, cmd, d)
365 # run post-hook, passing command result
365 # run post-hook, passing command result
366 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
366 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
367 result = ret)
367 result = ret)
368 return ret
368 return ret
369
369
370 def _runcommand(ui, options, cmd, cmdfunc):
370 def _runcommand(ui, options, cmd, cmdfunc):
371 def checkargs():
371 def checkargs():
372 try:
372 try:
373 return cmdfunc()
373 return cmdfunc()
374 except TypeError, inst:
374 except TypeError, inst:
375 # was this an argument error?
375 # was this an argument error?
376 tb = traceback.extract_tb(sys.exc_info()[2])
376 tb = traceback.extract_tb(sys.exc_info()[2])
377 if len(tb) != 2: # no
377 if len(tb) != 2: # no
378 raise
378 raise
379 raise ParseError(cmd, _("invalid arguments"))
379 raise ParseError(cmd, _("invalid arguments"))
380
380
381 if options['profile']:
381 if options['profile']:
382 import hotshot, hotshot.stats
382 import hotshot, hotshot.stats
383 prof = hotshot.Profile("hg.prof")
383 prof = hotshot.Profile("hg.prof")
384 try:
384 try:
385 try:
385 try:
386 return prof.runcall(checkargs)
386 return prof.runcall(checkargs)
387 except:
387 except:
388 try:
388 try:
389 ui.warn(_('exception raised - generating '
389 ui.warn(_('exception raised - generating '
390 'profile anyway\n'))
390 'profile anyway\n'))
391 except:
391 except:
392 pass
392 pass
393 raise
393 raise
394 finally:
394 finally:
395 prof.close()
395 prof.close()
396 stats = hotshot.stats.load("hg.prof")
396 stats = hotshot.stats.load("hg.prof")
397 stats.strip_dirs()
397 stats.strip_dirs()
398 stats.sort_stats('time', 'calls')
398 stats.sort_stats('time', 'calls')
399 stats.print_stats(40)
399 stats.print_stats(40)
400 elif options['lsprof']:
400 elif options['lsprof']:
401 try:
401 try:
402 from mercurial import lsprof
402 from mercurial import lsprof
403 except ImportError:
403 except ImportError:
404 raise util.Abort(_(
404 raise util.Abort(_(
405 'lsprof not available - install from '
405 'lsprof not available - install from '
406 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
406 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
407 p = lsprof.Profiler()
407 p = lsprof.Profiler()
408 p.enable(subcalls=True)
408 p.enable(subcalls=True)
409 try:
409 try:
410 return checkargs()
410 return checkargs()
411 finally:
411 finally:
412 p.disable()
412 p.disable()
413 stats = lsprof.Stats(p.getstats())
413 stats = lsprof.Stats(p.getstats())
414 stats.sort()
414 stats.sort()
415 stats.pprint(top=10, file=sys.stderr, climit=5)
415 stats.pprint(top=10, file=sys.stderr, climit=5)
416 else:
416 else:
417 return checkargs()
417 return checkargs()
General Comments 0
You need to be logged in to leave comments. Login now