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