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