mercurial/dispatch.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 11 Jan 2019 13:11:49 -0800
changeset 41193 dd97354b8891
parent 40729 c93d046d4300
child 43076 2372284d9457
permissions -rw-r--r--
dispatch: add newline after ui.log "ui blocked ms" message Differential Revision: https://phab.mercurial-scm.org/D5573
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# dispatch.py - command dispatching for mercurial
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8206
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9993
diff changeset
     6
# GNU General Public License version 2 or any later version.
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
27615
4030d3b79953 dispatch: use print function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27516
diff changeset
     8
from __future__ import absolute_import, print_function
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
     9
24221
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
    10
import difflib
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    11
import errno
30576
541949a10a68 fancyopts: switch from fancyopts.getopt.* to getopt.*
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
    12
import getopt
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    13
import os
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    14
import pdb
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    15
import re
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    16
import signal
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    17
import sys
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    18
import time
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    19
import traceback
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    20
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    21
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    22
from .i18n import _
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    23
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
    24
from hgdemandimport import tracing
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
    25
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    26
from . import (
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    27
    cmdutil,
30653
b2be4ccaff1d color: load 'colortable' from extension using an 'extraloader'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30586
diff changeset
    28
    color,
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    29
    commands,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    30
    demandimport,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    31
    encoding,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    32
    error,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    33
    extensions,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    34
    fancyopts,
31060
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
    35
    help,
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    36
    hg,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    37
    hook,
29781
2654a0aac80d profiling: move profiling code from dispatch.py (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29761
diff changeset
    38
    profiling,
30468
7f2b18c34c02 py3: use pycompat.sysargv in dispatch.run()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30401
diff changeset
    39
    pycompat,
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
    40
    registrar,
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
    41
    scmutil,
25932
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    42
    ui as uimod,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    43
    util,
d491f289045f dispatch: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25834
diff changeset
    44
)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
    46
from .utils import (
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    47
    procutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
    48
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
    49
)
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
    50
14438
08bfec2ef031 dispatch: wrap dispatch related information in a request class
Idan Kamara <idankk86@gmail.com>
parents: 14286
diff changeset
    51
class request(object):
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16609
diff changeset
    52
    def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
40587
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
    53
                 ferr=None, fmsg=None, prereposetups=None):
14438
08bfec2ef031 dispatch: wrap dispatch related information in a request class
Idan Kamara <idankk86@gmail.com>
parents: 14286
diff changeset
    54
        self.args = args
14439
80c599eee3f3 dispatch: use the request to store the ui object
Idan Kamara <idankk86@gmail.com>
parents: 14438
diff changeset
    55
        self.ui = ui
14510
eccbb9980ada dispatch: add repo to the request
Idan Kamara <idankk86@gmail.com>
parents: 14439
diff changeset
    56
        self.repo = repo
14438
08bfec2ef031 dispatch: wrap dispatch related information in a request class
Idan Kamara <idankk86@gmail.com>
parents: 14286
diff changeset
    57
14613
ea8938d3a5aa dispatch: add I/O descriptors to the request
Idan Kamara <idankk86@gmail.com>
parents: 14601
diff changeset
    58
        # input/output/error streams
ea8938d3a5aa dispatch: add I/O descriptors to the request
Idan Kamara <idankk86@gmail.com>
parents: 14601
diff changeset
    59
        self.fin = fin
ea8938d3a5aa dispatch: add I/O descriptors to the request
Idan Kamara <idankk86@gmail.com>
parents: 14601
diff changeset
    60
        self.fout = fout
ea8938d3a5aa dispatch: add I/O descriptors to the request
Idan Kamara <idankk86@gmail.com>
parents: 14601
diff changeset
    61
        self.ferr = ferr
40587
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
    62
        # separate stream for status/error messages
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
    63
        self.fmsg = fmsg
14613
ea8938d3a5aa dispatch: add I/O descriptors to the request
Idan Kamara <idankk86@gmail.com>
parents: 14601
diff changeset
    64
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
    65
        # remember options pre-parsed by _earlyparseopts()
35030
d9aba3730d30 dispatch: abort if early boolean options can't be parsed
Yuya Nishihara <yuya@tcha.org>
parents: 35029
diff changeset
    66
        self.earlyoptions = {}
d9aba3730d30 dispatch: abort if early boolean options can't be parsed
Yuya Nishihara <yuya@tcha.org>
parents: 35029
diff changeset
    67
32379
71e735bd8170 dispatch: make request accept additional reposetups
Jun Wu <quark@fb.com>
parents: 32377
diff changeset
    68
        # reposetups which run before extensions, useful for chg to pre-fill
71e735bd8170 dispatch: make request accept additional reposetups
Jun Wu <quark@fb.com>
parents: 32377
diff changeset
    69
        # low-level repo state (for example, changelog) before extensions.
71e735bd8170 dispatch: make request accept additional reposetups
Jun Wu <quark@fb.com>
parents: 32377
diff changeset
    70
        self.prereposetups = prereposetups or []
71e735bd8170 dispatch: make request accept additional reposetups
Jun Wu <quark@fb.com>
parents: 32377
diff changeset
    71
40402
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
    72
        # store the parsed and canonical command
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
    73
        self.canonical_command = None
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
    74
31956
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    75
    def _runexithandlers(self):
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    76
        exc = None
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    77
        handlers = self.ui._exithandlers
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    78
        try:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    79
            while handlers:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    80
                func, args, kwargs = handlers.pop()
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    81
                try:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    82
                    func(*args, **kwargs)
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    83
                except: # re-raises below
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    84
                    if exc is None:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    85
                        exc = sys.exc_info()[1]
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    86
                    self.ui.warn(('error in exit handlers:\n'))
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    87
                    self.ui.traceback(force=True)
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    88
        finally:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    89
            if exc is not None:
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    90
                raise exc
c13ff31818b0 ui: add special-purpose atexit functionality
Bryan O'Sullivan <bryano@fb.com>
parents: 31629
diff changeset
    91
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
def run():
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
    "run the command in sys.argv"
37944
dc1ed7fe33e4 sshserver: do setbinary() by caller (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37717
diff changeset
    94
    initstdio()
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
    95
    with tracing.log('parse args into request'):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
    96
        req = request(pycompat.sysargv[1:])
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
    97
    err = None
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
    98
    try:
37995
6f9ac3cb0987 dispatch: unify handling of None returned by a command function
Yuya Nishihara <yuya@tcha.org>
parents: 37994
diff changeset
    99
        status = dispatch(req)
34532
b09b3eaf9c96 py3: work around the scope of exception variable in dispatch.run()
Yuya Nishihara <yuya@tcha.org>
parents: 34486
diff changeset
   100
    except error.StdioError as e:
b09b3eaf9c96 py3: work around the scope of exception variable in dispatch.run()
Yuya Nishihara <yuya@tcha.org>
parents: 34486
diff changeset
   101
        err = e
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   102
        status = -1
37994
e9c588802529 dispatch: minor code refactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37944
diff changeset
   103
e9c588802529 dispatch: minor code refactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37944
diff changeset
   104
    # In all cases we try to flush stdio streams.
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   105
    if util.safehasattr(req.ui, 'fout'):
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   106
        try:
32687
12941a782928 dispatch: do not close stdout and stderr, just flush() instead
Yuya Nishihara <yuya@tcha.org>
parents: 32652
diff changeset
   107
            req.ui.fout.flush()
34532
b09b3eaf9c96 py3: work around the scope of exception variable in dispatch.run()
Yuya Nishihara <yuya@tcha.org>
parents: 34486
diff changeset
   108
        except IOError as e:
b09b3eaf9c96 py3: work around the scope of exception variable in dispatch.run()
Yuya Nishihara <yuya@tcha.org>
parents: 34486
diff changeset
   109
            err = e
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   110
            status = -1
37994
e9c588802529 dispatch: minor code refactor
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37944
diff changeset
   111
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   112
    if util.safehasattr(req.ui, 'ferr'):
35653
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   113
        try:
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   114
            if err is not None and err.errno != errno.EPIPE:
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   115
                req.ui.ferr.write('abort: %s\n' %
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   116
                                  encoding.strtolocal(err.strerror))
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   117
            req.ui.ferr.flush()
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   118
        # There's not much we can do about an I/O error here. So (possibly)
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   119
        # change the status code and move on.
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   120
        except IOError:
48fe4f56a3b4 dispatch: handle IOError when writing to stderr
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35466
diff changeset
   121
            status = -1
36637
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   122
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   123
    _silencestdio()
31960
71dcd4a4fa2f stdio: catch StdioError in dispatch.run and clean up appropriately
Bryan O'Sullivan <bryano@fb.com>
parents: 31958
diff changeset
   124
    sys.exit(status & 255)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
36636
c263c684da91 py3: conditionalize initialization of stdio flags
Yuya Nishihara <yuya@tcha.org>
parents: 36503
diff changeset
   126
if pycompat.ispy3:
37944
dc1ed7fe33e4 sshserver: do setbinary() by caller (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37717
diff changeset
   127
    def initstdio():
36636
c263c684da91 py3: conditionalize initialization of stdio flags
Yuya Nishihara <yuya@tcha.org>
parents: 36503
diff changeset
   128
        pass
36637
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   129
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   130
    def _silencestdio():
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   131
        for fp in (sys.stdout, sys.stderr):
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   132
            # Check if the file is okay
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   133
            try:
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   134
                fp.flush()
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   135
                continue
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   136
            except IOError:
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   137
                pass
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   138
            # Otherwise mark it as closed to silence "Exception ignored in"
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   139
            # message emitted by the interpreter finalizer. Be careful to
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   140
            # not close procutil.stdout, which may be a fdopen-ed file object
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   141
            # and its close() actually closes the underlying file descriptor.
36637
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   142
            try:
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   143
                fp.close()
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   144
            except IOError:
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   145
                pass
36636
c263c684da91 py3: conditionalize initialization of stdio flags
Yuya Nishihara <yuya@tcha.org>
parents: 36503
diff changeset
   146
else:
37944
dc1ed7fe33e4 sshserver: do setbinary() by caller (API)
Yuya Nishihara <yuya@tcha.org>
parents: 37717
diff changeset
   147
    def initstdio():
36636
c263c684da91 py3: conditionalize initialization of stdio flags
Yuya Nishihara <yuya@tcha.org>
parents: 36503
diff changeset
   148
        for fp in (sys.stdin, sys.stdout, sys.stderr):
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   149
            procutil.setbinary(fp)
34533
163fa0aea71e dispatch: move initialization of sys.std* files
Yuya Nishihara <yuya@tcha.org>
parents: 34532
diff changeset
   150
36637
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   151
    def _silencestdio():
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   152
        pass
e8c361316803 py3: silence the final IOError by closing stdout/err slightly early
Yuya Nishihara <yuya@tcha.org>
parents: 36636
diff changeset
   153
24221
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   154
def _getsimilar(symbols, value):
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   155
    sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   156
    # The cutoff for similarity here is pretty arbitrary. It should
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   157
    # probably be investigated and tweaked.
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   158
    return [s for s in symbols if sim(s) > 0.6]
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   159
27623
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   160
def _reportsimilar(write, similar):
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   161
    if len(similar) == 1:
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   162
        write(_("(did you mean %s?)\n") % similar[0])
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   163
    elif similar:
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   164
        ss = ", ".join(sorted(similar))
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   165
        write(_("(did you mean one of %s?)\n") % ss)
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   166
24039
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   167
def _formatparse(write, inst):
24221
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   168
    similar = []
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   169
    if isinstance(inst, error.UnknownIdentifier):
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   170
        # make sure to check fileset first, as revset can invoke fileset
4e240d6ab898 dispatch: offer near-edit-distance suggestions for {file,rev}set functions
Augie Fackler <augie@google.com>
parents: 24163
diff changeset
   171
        similar = _getsimilar(inst.symbols, inst.function)
24039
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   172
    if len(inst.args) > 1:
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   173
        write(_("hg: parse error at %s: %s\n") %
36503
8b662717c53f py3: use bytestr() to coerce position carried by ParseError to string
Yuya Nishihara <yuya@tcha.org>
parents: 36124
diff changeset
   174
              (pycompat.bytestr(inst.args[1]), inst.args[0]))
36729
389b950f5190 py3: use startswith() instead of slicing to detect leading whitespace
Yuya Nishihara <yuya@tcha.org>
parents: 36720
diff changeset
   175
        if inst.args[0].startswith(' '):
24039
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   176
            write(_("unexpected leading whitespace\n"))
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   177
    else:
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   178
        write(_("hg: parse error: %s\n") % inst.args[0])
27623
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   179
        _reportsimilar(write, similar)
28515
491eabd0df79 dispatch: extract common logic for handling ParseError
Jun Wu <quark@fb.com>
parents: 28447
diff changeset
   180
    if inst.hint:
491eabd0df79 dispatch: extract common logic for handling ParseError
Jun Wu <quark@fb.com>
parents: 28447
diff changeset
   181
        write(_("(%s)\n") % inst.hint)
24039
2ee35b6ee4fb dispatch: consolidate formatting of ParseErrors
Augie Fackler <augie@google.com>
parents: 23871
diff changeset
   182
31492
3c77414a0f9c dispatch: consolidate formatting of arguments
Augie Fackler <augie@google.com>
parents: 31491
diff changeset
   183
def _formatargs(args):
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   184
    return ' '.join(procutil.shellquote(a) for a in args)
31492
3c77414a0f9c dispatch: consolidate formatting of arguments
Augie Fackler <augie@google.com>
parents: 31491
diff changeset
   185
14438
08bfec2ef031 dispatch: wrap dispatch related information in a request class
Idan Kamara <idankk86@gmail.com>
parents: 14286
diff changeset
   186
def dispatch(req):
37995
6f9ac3cb0987 dispatch: unify handling of None returned by a command function
Yuya Nishihara <yuya@tcha.org>
parents: 37994
diff changeset
   187
    """run the command specified in req.args; returns an integer status code"""
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   188
    with tracing.log('dispatch.dispatch'):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   189
        if req.ferr:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   190
            ferr = req.ferr
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   191
        elif req.ui:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   192
            ferr = req.ui.ferr
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   193
        else:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   194
            ferr = procutil.stderr
14615
9fba795dd030 dispatch: assign I/O descriptors from the request to the ui
Idan Kamara <idankk86@gmail.com>
parents: 14613
diff changeset
   195
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   196
        try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   197
            if not req.ui:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   198
                req.ui = uimod.ui.load()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   199
            req.earlyoptions.update(_earlyparseopts(req.ui, req.args))
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   200
            if req.earlyoptions['traceback']:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   201
                req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
14615
9fba795dd030 dispatch: assign I/O descriptors from the request to the ui
Idan Kamara <idankk86@gmail.com>
parents: 14613
diff changeset
   202
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   203
            # set ui streams from the request
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   204
            if req.fin:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   205
                req.ui.fin = req.fin
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   206
            if req.fout:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   207
                req.ui.fout = req.fout
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   208
            if req.ferr:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   209
                req.ui.ferr = req.ferr
40587
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
   210
            if req.fmsg:
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
   211
                req.ui.fmsg = req.fmsg
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   212
        except error.Abort as inst:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   213
            ferr.write(_("abort: %s\n") % inst)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   214
            if inst.hint:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   215
                ferr.write(_("(%s)\n") % inst.hint)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   216
            return -1
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   217
        except error.ParseError as inst:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   218
            _formatparse(ferr.write, inst)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   219
            return -1
14615
9fba795dd030 dispatch: assign I/O descriptors from the request to the ui
Idan Kamara <idankk86@gmail.com>
parents: 14613
diff changeset
   220
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   221
        msg = _formatargs(req.args)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   222
        starttime = util.timer()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   223
        ret = 1  # default of Python exit code on unhandled exception
28520
84cc72c5771e dispatch: catch KeyboardInterrupt more broadly
Yuya Nishihara <yuya@tcha.org>
parents: 28515
diff changeset
   224
        try:
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   225
            ret = _runcatch(req) or 0
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   226
        except error.ProgrammingError as inst:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   227
            req.ui.error(_('** ProgrammingError: %s\n') % inst)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   228
            if inst.hint:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   229
                req.ui.error(_('** (%s)\n') % inst.hint)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   230
            raise
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   231
        except KeyboardInterrupt as inst:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   232
            try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   233
                if isinstance(inst, error.SignalInterrupt):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   234
                    msg = _("killed!\n")
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   235
                else:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   236
                    msg = _("interrupted!\n")
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   237
                req.ui.error(msg)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   238
            except error.SignalInterrupt:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   239
                # maybe pager would quit without consuming all the output, and
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   240
                # SIGPIPE was raised. we cannot print anything in this case.
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   241
                pass
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   242
            except IOError as inst:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   243
                if inst.errno != errno.EPIPE:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   244
                    raise
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   245
            ret = -1
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   246
        finally:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   247
            duration = util.timer() - starttime
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   248
            req.ui.flush()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   249
            if req.ui.logblockedtimes:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   250
                req.ui._blockedtimes['command_duration'] = duration * 1000
41193
dd97354b8891 dispatch: add newline after ui.log "ui blocked ms" message
Martin von Zweigbergk <martinvonz@google.com>
parents: 40729
diff changeset
   251
                req.ui.log('uiblocked', 'ui blocked ms\n',
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   252
                           **pycompat.strkwargs(req.ui._blockedtimes))
40651
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   253
            return_code = ret & 255
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   254
            req.ui.log(
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   255
                "commandfinish",
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   256
                "%s exited %d after %0.2f seconds\n",
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   257
                msg,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   258
                return_code,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   259
                duration,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   260
                return_code=return_code,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   261
                duration=duration,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   262
                canonical_command=req.canonical_command,
1243295fcc3a logtoprocess: update commandfinish options arguments
Boris Feld <boris.feld@octobus.net>
parents: 40587
diff changeset
   263
            )
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   264
            try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   265
                req._runexithandlers()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   266
            except: # exiting, so no re-raises
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   267
                ret = ret or -1
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   268
        return ret
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   269
14439
80c599eee3f3 dispatch: use the request to store the ui object
Idan Kamara <idankk86@gmail.com>
parents: 14438
diff changeset
   270
def _runcatch(req):
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   271
    with tracing.log('dispatch._runcatch'):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   272
        def catchterm(*args):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   273
            raise error.SignalInterrupt
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   274
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   275
        ui = req.ui
32050
77eaf9539499 dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
Augie Fackler <augie@google.com>
parents: 30678
diff changeset
   276
        try:
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   277
            for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   278
                num = getattr(signal, name, None)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   279
                if num:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   280
                    signal.signal(num, catchterm)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   281
        except ValueError:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   282
            pass # happens if called in a thread
32050
77eaf9539499 dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
Augie Fackler <augie@google.com>
parents: 30678
diff changeset
   283
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   284
        def _runcatchfunc():
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   285
            realcmd = None
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   286
            try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   287
                cmdargs = fancyopts.fancyopts(
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   288
                    req.args[:], commands.globalopts, {})
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   289
                cmd = cmdargs[0]
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   290
                aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   291
                realcmd = aliases[0]
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   292
            except (error.UnknownCommand, error.AmbiguousCommand,
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   293
                    IndexError, getopt.GetoptError):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   294
                # Don't handle this here. We know the command is
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   295
                # invalid, but all we're worried about for now is that
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   296
                # it's not a command that server operators expect to
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   297
                # be safe to offer to users in a sandbox.
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   298
                pass
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   299
            if realcmd == 'serve' and '--stdio' in cmdargs:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   300
                # We want to constrain 'hg serve --stdio' instances pretty
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   301
                # closely, as many shared-ssh access tools want to grant
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   302
                # access to run *only* 'hg -R $repo serve --stdio'. We
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   303
                # restrict to exactly that set of arguments, and prohibit
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   304
                # any repo name that starts with '--' to prevent
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   305
                # shenanigans wherein a user does something like pass
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   306
                # --debugger or --config=ui.debugger=1 as a repo
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   307
                # name. This used to actually run the debugger.
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   308
                if (len(req.args) != 4 or
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   309
                    req.args[0] != '-R' or
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   310
                    req.args[1].startswith('--') or
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   311
                    req.args[2] != 'serve' or
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   312
                    req.args[3] != '--stdio'):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   313
                    raise error.Abort(
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   314
                        _('potentially unsafe serve --stdio invocation: %s') %
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   315
                        (stringutil.pprint(req.args),))
19639
09573ad59f7b dispatch: move command line --config argument parsing to _runcatch()
Sean Farley <sean.michael.farley@gmail.com>
parents: 19229
diff changeset
   316
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   317
            try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   318
                debugger = 'pdb'
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   319
                debugtrace = {
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   320
                    'pdb': pdb.set_trace
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   321
                }
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   322
                debugmortem = {
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   323
                    'pdb': pdb.post_mortem
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   324
                }
19639
09573ad59f7b dispatch: move command line --config argument parsing to _runcatch()
Sean Farley <sean.michael.farley@gmail.com>
parents: 19229
diff changeset
   325
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   326
                # read --config before doing anything else
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   327
                # (e.g. to change trust settings for reading .hg/hgrc)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   328
                cfgs = _parseconfig(req.ui, req.earlyoptions['config'])
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   329
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   330
                if req.repo:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   331
                    # copy configs that were passed on the cmdline (--config) to
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   332
                    # the repo ui
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   333
                    for sec, name, val in cfgs:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   334
                        req.repo.ui.setconfig(sec, name, val, source='--config')
19640
472fa3b782b1 dispatch: add ability to specify a custom pdb module as a debugger
Sean Farley <sean.michael.farley@gmail.com>
parents: 19639
diff changeset
   335
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   336
                # developer config: ui.debugger
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   337
                debugger = ui.config("ui", "debugger")
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   338
                debugmod = pdb
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   339
                if not debugger or ui.plain():
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   340
                    # if we are in HGPLAIN mode, then disable custom debugging
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   341
                    debugger = 'pdb'
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   342
                elif req.earlyoptions['debugger']:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   343
                    # This import can be slow for fancy debuggers, so only
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   344
                    # do it when absolutely necessary, i.e. when actual
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   345
                    # debugging has been requested
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   346
                    with demandimport.deactivated():
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   347
                        try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   348
                            debugmod = __import__(debugger)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   349
                        except ImportError:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   350
                            pass # Leave debugmod = pdb
19640
472fa3b782b1 dispatch: add ability to specify a custom pdb module as a debugger
Sean Farley <sean.michael.farley@gmail.com>
parents: 19639
diff changeset
   351
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   352
                debugtrace[debugger] = debugmod.set_trace
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   353
                debugmortem[debugger] = debugmod.post_mortem
19640
472fa3b782b1 dispatch: add ability to specify a custom pdb module as a debugger
Sean Farley <sean.michael.farley@gmail.com>
parents: 19639
diff changeset
   354
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   355
                # enter the debugger before command execution
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   356
                if req.earlyoptions['debugger']:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   357
                    ui.warn(_("entering debugger - "
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   358
                            "type c to continue starting hg or h for help\n"))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   359
39255
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   360
                    if (debugger != 'pdb' and
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   361
                        debugtrace[debugger] == debugtrace['pdb']):
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   362
                        ui.warn(_("%s debugger specified "
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   363
                                  "but its module was not found\n") % debugger)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   364
                    with demandimport.deactivated():
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   365
                        debugtrace[debugger]()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   366
                try:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   367
                    return _dispatch(req)
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   368
                finally:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   369
                    ui.flush()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   370
            except: # re-raises
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   371
                # enter the debugger when we hit an exception
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   372
                if req.earlyoptions['debugger']:
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   373
                    traceback.print_exc()
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   374
                    debugmortem[debugger](sys.exc_info()[2])
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   375
                raise
4019b4542e61 dispatch: have dispatch.dispatch and dispatch._runcatch emit trace events
Augie Fackler <augie@google.com>
parents: 38788
diff changeset
   376
        return _callcatch(ui, _runcatchfunc)
29761
39149b6036e6 dispatch: split global error handling out so it can be reused
Jun Wu <quark@fb.com>
parents: 29132
diff changeset
   377
32040
0fb78cb90ca7 dispatch: mark callcatch() as a private function
Yuya Nishihara <yuya@tcha.org>
parents: 31960
diff changeset
   378
def _callcatch(ui, func):
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   379
    """like scmutil.callcatch but handles more high-level exceptions about
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   380
    config parsing and commands. besides, use handlecommandexception to handle
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   381
    uncaught exceptions.
29761
39149b6036e6 dispatch: split global error handling out so it can be reused
Jun Wu <quark@fb.com>
parents: 29132
diff changeset
   382
    """
39149b6036e6 dispatch: split global error handling out so it can be reused
Jun Wu <quark@fb.com>
parents: 29132
diff changeset
   383
    try:
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   384
        return scmutil.callcatch(ui, func)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25329
diff changeset
   385
    except error.AmbiguousCommand as inst:
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   386
        ui.warn(_("hg: command '%s' is ambiguous:\n    %s\n") %
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   387
                (inst.args[0], " ".join(inst.args[1])))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25329
diff changeset
   388
    except error.CommandError as inst:
7645
020a896a5292 dispatch: sort exception handlers
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
   389
        if inst.args[0]:
31266
8089de5fab89 dispatch: add pagination of two more help cases
Augie Fackler <augie@google.com>
parents: 31199
diff changeset
   390
            ui.pager('help')
32620
3ce53a499334 dispatch: convert exception payload to bytes more carefully
Augie Fackler <raf@durin42.com>
parents: 32566
diff changeset
   391
            msgbytes = pycompat.bytestr(inst.args[1])
3ce53a499334 dispatch: convert exception payload to bytes more carefully
Augie Fackler <raf@durin42.com>
parents: 32566
diff changeset
   392
            ui.warn(_("hg %s: %s\n") % (inst.args[0], msgbytes))
14286
005a540e9aee help: add -c/--command flag to only show command help (issue2799)
Martin Geisler <mg@aragost.com>
parents: 14265
diff changeset
   393
            commands.help_(ui, inst.args[0], full=False, command=True)
7645
020a896a5292 dispatch: sort exception handlers
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
   394
        else:
020a896a5292 dispatch: sort exception handlers
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
   395
            ui.warn(_("hg: %s\n") % inst.args[1])
38788
a9ff2b0c11dd dispatch: show a short error message when invalid global option given
Martin von Zweigbergk <martinvonz@google.com>
parents: 38787
diff changeset
   396
            ui.warn(_("(use 'hg help -v' for a list of global options)\n"))
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   397
    except error.ParseError as inst:
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   398
        _formatparse(ui.warn, inst)
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   399
        return -1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25329
diff changeset
   400
    except error.UnknownCommand as inst:
31060
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
   401
        nocmdmsg = _("hg: unknown command '%s'\n") % inst.args[0]
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   402
        try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   403
            # check if the command is in a disabled extension
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   404
            # (but don't check for extensions themselves)
32566
1b90036f42f0 help: pass commands module by argument
Yuya Nishihara <yuya@tcha.org>
parents: 32379
diff changeset
   405
            formatted = help.formattedhelp(ui, commands, inst.args[0],
1b90036f42f0 help: pass commands module by argument
Yuya Nishihara <yuya@tcha.org>
parents: 32379
diff changeset
   406
                                           unknowncmd=True)
31060
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
   407
            ui.warn(nocmdmsg)
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
   408
            ui.write(formatted)
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   409
        except (error.UnknownCommand, error.Abort):
24222
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   410
            suggested = False
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   411
            if len(inst.args) == 2:
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   412
                sim = _getsimilar(inst.args[1], inst.args[0])
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   413
                if sim:
31060
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
   414
                    ui.warn(nocmdmsg)
27623
b3376fba4ab9 dispatch: report similar names consistently
Bryan O'Sullivan <bos@serpentine.com>
parents: 27615
diff changeset
   415
                    _reportsimilar(ui.warn, sim)
24222
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   416
                    suggested = True
02d7b5cd373b dispatch: offer suggestions of similar-named commands
Augie Fackler <augie@google.com>
parents: 24221
diff changeset
   417
            if not suggested:
31060
ab20491b1760 dispatch: rearrange 'unknown command' code to better employ pager
Augie Fackler <augie@google.com>
parents: 31027
diff changeset
   418
                ui.warn(nocmdmsg)
38787
5199c5b6fd29 dispatch: don't show list of commands on bogus command
Martin von Zweigbergk <martinvonz@google.com>
parents: 38768
diff changeset
   419
                ui.warn(_("(use 'hg help' for a list of commands)\n"))
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   420
    except IOError:
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   421
        raise
7645
020a896a5292 dispatch: sort exception handlers
Matt Mackall <mpm@selenic.com>
parents: 7644
diff changeset
   422
    except KeyboardInterrupt:
28520
84cc72c5771e dispatch: catch KeyboardInterrupt more broadly
Yuya Nishihara <yuya@tcha.org>
parents: 28515
diff changeset
   423
        raise
30520
4338f87dbf6f dispatch: move part of callcatch to scmutil
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
   424
    except:  # probably re-raises
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
   425
        if not handlecommandexception(ui):
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
   426
            raise
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   427
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   428
    return -1
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   429
14265
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   430
def aliasargs(fn, givenargs):
34087
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   431
    args = []
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   432
    # only care about alias 'args', ignore 'args' set by extensions.wrapfunction
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   433
    if not util.safehasattr(fn, '_origfunc'):
5361771f9714 wrapfunction: use functools.partial if possible
Jun Wu <quark@fb.com>
parents: 34022
diff changeset
   434
        args = getattr(fn, 'args', args)
16294
795d591b6ef5 alias: abort on missing positional args (issue3331)
Matt Mackall <mpm@selenic.com>
parents: 16277
diff changeset
   435
    if args:
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   436
        cmd = ' '.join(map(procutil.shellquote, args))
14265
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   437
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   438
        nums = []
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   439
        def replacer(m):
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   440
            num = int(m.group(1)) - 1
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   441
            nums.append(num)
16277
1c2aaf05f7d7 aliases: use empty string for missing position parameters (issue3331)
Matt Mackall <mpm@selenic.com>
parents: 15781
diff changeset
   442
            if num < len(givenargs):
1c2aaf05f7d7 aliases: use empty string for missing position parameters (issue3331)
Matt Mackall <mpm@selenic.com>
parents: 15781
diff changeset
   443
                return givenargs[num]
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   444
            raise error.Abort(_('too few arguments for command alias'))
31491
492c64afc54c py3: make the regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31305
diff changeset
   445
        cmd = re.sub(br'\$(\d+|\$)', replacer, cmd)
14265
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   446
        givenargs = [x for i, x in enumerate(givenargs)
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   447
                     if i not in nums]
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30653
diff changeset
   448
        args = pycompat.shlexsplit(cmd)
14265
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   449
    return args + givenargs
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   450
22158
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   451
def aliasinterpolate(name, args, cmd):
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   452
    '''interpolate args into cmd for shell aliases
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   453
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   454
    This also handles $0, $@ and "$@".
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   455
    '''
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   456
    # util.interpolate can't deal with "$@" (with quotes) because it's only
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   457
    # built to match prefix + patterns.
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   458
    replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args))
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   459
    replacemap['$0'] = name
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   460
    replacemap['$$'] = '$'
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   461
    replacemap['$@'] = ' '.join(args)
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   462
    # Typical Unix shells interpolate "$@" (with quotes) as all the positional
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   463
    # parameters, separated out into words. Emulate the same behavior here by
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   464
    # quoting the arguments individually. POSIX shells will then typically
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   465
    # tokenize each argument into exactly one word.
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
   466
    replacemap['"$@"'] = ' '.join(procutil.shellquote(arg) for arg in args)
22158
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   467
    # escape '\$' for regex
35145
25c543944bc0 py3: add b'' to regular expressions which are raw strings
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34781
diff changeset
   468
    regex = '|'.join(replacemap.keys()).replace('$', br'\$')
22158
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   469
    r = re.compile(regex)
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   470
    return r.sub(lambda x: replacemap[x.group()], cmd)
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   471
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   472
class cmdalias(object):
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   473
    def __init__(self, ui, name, definition, cmdtable, source):
12039
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   474
        self.name = self.cmd = name
12092
4982fa38e544 alias: print what command is being shadowed in debug message
Brodie Rao <brodie@bitheap.org>
parents: 12070
diff changeset
   475
        self.cmdname = ''
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   476
        self.definition = definition
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   477
        self.fn = None
29087
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   478
        self.givenargs = []
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   479
        self.opts = []
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   480
        self.help = ''
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   481
        self.badalias = None
22161
063628423fd1 alias: provide "unknowncmd" flag to tell help to look for disabled command
Yuya Nishihara <yuya@tcha.org>
parents: 22160
diff changeset
   482
        self.unknowncmd = False
28828
3640c1702c43 help: report source of aliases
timeless <timeless@mozdev.org>
parents: 28821
diff changeset
   483
        self.source = source
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   484
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   485
        try:
12039
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   486
            aliases, entry = cmdutil.findcmd(self.name, cmdtable)
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   487
            for alias, e in cmdtable.iteritems():
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   488
                if e is entry:
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   489
                    self.cmd = alias
18e1e7520b67 alias: make shadowing behavior more consistent (issue2054)
Brodie Rao <brodie@bitheap.org>
parents: 11712
diff changeset
   490
                    break
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   491
            self.shadows = True
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   492
        except error.UnknownCommand:
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   493
            self.shadows = False
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   494
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   495
        if not self.definition:
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   496
            self.badalias = _("no definition for alias '%s'") % self.name
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   497
            return
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   498
11524
24965bb270b7 dispatch: add shell aliases
Steve Losh <steve@stevelosh.com>
parents: 11495
diff changeset
   499
        if self.definition.startswith('!'):
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   500
            shdef = self.definition[1:]
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   501
            self.shell = True
11524
24965bb270b7 dispatch: add shell aliases
Steve Losh <steve@stevelosh.com>
parents: 11495
diff changeset
   502
            def fn(ui, *args):
11989
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   503
                env = {'HG_ARGS': ' '.join((self.name,) + args)}
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   504
                def _checkvar(m):
13392
777cef34a890 dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents: 13382
diff changeset
   505
                    if m.groups()[0] == '$':
777cef34a890 dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents: 13382
diff changeset
   506
                        return m.group()
777cef34a890 dispatch: support for $ escaping in shell-alias definition
Roman Sokolov <sokolov.r.v@gmail.com>
parents: 13382
diff changeset
   507
                    elif int(m.groups()[0]) <= len(args):
11989
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   508
                        return m.group()
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   509
                    else:
14708
8083f4d00bd1 i18n: remove translation of debug messages
David Soria Parra <dsp@php.net>
parents: 14704
diff changeset
   510
                        ui.debug("No argument found for substitution "
35466
7906354cbc68 debug: add newlines at the end of three locations that appear to need it
Kyle Lippincott <spectral@google.com>
parents: 35354
diff changeset
   511
                                 "of %i variable in alias '%s' definition.\n"
13393
d38d500deb08 dispatch: debug message for missing arguments in shell alias
Roman Sokolov <sokolov.r.v@gmail.com>
parents: 13392
diff changeset
   512
                                 % (int(m.groups()[0]), self.name))
11989
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   513
                        return ''
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   514
                cmd = re.sub(br'\$(\d+|\$)', _checkvar, shdef)
22158
bc2132dfc0a4 alias: expand "$@" as list of parameters quoted individually (BC) (issue4200)
Siddharth Agarwal <sid0@fb.com>
parents: 21961
diff changeset
   515
                cmd = aliasinterpolate(self.name, args, cmd)
31199
3a03264de3eb dispatch: set a blockedtag when running an external alias
Simon Farnsworth <simonfar@fb.com>
parents: 31180
diff changeset
   516
                return ui.system(cmd, environ=env,
3a03264de3eb dispatch: set a blockedtag when running an external alias
Simon Farnsworth <simonfar@fb.com>
parents: 31180
diff changeset
   517
                                 blockedtag='alias_%s' % self.name)
11524
24965bb270b7 dispatch: add shell aliases
Steve Losh <steve@stevelosh.com>
parents: 11495
diff changeset
   518
            self.fn = fn
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   519
            self.alias = True
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   520
            self._populatehelp(ui, name, shdef, self.fn)
11524
24965bb270b7 dispatch: add shell aliases
Steve Losh <steve@stevelosh.com>
parents: 11495
diff changeset
   521
            return
24965bb270b7 dispatch: add shell aliases
Steve Losh <steve@stevelosh.com>
parents: 11495
diff changeset
   522
21569
c5afb07c33d3 alias: handle shlex error in command aliases
Yuya Nishihara <yuya@tcha.org>
parents: 21556
diff changeset
   523
        try:
30678
caf7e1c5efe4 py3: have a bytes version of shlex.split()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30653
diff changeset
   524
            args = pycompat.shlexsplit(self.definition)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25329
diff changeset
   525
        except ValueError as inst:
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   526
            self.badalias = (_("error in definition for alias '%s': %s")
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
   527
                             % (self.name, stringutil.forcebytestr(inst)))
21569
c5afb07c33d3 alias: handle shlex error in command aliases
Yuya Nishihara <yuya@tcha.org>
parents: 21556
diff changeset
   528
            return
35225
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   529
        earlyopts, args = _earlysplitopts(args)
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   530
        if earlyopts:
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   531
            self.badalias = (_("error in definition for alias '%s': %s may "
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   532
                               "only be given on the command line")
35942
f81df691efe7 py3: use pycompat.ziplist instead of zip
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35899
diff changeset
   533
                             % (self.name, '/'.join(pycompat.ziplist(*earlyopts)
f81df691efe7 py3: use pycompat.ziplist instead of zip
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35899
diff changeset
   534
                                                    [0])))
35225
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   535
            return
12092
4982fa38e544 alias: print what command is being shadowed in debug message
Brodie Rao <brodie@bitheap.org>
parents: 12070
diff changeset
   536
        self.cmdname = cmd = args.pop(0)
29087
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   537
        self.givenargs = args
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   538
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   539
        try:
9993
8bce1e0d2801 alias: do not crash when aliased command has no usage help text
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9825
diff changeset
   540
            tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
8bce1e0d2801 alias: do not crash when aliased command has no usage help text
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9825
diff changeset
   541
            if len(tableentry) > 2:
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   542
                self.fn, self.opts, cmdhelp = tableentry
9993
8bce1e0d2801 alias: do not crash when aliased command has no usage help text
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9825
diff changeset
   543
            else:
8bce1e0d2801 alias: do not crash when aliased command has no usage help text
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9825
diff changeset
   544
                self.fn, self.opts = tableentry
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   545
                cmdhelp = None
9993
8bce1e0d2801 alias: do not crash when aliased command has no usage help text
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9825
diff changeset
   546
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   547
            self.alias = True
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   548
            self._populatehelp(ui, name, cmd, self.fn, cmdhelp)
9876
6e8a16dd3e30 alias: improve help text for command aliases
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 9875
diff changeset
   549
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   550
        except error.UnknownCommand:
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   551
            self.badalias = (_("alias '%s' resolves to unknown command '%s'")
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   552
                             % (self.name, cmd))
22161
063628423fd1 alias: provide "unknowncmd" flag to tell help to look for disabled command
Yuya Nishihara <yuya@tcha.org>
parents: 22160
diff changeset
   553
            self.unknowncmd = True
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   554
        except error.AmbiguousCommand:
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   555
            self.badalias = (_("alias '%s' resolves to ambiguous command '%s'")
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   556
                             % (self.name, cmd))
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   557
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   558
    def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
37139
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   559
        # confine strings to be passed to i18n.gettext()
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   560
        cfg = {}
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   561
        for k in ('doc', 'help', 'category'):
37139
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   562
            v = ui.config('alias', '%s:%s' % (name, k), None)
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   563
            if v is None:
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   564
                continue
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   565
            if not encoding.isasciistr(v):
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   566
                self.badalias = (_("non-ASCII character in alias definition "
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   567
                                   "'%s:%s'") % (name, k))
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   568
                return
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   569
            cfg[k] = v
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   570
aa55c5354b8f alias: reject non-ascii characters in user help/doc strings
Yuya Nishihara <yuya@tcha.org>
parents: 37134
diff changeset
   571
        self.help = cfg.get('help', defaulthelp or '')
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   572
        if self.help and self.help.startswith("hg " + cmd):
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   573
            # drop prefix in old-style help lines so hg shows the alias
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   574
            self.help = self.help[4 + len(cmd):]
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   575
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   576
        self.owndoc = 'doc' in cfg
37140
1d56c539794e py3: bytes/unicode dance on __doc__ of cmdalias
Yuya Nishihara <yuya@tcha.org>
parents: 37139
diff changeset
   577
        doc = cfg.get('doc', pycompat.getdoc(fn))
1d56c539794e py3: bytes/unicode dance on __doc__ of cmdalias
Yuya Nishihara <yuya@tcha.org>
parents: 37139
diff changeset
   578
        if doc is not None:
1d56c539794e py3: bytes/unicode dance on __doc__ of cmdalias
Yuya Nishihara <yuya@tcha.org>
parents: 37139
diff changeset
   579
            doc = pycompat.sysstr(doc)
1d56c539794e py3: bytes/unicode dance on __doc__ of cmdalias
Yuya Nishihara <yuya@tcha.org>
parents: 37139
diff changeset
   580
        self.__doc__ = doc
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   581
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   582
        self.helpcategory = cfg.get('category', registrar.command.CATEGORY_NONE)
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   583
29087
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   584
    @property
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   585
    def args(self):
31629
2632df096fc0 dispatch: use pycompat.maplist() instead of map() to get a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31502
diff changeset
   586
        args = pycompat.maplist(util.expandpath, self.givenargs)
29087
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   587
        return aliasargs(self.fn, args)
ad1bdea43965 dispatch: defer environment variable resolution in alias commands (BC)
Jun Wu <quark@fb.com>
parents: 28861
diff changeset
   588
28621
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   589
    def __getattr__(self, name):
37716
dfc51a482031 registrar: replace "cmdtype" with an intent-based mechanism (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37140
diff changeset
   590
        adefaults = {r'norepo': True, r'intents': set(),
32158
89153b0d4881 py3: make adefaults keys str to be compatible with getattr
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32130
diff changeset
   591
                     r'optionalrepo': False, r'inferrepo': False}
28621
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   592
        if name not in adefaults:
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   593
            raise AttributeError(name)
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   594
        if self.badalias or util.safehasattr(self, 'shell'):
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   595
            return adefaults[name]
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   596
        return getattr(self.fn, name)
d856e85a8a7a dispatch: make cmdalias forward command attributes to function
Yuya Nishihara <yuya@tcha.org>
parents: 28538
diff changeset
   597
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   598
    def __call__(self, ui, *args, **opts):
22160
645457f73aa6 alias: keep error message in "badalias" so that help can see it
Yuya Nishihara <yuya@tcha.org>
parents: 22158
diff changeset
   599
        if self.badalias:
22164
efd65e51bc0b alias: exit from bad definition by Abort
Yuya Nishihara <yuya@tcha.org>
parents: 22163
diff changeset
   600
            hint = None
22161
063628423fd1 alias: provide "unknowncmd" flag to tell help to look for disabled command
Yuya Nishihara <yuya@tcha.org>
parents: 22160
diff changeset
   601
            if self.unknowncmd:
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   602
                try:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   603
                    # check if the command is in a disabled extension
22163
01ef4347e4ab alias: show one-line hint for command provided by disabled extension
Yuya Nishihara <yuya@tcha.org>
parents: 22161
diff changeset
   604
                    cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
22164
efd65e51bc0b alias: exit from bad definition by Abort
Yuya Nishihara <yuya@tcha.org>
parents: 22163
diff changeset
   605
                    hint = _("'%s' is provided by '%s' extension") % (cmd, ext)
10364
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   606
                except error.UnknownCommand:
de1e7099d100 dispatch: provide help for disabled extensions and commands
Brodie Rao <me+hg@dackz.net>
parents: 10282
diff changeset
   607
                    pass
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   608
            raise error.Abort(self.badalias, hint=hint)
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   609
        if self.shadows:
14704
b24d596fcd25 Backed out changeset 1ec8bd909ac3
Martin Geisler <mg@aragost.com>
parents: 14702
diff changeset
   610
            ui.debug("alias '%s' shadows command '%s'\n" %
12092
4982fa38e544 alias: print what command is being shadowed in debug message
Brodie Rao <brodie@bitheap.org>
parents: 12070
diff changeset
   611
                     (self.name, self.cmdname))
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   612
29846
318e2b600b80 blackbox: also log alias expansions
Augie Fackler <augie@google.com>
parents: 29841
diff changeset
   613
        ui.log('commandalias', "alias '%s' expands to '%s'\n",
318e2b600b80 blackbox: also log alias expansions
Augie Fackler <augie@google.com>
parents: 29841
diff changeset
   614
               self.name, self.definition)
14950
144e97421f6b dispatch: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14918
diff changeset
   615
        if util.safehasattr(self, 'shell'):
11989
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   616
            return self.fn(ui, *args, **opts)
f853873fc66d aliases: provide more flexible ways to work with shell alias arguments
Steve Losh <steve@stevelosh.com>
parents: 11985
diff changeset
   617
        else:
12093
cd895084a4cd alias: on --debug, print expansion when it has invalid arguments
Brodie Rao <brodie@bitheap.org>
parents: 12092
diff changeset
   618
            try:
21556
5e13507a3b4e alias: fix loss of non-zero return code in command aliases
Yuya Nishihara <yuya@tcha.org>
parents: 20829
diff changeset
   619
                return util.checksignature(self.fn)(ui, *args, **opts)
12093
cd895084a4cd alias: on --debug, print expansion when it has invalid arguments
Brodie Rao <brodie@bitheap.org>
parents: 12092
diff changeset
   620
            except error.SignatureError:
cd895084a4cd alias: on --debug, print expansion when it has invalid arguments
Brodie Rao <brodie@bitheap.org>
parents: 12092
diff changeset
   621
                args = ' '.join([self.cmdname] + self.args)
14704
b24d596fcd25 Backed out changeset 1ec8bd909ac3
Martin Geisler <mg@aragost.com>
parents: 14702
diff changeset
   622
                ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
12093
cd895084a4cd alias: on --debug, print expansion when it has invalid arguments
Brodie Rao <brodie@bitheap.org>
parents: 12092
diff changeset
   623
                raise
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   624
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   625
class lazyaliasentry(object):
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   626
    """like a typical command entry (func, opts, help), but is lazy"""
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   627
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   628
    def __init__(self, ui, name, definition, cmdtable, source):
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   629
        self.ui = ui
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   630
        self.name = name
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   631
        self.definition = definition
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   632
        self.cmdtable = cmdtable.copy()
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   633
        self.source = source
40414
444861dc1e55 help: displaying documented aliases by default
rdamazio@google.com
parents: 40402
diff changeset
   634
        self.alias = True
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   635
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   636
    @util.propertycache
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   637
    def _aliasdef(self):
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   638
        return cmdalias(self.ui, self.name, self.definition, self.cmdtable,
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   639
                        self.source)
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   640
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   641
    def __getitem__(self, n):
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   642
        aliasdef = self._aliasdef
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   643
        if n == 0:
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   644
            return aliasdef
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   645
        elif n == 1:
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   646
            return aliasdef.opts
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   647
        elif n == 2:
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   648
            return aliasdef.help
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   649
        else:
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   650
            raise IndexError
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   651
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   652
    def __iter__(self):
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   653
        for i in range(3):
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   654
            yield self[i]
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   655
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   656
    def __len__(self):
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   657
        return 3
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   658
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   659
def addaliases(ui, cmdtable):
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   660
    # aliases are processed after extensions have been loaded, so they
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   661
    # may use extension commands. Aliases can also use other alias definitions,
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   662
    # but only if they have been defined prior to the current definition.
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   663
    for alias, definition in ui.configitems('alias', ignoresub=True):
15019
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   664
        try:
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   665
            if cmdtable[alias].definition == definition:
15019
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   666
                continue
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   667
        except (KeyError, AttributeError):
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   668
            # definition might not exist or it might not be a cmdalias
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   669
            pass
f4b7be3f8430 dispatch: don't rewrap aliases that have the same definition
Idan Kamara <idankk86@gmail.com>
parents: 14992
diff changeset
   670
34305
0e48813cc106 alias: test duplicated definition earlier
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
   671
        source = ui.configsource('alias', alias)
37134
6890b7e991a4 help: supporting both help and doc for aliases
Rodrigo Damazio <rdamazio@google.com>
parents: 37120
diff changeset
   672
        entry = lazyaliasentry(ui, alias, definition, cmdtable, source)
34306
bd50aa1aa035 alias: make alias command lazily resolved
Jun Wu <quark@fb.com>
parents: 34305
diff changeset
   673
        cmdtable[alias] = entry
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   674
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   675
def _parse(ui, args):
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   676
    options = {}
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   677
    cmdoptions = {}
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   678
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   679
    try:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   680
        args = fancyopts.fancyopts(args, commands.globalopts, options)
30576
541949a10a68 fancyopts: switch from fancyopts.getopt.* to getopt.*
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   681
    except getopt.GetoptError as inst:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
   682
        raise error.CommandError(None, stringutil.forcebytestr(inst))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   683
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   684
    if args:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   685
        cmd, args = args[0], args[1:]
9875
d6a95c5f6ff9 dispatch: minor refactoring
Henri Wiechers <hwiechers@gmail.com>
parents: 9825
diff changeset
   686
        aliases, entry = cmdutil.findcmd(cmd, commands.table,
16591
46e9ed223d2c commands: parse ui.strict config item as bool
Yuya Nishihara <yuya@tcha.org>
parents: 16392
diff changeset
   687
                                         ui.configbool("ui", "strict"))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   688
        cmd = aliases[0]
14265
e4ab5ae193f2 add positional arguments to non-shell aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14096
diff changeset
   689
        args = aliasargs(entry[0], args)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   690
        defaults = ui.config("defaults", cmd)
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   691
        if defaults:
31502
9916b3d579a9 dispatch: use pycompat.maplist to allow summing with args
Augie Fackler <augie@google.com>
parents: 31500
diff changeset
   692
            args = pycompat.maplist(
9916b3d579a9 dispatch: use pycompat.maplist to allow summing with args
Augie Fackler <augie@google.com>
parents: 31500
diff changeset
   693
                util.expandpath, pycompat.shlexsplit(defaults)) + args
9875
d6a95c5f6ff9 dispatch: minor refactoring
Henri Wiechers <hwiechers@gmail.com>
parents: 9825
diff changeset
   694
        c = list(entry[1])
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   695
    else:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   696
        cmd = None
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   697
        c = []
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   698
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   699
    # combine global options into local
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   700
    for o in commands.globalopts:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   701
        c.append((o[0], o[1], options[o[1]], o[3]))
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   702
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   703
    try:
29822
61a4cdc98307 dispatch: explicitly pass fancyopts optional arg as a keyword
Augie Fackler <augie@google.com>
parents: 29784
diff changeset
   704
        args = fancyopts.fancyopts(args, c, cmdoptions, gnu=True)
30576
541949a10a68 fancyopts: switch from fancyopts.getopt.* to getopt.*
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   705
    except getopt.GetoptError as inst:
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
   706
        raise error.CommandError(cmd, stringutil.forcebytestr(inst))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   707
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   708
    # separate global options back out
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   709
    for o in commands.globalopts:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   710
        n = o[1]
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   711
        options[n] = cmdoptions[n]
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   712
        del cmdoptions[n]
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   713
9875
d6a95c5f6ff9 dispatch: minor refactoring
Henri Wiechers <hwiechers@gmail.com>
parents: 9825
diff changeset
   714
    return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   715
8137
7fd0616b3d80 ui: kill updateopts
Matt Mackall <mpm@selenic.com>
parents: 8136
diff changeset
   716
def _parseconfig(ui, config):
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   717
    """parse the --config options from the command line"""
14753
10dcb3e7cb55 dispatch: return read config options
Idan Kamara <idankk86@gmail.com>
parents: 14752
diff changeset
   718
    configs = []
10dcb3e7cb55 dispatch: return read config options
Idan Kamara <idankk86@gmail.com>
parents: 14752
diff changeset
   719
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   720
    for cfg in config:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   721
        try:
28081
a6344df5108e dispatch: strip command line options like config file options
Tony Tung <ttung@fb.com>
parents: 27679
diff changeset
   722
            name, value = [cfgelem.strip()
a6344df5108e dispatch: strip command line options like config file options
Tony Tung <ttung@fb.com>
parents: 27679
diff changeset
   723
                           for cfgelem in cfg.split('=', 1)]
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   724
            section, name = name.split('.', 1)
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   725
            if not section or not name:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   726
                raise IndexError
20788
f144928dd058 config: give a useful hint of source for the most common command line settings
Mads Kiilerich <madski@unity3d.com>
parents: 20330
diff changeset
   727
            ui.setconfig(section, name, value, '--config')
14753
10dcb3e7cb55 dispatch: return read config options
Idan Kamara <idankk86@gmail.com>
parents: 14752
diff changeset
   728
            configs.append((section, name, value))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   729
        except (IndexError, ValueError):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26421
diff changeset
   730
            raise error.Abort(_('malformed --config option: %r '
36641
77f98867538f py3: fix some unicode madness in global exception catcher
Yuya Nishihara <yuya@tcha.org>
parents: 36637
diff changeset
   731
                                '(use --config section.name=value)')
77f98867538f py3: fix some unicode madness in global exception catcher
Yuya Nishihara <yuya@tcha.org>
parents: 36637
diff changeset
   732
                              % pycompat.bytestr(cfg))
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   733
14753
10dcb3e7cb55 dispatch: return read config options
Idan Kamara <idankk86@gmail.com>
parents: 14752
diff changeset
   734
    return configs
10dcb3e7cb55 dispatch: return read config options
Idan Kamara <idankk86@gmail.com>
parents: 14752
diff changeset
   735
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   736
def _earlyparseopts(ui, args):
35170
c9740b69b9b7 dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options
Yuya Nishihara <yuya@tcha.org>
parents: 35034
diff changeset
   737
    options = {}
c9740b69b9b7 dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options
Yuya Nishihara <yuya@tcha.org>
parents: 35034
diff changeset
   738
    fancyopts.fancyopts(args, commands.globalopts, options,
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   739
                        gnu=not ui.plain('strictflags'), early=True,
35223
4edd2202f7d7 dispatch: alias --repo to --repository while parsing early options
Yuya Nishihara <yuya@tcha.org>
parents: 35186
diff changeset
   740
                        optaliases={'repository': ['repo']})
35170
c9740b69b9b7 dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options
Yuya Nishihara <yuya@tcha.org>
parents: 35034
diff changeset
   741
    return options
c9740b69b9b7 dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options
Yuya Nishihara <yuya@tcha.org>
parents: 35034
diff changeset
   742
35225
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   743
def _earlysplitopts(args):
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   744
    """Split args into a list of possible early options and remainder args"""
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   745
    shortoptions = 'R:'
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   746
    # TODO: perhaps 'debugger' should be included
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   747
    longoptions = ['cwd=', 'repository=', 'repo=', 'config=']
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   748
    return fancyopts.earlygetopt(args, shortoptions, longoptions,
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   749
                                 gnu=True, keepsep=True)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   750
11330
713ae78bb583 provide pre- and post- hooks with parsed command line arguments.
Chad Dombrova <chadrik@gmail.com>
parents: 11305
diff changeset
   751
def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
7819
14b703252f14 dispatch: extract command execution block into method
Bill Barry <after.fallout@gmail.com>
parents: 7772
diff changeset
   752
    # run pre-hook, and abort if it fails
19011
12acbea17625 dispatch: print 'abort:' when a pre-command hook fails (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 18935
diff changeset
   753
    hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
12acbea17625 dispatch: print 'abort:' when a pre-command hook fails (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 18935
diff changeset
   754
              pats=cmdpats, opts=cmdoptions)
29129
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   755
    try:
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   756
        ret = _runcommand(ui, options, cmd, d)
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   757
        # run post-hook, passing command result
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   758
        hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   759
                  result=ret, pats=cmdpats, opts=cmdoptions)
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   760
    except Exception:
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   761
        # run failure hook and re-raise
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   762
        hook.hook(lui, repo, "fail-%s" % cmd, False, args=" ".join(fullargs),
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   763
                  pats=cmdpats, opts=cmdoptions)
e6dfb0e4eeef dispatch: add fail-* family of hooks
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 29114
diff changeset
   764
        raise
7819
14b703252f14 dispatch: extract command execution block into method
Bill Barry <after.fallout@gmail.com>
parents: 7772
diff changeset
   765
    return ret
14b703252f14 dispatch: extract command execution block into method
Bill Barry <after.fallout@gmail.com>
parents: 7772
diff changeset
   766
28263
59509c6724c7 dispatch: add wd parameter to _getlocal
Jun Wu <quark@fb.com>
parents: 28081
diff changeset
   767
def _getlocal(ui, rpath, wd=None):
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   768
    """Return (path, local ui object) for the given target path.
12770
614f0d8724ab check-code: find trailing whitespace
Martin Geisler <mg@lazybytes.net>
parents: 12748
diff changeset
   769
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   770
    Takes paths in [cwd]/.hg/hgrc into account."
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   771
    """
28263
59509c6724c7 dispatch: add wd parameter to _getlocal
Jun Wu <quark@fb.com>
parents: 28081
diff changeset
   772
    if wd is None:
59509c6724c7 dispatch: add wd parameter to _getlocal
Jun Wu <quark@fb.com>
parents: 28081
diff changeset
   773
        try:
39818
24e493ec2229 py3: rename pycompat.getcwd() to encoding.getcwd() (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39512
diff changeset
   774
            wd = encoding.getcwd()
28263
59509c6724c7 dispatch: add wd parameter to _getlocal
Jun Wu <quark@fb.com>
parents: 28081
diff changeset
   775
        except OSError as e:
59509c6724c7 dispatch: add wd parameter to _getlocal
Jun Wu <quark@fb.com>
parents: 28081
diff changeset
   776
            raise error.Abort(_("error getting current working directory: %s") %
34022
d5b2beca16c0 python3: wrap all uses of <exception>.strerror with strtolocal
Augie Fackler <raf@durin42.com>
parents: 33620
diff changeset
   777
                              encoding.strtolocal(e.strerror))
11675
f92f8921a5cc dispatch: give better error message when cwd doesn't exist (issue2293)
Mads Kiilerich <mads@kiilerich.com>
parents: 11600
diff changeset
   778
    path = cmdutil.findrepo(wd) or ""
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   779
    if not path:
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   780
        lui = ui
9436
96379c93ba6f improve code readability
Andrey Somov <py4fun@gmail.com>
parents: 9411
diff changeset
   781
    else:
12636
c24215aa7e69 dispatch: remove superfluous try/except when reading local ui config
Brodie Rao <brodie@bitheap.org>
parents: 12633
diff changeset
   782
        lui = ui.copy()
12637
42ca7aef28d3 dispatch: properly handle relative path aliases used with -R (issue2376)
Brodie Rao <brodie@bitheap.org>
parents: 12636
diff changeset
   783
        lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   784
35033
d3d35a55e03b dispatch: convert non-list option parsed by _earlygetopt() to string
Yuya Nishihara <yuya@tcha.org>
parents: 35032
diff changeset
   785
    if rpath:
d3d35a55e03b dispatch: convert non-list option parsed by _earlygetopt() to string
Yuya Nishihara <yuya@tcha.org>
parents: 35032
diff changeset
   786
        path = lui.expandpath(rpath)
8190
9b8ac5fb7760 ui: kill most users of parentui name and arg, replace with .copy()
Matt Mackall <mpm@selenic.com>
parents: 8144
diff changeset
   787
        lui = ui.copy()
12637
42ca7aef28d3 dispatch: properly handle relative path aliases used with -R (issue2376)
Brodie Rao <brodie@bitheap.org>
parents: 12636
diff changeset
   788
        lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   789
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   790
    return path, lui
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   791
29132
12769703d4ba dispatch: always load extensions before running shell aliases (issue5230)
Jun Wu <quark@fb.com>
parents: 29129
diff changeset
   792
def _checkshellalias(lui, ui, args):
12769703d4ba dispatch: always load extensions before running shell aliases (issue5230)
Jun Wu <quark@fb.com>
parents: 29129
diff changeset
   793
    """Return the function to run the shell alias, if it is required"""
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   794
    options = {}
12748
d10369fefd01 alias: fail gracefully when invalid global options are given (issue2442)
Steve Losh <steve@stevelosh.com>
parents: 12637
diff changeset
   795
d10369fefd01 alias: fail gracefully when invalid global options are given (issue2442)
Steve Losh <steve@stevelosh.com>
parents: 12637
diff changeset
   796
    try:
d10369fefd01 alias: fail gracefully when invalid global options are given (issue2442)
Steve Losh <steve@stevelosh.com>
parents: 12637
diff changeset
   797
        args = fancyopts.fancyopts(args, commands.globalopts, options)
30576
541949a10a68 fancyopts: switch from fancyopts.getopt.* to getopt.*
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30559
diff changeset
   798
    except getopt.GetoptError:
12748
d10369fefd01 alias: fail gracefully when invalid global options are given (issue2442)
Steve Losh <steve@stevelosh.com>
parents: 12637
diff changeset
   799
        return
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   800
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   801
    if not args:
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   802
        return
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   803
29132
12769703d4ba dispatch: always load extensions before running shell aliases (issue5230)
Jun Wu <quark@fb.com>
parents: 29129
diff changeset
   804
    cmdtable = commands.table
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   805
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   806
    cmd = args[0]
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   807
    try:
29132
12769703d4ba dispatch: always load extensions before running shell aliases (issue5230)
Jun Wu <quark@fb.com>
parents: 29129
diff changeset
   808
        strict = ui.configbool("ui", "strict")
22377
f98abe3146b2 dispatch: check shell alias again after loading extensions (issue4355)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22376
diff changeset
   809
        aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
12932
ab93029ab622 alias: fall back to normal error handling for ambigious commands (fixes issue2475)
Steve Losh <steve@stevelosh.com>
parents: 12831
diff changeset
   810
    except (error.AmbiguousCommand, error.UnknownCommand):
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   811
        return
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   812
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   813
    cmd = aliases[0]
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   814
    fn = entry[0]
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   815
14950
144e97421f6b dispatch: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14918
diff changeset
   816
    if cmd and util.safehasattr(fn, 'shell'):
35034
02845f7441af dispatch: verify result of early command parsing
Yuya Nishihara <yuya@tcha.org>
parents: 35033
diff changeset
   817
        # shell alias shouldn't receive early options which are consumed by hg
35225
7ce0ba3a1c32 dispatch: replace _earlygetopt(strip=True) with new parser
Yuya Nishihara <yuya@tcha.org>
parents: 35224
diff changeset
   818
        _earlyopts, args = _earlysplitopts(args)
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   819
        d = lambda: fn(ui, *args[1:])
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16609
diff changeset
   820
        return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16609
diff changeset
   821
                                  [], {})
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   822
14439
80c599eee3f3 dispatch: use the request to store the ui object
Idan Kamara <idankk86@gmail.com>
parents: 14438
diff changeset
   823
def _dispatch(req):
14438
08bfec2ef031 dispatch: wrap dispatch related information in a request class
Idan Kamara <idankk86@gmail.com>
parents: 14286
diff changeset
   824
    args = req.args
14439
80c599eee3f3 dispatch: use the request to store the ui object
Idan Kamara <idankk86@gmail.com>
parents: 14438
diff changeset
   825
    ui = req.ui
80c599eee3f3 dispatch: use the request to store the ui object
Idan Kamara <idankk86@gmail.com>
parents: 14438
diff changeset
   826
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   827
    # check for cwd
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   828
    cwd = req.earlyoptions['cwd']
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   829
    if cwd:
35033
d3d35a55e03b dispatch: convert non-list option parsed by _earlygetopt() to string
Yuya Nishihara <yuya@tcha.org>
parents: 35032
diff changeset
   830
        os.chdir(cwd)
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   831
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   832
    rpath = req.earlyoptions['repository']
12536
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   833
    path, lui = _getlocal(ui, rpath)
208fc9ad6a48 alias: only allow global options before a shell alias, pass later ones through
Steve Losh <steve@stevelosh.com>
parents: 12276
diff changeset
   834
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32158
diff changeset
   835
    uis = {ui, lui}
30933
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   836
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   837
    if req.repo:
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   838
        uis.add(req.repo.ui)
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   839
38534
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   840
    if (req.earlyoptions['verbose'] or req.earlyoptions['debug']
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   841
            or req.earlyoptions['quiet']):
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   842
        for opt in ('verbose', 'debug', 'quiet'):
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   843
            val = pycompat.bytestr(bool(req.earlyoptions[opt]))
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   844
            for ui_ in uis:
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   845
                ui_.setconfig('ui', opt, val, '--' + opt)
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   846
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
   847
    if req.earlyoptions['profile']:
30933
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   848
        for ui_ in uis:
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   849
            ui_.setconfig('profiling', 'enabled', 'true', '--profile')
69a3c6c8bf95 dispatch: move detection of profiling earlier during startup
Bryan O'Sullivan <bryano@fb.com>
parents: 30917
diff changeset
   850
32788
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32787
diff changeset
   851
    profile = lui.configbool('profiling', 'enabled')
eede022fc142 profile: drop maybeprofile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32787
diff changeset
   852
    with profiling.profile(lui, enabled=profile) as profiler:
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   853
        # Configure extensions in phases: uisetup, extsetup, cmdtable, and
33053
ef46d432e2e4 dispatch: remove unused _loaded
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33052
diff changeset
   854
        # reposetup
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   855
        extensions.loadall(lui)
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   856
        # Propagate any changes to lui.__class__ by extensions
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   857
        ui.__class__ = lui.__class__
5828
863e237b58fb dispatch: allow extensions to provide setup code
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5664
diff changeset
   858
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   859
        # (uisetup and extsetup are handled in extensions.loadall)
5828
863e237b58fb dispatch: allow extensions to provide setup code
Kirill Smelkov <kirr@mns.spb.ru>
parents: 5664
diff changeset
   860
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   861
        # (reposetup is handled in hg.repository)
9410
1c83938b6a8e extensions: load and configure extensions in well-defined phases
Martin Geisler <mg@lazybytes.net>
parents: 8936
diff changeset
   862
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   863
        addaliases(lui, commands.table)
8655
21688b8a594b Move alias into core
Brendan Cully <brendan@kublai.com>
parents: 8304
diff changeset
   864
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   865
        # All aliases and commands are completely defined, now.
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   866
        # Check abbreviation/ambiguity of shell alias.
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   867
        shellaliasfn = _checkshellalias(lui, ui, args)
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   868
        if shellaliasfn:
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   869
            # no additional configs will be set, set up the ui instances
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   870
            for ui_ in uis:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   871
                extensions.populateui(ui_)
30006
b19c2679289c dispatch: make hg --profile wrap reposetup
Arun Kulshreshtha <kulshrax@fb.com>
parents: 30005
diff changeset
   872
            return shellaliasfn()
22377
f98abe3146b2 dispatch: check shell alias again after loading extensions (issue4355)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22376
diff changeset
   873
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   874
        # check for fallback encoding
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   875
        fallback = lui.config('ui', 'fallbackencoding')
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   876
        if fallback:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   877
            encoding.fallbackencoding = fallback
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   878
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   879
        fullargs = args
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   880
        cmd, func, args, options, cmdoptions = _parse(lui, args)
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   881
40402
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
   882
        # store the canonical command name in request object for later access
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
   883
        req.canonical_command = cmd
106adc261492 logtoprocess: sends the canonical command name to the subprocess
Boris Feld <boris.feld@octobus.net>
parents: 39818
diff changeset
   884
35034
02845f7441af dispatch: verify result of early command parsing
Yuya Nishihara <yuya@tcha.org>
parents: 35033
diff changeset
   885
        if options["config"] != req.earlyoptions["config"]:
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   886
            raise error.Abort(_("option --config may not be abbreviated!"))
35034
02845f7441af dispatch: verify result of early command parsing
Yuya Nishihara <yuya@tcha.org>
parents: 35033
diff changeset
   887
        if options["cwd"] != req.earlyoptions["cwd"]:
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   888
            raise error.Abort(_("option --cwd may not be abbreviated!"))
35034
02845f7441af dispatch: verify result of early command parsing
Yuya Nishihara <yuya@tcha.org>
parents: 35033
diff changeset
   889
        if options["repository"] != req.earlyoptions["repository"]:
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   890
            raise error.Abort(_(
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   891
                "option -R has to be separated from other options (e.g. not "
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   892
                "-qR) and --repository may only be abbreviated as --repo!"))
35030
d9aba3730d30 dispatch: abort if early boolean options can't be parsed
Yuya Nishihara <yuya@tcha.org>
parents: 35029
diff changeset
   893
        if options["debugger"] != req.earlyoptions["debugger"]:
d9aba3730d30 dispatch: abort if early boolean options can't be parsed
Yuya Nishihara <yuya@tcha.org>
parents: 35029
diff changeset
   894
            raise error.Abort(_("option --debugger may not be abbreviated!"))
d9aba3730d30 dispatch: abort if early boolean options can't be parsed
Yuya Nishihara <yuya@tcha.org>
parents: 35029
diff changeset
   895
        # don't validate --profile/--traceback, which can be enabled from now
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   896
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   897
        if options["encoding"]:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   898
            encoding.encoding = options["encoding"]
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   899
        if options["encodingmode"]:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   900
            encoding.encodingmode = options["encodingmode"]
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   901
        if options["time"]:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   902
            def get_times():
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   903
                t = os.times()
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   904
                if t[4] == 0.0:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   905
                    # Windows leaves this as zero, so use time.clock()
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   906
                    t = (t[0], t[1], t[2], t[3], time.clock())
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   907
                return t
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   908
            s = get_times()
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   909
            def print_time():
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   910
                t = get_times()
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   911
                ui.warn(
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   912
                    _("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   913
                    (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
31958
de5c9d0e02ea atexit: switch to home-grown implementation
Bryan O'Sullivan <bryano@fb.com>
parents: 31956
diff changeset
   914
            ui.atexit(print_time)
32787
545f69cd6042 profile: support --profile in alias and abbreviated version (--prof)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32687
diff changeset
   915
        if options["profile"]:
545f69cd6042 profile: support --profile in alias and abbreviated version (--prof)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32687
diff changeset
   916
            profiler.start()
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   917
38534
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   918
        # if abbreviated version of this were used, take them in account, now
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   919
        if options['verbose'] or options['debug'] or options['quiet']:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   920
            for opt in ('verbose', 'debug', 'quiet'):
38534
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   921
                if options[opt] == req.earlyoptions[opt]:
b86664c81833 debug: process --debug flag earlier
Boris Feld <boris.feld@octobus.net>
parents: 38110
diff changeset
   922
                    continue
35898
a2b3b5c5a25a py3: replace "if ispy3" by pycompat.bytestr()
Yuya Nishihara <yuya@tcha.org>
parents: 35653
diff changeset
   923
                val = pycompat.bytestr(bool(options[opt]))
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   924
                for ui_ in uis:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   925
                    ui_.setconfig('ui', opt, val, '--' + opt)
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   926
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   927
        if options['traceback']:
14752
99ace3cb7352 dispatch: set global options on the request repo.ui
Idan Kamara <idankk86@gmail.com>
parents: 14748
diff changeset
   928
            for ui_ in uis:
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   929
                ui_.setconfig('ui', 'traceback', 'on', '--traceback')
14992
188936b334b1 dispatch: make sure global options on the command line take precedence
Idan Kamara <idankk86@gmail.com>
parents: 14914
diff changeset
   930
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   931
        if options['noninteractive']:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   932
            for ui_ in uis:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   933
                ui_.setconfig('ui', 'interactive', 'off', '-y')
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   934
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   935
        if cmdoptions.get('insecure', False):
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   936
            for ui_ in uis:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   937
                ui_.insecureconnections = True
13328
a939f08fae9c url: add --insecure option to bypass verification of ssl certificates
Yuya Nishihara <yuya@tcha.org>
parents: 12932
diff changeset
   938
32383
f928d53b687c dispatch: setup color before pager for correct console information on windows
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32054
diff changeset
   939
        # setup color handling before pager, because setting up pager
f928d53b687c dispatch: setup color before pager for correct console information on windows
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32054
diff changeset
   940
        # might cause incorrect console information
31110
7fec37746417 color: add a 'ui.color' option to control color behavior
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31105
diff changeset
   941
        coloropt = options['color']
31105
45be7590301d color: move triggering of the initialisation logic in core
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31060
diff changeset
   942
        for ui_ in uis:
31110
7fec37746417 color: add a 'ui.color' option to control color behavior
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31105
diff changeset
   943
            if coloropt:
7fec37746417 color: add a 'ui.color' option to control color behavior
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31105
diff changeset
   944
                ui_.setconfig('ui', 'color', coloropt, '--color')
7fec37746417 color: add a 'ui.color' option to control color behavior
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31105
diff changeset
   945
            color.setup(ui_)
31105
45be7590301d color: move triggering of the initialisation logic in core
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31060
diff changeset
   946
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
   947
        if stringutil.parsebool(options['pager']):
33620
cc047a733f69 ui: enable pager always for explicit --pager=on (issue5580)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33499
diff changeset
   948
            # ui.pager() expects 'internal-always-' prefix in this case
32383
f928d53b687c dispatch: setup color before pager for correct console information on windows
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32054
diff changeset
   949
            ui.pager('internal-always-' + cmd)
f928d53b687c dispatch: setup color before pager for correct console information on windows
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32054
diff changeset
   950
        elif options['pager'] != 'auto':
34638
021607b4ef49 dispatch: when --pager=no is passed, also disable pager on req.repo.ui
Jun Wu <quark@fb.com>
parents: 34533
diff changeset
   951
            for ui_ in uis:
021607b4ef49 dispatch: when --pager=no is passed, also disable pager on req.repo.ui
Jun Wu <quark@fb.com>
parents: 34533
diff changeset
   952
                ui_.disablepager()
32383
f928d53b687c dispatch: setup color before pager for correct console information on windows
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32054
diff changeset
   953
40729
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   954
        # configs are fully loaded, set up the ui instances
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   955
        for ui_ in uis:
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   956
            extensions.populateui(ui_)
c93d046d4300 extensions: add "uipopulate" hook, called per instance, not per process
Yuya Nishihara <yuya@tcha.org>
parents: 40651
diff changeset
   957
30934
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   958
        if options['version']:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   959
            return commands.version_(ui)
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   960
        if options['help']:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   961
            return commands.help_(ui, cmd, command=cmd is not None)
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   962
        elif not cmd:
6d642ecf1a89 dispatch: start profiling earlier
Bryan O'Sullivan <bryano@fb.com>
parents: 30933
diff changeset
   963
            return commands.help_(ui, 'shortlist')
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   964
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   965
        repo = None
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   966
        cmdpats = args[:]
30485
acd30a959980 dispatch: stop supporting non-use of @command
Augie Fackler <augie@google.com>
parents: 30473
diff changeset
   967
        if not func.norepo:
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   968
            # use the repo from the request only if we don't have -R
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   969
            if not rpath and not cwd:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   970
                repo = req.repo
14510
eccbb9980ada dispatch: add repo to the request
Idan Kamara <idankk86@gmail.com>
parents: 14439
diff changeset
   971
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   972
            if repo:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   973
                # set the descriptors of the repo ui to those of ui
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   974
                repo.ui.fin = ui.fin
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   975
                repo.ui.fout = ui.fout
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   976
                repo.ui.ferr = ui.ferr
40587
5542bc9125c9 dispatch: pass around ui.fmsg channel
Yuya Nishihara <yuya@tcha.org>
parents: 40414
diff changeset
   977
                repo.ui.fmsg = ui.fmsg
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   978
            else:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   979
                try:
32379
71e735bd8170 dispatch: make request accept additional reposetups
Jun Wu <quark@fb.com>
parents: 32377
diff changeset
   980
                    repo = hg.repository(ui, path=path,
37717
0664be4f0c1f hg: pass command intents to repo/peer creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37716
diff changeset
   981
                                         presetupfuncs=req.prereposetups,
0664be4f0c1f hg: pass command intents to repo/peer creation (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37716
diff changeset
   982
                                         intents=func.intents)
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   983
                    if not repo.local():
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   984
                        raise error.Abort(_("repository '%s' is not local")
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   985
                                          % path)
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   986
                    repo.ui.setconfig("bundle", "mainreporoot", repo.root,
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   987
                                      'repo')
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   988
                except error.RequirementError:
26142
7332bf4ae959 dispatch: error out on invalid -R path even if optionalrepo (issue4805) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 25932
diff changeset
   989
                    raise
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   990
                except error.RepoError:
35033
d3d35a55e03b dispatch: convert non-list option parsed by _earlygetopt() to string
Yuya Nishihara <yuya@tcha.org>
parents: 35032
diff changeset
   991
                    if rpath: # invalid -R path
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   992
                        raise
30485
acd30a959980 dispatch: stop supporting non-use of @command
Augie Fackler <augie@google.com>
parents: 30473
diff changeset
   993
                    if not func.optionalrepo:
acd30a959980 dispatch: stop supporting non-use of @command
Augie Fackler <augie@google.com>
parents: 30473
diff changeset
   994
                        if func.inferrepo and args and not path:
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   995
                            # try to infer -R from command args
35149
e6487522ef92 py3: use pycompat.maplist() instead of map()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35145
diff changeset
   996
                            repos = pycompat.maplist(cmdutil.findrepo, args)
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   997
                            guess = repos[0]
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   998
                            if guess and repos.count(guess) == len(repos):
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
   999
                                req.args = ['--repository', guess] + fullargs
35224
6e6d0a5b88e6 dispatch: replace _earlyreq*() with new fancyopts-based parser
Yuya Nishihara <yuya@tcha.org>
parents: 35223
diff changeset
  1000
                                req.earlyoptions['repository'] = guess
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1001
                                return _dispatch(req)
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1002
                        if not path:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1003
                            raise error.RepoError(_("no repository found in"
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1004
                                                    " '%s' (.hg not found)")
39818
24e493ec2229 py3: rename pycompat.getcwd() to encoding.getcwd() (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39512
diff changeset
  1005
                                                  % encoding.getcwd())
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1006
                        raise
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1007
            if repo:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1008
                ui = repo.ui
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1009
                if options['hidden']:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1010
                    repo = repo.unfiltered()
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1011
            args.insert(0, repo)
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1012
        elif rpath:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1013
            ui.warn(_("warning: --repository ignored\n"))
7388
5751631246de dispatch: generalize signature checking for extension command wrapping
Matt Mackall <mpm@selenic.com>
parents: 7280
diff changeset
  1014
31492
3c77414a0f9c dispatch: consolidate formatting of arguments
Augie Fackler <augie@google.com>
parents: 31491
diff changeset
  1015
        msg = _formatargs(fullargs)
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1016
        ui.log("command", '%s\n', msg)
30586
2d555d753f0e py3: make keys of keyword arguments strings
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30576
diff changeset
  1017
        strcmdopt = pycompat.strkwargs(cmdoptions)
2d555d753f0e py3: make keys of keyword arguments strings
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30576
diff changeset
  1018
        d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
30005
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1019
        try:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1020
            return runcommand(lui, repo, cmd, fullargs, ui, options, d,
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1021
                              cmdpats, cmdoptions)
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1022
        finally:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1023
            if repo and repo != req.repo:
dfd97e60044c dispatch: change indentation level in _dispatch()
Arun Kulshreshtha <kulshrax@fb.com>
parents: 29884
diff changeset
  1024
                repo.close()
5178
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1025
18a9fbb5cd78 dispatch: move command dispatching into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1026
def _runcommand(ui, options, cmd, cmdfunc):
29784
e3501546f7e4 profiling: add a context manager that no-ops if profiling isn't enabled
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29783
diff changeset
  1027
    """Run a command function, possibly with profiling enabled."""
30006
b19c2679289c dispatch: make hg --profile wrap reposetup
Arun Kulshreshtha <kulshrax@fb.com>
parents: 30005
diff changeset
  1028
    try:
39512
ec0a2601bc76 tracing: trace command function execution
Boris Feld <boris.feld@octobus.net>
parents: 39255
diff changeset
  1029
        with tracing.log("Running %s command" % cmd):
ec0a2601bc76 tracing: trace command function execution
Boris Feld <boris.feld@octobus.net>
parents: 39255
diff changeset
  1030
            return cmdfunc()
30006
b19c2679289c dispatch: make hg --profile wrap reposetup
Arun Kulshreshtha <kulshrax@fb.com>
parents: 30005
diff changeset
  1031
    except error.SignatureError:
b19c2679289c dispatch: make hg --profile wrap reposetup
Arun Kulshreshtha <kulshrax@fb.com>
parents: 30005
diff changeset
  1032
        raise error.CommandError(cmd, _('invalid arguments'))
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1033
28821
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1034
def _exceptionwarning(ui):
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1035
    """Produce a warning message for the current active exception"""
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1036
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1037
    # For compatibility checking, we discard the portion of the hg
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1038
    # version after the + on the assumption that if a "normal
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1039
    # user" is running a build with a + in it the packager
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1040
    # probably built from fairly close to a tag and anyone with a
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1041
    # 'make local' copy of hg (where the version number can be out
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1042
    # of date) will be clueful enough to notice the implausible
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1043
    # version number and try updating.
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1044
    ct = util.versiontuple(n=2)
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1045
    worst = None, ct, ''
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33053
diff changeset
  1046
    if ui.config('ui', 'supportcontact') is None:
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1047
        for name, mod in extensions.extensions():
35899
d5457d94e1c9 py3: replace "if ispy3" by pycompat.sysbytes() or util.forcebytestr()
Yuya Nishihara <yuya@tcha.org>
parents: 35898
diff changeset
  1048
            # 'testedwith' should be bytes, but not all extensions are ported
d5457d94e1c9 py3: replace "if ispy3" by pycompat.sysbytes() or util.forcebytestr()
Yuya Nishihara <yuya@tcha.org>
parents: 35898
diff changeset
  1049
            # to py3 and we don't want UnicodeException because of that.
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
  1050
            testedwith = stringutil.forcebytestr(getattr(mod, 'testedwith', ''))
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1051
            report = getattr(mod, 'buglink', _('the extension author.'))
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1052
            if not testedwith.strip():
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1053
                # We found an untested extension. It's likely the culprit.
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1054
                worst = name, 'unknown', report
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1055
                break
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1056
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1057
            # Never blame on extensions bundled with Mercurial.
29884
ed793f41e83f extensions: use ismoduleinternal() thoroughly
Yuya Nishihara <yuya@tcha.org>
parents: 29846
diff changeset
  1058
            if extensions.ismoduleinternal(mod):
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1059
                continue
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1060
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1061
            tested = [util.versiontuple(t, 2) for t in testedwith.split()]
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1062
            if ct in tested:
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1063
                continue
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1064
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1065
            lower = [t for t in tested if t < ct]
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1066
            nearest = max(lower or tested)
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1067
            if worst[0] is None or nearest < worst[1]:
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1068
                worst = name, nearest, report
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1069
    if worst[0] is not None:
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1070
        name, testedwith, report = worst
31179
49ad6bf63107 dispatch: allow testedwith to be bytes or str
Augie Fackler <raf@durin42.com>
parents: 31110
diff changeset
  1071
        if not isinstance(testedwith, (bytes, str)):
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
  1072
            testedwith = '.'.join([stringutil.forcebytestr(c)
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36729
diff changeset
  1073
                                   for c in testedwith])
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1074
        warning = (_('** Unknown exception encountered with '
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1075
                     'possibly-broken third-party extension %s\n'
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1076
                     '** which supports versions %s of Mercurial.\n'
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1077
                     '** Please disable %s and try your action again.\n'
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1078
                     '** If that fixes the bug please report it to %s\n')
38025
5046c906b25d py3: convert the report to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 38023
diff changeset
  1079
                   % (name, testedwith, name, stringutil.forcebytestr(report)))
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1080
    else:
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33053
diff changeset
  1081
        bugtracker = ui.config('ui', 'supportcontact')
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1082
        if bugtracker is None:
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1083
            bugtracker = _("https://mercurial-scm.org/wiki/BugTracker")
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1084
        warning = (_("** unknown exception encountered, "
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1085
                     "please report by visiting\n** ") + bugtracker + '\n')
35899
d5457d94e1c9 py3: replace "if ispy3" by pycompat.sysbytes() or util.forcebytestr()
Yuya Nishihara <yuya@tcha.org>
parents: 35898
diff changeset
  1086
    sysversion = pycompat.sysbytes(sys.version).replace('\n', '')
31180
27e3b66ec7c5 dispatch: cope with sys.version being unicode on Python 3
Augie Fackler <raf@durin42.com>
parents: 31179
diff changeset
  1087
    warning += ((_("** Python %s\n") % sysversion) +
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1088
                (_("** Mercurial Distributed SCM (version %s)\n") %
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1089
                 util.version()) +
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1090
                (_("** Extensions loaded: %s\n") %
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1091
                 ", ".join([x[0] for x in extensions.extensions()])))
28821
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1092
    return warning
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1093
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1094
def handlecommandexception(ui):
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1095
    """Produce a warning message for broken commands
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1096
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1097
    Called when handling an exception; the exception is reraised if
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1098
    this function returns False, ignored otherwise.
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1099
    """
d3369dc6c1d0 dispatch: split out warning message generation to separate function
Martijn Pieters <mjpieters@fb.com>
parents: 28784
diff changeset
  1100
    warning = _exceptionwarning(ui)
36124
976a9fd706ed py3: convert traceback representation to bytes when logging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35942
diff changeset
  1101
    ui.log("commandexception", "%s\n%s\n", warning,
976a9fd706ed py3: convert traceback representation to bytes when logging
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35942
diff changeset
  1102
           pycompat.sysbytes(traceback.format_exc()))
28784
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1103
    ui.warn(warning)
09750b1231c2 dispatch: factor out command failure handling into a function
Martijn Pieters <mjpieters@fb.com>
parents: 28695
diff changeset
  1104
    return False  # re-raise the exception