##// END OF EJS Templates
win32mbcs: allow win32mbcs extension to be enabled on cygwin platform...
win32mbcs: allow win32mbcs extension to be enabled on cygwin platform this patch allows win32mbcs extension to be enabled on cygwin platform for problematic character encodings. on recent cygwin platform, even though "os.path.supports_unicode_filenames" is False, "os.listdir()" and other path manipulation functions can return the result correctly decoded in unicode for invocations with unicode arguments, if locale is configured properly. existing code to check "os.path.supports_unicode_filenames" is kept to prevent win32mbcs from being enabled on unexpected platform.

File last commit:

r15632:c9913ef7 default
r15724:9e6a13c2 default
Show More
dispatch.py
737 lines | 25.2 KiB | text/x-python | PythonLexer
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 # dispatch.py - command dispatching for mercurial
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
from i18n import _
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
Peter Arrenbrecht
cleanup: drop unused imports
r7873 import util, commands, hg, fancyopts, extensions, hook, error
Matt Mackall
move encoding bits from util to encoding...
r7948 import cmdutil, encoding
Benoit Boissinot
style: use consistent variable names (*mod) with imports which would shadow
r10651 import ui as uimod
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 class request(object):
Idan Kamara
dispatch: add I/O descriptors to the request
r14613 def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None):
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 self.args = args
Idan Kamara
dispatch: use the request to store the ui object...
r14439 self.ui = ui
Idan Kamara
dispatch: add repo to the request...
r14510 self.repo = repo
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438
Idan Kamara
dispatch: add I/O descriptors to the request
r14613 # input/output/error streams
self.fin = fin
self.fout = fout
self.ferr = ferr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def run():
"run the command in sys.argv"
Mads Kiilerich
dispatch: exit with 8-bit exit code...
r15439 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 def dispatch(req):
"run the command specified in req.args"
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 if req.ferr:
ferr = req.ferr
elif req.ui:
ferr = req.ui.ferr
else:
ferr = sys.stderr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 if not req.ui:
req.ui = uimod.ui()
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--traceback' in req.args:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 req.ui.setconfig('ui', 'traceback', 'on')
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615
# set ui streams from the request
if req.fin:
req.ui.fin = req.fin
if req.fout:
req.ui.fout = req.fout
if req.ferr:
req.ui.ferr = req.ferr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except util.Abort, inst:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("abort: %s\n") % inst)
Benoit Boissinot
Abort: add a hint argument, printed in the next line inside parenthesis...
r11574 if inst.hint:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 return -1
Matt Mackall
error: add new ParseError for various parsing errors
r11288 except error.ParseError, inst:
if len(inst.args) > 1:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("hg: parse error at %s: %s\n") %
Matt Mackall
error: add new ParseError for various parsing errors
r11288 (inst.args[1], inst.args[0]))
else:
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
Martin Geisler
dispatch: catch ConfigError while constructing ui
r9470 return -1
Idan Kamara
dispatch: assign I/O descriptors from the request to the ui
r14615
Idan Kamara
dispatch: use the request to store the ui object...
r14439 return _runcatch(req)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: use the request to store the ui object...
r14439 def _runcatch(req):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def catchterm(*args):
Matt Mackall
error: move SignalInterrupt...
r7644 raise error.SignalInterrupt
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: use the request to store the ui object...
r14439 ui = req.ui
Simon Heimberg
dispatch: ignore if signals can not be set...
r10952 try:
for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
num = getattr(signal, name, None)
if num:
signal.signal(num, catchterm)
except ValueError:
pass # happens if called in a thread
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
try:
try:
# enter the debugger before command execution
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--debugger' in req.args:
Mads Kiilerich
debugger: give a little intro before entering pdb
r11495 ui.warn(_("entering debugger - "
"type c to continue starting hg or h for help\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 pdb.set_trace()
try:
Idan Kamara
dispatch: use the request to store the ui object...
r14439 return _dispatch(req)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 finally:
ui.flush()
except:
# enter the debugger when we hit an exception
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 if '--debugger' in req.args:
Mads Kiilerich
debugger: show traceback before entering pdb post-mortem
r11494 traceback.print_exc()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 pdb.post_mortem(sys.exc_info()[2])
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
Matt Mackall
dispatch: sort exception handlers
r7645 # Global exception handling, alphabetically
# Mercurial-specific first, followed by built-in and library exceptions
Matt Mackall
error: move UnknownCommand and AmbiguousCommand
r7643 except error.AmbiguousCommand, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
(inst.args[0], " ".join(inst.args[1])))
Matt Mackall
error: add new ParseError for various parsing errors
r11288 except error.ParseError, inst:
if len(inst.args) > 1:
ui.warn(_("hg: parse error at %s: %s\n") %
(inst.args[1], inst.args[0]))
else:
ui.warn(_("hg: parse error: %s\n") % inst.args[0])
return -1
Matt Mackall
error: move lock errors...
r7640 except error.LockHeld, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if inst.errno == errno.ETIMEDOUT:
reason = _('timed out waiting for lock held by %s') % inst.locker
else:
reason = _('lock held by %s') % inst.locker
ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
Matt Mackall
error: move lock errors...
r7640 except error.LockUnavailable, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: could not lock %s: %s\n") %
(inst.desc or inst.filename, inst.strerror))
Matt Mackall
error: change ParseError to CommandError
r11287 except error.CommandError, inst:
Matt Mackall
dispatch: sort exception handlers
r7645 if inst.args[0]:
ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
Martin Geisler
help: add -c/--command flag to only show command help (issue2799)
r14286 commands.help_(ui, inst.args[0], full=False, command=True)
Matt Mackall
dispatch: sort exception handlers
r7645 else:
ui.warn(_("hg: %s\n") % inst.args[1])
commands.help_(ui, 'shortlist')
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 except error.OutOfBandError, inst:
Mads Kiilerich
add missing localization markup
r15497 ui.warn(_("abort: remote error:\n"))
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 ui.warn(''.join(inst.args))
Matt Mackall
dispatch: sort exception handlers
r7645 except error.RepoError, inst:
ui.warn(_("abort: %s!\n") % inst)
Pierre-Yves David
error: Add a hint argument to RepoError...
r14761 if inst.hint:
ui.warn(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: sort exception handlers
r7645 except error.ResponseError, inst:
ui.warn(_("abort: %s") % inst.args[0])
if not isinstance(inst.args[1], basestring):
ui.warn(" %r\n" % (inst.args[1],))
elif not inst.args[1]:
ui.warn(_(" empty string\n"))
else:
ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
Matt Mackall
errors: move revlog errors...
r7633 except error.RevlogError, inst:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: %s!\n") % inst)
Matt Mackall
error: move SignalInterrupt...
r7644 except error.SignalInterrupt:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("killed!\n"))
Matt Mackall
dispatch: sort exception handlers
r7645 except error.UnknownCommand, inst:
ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
Brodie Rao
dispatch: provide help for disabled extensions and commands...
r10364 try:
# check if the command is in a disabled extension
# (but don't check for extensions themselves)
commands.help_(ui, inst.args[0], unknowncmd=True)
except error.UnknownCommand:
commands.help_(ui, 'shortlist')
Matt Mackall
dispatch: sort exception handlers
r7645 except util.Abort, inst:
ui.warn(_("abort: %s\n") % inst)
Benoit Boissinot
Abort: add a hint argument, printed in the next line inside parenthesis...
r11574 if inst.hint:
Patrick Mezard
dispatch: write Abort hint to stderr too
r11683 ui.warn(_("(%s)\n") % inst.hint)
Matt Mackall
dispatch: sort exception handlers
r7645 except ImportError, inst:
Dan Villiom Podlaski Christiansen
dispatch: don't mangle ImportError abort messages...
r11053 ui.warn(_("abort: %s!\n") % inst)
Matt Mackall
dispatch: sort exception handlers
r7645 m = str(inst).split()[-1]
if m in "mpatch bdiff".split():
ui.warn(_("(did you forget to compile extensions?)\n"))
elif m in "zlib".split():
ui.warn(_("(is your Python install correct?)\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except IOError, inst:
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if util.safehasattr(inst, "code"):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("abort: %s\n") % inst)
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 elif util.safehasattr(inst, "reason"):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try: # usually it is in the form (errno, strerror)
reason = inst.reason.args[1]
Dan Villiom Podlaski Christiansen
dispatch: handle IndexErrors
r14096 except (AttributeError, IndexError):
# it might be anything, for example a string
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 reason = inst.reason
ui.warn(_("abort: error: %s\n") % reason)
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if ui.debugflag:
ui.warn(_("broken pipe\n"))
elif getattr(inst, "strerror", None):
if getattr(inst, "filename", None):
ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
else:
ui.warn(_("abort: %s\n") % inst.strerror)
else:
raise
except OSError, inst:
if getattr(inst, "filename", None):
ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
else:
ui.warn(_("abort: %s\n") % inst.strerror)
Matt Mackall
dispatch: sort exception handlers
r7645 except KeyboardInterrupt:
try:
ui.warn(_("interrupted!\n"))
except IOError, inst:
if inst.errno == errno.EPIPE:
if ui.debugflag:
ui.warn(_("\nbroken pipe\n"))
else:
raise
Matt Mackall
dispatch: report OOM rather than traceback
r5633 except MemoryError:
ui.warn(_("abort: out of memory\n"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except SystemExit, inst:
# Commands shouldn't sys.exit directly, but give a return code.
# Just in case catch this and and pass exit code to caller.
return inst.code
Matt Mackall
dispatch: sort exception handlers
r7645 except socket.error, inst:
ui.warn(_("abort: %s\n") % inst.args[-1])
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except:
Matt Mackall
traceback: point to BugTracker on the wiki
r12831 ui.warn(_("** unknown exception encountered,"
" please report by visiting\n"))
ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
Martin Geisler
dispatch: include Python version in traceback
r11206 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
Matt Mackall
refactor version code...
r7632 % util.version())
Benoit Boissinot
show extensions loaded on traceback
r6985 ui.warn(_("** Extensions loaded: %s\n")
% ", ".join([x[0] for x in extensions.extensions()]))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
return -1
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 def aliasargs(fn, givenargs):
args = getattr(fn, 'args', [])
if args and givenargs:
cmd = ' '.join(map(util.shellquote, args))
nums = []
def replacer(m):
num = int(m.group(1)) - 1
nums.append(num)
return givenargs[num]
cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
givenargs = [x for i, x in enumerate(givenargs)
if i not in nums]
args = shlex.split(cmd)
return args + givenargs
Brendan Cully
Move alias into core
r8655
class cmdalias(object):
def __init__(self, name, definition, cmdtable):
Brodie Rao
alias: make shadowing behavior more consistent (issue2054)...
r12039 self.name = self.cmd = name
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 self.cmdname = ''
Brendan Cully
Move alias into core
r8655 self.definition = definition
self.args = []
self.opts = []
self.help = ''
self.norepo = True
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = False
Brendan Cully
Move alias into core
r8655
try:
Brodie Rao
alias: make shadowing behavior more consistent (issue2054)...
r12039 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
for alias, e in cmdtable.iteritems():
if e is entry:
self.cmd = alias
break
Brendan Cully
Move alias into core
r8655 self.shadows = True
except error.UnknownCommand:
self.shadows = False
if not self.definition:
def fn(ui, *args):
ui.warn(_("no definition for alias '%s'\n") % self.name)
return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655 return
Steve Losh
dispatch: add shell aliases...
r11524 if self.definition.startswith('!'):
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 self.shell = True
Steve Losh
dispatch: add shell aliases...
r11524 def fn(ui, *args):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 env = {'HG_ARGS': ' '.join((self.name,) + args)}
def _checkvar(m):
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 if m.groups()[0] == '$':
return m.group()
elif int(m.groups()[0]) <= len(args):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return m.group()
else:
David Soria Parra
i18n: remove translation of debug messages
r14708 ui.debug("No argument found for substitution "
"of %i variable in alias '%s' definition."
Roman Sokolov
dispatch: debug message for missing arguments in shell alias...
r13393 % (int(m.groups()[0]), self.name))
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return ''
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
replace['0'] = self.name
replace['@'] = ' '.join(args)
Roman Sokolov
dispatch: support for $ escaping in shell-alias definition...
r13392 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
Idan Kamara
dispatch: write shell alias output to ui out descriptor
r14640 return util.system(cmd, environ=env, out=ui.fout)
Steve Losh
dispatch: add shell aliases...
r11524 self.fn = fn
return
Brendan Cully
Move alias into core
r8655 args = shlex.split(self.definition)
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 self.cmdname = cmd = args.pop(0)
Alexander Solovyov
expand paths in aliases
r10793 args = map(util.expandpath, args)
Brendan Cully
Move alias into core
r8655
Dan Villiom Podlaski Christiansen
alias: improved diagnostic when arguments include --cwd, etc....
r11695 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
if _earlygetopt([invalidarg], args):
def fn(ui, *args):
ui.warn(_("error in definition for alias '%s': %s may only "
"be given on the command line\n")
% (self.name, invalidarg))
return 1
self.fn = fn
self.badalias = True
return
Brendan Cully
Move alias into core
r8655 try:
Nicolas Dumazet
alias: do not crash when aliased command has no usage help text
r9993 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
if len(tableentry) > 2:
self.fn, self.opts, self.help = tableentry
else:
self.fn, self.opts = tableentry
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 self.args = aliasargs(self.fn, args)
Brendan Cully
Move alias into core
r8655 if cmd not in commands.norepo.split(' '):
self.norepo = False
Peter Arrenbrecht
alias: improve help text for command aliases...
r9876 if self.help.startswith("hg " + cmd):
# drop prefix in old-style help lines so hg shows the alias
self.help = self.help[4 + len(cmd):]
Yuya Nishihara
alias: fixes exception when displaying translated help text...
r10564 self.__doc__ = self.fn.__doc__
Peter Arrenbrecht
alias: improve help text for command aliases...
r9876
Brendan Cully
Move alias into core
r8655 except error.UnknownCommand:
def fn(ui, *args):
ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
% (self.name, cmd))
Brodie Rao
dispatch: provide help for disabled extensions and commands...
r10364 try:
# check if the command is in a disabled extension
commands.help_(ui, cmd, unknowncmd=True)
except error.UnknownCommand:
pass
Brendan Cully
Move alias into core
r8655 return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655 except error.AmbiguousCommand:
def fn(ui, *args):
ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
% (self.name, cmd))
return 1
self.fn = fn
Brodie Rao
help: don't display bogus help messages for invalid aliases
r10021 self.badalias = True
Brendan Cully
Move alias into core
r8655
def __call__(self, ui, *args, **opts):
if self.shadows:
Martin Geisler
Backed out changeset 1ec8bd909ac3...
r14704 ui.debug("alias '%s' shadows command '%s'\n" %
Brodie Rao
alias: print what command is being shadowed in debug message
r12092 (self.name, self.cmdname))
Brendan Cully
Move alias into core
r8655
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if util.safehasattr(self, 'shell'):
Steve Losh
aliases: provide more flexible ways to work with shell alias arguments...
r11989 return self.fn(ui, *args, **opts)
else:
Brodie Rao
alias: on --debug, print expansion when it has invalid arguments
r12093 try:
util.checksignature(self.fn)(ui, *args, **opts)
except error.SignatureError:
args = ' '.join([self.cmdname] + self.args)
Martin Geisler
Backed out changeset 1ec8bd909ac3...
r14704 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
Brodie Rao
alias: on --debug, print expansion when it has invalid arguments
r12093 raise
Brendan Cully
Move alias into core
r8655
def addaliases(ui, cmdtable):
# aliases are processed after extensions have been loaded, so they
# may use extension commands. Aliases can also use other alias definitions,
# but only if they have been defined prior to the current definition.
for alias, definition in ui.configitems('alias'):
aliasdef = cmdalias(alias, definition, cmdtable)
Idan Kamara
dispatch: don't rewrap aliases that have the same definition...
r15019
try:
olddef = cmdtable[aliasdef.cmd][0]
if olddef.definition == aliasdef.definition:
continue
except (KeyError, AttributeError):
# definition might not exist or it might not be a cmdalias
pass
Augie Fackler
alias: don't shadow commands that we only partially matched (issue2993) (BC)...
r15233 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
Brendan Cully
Move alias into core
r8655 if aliasdef.norepo:
commands.norepo += ' %s' % alias
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def _parse(ui, args):
options = {}
cmdoptions = {}
try:
args = fancyopts.fancyopts(args, commands.globalopts, options)
except fancyopts.getopt.GetoptError, inst:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(None, inst)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
if args:
cmd, args = args[0], args[1:]
Henri Wiechers
dispatch: minor refactoring...
r9875 aliases, entry = cmdutil.findcmd(cmd, commands.table,
Thomas Arendsen Hein
Minor cleanup: Add missing space forgotten in recent change.
r7224 ui.config("ui", "strict"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 cmd = aliases[0]
Alexander Solovyov
add positional arguments to non-shell aliases
r14265 args = aliasargs(entry[0], args)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 defaults = ui.config("defaults", cmd)
if defaults:
Alexander Solovyov
make path expanding more consistent...
r9610 args = map(util.expandpath, shlex.split(defaults)) + args
Henri Wiechers
dispatch: minor refactoring...
r9875 c = list(entry[1])
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 else:
cmd = None
c = []
# combine global options into local
for o in commands.globalopts:
c.append((o[0], o[1], options[o[1]], o[3]))
try:
Augie Fackler
fancyopts: Parse options that occur after arguments....
r7772 args = fancyopts.fancyopts(args, c, cmdoptions, True)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except fancyopts.getopt.GetoptError, inst:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(cmd, inst)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
# separate global options back out
for o in commands.globalopts:
n = o[1]
options[n] = cmdoptions[n]
del cmdoptions[n]
Henri Wiechers
dispatch: minor refactoring...
r9875 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Matt Mackall
ui: kill updateopts...
r8137 def _parseconfig(ui, config):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 """parse the --config options from the command line"""
Idan Kamara
dispatch: return read config options
r14753 configs = []
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 for cfg in config:
try:
name, value = cfg.split('=', 1)
section, name = name.split('.', 1)
if not section or not name:
raise IndexError
Matt Mackall
ui: kill updateopts...
r8137 ui.setconfig(section, name, value)
Idan Kamara
dispatch: return read config options
r14753 configs.append((section, name, value))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 except (IndexError, ValueError):
Bill Schroeder
dispatch: better error message for --config option
r9825 raise util.Abort(_('malformed --config option: %r '
'(use --config section.name=value)') % cfg)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Idan Kamara
dispatch: return read config options
r14753 return configs
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 def _earlygetopt(aliases, args):
"""Return list of values for an option (or aliases).
The values are listed in the order they appear in args.
The options and values are removed from args.
"""
try:
argcount = args.index("--")
except ValueError:
argcount = len(args)
shortopts = [opt for opt in aliases if len(opt) == 2]
values = []
pos = 0
while pos < argcount:
if args[pos] in aliases:
if pos + 1 >= argcount:
# ignore and let getopt report an error if there is no value
break
del args[pos]
values.append(args.pop(pos))
argcount -= 2
elif args[pos][:2] in shortopts:
# short option can have no following space, e.g. hg log -Rfoo
values.append(args.pop(pos)[2:])
argcount -= 1
else:
pos += 1
return values
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
Bill Barry
dispatch: extract command execution block into method...
r7819 # run pre-hook, and abort if it fails
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
pats=cmdpats, opts=cmdoptions)
Bill Barry
dispatch: extract command execution block into method...
r7819 if ret:
return ret
ret = _runcommand(ui, options, cmd, d)
# run post-hook, passing command result
hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 result=ret, pats=cmdpats, opts=cmdoptions)
Bill Barry
dispatch: extract command execution block into method...
r7819 return ret
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 def _getlocal(ui, rpath):
"""Return (path, local ui object) for the given target path.
Martin Geisler
check-code: find trailing whitespace
r12770
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 Takes paths in [cwd]/.hg/hgrc into account."
"""
Mads Kiilerich
dispatch: give better error message when cwd doesn't exist (issue2293)...
r11675 try:
wd = os.getcwd()
except OSError, e:
Nicolas Dumazet
dispatch: trailing whitespace
r11712 raise util.Abort(_("error getting current working directory: %s") %
Mads Kiilerich
dispatch: give better error message when cwd doesn't exist (issue2293)...
r11675 e.strerror)
path = cmdutil.findrepo(wd) or ""
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if not path:
lui = ui
Andrey Somov
improve code readability
r9436 else:
Brodie Rao
dispatch: remove superfluous try/except when reading local ui config...
r12636 lui = ui.copy()
Brodie Rao
dispatch: properly handle relative path aliases used with -R (issue2376)...
r12637 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Matt Mackall
dispatch: fix checking of rpath in _getlocal...
r14860 if rpath and rpath[-1]:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 path = lui.expandpath(rpath[-1])
Matt Mackall
ui: kill most users of parentui name and arg, replace with .copy()
r8190 lui = ui.copy()
Brodie Rao
dispatch: properly handle relative path aliases used with -R (issue2376)...
r12637 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 return path, lui
Matt Mackall
alias: pass local ui to shell alias...
r14888 def _checkshellalias(lui, ui, args):
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 norepo = commands.norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 options = {}
Steve Losh
alias: fail gracefully when invalid global options are given (issue2442)...
r12748
try:
args = fancyopts.fancyopts(args, commands.globalopts, options)
except fancyopts.getopt.GetoptError:
return
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
if not args:
return
cmdtable = commands.table.copy()
addaliases(lui, cmdtable)
cmd = args[0]
try:
aliases, entry = cmdutil.findcmd(cmd, cmdtable, lui.config("ui", "strict"))
Steve Losh
alias: fall back to normal error handling for ambigious commands (fixes issue2475)
r12932 except (error.AmbiguousCommand, error.UnknownCommand):
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 commands.norepo = norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 return
cmd = aliases[0]
fn = entry[0]
Augie Fackler
dispatch: use safehasattr instead of hasattr
r14950 if cmd and util.safehasattr(fn, 'shell'):
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 d = lambda: fn(ui, *args[1:])
return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
Steve Losh
alias: back up and restore commands.norepo before checking for shell aliases
r12633 commands.norepo = norepo
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
_loaded = set()
Idan Kamara
dispatch: use the request to store the ui object...
r14439 def _dispatch(req):
Idan Kamara
dispatch: wrap dispatch related information in a request class...
r14438 args = req.args
Idan Kamara
dispatch: use the request to store the ui object...
r14439 ui = req.ui
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536 # read --config before doing anything else
# (e.g. to change trust settings for reading .hg/hgrc)
Idan Kamara
dispatch: set config options on the request repo.ui
r14754 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
Steve Losh
alias: only allow global options before a shell alias, pass later ones through...
r12536
# check for cwd
cwd = _earlygetopt(['--cwd'], args)
if cwd:
os.chdir(cwd[-1])
rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
path, lui = _getlocal(ui, rpath)
Matt Mackall
dispatch: move shell alias handling after early arg handling...
r14886 # Now that we're operating in the right directory/repository with
# the right config settings, check for shell aliases
Matt Mackall
alias: pass local ui to shell alias...
r14888 shellaliasfn = _checkshellalias(lui, ui, args)
Matt Mackall
dispatch: move shell alias handling after early arg handling...
r14886 if shellaliasfn:
return shellaliasfn()
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
# reposetup. Programs like TortoiseHg will call _dispatch several
# times so we keep track of configured extensions in _loaded.
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 extensions.loadall(lui)
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 # Propagate any changes to lui.__class__ by extensions
ui.__class__ = lui.__class__
Kirill Smelkov
dispatch: allow extensions to provide setup code...
r5828
Yuya Nishihara
extensions: changed to call extsetup() from extensions.loadall()...
r9660 # (uisetup and extsetup are handled in extensions.loadall)
Kirill Smelkov
dispatch: allow extensions to provide setup code...
r5828
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 for name, module in exts:
Alexis S. L. Carvalho
Move cmdtable and reposetup handling out of extensions.py...
r5192 cmdtable = getattr(module, 'cmdtable', {})
overrides = [cmd for cmd in cmdtable if cmd in commands.table]
if overrides:
ui.warn(_("extension '%s' overrides commands: %s\n")
% (name, " ".join(overrides)))
commands.table.update(cmdtable)
Martin Geisler
dispatch: remember loaded extensions in a real set
r8304 _loaded.add(name)
Brendan Cully
Move alias into core
r8655
Martin Geisler
extensions: load and configure extensions in well-defined phases...
r9410 # (reposetup is handled in hg.repository)
Brendan Cully
Move alias into core
r8655 addaliases(lui, commands.table)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 # check for fallback encoding
fallback = lui.config('ui', 'fallbackencoding')
if fallback:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.fallbackencoding = fallback
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
fullargs = args
cmd, func, args, options, cmdoptions = _parse(lui, args)
if options["config"]:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_("option --config may not be abbreviated!"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["cwd"]:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_("option --cwd may not be abbreviated!"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["repository"]:
raise util.Abort(_(
Sune Foldager
translated a bunch of strings to danish
r8911 "Option -R has to be separated from other options (e.g. not -qR) "
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 "and --repository may only be abbreviated as --repo!"))
if options["encoding"]:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.encoding = options["encoding"]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["encodingmode"]:
Matt Mackall
move encoding bits from util to encoding...
r7948 encoding.encodingmode = options["encodingmode"]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options["time"]:
def get_times():
t = os.times()
if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
t = (t[0], t[1], t[2], t[3], time.clock())
return t
s = get_times()
def print_time():
t = get_times()
ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
(t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
atexit.register(print_time)
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 uis = set([ui, lui])
if req.repo:
uis.add(req.repo.ui)
Idan Kamara
dispatch: set config options on the request repo.ui
r14754 # copy configs that were passed on the cmdline (--config) to the repo ui
for cfg in cfgs:
req.repo.ui.setconfig(*cfg)
Idan Kamara
dispatch: make sure global options on the command line take precedence...
r14992 if options['verbose'] or options['debug'] or options['quiet']:
for opt in ('verbose', 'debug', 'quiet'):
val = str(bool(options[opt]))
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: make sure global options on the command line take precedence...
r14992 ui_.setconfig('ui', opt, val)
if options['traceback']:
for ui_ in uis:
ui_.setconfig('ui', 'traceback', 'on')
Idan Kamara
dispatch: make sure unspecified global ui options don't override old values
r14748
Matt Mackall
ui: refactor option setting...
r8136 if options['noninteractive']:
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: fix for-loop variable name
r14618 ui_.setconfig('ui', 'interactive', 'off')
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Yuya Nishihara
url: add --insecure option to bypass verification of ssl certificates...
r13328 if cmdoptions.get('insecure', False):
Idan Kamara
dispatch: set global options on the request repo.ui...
r14752 for ui_ in uis:
Idan Kamara
dispatch: fix for-loop variable name
r14618 ui_.setconfig('web', 'cacerts', '')
Yuya Nishihara
url: add --insecure option to bypass verification of ssl certificates...
r13328
Matt Mackall
help: drop with_version...
r15020 if options['version']:
return commands.version_(ui)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if options['help']:
Matt Mackall
help: drop with_version...
r15020 return commands.help_(ui, cmd)
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 elif not cmd:
return commands.help_(ui, 'shortlist')
repo = None
Chad Dombrova
provide pre- and post- hooks with parsed command line arguments....
r11330 cmdpats = args[:]
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 if cmd not in commands.norepo.split():
Idan Kamara
dispatch: add repo to the request...
r14510 # use the repo from the request only if we don't have -R
Idan Kamara
dispatch: don't use request repo if we have --cwd
r14863 if not rpath and not cwd:
Idan Kamara
dispatch: add repo to the request...
r14510 repo = req.repo
Idan Kamara
dispatch: set descriptors on the request repo.ui
r14744 if repo:
# set the descriptors of the repo ui to those of ui
repo.ui.fin = ui.fin
repo.ui.fout = ui.fout
repo.ui.ferr = ui.ferr
else:
Idan Kamara
dispatch: add repo to the request...
r14510 try:
repo = hg.repository(ui, path=path)
if not repo.local():
raise util.Abort(_("repository '%s' is not local") % path)
Idan Kamara
dispatch: pass the correct ui to runcommand...
r14743 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
Idan Kamara
dispatch: add repo to the request...
r14510 except error.RequirementError:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 raise
Idan Kamara
dispatch: add repo to the request...
r14510 except error.RepoError:
if cmd not in commands.optionalrepo.split():
if args and not path: # try to infer -R from command args
repos = map(cmdutil.findrepo, args)
guess = repos[0]
if guess and repos.count(guess) == len(repos):
req.args = ['--repository', guess] + fullargs
return _dispatch(req)
if not path:
David Golub
dispatch: avoid double backslashes in error message...
r14914 raise error.RepoError(_("no repository found in '%s'"
Idan Kamara
dispatch: add repo to the request...
r14510 " (.hg not found)") % os.getcwd())
raise
Idan Kamara
dispatch: pass the correct ui to runcommand...
r14743 if repo:
ui = repo.ui
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388 args.insert(0, repo)
Matt Mackall
warn if --repository provided for norepo commands
r7733 elif rpath:
Martin Geisler
mark ui.warn strings for translation
r11600 ui.warn(_("warning: --repository ignored\n"))
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388
Matt Mackall
log: add logging for commands
r11985 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
ui.log("command", msg + "\n")
Matt Mackall
dispatch: generalize signature checking for extension command wrapping
r7388 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
Adrian Buehlmann
Make sure bundlerepo doesn't leak temp files (issue2491)...
r13382 try:
return runcommand(lui, repo, cmd, fullargs, ui, options, d,
cmdpats, cmdoptions)
finally:
Idan Kamara
dispatch: check for None before closing repo...
r14727 if repo and repo != req.repo:
Adrian Buehlmann
Make sure bundlerepo doesn't leak temp files (issue2491)...
r13382 repo.close()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
def _runcommand(ui, options, cmd, cmdfunc):
def checkargs():
try:
return cmdfunc()
Matt Mackall
error: move SignatureError
r7646 except error.SignatureError:
Matt Mackall
error: change ParseError to CommandError
r11287 raise error.CommandError(cmd, _("invalid arguments"))
Matt Mackall
dispatch: move command dispatching into its own module...
r5178
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 if options['profile']:
Nicolas Dumazet
profiling: Adding a profiling.format config variable...
r8023 format = ui.config('profiling', 'format', default='text')
Nicolas Dumazet
profiling: Adding support for kcachegrind output format, using lsprofcalltree
r8024 if not format in ['text', 'kcachegrind']:
Nicolas Dumazet
profiling: Adding a profiling.format config variable...
r8023 ui.warn(_("unrecognized profiling format '%s'"
" - Ignored\n") % format)
format = 'text'
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022 output = ui.config('profiling', 'output')
if output:
Alexander Solovyov
make path expanding more consistent...
r9610 path = ui.expandpath(output)
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022 ostream = open(path, 'wb')
else:
ostream = sys.stderr
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 try:
from mercurial import lsprof
except ImportError:
raise util.Abort(_(
'lsprof not available - install from '
'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
p = lsprof.Profiler()
p.enable(subcalls=True)
try:
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 return checkargs()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 finally:
p.disable()
Nicolas Dumazet
profiling: Adding support for kcachegrind output format, using lsprofcalltree
r8024
if format == 'kcachegrind':
import lsprofcalltree
calltree = lsprofcalltree.KCacheGrind(p)
calltree.output(ostream)
else:
# format == 'text'
stats = lsprof.Stats(p.getstats())
stats.sort()
stats.pprint(top=10, file=ostream, climit=5)
Nicolas Dumazet
profiling: Adding profiling.output config variable...
r8022
if output:
ostream.close()
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 else:
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 return checkargs()