##// END OF EJS Templates
dispatch: remove superfluous try/except when reading local ui config...
Brodie Rao -
r12636:c24215aa default
parent child Browse files
Show More
@@ -1,641 +1,638
1 1 # dispatch.py - command dispatching for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import _
9 9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
10 10 import util, commands, hg, fancyopts, extensions, hook, error
11 11 import cmdutil, encoding
12 12 import ui as uimod
13 13
14 14 def run():
15 15 "run the command in sys.argv"
16 16 sys.exit(dispatch(sys.argv[1:]))
17 17
18 18 def dispatch(args):
19 19 "run the command specified in args"
20 20 try:
21 21 u = uimod.ui()
22 22 if '--traceback' in args:
23 23 u.setconfig('ui', 'traceback', 'on')
24 24 except util.Abort, inst:
25 25 sys.stderr.write(_("abort: %s\n") % inst)
26 26 if inst.hint:
27 27 sys.stderr.write("(%s)\n" % inst.hint)
28 28 return -1
29 29 except error.ParseError, inst:
30 30 if len(inst.args) > 1:
31 31 sys.stderr.write(_("hg: parse error at %s: %s\n") %
32 32 (inst.args[1], inst.args[0]))
33 33 else:
34 34 sys.stderr.write(_("hg: parse error: %s\n") % inst.args[0])
35 35 return -1
36 36 return _runcatch(u, args)
37 37
38 38 def _runcatch(ui, args):
39 39 def catchterm(*args):
40 40 raise error.SignalInterrupt
41 41
42 42 try:
43 43 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
44 44 num = getattr(signal, name, None)
45 45 if num:
46 46 signal.signal(num, catchterm)
47 47 except ValueError:
48 48 pass # happens if called in a thread
49 49
50 50 try:
51 51 try:
52 52 # enter the debugger before command execution
53 53 if '--debugger' in args:
54 54 ui.warn(_("entering debugger - "
55 55 "type c to continue starting hg or h for help\n"))
56 56 pdb.set_trace()
57 57 try:
58 58 return _dispatch(ui, args)
59 59 finally:
60 60 ui.flush()
61 61 except:
62 62 # enter the debugger when we hit an exception
63 63 if '--debugger' in args:
64 64 traceback.print_exc()
65 65 pdb.post_mortem(sys.exc_info()[2])
66 66 ui.traceback()
67 67 raise
68 68
69 69 # Global exception handling, alphabetically
70 70 # Mercurial-specific first, followed by built-in and library exceptions
71 71 except error.AmbiguousCommand, inst:
72 72 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
73 73 (inst.args[0], " ".join(inst.args[1])))
74 74 except error.ParseError, inst:
75 75 if len(inst.args) > 1:
76 76 ui.warn(_("hg: parse error at %s: %s\n") %
77 77 (inst.args[1], inst.args[0]))
78 78 else:
79 79 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
80 80 return -1
81 81 except error.LockHeld, inst:
82 82 if inst.errno == errno.ETIMEDOUT:
83 83 reason = _('timed out waiting for lock held by %s') % inst.locker
84 84 else:
85 85 reason = _('lock held by %s') % inst.locker
86 86 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
87 87 except error.LockUnavailable, inst:
88 88 ui.warn(_("abort: could not lock %s: %s\n") %
89 89 (inst.desc or inst.filename, inst.strerror))
90 90 except error.CommandError, inst:
91 91 if inst.args[0]:
92 92 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
93 93 commands.help_(ui, inst.args[0])
94 94 else:
95 95 ui.warn(_("hg: %s\n") % inst.args[1])
96 96 commands.help_(ui, 'shortlist')
97 97 except error.RepoError, inst:
98 98 ui.warn(_("abort: %s!\n") % inst)
99 99 except error.ResponseError, inst:
100 100 ui.warn(_("abort: %s") % inst.args[0])
101 101 if not isinstance(inst.args[1], basestring):
102 102 ui.warn(" %r\n" % (inst.args[1],))
103 103 elif not inst.args[1]:
104 104 ui.warn(_(" empty string\n"))
105 105 else:
106 106 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
107 107 except error.RevlogError, inst:
108 108 ui.warn(_("abort: %s!\n") % inst)
109 109 except error.SignalInterrupt:
110 110 ui.warn(_("killed!\n"))
111 111 except error.UnknownCommand, inst:
112 112 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
113 113 try:
114 114 # check if the command is in a disabled extension
115 115 # (but don't check for extensions themselves)
116 116 commands.help_(ui, inst.args[0], unknowncmd=True)
117 117 except error.UnknownCommand:
118 118 commands.help_(ui, 'shortlist')
119 119 except util.Abort, inst:
120 120 ui.warn(_("abort: %s\n") % inst)
121 121 if inst.hint:
122 122 ui.warn(_("(%s)\n") % inst.hint)
123 123 except ImportError, inst:
124 124 ui.warn(_("abort: %s!\n") % inst)
125 125 m = str(inst).split()[-1]
126 126 if m in "mpatch bdiff".split():
127 127 ui.warn(_("(did you forget to compile extensions?)\n"))
128 128 elif m in "zlib".split():
129 129 ui.warn(_("(is your Python install correct?)\n"))
130 130 except IOError, inst:
131 131 if hasattr(inst, "code"):
132 132 ui.warn(_("abort: %s\n") % inst)
133 133 elif hasattr(inst, "reason"):
134 134 try: # usually it is in the form (errno, strerror)
135 135 reason = inst.reason.args[1]
136 136 except: # it might be anything, for example a string
137 137 reason = inst.reason
138 138 ui.warn(_("abort: error: %s\n") % reason)
139 139 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
140 140 if ui.debugflag:
141 141 ui.warn(_("broken pipe\n"))
142 142 elif getattr(inst, "strerror", None):
143 143 if getattr(inst, "filename", None):
144 144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
145 145 else:
146 146 ui.warn(_("abort: %s\n") % inst.strerror)
147 147 else:
148 148 raise
149 149 except OSError, inst:
150 150 if getattr(inst, "filename", None):
151 151 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
152 152 else:
153 153 ui.warn(_("abort: %s\n") % inst.strerror)
154 154 except KeyboardInterrupt:
155 155 try:
156 156 ui.warn(_("interrupted!\n"))
157 157 except IOError, inst:
158 158 if inst.errno == errno.EPIPE:
159 159 if ui.debugflag:
160 160 ui.warn(_("\nbroken pipe\n"))
161 161 else:
162 162 raise
163 163 except MemoryError:
164 164 ui.warn(_("abort: out of memory\n"))
165 165 except SystemExit, inst:
166 166 # Commands shouldn't sys.exit directly, but give a return code.
167 167 # Just in case catch this and and pass exit code to caller.
168 168 return inst.code
169 169 except socket.error, inst:
170 170 ui.warn(_("abort: %s\n") % inst.args[-1])
171 171 except:
172 172 ui.warn(_("** unknown exception encountered, details follow\n"))
173 173 ui.warn(_("** report bug details to "
174 174 "http://mercurial.selenic.com/bts/\n"))
175 175 ui.warn(_("** or mercurial@selenic.com\n"))
176 176 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
177 177 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
178 178 % util.version())
179 179 ui.warn(_("** Extensions loaded: %s\n")
180 180 % ", ".join([x[0] for x in extensions.extensions()]))
181 181 raise
182 182
183 183 return -1
184 184
185 185 def aliasargs(fn):
186 186 if hasattr(fn, 'args'):
187 187 return fn.args
188 188 return []
189 189
190 190 class cmdalias(object):
191 191 def __init__(self, name, definition, cmdtable):
192 192 self.name = self.cmd = name
193 193 self.cmdname = ''
194 194 self.definition = definition
195 195 self.args = []
196 196 self.opts = []
197 197 self.help = ''
198 198 self.norepo = True
199 199 self.badalias = False
200 200
201 201 try:
202 202 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
203 203 for alias, e in cmdtable.iteritems():
204 204 if e is entry:
205 205 self.cmd = alias
206 206 break
207 207 self.shadows = True
208 208 except error.UnknownCommand:
209 209 self.shadows = False
210 210
211 211 if not self.definition:
212 212 def fn(ui, *args):
213 213 ui.warn(_("no definition for alias '%s'\n") % self.name)
214 214 return 1
215 215 self.fn = fn
216 216 self.badalias = True
217 217
218 218 return
219 219
220 220 if self.definition.startswith('!'):
221 221 self.shell = True
222 222 def fn(ui, *args):
223 223 env = {'HG_ARGS': ' '.join((self.name,) + args)}
224 224 def _checkvar(m):
225 225 if int(m.groups()[0]) <= len(args):
226 226 return m.group()
227 227 else:
228 228 return ''
229 229 cmd = re.sub(r'\$(\d+)', _checkvar, self.definition[1:])
230 230 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
231 231 replace['0'] = self.name
232 232 replace['@'] = ' '.join(args)
233 233 cmd = util.interpolate(r'\$', replace, cmd)
234 234 return util.system(cmd, environ=env)
235 235 self.fn = fn
236 236 return
237 237
238 238 args = shlex.split(self.definition)
239 239 self.cmdname = cmd = args.pop(0)
240 240 args = map(util.expandpath, args)
241 241
242 242 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
243 243 if _earlygetopt([invalidarg], args):
244 244 def fn(ui, *args):
245 245 ui.warn(_("error in definition for alias '%s': %s may only "
246 246 "be given on the command line\n")
247 247 % (self.name, invalidarg))
248 248 return 1
249 249
250 250 self.fn = fn
251 251 self.badalias = True
252 252 return
253 253
254 254 try:
255 255 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
256 256 if len(tableentry) > 2:
257 257 self.fn, self.opts, self.help = tableentry
258 258 else:
259 259 self.fn, self.opts = tableentry
260 260
261 261 self.args = aliasargs(self.fn) + args
262 262 if cmd not in commands.norepo.split(' '):
263 263 self.norepo = False
264 264 if self.help.startswith("hg " + cmd):
265 265 # drop prefix in old-style help lines so hg shows the alias
266 266 self.help = self.help[4 + len(cmd):]
267 267 self.__doc__ = self.fn.__doc__
268 268
269 269 except error.UnknownCommand:
270 270 def fn(ui, *args):
271 271 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
272 272 % (self.name, cmd))
273 273 try:
274 274 # check if the command is in a disabled extension
275 275 commands.help_(ui, cmd, unknowncmd=True)
276 276 except error.UnknownCommand:
277 277 pass
278 278 return 1
279 279 self.fn = fn
280 280 self.badalias = True
281 281 except error.AmbiguousCommand:
282 282 def fn(ui, *args):
283 283 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
284 284 % (self.name, cmd))
285 285 return 1
286 286 self.fn = fn
287 287 self.badalias = True
288 288
289 289 def __call__(self, ui, *args, **opts):
290 290 if self.shadows:
291 291 ui.debug("alias '%s' shadows command '%s'\n" %
292 292 (self.name, self.cmdname))
293 293
294 294 if self.definition.startswith('!'):
295 295 return self.fn(ui, *args, **opts)
296 296 else:
297 297 try:
298 298 util.checksignature(self.fn)(ui, *args, **opts)
299 299 except error.SignatureError:
300 300 args = ' '.join([self.cmdname] + self.args)
301 301 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
302 302 raise
303 303
304 304 def addaliases(ui, cmdtable):
305 305 # aliases are processed after extensions have been loaded, so they
306 306 # may use extension commands. Aliases can also use other alias definitions,
307 307 # but only if they have been defined prior to the current definition.
308 308 for alias, definition in ui.configitems('alias'):
309 309 aliasdef = cmdalias(alias, definition, cmdtable)
310 310 cmdtable[aliasdef.cmd] = (aliasdef, aliasdef.opts, aliasdef.help)
311 311 if aliasdef.norepo:
312 312 commands.norepo += ' %s' % alias
313 313
314 314 def _parse(ui, args):
315 315 options = {}
316 316 cmdoptions = {}
317 317
318 318 try:
319 319 args = fancyopts.fancyopts(args, commands.globalopts, options)
320 320 except fancyopts.getopt.GetoptError, inst:
321 321 raise error.CommandError(None, inst)
322 322
323 323 if args:
324 324 cmd, args = args[0], args[1:]
325 325 aliases, entry = cmdutil.findcmd(cmd, commands.table,
326 326 ui.config("ui", "strict"))
327 327 cmd = aliases[0]
328 328 args = aliasargs(entry[0]) + args
329 329 defaults = ui.config("defaults", cmd)
330 330 if defaults:
331 331 args = map(util.expandpath, shlex.split(defaults)) + args
332 332 c = list(entry[1])
333 333 else:
334 334 cmd = None
335 335 c = []
336 336
337 337 # combine global options into local
338 338 for o in commands.globalopts:
339 339 c.append((o[0], o[1], options[o[1]], o[3]))
340 340
341 341 try:
342 342 args = fancyopts.fancyopts(args, c, cmdoptions, True)
343 343 except fancyopts.getopt.GetoptError, inst:
344 344 raise error.CommandError(cmd, inst)
345 345
346 346 # separate global options back out
347 347 for o in commands.globalopts:
348 348 n = o[1]
349 349 options[n] = cmdoptions[n]
350 350 del cmdoptions[n]
351 351
352 352 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
353 353
354 354 def _parseconfig(ui, config):
355 355 """parse the --config options from the command line"""
356 356 for cfg in config:
357 357 try:
358 358 name, value = cfg.split('=', 1)
359 359 section, name = name.split('.', 1)
360 360 if not section or not name:
361 361 raise IndexError
362 362 ui.setconfig(section, name, value)
363 363 except (IndexError, ValueError):
364 364 raise util.Abort(_('malformed --config option: %r '
365 365 '(use --config section.name=value)') % cfg)
366 366
367 367 def _earlygetopt(aliases, args):
368 368 """Return list of values for an option (or aliases).
369 369
370 370 The values are listed in the order they appear in args.
371 371 The options and values are removed from args.
372 372 """
373 373 try:
374 374 argcount = args.index("--")
375 375 except ValueError:
376 376 argcount = len(args)
377 377 shortopts = [opt for opt in aliases if len(opt) == 2]
378 378 values = []
379 379 pos = 0
380 380 while pos < argcount:
381 381 if args[pos] in aliases:
382 382 if pos + 1 >= argcount:
383 383 # ignore and let getopt report an error if there is no value
384 384 break
385 385 del args[pos]
386 386 values.append(args.pop(pos))
387 387 argcount -= 2
388 388 elif args[pos][:2] in shortopts:
389 389 # short option can have no following space, e.g. hg log -Rfoo
390 390 values.append(args.pop(pos)[2:])
391 391 argcount -= 1
392 392 else:
393 393 pos += 1
394 394 return values
395 395
396 396 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
397 397 # run pre-hook, and abort if it fails
398 398 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
399 399 pats=cmdpats, opts=cmdoptions)
400 400 if ret:
401 401 return ret
402 402 ret = _runcommand(ui, options, cmd, d)
403 403 # run post-hook, passing command result
404 404 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
405 405 result=ret, pats=cmdpats, opts=cmdoptions)
406 406 return ret
407 407
408 408 def _getlocal(ui, rpath):
409 409 """Return (path, local ui object) for the given target path.
410 410
411 411 Takes paths in [cwd]/.hg/hgrc into account."
412 412 """
413 413 try:
414 414 wd = os.getcwd()
415 415 except OSError, e:
416 416 raise util.Abort(_("error getting current working directory: %s") %
417 417 e.strerror)
418 418 path = cmdutil.findrepo(wd) or ""
419 419 if not path:
420 420 lui = ui
421 421 else:
422 try:
423 422 lui = ui.copy()
424 423 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
425 except IOError:
426 pass
427 424
428 425 if rpath:
429 426 path = lui.expandpath(rpath[-1])
430 427 lui = ui.copy()
431 428 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
432 429
433 430 return path, lui
434 431
435 432 def _checkshellalias(ui, args):
436 433 cwd = os.getcwd()
437 434 norepo = commands.norepo
438 435 options = {}
439 436 args = fancyopts.fancyopts(args, commands.globalopts, options)
440 437
441 438 if not args:
442 439 return
443 440
444 441 _parseconfig(ui, options['config'])
445 442 if options['cwd']:
446 443 os.chdir(options['cwd'])
447 444
448 445 path, lui = _getlocal(ui, [options['repository']])
449 446
450 447 cmdtable = commands.table.copy()
451 448 addaliases(lui, cmdtable)
452 449
453 450 cmd = args[0]
454 451 try:
455 452 aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
456 453 except error.UnknownCommand:
457 454 commands.norepo = norepo
458 455 os.chdir(cwd)
459 456 return
460 457
461 458 cmd = aliases[0]
462 459 fn = entry[0]
463 460
464 461 if cmd and hasattr(fn, 'shell'):
465 462 d = lambda: fn(ui, *args[1:])
466 463 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
467 464
468 465 commands.norepo = norepo
469 466 os.chdir(cwd)
470 467
471 468 _loaded = set()
472 469 def _dispatch(ui, args):
473 470 shellaliasfn = _checkshellalias(ui, args)
474 471 if shellaliasfn:
475 472 return shellaliasfn()
476 473
477 474 # read --config before doing anything else
478 475 # (e.g. to change trust settings for reading .hg/hgrc)
479 476 _parseconfig(ui, _earlygetopt(['--config'], args))
480 477
481 478 # check for cwd
482 479 cwd = _earlygetopt(['--cwd'], args)
483 480 if cwd:
484 481 os.chdir(cwd[-1])
485 482
486 483 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
487 484 path, lui = _getlocal(ui, rpath)
488 485
489 486 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
490 487 # reposetup. Programs like TortoiseHg will call _dispatch several
491 488 # times so we keep track of configured extensions in _loaded.
492 489 extensions.loadall(lui)
493 490 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
494 491 # Propagate any changes to lui.__class__ by extensions
495 492 ui.__class__ = lui.__class__
496 493
497 494 # (uisetup and extsetup are handled in extensions.loadall)
498 495
499 496 for name, module in exts:
500 497 cmdtable = getattr(module, 'cmdtable', {})
501 498 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
502 499 if overrides:
503 500 ui.warn(_("extension '%s' overrides commands: %s\n")
504 501 % (name, " ".join(overrides)))
505 502 commands.table.update(cmdtable)
506 503 _loaded.add(name)
507 504
508 505 # (reposetup is handled in hg.repository)
509 506
510 507 addaliases(lui, commands.table)
511 508
512 509 # check for fallback encoding
513 510 fallback = lui.config('ui', 'fallbackencoding')
514 511 if fallback:
515 512 encoding.fallbackencoding = fallback
516 513
517 514 fullargs = args
518 515 cmd, func, args, options, cmdoptions = _parse(lui, args)
519 516
520 517 if options["config"]:
521 518 raise util.Abort(_("option --config may not be abbreviated!"))
522 519 if options["cwd"]:
523 520 raise util.Abort(_("option --cwd may not be abbreviated!"))
524 521 if options["repository"]:
525 522 raise util.Abort(_(
526 523 "Option -R has to be separated from other options (e.g. not -qR) "
527 524 "and --repository may only be abbreviated as --repo!"))
528 525
529 526 if options["encoding"]:
530 527 encoding.encoding = options["encoding"]
531 528 if options["encodingmode"]:
532 529 encoding.encodingmode = options["encodingmode"]
533 530 if options["time"]:
534 531 def get_times():
535 532 t = os.times()
536 533 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
537 534 t = (t[0], t[1], t[2], t[3], time.clock())
538 535 return t
539 536 s = get_times()
540 537 def print_time():
541 538 t = get_times()
542 539 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
543 540 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
544 541 atexit.register(print_time)
545 542
546 543 if options['verbose'] or options['debug'] or options['quiet']:
547 544 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
548 545 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
549 546 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
550 547 if options['traceback']:
551 548 ui.setconfig('ui', 'traceback', 'on')
552 549 if options['noninteractive']:
553 550 ui.setconfig('ui', 'interactive', 'off')
554 551
555 552 if options['help']:
556 553 return commands.help_(ui, cmd, options['version'])
557 554 elif options['version']:
558 555 return commands.version_(ui)
559 556 elif not cmd:
560 557 return commands.help_(ui, 'shortlist')
561 558
562 559 repo = None
563 560 cmdpats = args[:]
564 561 if cmd not in commands.norepo.split():
565 562 try:
566 563 repo = hg.repository(ui, path=path)
567 564 ui = repo.ui
568 565 if not repo.local():
569 566 raise util.Abort(_("repository '%s' is not local") % path)
570 567 ui.setconfig("bundle", "mainreporoot", repo.root)
571 568 except error.RepoError:
572 569 if cmd not in commands.optionalrepo.split():
573 570 if args and not path: # try to infer -R from command args
574 571 repos = map(cmdutil.findrepo, args)
575 572 guess = repos[0]
576 573 if guess and repos.count(guess) == len(repos):
577 574 return _dispatch(ui, ['--repository', guess] + fullargs)
578 575 if not path:
579 576 raise error.RepoError(_("There is no Mercurial repository"
580 577 " here (.hg not found)"))
581 578 raise
582 579 args.insert(0, repo)
583 580 elif rpath:
584 581 ui.warn(_("warning: --repository ignored\n"))
585 582
586 583 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
587 584 ui.log("command", msg + "\n")
588 585 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
589 586 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
590 587 cmdpats, cmdoptions)
591 588
592 589 def _runcommand(ui, options, cmd, cmdfunc):
593 590 def checkargs():
594 591 try:
595 592 return cmdfunc()
596 593 except error.SignatureError:
597 594 raise error.CommandError(cmd, _("invalid arguments"))
598 595
599 596 if options['profile']:
600 597 format = ui.config('profiling', 'format', default='text')
601 598
602 599 if not format in ['text', 'kcachegrind']:
603 600 ui.warn(_("unrecognized profiling format '%s'"
604 601 " - Ignored\n") % format)
605 602 format = 'text'
606 603
607 604 output = ui.config('profiling', 'output')
608 605
609 606 if output:
610 607 path = ui.expandpath(output)
611 608 ostream = open(path, 'wb')
612 609 else:
613 610 ostream = sys.stderr
614 611
615 612 try:
616 613 from mercurial import lsprof
617 614 except ImportError:
618 615 raise util.Abort(_(
619 616 'lsprof not available - install from '
620 617 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
621 618 p = lsprof.Profiler()
622 619 p.enable(subcalls=True)
623 620 try:
624 621 return checkargs()
625 622 finally:
626 623 p.disable()
627 624
628 625 if format == 'kcachegrind':
629 626 import lsprofcalltree
630 627 calltree = lsprofcalltree.KCacheGrind(p)
631 628 calltree.output(ostream)
632 629 else:
633 630 # format == 'text'
634 631 stats = lsprof.Stats(p.getstats())
635 632 stats.sort()
636 633 stats.pprint(top=10, file=ostream, climit=5)
637 634
638 635 if output:
639 636 ostream.close()
640 637 else:
641 638 return checkargs()
General Comments 0
You need to be logged in to leave comments. Login now