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